index

Quantization, Visualized: Rounding, Outliers, Memory, and Speed

A 4-bit weight occupies half a byte before metadata. That fact tells us neither how much quality a model retains nor how quickly a device can execute it. Those outcomes depend on which values share a scale, how the rounding errors interact with inputs, and what the runtime does with the compressed representation.

Quantization has a simple numerical core. The complexity comes from applying it to an entire inference system. The six experiments below follow that path, beginning with one scalar and ending with a memory and runtime budget.

Every chart uses deterministic teaching data or an explicit analytical model. None presents measured model accuracy, perplexity, or device performance. The low-precision architecture article discusses architectural choices; this article makes the arithmetic behind them inspectable.

A scale gives integer codes a meaning

An affine quantizer represents a real value with an integer code qq, a positive scale ss, and an integer zero point zz:

q=clip⁡(round⁡(x/s)+z,  qmin⁡,  qmax⁡),x^=s(q−z)q=\operatorname{clip}\left( \operatorname{round}(x/s)+z,\;q_{\min},\;q_{\max} \right),\qquad \hat x=s(q-z)

The stored code only becomes an approximate real value after decoding. Jacob and colleagues describe this affine representation and how integer arithmetic can carry it through neural-network inference.1

For the first experiments, use a simpler symmetric convention with z=0z=0. A bb-bit code uses the integers from −Q-Q through QQ, where:

Q=2b−1−1,s=c/QQ=2^{b-1}-1,\qquad s=c/Q

The clipping bound is cc. This convention leaves one signed code unused, so 4 bits provide fifteen decoded levels, including zero. Other formats can use a different code range or codebook. The visualization states its convention because changing that convention changes the arithmetic.

01 / Watch continuous values become discrete levels

Change the bit width, then move the input. The solid staircase is the decoded value; the dashed line is exact identity.

Decoded value against Input value. Exact; Decoded; Selected input.-2.2-2-0.7-0.70.70.72.22Decoded valueInput valueSelected input: 0.571 at 0.65
Scale / step
0.2857
Integer code
2
Decoded
0.5714

15 symmetric levels; one signed code is unused. Absolute error 0.0786. Rounding ties go away from zero.

Try 2 bits, then move the input slowly around zero. The decoded value stays fixed before jumping to the next level. More bits make the steps smaller without changing the clipping range.

Inside the unclipped range, nearest rounding gives absolute error at most s/2s/2. The experiment rounds exact ties away from zero. Production implementations can use other tie-breaking rules, so bit-for-bit reproduction requires matching the rounding rule too.

An outlier spends the range on itself

With one shared symmetric scale, the largest absolute value determines the step size if the quantizer covers the entire range. Most values may occupy only a small part of that range.

The next example contains sixty-three moderate values and one value at eight. At 4 bits, covering the outlier requires a step of 8/78/7, which is larger than many ordinary values in the example. Some of those values round to zero.

02 / Trade rounding error against clipping error

A deterministic 64-value example has one outlier at 8. Open circles are original values; crosses are their low-bit reconstructions.

Weight value against Weight index. Original; Decoded.-1.202215.3428.563Weight valueWeight indexOriginal: 0.24 at 0Original: 0.908 at 1Original: -0.037 at 2Original: -0.61 at 3Original: 0.273 at 4Original: 0.39 at 5Original: -0.718 at 6Original: -0.67 at 7Original: 0.406 at 8Original: 0.166 at 9Original: -0.676 at 10Original: 0.002 at 11Original: 0.892 at 12Original: 0.16 at 13Original: -0.451 at 14Original: 0.424 at 15Original: 0.694 at 16Original: -0.442 at 17Original: -0.647 at 18Original: 0.33 at 19Original: 0.13 at 20Original: -0.853 at 21Original: -0.353 at 22Original: 0.646 at 23Original: 0.096 at 24Original: -0.533 at 25Original: 0.377 at 26Original: 0.896 at 27Original: -0.122 at 28Original: -0.459 at 29Original: 0.478 at 30Original: 0.354 at 31Original: -0.775 at 32Original: -0.539 at 33Original: 0.433 at 34Original: -0.045 at 35Original: -0.783 at 36Original: 0.074 at 37Original: 0.818 at 38Original: -0.016 at 39Original: -0.389 at 40Original: 0.606 at 41Original: 0.68 at 42Original: -0.473 at 43Original: -0.456 at 44Original: 0.464 at 45Original: 0.01 at 46Original: -0.923 at 47Original: -0.259 at 48Original: 0.577 at 49Original: -0.138 at 50Original: -0.572 at 51Original: 0.48 at 52Original: 0.825 at 53Original: -0.215 at 54Original: -0.295 at 55Original: 0.66 at 56Original: 0.308 at 57Original: -0.782 at 58Original: -0.366 at 59Original: 0.457 at 60Original: -0.241 at 61Original: -0.847 at 62Original: 8 at 63Decoded: 0 at 0Decoded: 1.143 at 1Decoded: 0 at 2Decoded: -1.143 at 3Decoded: 0 at 4Decoded: 0 at 5Decoded: -1.143 at 6Decoded: -1.143 at 7Decoded: 0 at 8Decoded: 0 at 9Decoded: -1.143 at 10Decoded: 0 at 11Decoded: 1.143 at 12Decoded: 0 at 13Decoded: 0 at 14Decoded: 0 at 15Decoded: 1.143 at 16Decoded: 0 at 17Decoded: -1.143 at 18Decoded: 0 at 19Decoded: 0 at 20Decoded: -1.143 at 21Decoded: 0 at 22Decoded: 1.143 at 23Decoded: 0 at 24Decoded: 0 at 25Decoded: 0 at 26Decoded: 1.143 at 27Decoded: 0 at 28Decoded: 0 at 29Decoded: 0 at 30Decoded: 0 at 31Decoded: -1.143 at 32Decoded: 0 at 33Decoded: 0 at 34Decoded: 0 at 35Decoded: -1.143 at 36Decoded: 0 at 37Decoded: 1.143 at 38Decoded: 0 at 39Decoded: 0 at 40Decoded: 1.143 at 41Decoded: 1.143 at 42Decoded: 0 at 43Decoded: 0 at 44Decoded: 0 at 45Decoded: 0 at 46Decoded: -1.143 at 47Decoded: 0 at 48Decoded: 1.143 at 49Decoded: 0 at 50Decoded: -1.143 at 51Decoded: 0 at 52Decoded: 1.143 at 53Decoded: 0 at 54Decoded: 0 at 55Decoded: 1.143 at 56Decoded: 0 at 57Decoded: -1.143 at 58Decoded: 0 at 59Decoded: 0 at 60Decoded: 0 at 61Decoded: -1.143 at 62Decoded: 8 at 63

○ Original · × Quantized

Clipped values
0
All-value MSE
0.1338
Non-outlier MSE
0.1359

Lower bounds can improve small values while clipping the outlier. The total MSE includes that clipped value.

Lower the clipping bound. The smaller values receive finer steps, but the outlier can no longer be represented. Its error increases as the bound shrinks. Compare the total mean squared error with the error calculated only over the non-outlier values.

Neither average is a universal quality metric. If the outlier carries an important computation, accepting a large error there can be costly even when most values improve. If it barely affects the deployed task, preserving it perfectly may be a poor use of the available levels.

Calibration is how a quantizer estimates which ranges and inputs matter. A calibration corpus with short English prose may give a weak picture of long-context code or another language. Pin its provenance and evaluate on held-out workloads that resemble deployment.

A group scale localizes the damage

Per-tensor quantization shares a scale widely. Per-channel and group-wise quantization reduce the number of values competing for that range. An outlier then affects fewer neighbors.

03 / Limit how many values share an outlier’s scale

Each bar is one weight’s absolute reconstruction error. Groups use their own maximum absolute value and one FP16 scale.

Absolute error for each of 64 weights, with dashed group boundaries.Absolute error0.660Weight 0: error 0.0195Weight 1: error 0Weight 2: error 0.0373Weight 3: error 0.039Weight 4: error 0.0134Weight 5: error 0.0011Weight 6: error 0.0608Weight 7: error 0.0214Weight 8: error 0.0167Weight 9: error 0.0366Weight 10: error 0.0273Weight 11: error 0.0017Weight 12: error 0.0162Weight 13: error 0.0306Weight 14: error 0.0615Weight 15: error 0.035Weight 16: error 0.0538Weight 17: error 0.0583Weight 18: error 0.0062Weight 19: error 0.0541Weight 20: error 0.0024Weight 21: error 0.0431Weight 22: error 0.0316Weight 23: error 0.0053Weight 24: error 0.0322Weight 25: error 0.0206Weight 26: error 0.0073Weight 27: error 0Weight 28: error 0.0062Weight 29: error 0.0532Weight 30: error 0.0342Weight 31: error 0.0301Weight 32: error 0.0167Weight 33: error 0.0113Weight 34: error 0.0377Weight 35: error 0.0445Weight 36: error 0.0085Weight 37: error 0.0576Weight 38: error 0.0267Weight 39: error 0.0162Weight 40: error 0.0069Weight 41: error 0.0539Weight 42: error 0.0204Weight 43: error 0.0549Weight 44: error 0.0601Weight 45: error 0.0632Weight 46: error 0.0097Weight 47: error 0Weight 48: error 0.2591Weight 49: error 0.5654Weight 50: error 0.1381Weight 51: error 0.5707Weight 52: error 0.4799Weight 53: error 0.3174Weight 54: error 0.2149Weight 55: error 0.2951Weight 56: error 0.4828Weight 57: error 0.3083Weight 58: error 0.361Weight 59: error 0.3656Weight 60: error 0.457Weight 61: error 0.2407Weight 62: error 0.2959Weight 63: error 0063Weight index
Scale overhead
1 bits/weight
All-value MSE
0.0344
Non-outlier MSE
0.0349

One outlier shares a scale with 15 neighbors. Smaller groups cost more scale bytes.

Set the group size to sixty-four, then reduce it. The final weight remains an outlier, but the scale it forces no longer applies to every other weight. The bars show actual reconstruction errors for this fixed vector; they do not estimate language-model accuracy.

The cost is metadata. With bb code bits and one sbs_b-bit scale per group of gg weights, the nominal effective rate is:

beffective=b+sbgb_{\mathrm{effective}}=b+\frac{s_b}{g}

At 4 bits with one FP16 scale per 128 weights, this is 4.1254.125 bits per weight. Add another sixteen bits per group for a zero point and it becomes 4.254.25. A particular format may use quantized scales, shared exponents, mixed tensor types, or additional headers. Count its actual representation.

This arithmetic explains why two files both described as “4-bit” can have different sizes. It also explains why reducing group size has a visible cost at low precision: metadata consumes a larger fraction of the remaining bytes.

Preserve the product while changing the ranges

For a layer Y=XWY=XW, introduce an invertible diagonal channel-scaling matrix SS:

Y=(XS−1)(SW)Y=(XS^{-1})(SW)

The exact product is unchanged. The two operands now have different numerical ranges. SmoothQuant uses this equivalence to move quantization difficulty from activations into weights before low-precision execution.2

04 / Move range between activations and weights

Four invented channel maxima. Rescaling changes each side of a product while preserving the exact dot product.

Comparison in Magnitude. Ch 1 · X′: 0.87; Ch 1 · W′: 0.87; Ch 2 · X′: 0.75; Ch 2 · W′: 0.75; Ch 3 · X′: 1.41; Ch 3 · W′: 1.41; Ch 4 · X′: 1.73; Ch 4 · W′: 1.73.MagnitudeCh 1 · X′Ch 1 · X′: 0.866 Magnitude0.87Ch 1 · W′Ch 1 · W′: 0.866 Magnitude0.87Ch 2 · X′Ch 2 · X′: 0.748 Magnitude0.75Ch 2 · W′Ch 2 · W′: 0.748 Magnitude0.75Ch 3 · X′Ch 3 · X′: 1.414 Magnitude1.41Ch 3 · W′Ch 3 · W′: 1.414 Magnitude1.41Ch 4 · X′Ch 4 · X′: 1.732 Magnitude1.73Ch 4 · W′Ch 4 · W′: 1.732 Magnitude1.73
Exact dot product
6.31
4-bit dot product
6.49
Absolute error
0.18

Solid bars: rescaled activations. Outlined bars: rescaled weights. Each side uses one symmetric 4-bit scale. This is a toy, not a SmoothQuant reproduction.

The experiment uses four invented channels and a single test vector. Its scaling rule is:

si=aiαwi1−αs_i=\frac{a_i^\alpha}{w_i^{1-\alpha}}

Here aia_i and wiw_i are the positive channel magnitudes shown in the toy. Changing α\alpha shifts the burden between the operands. The exact dot product stays at 6.316.31; independently quantizing the rescaled operands changes the approximate product.

This is a numerical demonstration of the equivalence, not a reproduction of SmoothQuant calibration or its reported W8A8 results. A full implementation must collect channel statistics, handle zero ranges, fold transformations where valid, and match the runtime’s quantizers.

Weight-only methods make different choices. GPTQ approximately minimizes layer-output reconstruction error using second-order information from calibration inputs.3 AWQ uses activation information to identify important weight channels and searches channel scalings that reduce quantization error.4 Neither method is adequately described by choosing the nearest integer for each weight in isolation.

To see why, let ΔW\Delta W be weight error for a linear layer. On an input xx:

Δy=ΔWx\Delta y=\Delta W x

Two weight-error matrices with the same norm can produce different output errors on the input distribution. Evaluating only the stored weights omits the inputs that multiply them.

The model file is one part of resident memory

For NN parameters at bb bits, Nb/8Nb/8 is the code payload in bytes. It excludes scales, higher-precision tensors, the KV cache, and runtime buffers.

For a conventional decoder with a full-context cache, the KV tensor estimate is:

MKV=2LHKVdh sKV T BM_{\mathrm{KV}}=2LH_{\mathrm{KV}}d_h\,s_{\mathrm{KV}}\,T\,B

The factors are layers, KV heads, head width, bytes per cached scalar, tokens per sequence, and concurrent sequences. The leading two counts keys and values. The KV-cache guide covers architectures and allocation strategies that change this estimate.

05 / Count the bytes beyond the weight codes

A derived footprint for a hypothetical decoder. The model has 32 layers, 8 KV heads, head width 128, an FP16 cache, and 1 GiB of workspace.

Comparison in GiB, shared scale. Weight codes: 3.69; FP16 scales: 0.12; Retained FP16: 0.15; KV cache: 1; Workspace: 1.GiB, shared scaleWeight codesWeight codes: 3.688 GiB, shared scale3.69FP16 scalesFP16 scales: 0.115 GiB, shared scale0.12Retained FP16Retained FP16: 0.149 GiB, shared scale0.15KV cacheKV cache: 1 GiB, shared scale1WorkspaceWorkspace: 1 GiB, shared scale1
Total resident estimate
5.95 GiB
Stored weight payload
3.95 GiB
Effective weight bits
4.244

Assumes 1% of weights stay FP16 and one FP16 scale per group for the rest. No zero points, packing padding, fragmentation, or offload. Cache geometry stays fixed when parameters change.

Increase context length or concurrent requests after reducing the weight bits. The cache can consume the memory saved by weight compression. Weight-only quantization leaves cache precision unchanged unless the deployment separately configures cache quantization.

The calculator reserves one percent of weights at FP16 and one GiB for workspace. Those are illustrative assumptions. It holds cache geometry fixed as parameter count changes, so it explores a memory budget rather than predicting a specific model family’s architecture. Allocator fragmentation, packing padding, temporary buffers, and device offload remain outside the estimate.

Be careful with units. Eight billion FP16 parameters require sixteen billion bytes, about 14.9014.90 GiB. A displayed GB value and a device’s GiB capacity can differ without either measurement being wrong.

Compression changes the bottleneck

A rough dense decode-step model compares weight-transfer time with arithmetic time:

tstep≳max⁡(Mweightsbandwidth,  2NBcompute throughput)t_{\mathrm{step}}\gtrsim \max\left( \frac{M_{\mathrm{weights}}}{\mathrm{bandwidth}},\; \frac{2NB}{\mathrm{compute\ throughput}} \right)

This assumes weights are read once for the batch and reused across its token computations. It omits attention-cache traffic and many runtime costs. Add an explicit overhead term for unpacking or dequantization to explore when compression stops helping.

06 / Find the bottleneck after compression

An idealized 8B decoder: 1 TB/s weight bandwidth, 100 TFLOP/s compute, one weight read per batch. KV traffic, metadata, and launch costs are omitted.

Decode step, ms against log₂(batch), 0=1, 8=256. FP16 lower bound; Low-bit plus overhead.0014.72.729.35.3448Decode step, mslog₂(batch), 0=1, 8=256

Dashed: FP16 · Solid: low-bit + overhead

FP16 step
16 ms
Low-bit step
4 ms
Modeled speed ratio
4×

Analytical bound, not a hardware benchmark. Compute throughput is held constant; native low-bit kernels can change it. Ratios below 1 mean the modeled low-bit path is slower.

At small batches, weight traffic can dominate this simplified model. At larger batches, arithmetic grows while the weight read is shared. Reducing stored bits eventually stops changing the larger term. Added low-bit overhead can make the compressed path slower under the chosen assumptions.

Actual kernels may also change arithmetic throughput. Some consume low-bit operands directly; others unpack weights into a higher precision. Fused dequantization can overlap work that a separate kernel would serialize. A measured result needs the exact device, kernel, shape, batch size, and output length.

The practical comparison is a deployment experiment. Measure peak resident memory, prefill latency, decode latency, and task quality against the same reference checkpoint. Keep sampling settings and evaluation inputs fixed. Include the workloads that are sensitive to mistakes, such as code, tool arguments, and retrieval at the target context length.

A bit width is a storage decision. The useful outcome is a measured combination of retained behavior, memory use, and latency for the system that will run it.

References

Footnotes

  1. Benoit Jacob et al., “Quantization and Training of Neural Networks for Efficient Integer-Arithmetic-Only Inference,” CVPR, 2018. Read the paper. ↩

  2. Guangxuan Xiao et al., “SmoothQuant: Accurate and Efficient Post-Training Quantization for Large Language Models,” ICML, 2023. Read the paper. ↩

  3. Elias Frantar et al., “GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers,” ICLR, 2023. Read the paper. ↩

  4. Ji Lin et al., “AWQ: Activation-aware Weight Quantization for LLM Compression and Acceleration,” MLSys, 2024. Read the paper. ↩