LLM Quantization:
A Comprehensive Guide

Why large language models are served in 8, 4 or fewer bits, how the number formats work, and how GPTQ, SmoothQuant and AWQ keep the accuracy.

Introduction

Llama 3.1 405B (Dubey & others, 2024) stores 405 billion parameters as 16-bit floats. That is 810 GB of weights, enough to fill nine 94 GB H100 GPUs (NVIDIA, 2023) before the model has read a single token. Store each parameter in 4 bits instead, and three GPUs are enough.

That is quantization: storing a model’s numbers with fewer bits, typically 8 or 4 instead of 16. Memory drops by half or by three quarters. Generation gets faster too, because producing a token is mostly a matter of reading the weights from memory, and smaller weights take less time to read.

The price is precision. A 4-bit number can take only 16 values, so every weight gets rounded, and a few billion rounding errors add up. The craft lies in choosing those 16 values so well that the model’s answers barely change.

One problem runs through all of it: outliers, the few values far larger than the rest, which stretch every grid they share. Most of the methods in this article are, at heart, ways of dealing with them.

We start with the bill, what a model costs in memory and bandwidth (Why do we need quantization?). Then we open up the numbers: how formats spend their bits, and how a scale maps real values onto a coarse grid (Basic concepts). A taxonomy of quantization methods lays out the choices every method makes. Advanced post-training quantization covers the methods behind most published 4-bit models: GPTQ (Frantar et al., 2023) and AWQ (Lin et al., 2024) for weights, SmoothQuant (Xiao et al., 2023) for activations, rotations that spread outliers out, SINQ (Müller et al., 2025), which needs no sample data, and KIVI (Liu et al., 2024) and TurboQuant (Zandieh et al., 2025) for the attention cache.

Every figure computes its values in your browser. Change the inputs and watch each method succeed, or fail.

Out of scope

Quantized fine-tuning such as QLoRA (Dettmers et al., 2023), weights at one or two bits, and compression by pruning each deserve their own article.

  1. Dettmers, T., Pagnoni, A., Holtzman, A., & Zettlemoyer, L. (2023). QLoRA: Efficient Finetuning of Quantized LLMs. Advances in Neural Information Processing Systems. https://arxiv.org/abs/2305.14314
  2. Dubey, A., & others. (2024). The Llama 3 Herd of Models. arXiv Preprint arXiv:2407.21783. https://arxiv.org/abs/2407.21783
  3. Frantar, E., Ashkboos, S., Hoefler, T., & Alistarh, D. (2023). GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers. International Conference on Learning Representations (ICLR). https://arxiv.org/abs/2210.17323
  4. Lin, J., Tang, J., Tang, H., Yang, S., Dang, X., Gan, C., & Han, S. (2024). AWQ: Activation-aware Weight Quantization for LLM Compression and Acceleration. Proceedings of Machine Learning and Systems (MLSys). https://arxiv.org/abs/2306.00978
  5. Liu, Z., Yuan, J., Jin, H., Zhong, S., Xu, Z., Braverman, V., Chen, B., & Hu, X. (2024). KIVI: A Tuning-Free Asymmetric 2bit Quantization for KV Cache. Proceedings of the 41st International Conference on Machine Learning (ICML). https://arxiv.org/abs/2402.02750
  6. Müller, L. K., Bich, P., Zhuang, J., Çelik, A., Benfenati, L., & Cavigelli, L. (2025). SINQ: Sinkhorn-Normalized Quantization for Calibration-Free Low-Precision LLM Weights. arXiv Preprint arXiv:2509.22944. https://arxiv.org/abs/2509.22944
  7. NVIDIA. (2023). NVIDIA H100 Tensor Core GPU. Product specifications. https://www.nvidia.com/en-us/data-center/h100/
  8. Xiao, G., Lin, J., Seznec, M., Wu, H., Demouth, J., & Han, S. (2023). SmoothQuant: Accurate and Efficient Post-Training Quantization for Large Language Models. Proceedings of the 40th International Conference on Machine Learning (ICML). https://arxiv.org/abs/2211.10438
  9. Zandieh, A., Daliri, M., Hadian, M., & Mirrokni, V. (2025). TurboQuant: Online Vector Quantization with Near-optimal Distortion Rate. arXiv Preprint arXiv:2504.19874. https://arxiv.org/abs/2504.19874

Why do we need quantization?

Serving a model costs two things: memory to hold it and time to run it. Both grow with the number of bytes each parameter takes, and that is exactly the number quantization cuts.

Computing memory requirements

The memory bill is a single multiplication. A model with PP parameters, each stored in BB bytes, needs

Mweights=P×B[bytes]M_{\text{weights}} = P \times B \quad [\text{bytes}]

The number format sets BB: 4 bytes for FP32, 2 for FP16 and BF16 (Kalamkar & others, 2019), 1 for FP8 (Micikevicius & others, 2022) and half a byte for INT4. For now only their size matters, and Numerical formats explains the rest. A 70B model in BF16 takes 70×109×2=14070 \times 10^9 \times 2 = 140 GB, already more than a single H100 can hold.

For the largest Llama 3.1, the same arithmetic turns into a hardware bill.

PrecisionBits per parameterWeight memoryH100 GPUs (94 GB)Cost (USD)
FP3232~1,620 GB18540k
FP16/BF1616~810 GB9270k
FP88~405 GB5150k
INT44~203 GB390k
Weight memory of Llama 3.1 405B and the H100 NVL GPUs (94 GB) needed to hold the weights alone. Cost assumes about 30,000 USD per GPU and is indicative.

Each halving of the bits roughly halves the hardware.

KV cache requirements

The weights are not alone in memory. Every token a model reads or writes adds to the KV cache, the attention keys and values of all past tokens, which each layer keeps so that it does not recompute them at every step. For a model with LL layers and nhn_h key-value heads of dimension dhd_h, serving NN sequences of TT tokens, the cache takes

MKV=2×L×nh×dh×T×N×B[bytes]M_{\text{KV}} = 2 \times L \times n_h \times d_h \times T \times N \times B \quad [\text{bytes}]

The 2 counts keys and values, and every other factor multiplies: double the context or the batch, and the cache doubles. Grouped-query attention (Ainslie et al., 2023) keeps nhn_h smaller than the number of query heads. All Llama 3.1 models use 8 key-value heads of dimension 128 (Dubey & others, 2024).

At long contexts, the cache rivals the weights. Llama 3.1 70B has 80 layers, so one sequence of 131,072 tokens fills 42.9 GB of BF16 cache, a third of its 140 GB of weights. Serve eight such sequences and the cache reaches 344 GB, more than twice the weights. For more details, see What can be quantized?.

The memory calculator adds the two up. Pick a model, a GPU (an H100 or an H200 (NVIDIA, 2024)), a context length and a batch size. Each bar is one precision for the weights, and the dashed lines mark how much one, two, three or more GPUs hold.

Weights and KV cache against GPU memory

Llama 3.1 405B with an 8,192-token context and batch size 1: FP32 weights need 1,620 GB (18 H100 NVL GPUs), BF16 810 GB (9), FP8 405 GB (5) and INT4 203 GB (3). The BF16 KV cache adds 4.2 GB.

Memory to serve Llama 3.1 models, computed from the two formulas above with nominal parameter counts. Scales, activations and framework overhead are not counted. Architecture from the Llama 3 report, GPU memory from NVIDIA's specifications.

Compute-bound and memory-bound phases

Inference has two phases:

The roofline model makes this precise (Pope et al., 2023; Williams et al., 2009). A kernel has two speed limits: the GPU’s peak arithmetic, and its memory bandwidth times the kernel’s arithmetic intensity, the operations it does per byte it loads. The lower of the two wins.

A linear layer that processes nn tokens per weight read does 2n2n operations per BB bytes. An H100 SXM moves 3.35 TB/s and computes 989 TFLOPS in BF16 (NVIDIA, 2023), so it needs about 295 tokens per weight read before arithmetic becomes the limit. Decode a single sequence and the GPU uses 0.3% of its compute. The rest sits idle, waiting for memory.

The roofline plots this for three weight formats. Each solid line is the lower of the two limits. Highlight a format to draw both limits as dashed lines, with the ridge where they cross, and the table below the chart shows which resource is saturated: one of compute and bandwidth is always at 100%.

Fewer bytes per weight raise the memory-bound part of the roofline

On an H100 SXM, a linear layer that processes 8 tokens per weight read reaches about 27 TFLOPS with BF16 weights, 107 TFLOPS with INT4 weights and 54 TFLOPS with FP8 weights. All three are limited by memory bandwidth, which is saturated, while the tensor cores run at 3–11% of their peak.

Roofline of one linear layer on an H100 SXM: 3.35 TB/s of bandwidth, 989 dense BF16 and 1,979 dense FP8 TFLOPS. Idealized: activation traffic, dequantization cost and kernel efficiency are ignored.

The memory bandwidth bottleneck

For a single sequence, the speed limit takes a simple form. Each decoding step reads every weight once, so it takes at least the size of the weights divided by the bandwidth:

Tokens/s≈Memory bandwidth [GB/s]Mweights [GB]=Memory bandwidth [GB/s]P×B / 109\text{Tokens/s} \approx \frac{\text{Memory bandwidth}\ [\text{GB/s}]}{M_{\text{weights}}\ [\text{GB}]} = \frac{\text{Memory bandwidth}\ [\text{GB/s}]}{P \times B\ /\ 10^9}

Halve the bytes and you double the ceiling. Llama 3.1 8B in BF16 takes 16 GB, so an H100 SXM generates at most about 209 tokens per second with it. In INT4 the model takes 4 GB, and the ceiling rises to about 840. Real systems fall short of these numbers, since they also read the KV cache and pay for attention and kernel launches, but the ratio holds.

Why batching does not remove the bottleneck

Serving systems batch sequences, so that one read of the weights serves NN tokens and the arithmetic intensity grows to about 2N/B2N/B. Batching helps throughput, but it has limits that quantization does not:

  • Each sequence brings its own KV cache, read at every step, so long contexts stay memory-bound however large the batch.
  • Interactive applications cannot wait to fill a large batch.
  • The batch size is capped by memory, and quantized weights are what free that memory.
Quantization buys capacity first, then speed

From 16 to 4 bits, Llama 3.1 405B goes from nine GPUs to three, and the ceiling on decoding speed rises fourfold. Prefill gets faster only when the arithmetic itself runs in low precision.

  1. Ainslie, J., Lee-Thorp, J., de Jong, M., Zemlyanskiy, Y., Lebrón, F., & Sanghai, S. (2023). GQA: Training Generalized Multi-Query Transformer Models from Multi-Head Checkpoints. Proceedings of the 2023 Conference on Empirical Methods in Natural Language Processing (EMNLP). https://arxiv.org/abs/2305.13245
  2. Dubey, A., & others. (2024). The Llama 3 Herd of Models. arXiv Preprint arXiv:2407.21783. https://arxiv.org/abs/2407.21783
  3. Kalamkar, D., & others. (2019). A Study of BFLOAT16 for Deep Learning Training. arXiv Preprint arXiv:1905.12322. https://arxiv.org/abs/1905.12322
  4. Micikevicius, P., & others. (2022). FP8 Formats for Deep Learning. arXiv Preprint arXiv:2209.05433. https://arxiv.org/abs/2209.05433
  5. NVIDIA. (2023). NVIDIA H100 Tensor Core GPU. Product specifications. https://www.nvidia.com/en-us/data-center/h100/ back: 1, 2
  6. NVIDIA. (2024). NVIDIA H200 Tensor Core GPU. Product specifications. https://www.nvidia.com/en-us/data-center/h200/
  7. NVIDIA. (2025). Introducing NVFP4 for Efficient and Accurate Low-Precision Inference. NVIDIA Technical Blog. https://developer.nvidia.com/blog/introducing-nvfp4-for-efficient-and-accurate-low-precision-inference/
  8. Pope, R., Douglas, S., Chowdhery, A., Devlin, J., Bradbury, J., Levskaya, A., Heek, J., Xiao, K., Agrawal, S., & Dean, J. (2023). Efficiently Scaling Transformer Inference. Proceedings of Machine Learning and Systems (MLSys). https://arxiv.org/abs/2211.05102
  9. Williams, S., Waterman, A., & Patterson, D. (2009). Roofline: An Insightful Visual Performance Model for Multicore Architectures. Communications of the ACM, 52(4), 65–76.

Basic concepts

Fewer bits have a price: every number gets rounded to one of a few values. How much that hurts depends on two choices, the number format and the scale.

Numerical formats

A floating-point number has three fields: a sign bit, an exponent and a mantissa. Its value is

value=(−1)sign×2 exponent−bias×(1+mantissa)\text{value} = (-1)^{\text{sign}} \times 2^{\,\text{exponent} - \text{bias}} \times (1 + \text{mantissa})

The exponent picks the power of two, and the mantissa the position between that power and the next:

Deep learning uses a handful of formats (IEEE, 2019; Micikevicius & others, 2022; Open Compute Project, 2023):

FormatExponentMantissaLargest valueTypical use
FP328233.4×10383.4 \times 10^{38}Training reference
BF16873.4×10383.4 \times 10^{38}Training and inference
FP1651065,504Inference
FP8 E5M25257,344Gradients
FP8 E4M343448Weights and activations
FP4 E2M1216Weights, in blocks

BF16 keeps the exponent of FP32, and with it the range, so activations that overflow FP16 fit in it. That made it the default for training (Kalamkar & others, 2019). FP8 comes in two variants (Micikevicius & others, 2022): E5M2 favours range, for gradients, and E4M3 precision, for weights and activations. FP4 has only 15 distinct values (Open Compute Project, 2023).

The format explorer shows the bits each format stores for a number you type.

The same number in six floating-point formats

The value 3.14159 stored in each format: FP32 keeps 3.1415901, BF16 and FP16 keep 3.140625, FP8 E5M2 keeps 3, FP8 E4M3 keeps 3.25 and FP4 E2M1 keeps 3. Fewer exponent bits shrink the range; fewer mantissa bits widen the gap between neighbouring values.

Encodings computed in your browser with round-to-nearest-even. FP32, BF16, FP16 and FP8 E5M2 follow IEEE 754. FP8 E4M3 and FP4 E2M1 follow the OCP conventions, which have no infinities, and values beyond their range are saturated to the largest one.

At 70000, FP16 and E5M2 overflow to infinity, while E4M3 and FP4 clamp to their largest value. At 0.00001, E4M3 and FP4 round to zero, and E5M2 keeps only a subnormal, 53% off.

Integers are the other option. INT8 stores whole numbers from −128 to 127, so on its own it cannot hold a weight like 0.013. Quantization pairs it with a scale, the real value of one step: with a scale of 0.001, the integer 13 stands for 0.013. Unlike a float, whose gaps grow with the magnitude (roughly a logarithmic grid), an integer grid has the same gap everywhere, so small values suffer the largest relative error (uniform and non-uniform quantization).

Quantization and dequantization

Quantization maps a real number xx onto an integer grid with three parameters: the bit width bb, the scale ss and the zero point zz.

xq(x,s,z,b)=Clip(Round(xs)+z, qmin⁡, qmax⁡)x_q(x, s, z, b) = \text{Clip}\left(\text{Round}\left(\frac{x}{s}\right) + z,\ q_{\min},\ q_{\max}\right)

Divide by the scale, round to a whole step, shift by the zero point and clamp to the grid. Dequantization goes back:

x^=s⋅(xq−z)\hat{x} = s \cdot (x_q - z)

Only the integers xqx_q and the pair (s,z)(s, z) are stored, and kernels compute x^\hat{x} on the fly. The difference ϵ=∣x−x^∣\epsilon = |x - \hat{x}| is the quantization error.

The mapping figure quantizes eight values: real values on the top axis, integer codes on the bottom one.

Quantizing eight values onto an integer grid

Eight values quantized to 4-bit integers over their min-max range. For signed weights between −7.11 and 13.43, the symmetric scale is 13.43 / 7 ≈ 1.92, and every reconstructed value lies within half a step (0.96) of the original. For non-negative values up to 2.95, a symmetric grid leaves its negative half unused (step 0.421), while an asymmetric grid with a zero point shrinks the step to 0.197.

Illustrative values, min-max range, round to nearest. The symmetric scheme uses a signed grid centred on zero; the asymmetric scheme shifts the grid with an integer zero point.

Each extra bit halves the step, and with it the worst-case error. At 2 bits most values collapse onto code 0, and at 8 bits the largest error is below 0.06.

Bit width, zero point and scale

The bit width bb sets the number of levels: [0, 2b−1][0,\ 2^b - 1] for unsigned integers, [−2b−1, 2b−1−1][-2^{b-1},\ 2^{b-1} - 1] for signed ones. Symmetric schemes often drop the most negative code, [−2b−1+1, 2b−1−1][-2^{b-1} + 1,\ 2^{b-1} - 1], so that the grid mirrors around zero. Values outside the grid are clipped to the nearest end.

The zero point zz slides the grid along the real line, and makes a real 0 map exactly onto an integer. That matters because zeros are everywhere (padding, ReLU outputs), and an error on each would bias every sum they enter (Jacob et al., 2018).

The scale ss is the size of one step. To cover a range [α,β][\alpha, \beta] with bb bits,

s=β−α2b−1s = \frac{\beta - \alpha}{2^b - 1}

A wider range, or fewer bits, means bigger steps and bigger rounding errors.

How to choose α and β

For values x={x1,…,xN}\mathbf{x} = \{x_1, \ldots, x_N\}, three choices are common (Nagel et al., 2021):

The clipping-rounding trade-off

The range trades one error for another:

  1. Clipping error hits values outside the range. A larger range clips less.
  2. Rounding error hits values inside it, at most half a step, s/2s/2. A smaller range rounds less.

A value is either clipped or rounded, so the two squared errors add up:

min⁡s,z E[(x−x^)2]=min⁡s,z(MSEclip+MSEround)\min_{s, z}\ \mathbb{E}\left[(x - \hat{x})^2\right] = \min_{s, z}\left(\text{MSE}_{\text{clip}} + \text{MSE}_{\text{round}}\right)

The clipping figure plots both on 4,000 synthetic values: a standard normal bulk, plus 0.5% outliers six times wider.

Clipping trades a few large errors for many small ones

4,000 synthetic values, mostly standard normal with 0.5% outliers six times wider, quantized to 4-bit symmetric integers. Min-max scaling (c = 15.1) gives a mean squared error of 0.39; clipping at c ≈ 6.1 lowers it to 0.12, because finer steps for the bulk of the values outweigh the error on the few clipped outliers.

Synthetic data from a fixed seed: 4,000 normal values, 0.5% of them scaled by six. Symmetric quantization with threshold c and scale c / q_max. Mean squared errors over all values, on a logarithmic axis.

At 4 bits, the lowest error comes from clipping at about 40% of the largest value, which cuts the error of min-max by more than three times. At 8 bits the steps are already fine, and the optimum moves back to about 97%.

Microscaling formats

At 4 bits, one scale per tensor is not enough: values that differ by orders of magnitude cannot share 15 levels. Microscaling (MX) formats (Rouhani & others, 2023) give each small block its own scale. The low-bit elements carry the local detail, and the shared scale carries the magnitude, for a few extra bits per block.

MXFP4

MXFP4, defined by the Open Compute Project (Open Compute Project, 2023), shares one scale across blocks of k=32k = 32 elements:

x^=xq⋅2S\hat{x} = x_q \cdot 2^S

Each xqx_q is an FP4 (E2M1) value, and SS an 8-bit power of two (E8M0), so applying the scale is just an exponent add. The catch is that a power of two can miss the ideal scale by up to a factor of two, and one outlier sets the step for its 31 neighbours.

How MXFP4 picks the shared exponent

The specification sets S=⌊log⁡2max⁡i∣xi∣⌋−2S = \lfloor \log_2 \max_i |x_i| \rfloor - 2, where 2 is the largest exponent of an E2M1 value. After dividing by 2S2^S, the largest element lands in [4,8)[4, 8). FP4 tops out at 6, so a block maximum between 6 and 8 gets clipped to 6. Rounding the scale down to a power of two costs up to 25% on the largest element, in exchange for a one-byte scale that is applied by adding exponents.

NVFP4: more local, more precise scales

NVFP4 keeps the FP4 elements and changes the scales (NVIDIA, 2025):

  1. Smaller blocks of k=16k = 16, so an outlier affects fewer neighbours, for twice the scale overhead.
  2. A finer scale, an FP8 E4M3 number instead of a power of two, applied by multiplication.
  3. Two levels: an FP32 scale per tensor brings the block scales into FP8’s range.
x^=xq⋅sblock⋅stensor,sblock∈FP8 (E4M3),stensor∈FP32\hat{x} = x_q \cdot s_{\text{block}} \cdot s_{\text{tensor}}, \qquad s_{\text{block}} \in \text{FP8 (E4M3)}, \quad s_{\text{tensor}} \in \text{FP32}

The microscaling figure stores 64 synthetic values in four groups of 16 with very different magnitudes, and one outlier in the first group.

Smaller blocks and finer scales keep FP4 accurate

64 synthetic values in four groups of different magnitude, with one outlier, stored as FP4 E2M1. One scale for the whole tensor leaves the small groups with almost no levels; MXFP4 shares a power-of-two scale per 32 values; NVFP4 shares an FP8 scale per 16 values and has the lowest error of the three.

Synthetic data from a fixed seed: four groups of 16 normal values with standard deviations 1, 0.08, 0.6 and 0.2, and one outlier in the first group. Symmetric-log vertical axis. Error is averaged over the four groups, each relative to its own energy, so small groups count as much as large ones.

In MXFP4, the small second group shares a block with the large first one, and most of its values round to zero. NVFP4 gives it its own scale and cuts the error by more than an order of magnitude. Its error also barely moves as the outlier grows, since the outlier sets the scale of its own block of 16 and nothing else. The table compares the two formats.

FeatureMXFP4NVFP4
Element formatE2M1 (FP4)E2M1 (FP4)
Block size3216
Scale formatE8M0 (power of two)E4M3 (FP8)
Scaling strategyPer blockPer block and per tensor
Overhead0.25 bits per element0.5 bits per element + FP32 per tensor
Cost of applying scaleExponent addMultiplication
Robustness to outliersLimitedImproved
MXFP4 and NVFP4 side by side.
  1. IEEE. (2019). IEEE Standard for Floating-Point Arithmetic. IEEE Std 754-2019.
  2. Jacob, B., Kligys, S., Chen, B., Zhu, M., Tang, M., Howard, A., Adam, H., & Kalenichenko, D. (2018). Quantization and Training of Neural Networks for Efficient Integer-Arithmetic-Only Inference. Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition (CVPR). https://arxiv.org/abs/1712.05877
  3. Kalamkar, D., & others. (2019). A Study of BFLOAT16 for Deep Learning Training. arXiv Preprint arXiv:1905.12322. https://arxiv.org/abs/1905.12322
  4. Micikevicius, P., & others. (2022). FP8 Formats for Deep Learning. arXiv Preprint arXiv:2209.05433. https://arxiv.org/abs/2209.05433 back: 1, 2
  5. Nagel, M., Fournarakis, M., Amjad, R. A., Bondarenko, Y., van Baalen, M., & Blankevoort, T. (2021). A White Paper on Neural Network Quantization. arXiv Preprint arXiv:2106.08295. https://arxiv.org/abs/2106.08295
  6. NVIDIA. (2025). Introducing NVFP4 for Efficient and Accurate Low-Precision Inference. NVIDIA Technical Blog. https://developer.nvidia.com/blog/introducing-nvfp4-for-efficient-and-accurate-low-precision-inference/
  7. Open Compute Project. (2023). OCP Microscaling Formats (MX) Specification, Version 1.0 [Techreport]. Open Compute Project. https://www.opencompute.org/documents/ocp-microscaling-formats-mx-v1-0-spec-final-pdf back: 1, 2, 3
  8. Rouhani, B. D., & others. (2023). Microscaling Data Formats for Deep Learning. arXiv Preprint arXiv:2310.10537. https://arxiv.org/abs/2310.10537

A taxonomy of quantization methods

Every quantization method answers the same six questions. Where does the grid sit? Are its levels evenly spaced? How many values share a scale? Is the scale fixed in advance? Which tensors get quantized? And does the model train through the rounding?

Symmetric and asymmetric quantization

Symmetric quantization centres the grid on zero: z=0z = 0, the grid runs from −qmax⁡-q_{\max} to qmax⁡q_{\max}, and the largest magnitude sets the step, s=max⁡i∣xi∣/qmax⁡s = \max_i |x_i| / q_{\max}. It is cheap, but it wastes levels on lopsided data. ReLU outputs are never negative, so half the grid goes unused.

Asymmetric quantization fits the grid to the actual range [α,β][\alpha, \beta], with the zero point

z=Round(qmax⁡−βs)z = \text{Round}\left(q_{\max} - \frac{\beta}{s}\right)

which puts the top code on β\beta and makes every code available to the data.

The mapping figure returns with non-negative values, as a ReLU produces.

Asymmetric quantization recovers the codes symmetric quantization wastes

Eight values quantized to 4-bit integers over their min-max range. For signed weights between −7.11 and 13.43, the symmetric scale is 13.43 / 7 ≈ 1.92, and every reconstructed value lies within half a step (0.96) of the original. For non-negative values up to 2.95, a symmetric grid leaves its negative half unused (step 0.421), while an asymmetric grid with a zero point shrinks the step to 0.197.

Illustrative non-negative values, as a ReLU produces. Min-max range, 4 bits, round to nearest.

In symmetric mode, the negative codes go to waste. Asymmetric mode halves the step and more than halves the largest error.

Symmetric quantization survives because zero points cost extra work when the matrix multiply runs on integers, as in W8A8 (8-bit weights and activations).

Where zero points cost extra work

A dot product between quantized weights and activations, y=∑jw^jx^jy = \sum_j \hat{w}_j \hat{x}_j, expands to

y=swsx(∑jqw,j qx,j−zx∑jqw,j−zw∑jqx,j+n zwzx)y = s_w s_x \left( \sum_j q_{w,j}\, q_{x,j} - z_x \sum_j q_{w,j} - z_w \sum_j q_{x,j} + n\, z_w z_x \right)

The first sum is the integer multiply the hardware accelerates. The second depends only on the weights, so you compute it once. The third depends on the activations, so you would have to compute it for every token, unless zw=0z_w = 0. That is why integer multiplies usually pair symmetric weights with symmetric or asymmetric activations (Nagel et al., 2021). Weight-only schemes convert the weights back to 16 bits before the multiply, so there a zero point costs just one subtraction per weight.

Uniform and non-uniform quantization

Uniform quantization spaces the levels evenly, so the absolute error is at most half a step everywhere. For small values that is a large relative error: anything below half a step rounds to zero.

Non-uniform quantization uses steps that grow with the magnitude, which keeps the relative error more even. Floating-point grids are non-uniform by construction: every power of two holds the same number of values, so their spacing is roughly logarithmic. So is NF4, the 4-bit format of QLoRA (Dettmers et al., 2023), whose levels follow the quantiles of a normal distribution.

The level-spacing figure compares three 4-bit grids, each with eight non-negative levels up to 6.

Uneven spacing spreads the relative error across magnitudes

Three 4-bit grids with eight non-negative levels up to 6. The uniform integer grid rounds 0.3 to 0 (100% relative error), FP4 E2M1 rounds it to 0.5 (67%) and a power-of-two grid rounds it to 0.375 (25%): non-uniform grids trade precision on large values for precision on small ones.

The eight non-negative levels of a uniform INT4 grid, FP4 E2M1 and a power-of-two grid, each scaled to a maximum of 6. Below: the relative error of rounding to the nearest level.

Below about 0.4, the uniform grid returns zero, a 100% error. The power-of-two grid keeps the relative error at or below a third for all but the smallest values, and FP4 sits in between.

Uniform grids still dominate for weights, because they are cheap to decode and every kernel supports them. Non-uniform grids need a lookup table, unless the hardware supports them natively, as Hopper GPUs do for FP8 (NVIDIA, 2023) and Blackwell GPUs for FP4 (NVIDIA, 2025).

Quantization granularity

The scale and zero point can be shared by many values or by few:

Finer granularity is cheap. With FP16 scales and groups of 128, a common choice for 4-bit weights (Lin et al., 2024), the scales add 16/128=0.12516 / 128 = 0.125 bits per weight, plus the zero points for asymmetric groups.

The granularity figure quantizes a synthetic 8 × 32 weight matrix with two outliers. Outlines mark which weights share a scale, and the lower heatmap shows the error.

Finer granularity isolates outliers

A synthetic 8 × 32 weight matrix whose rows have different magnitudes and two outliers, quantized to 4-bit symmetric integers. One scale for the tensor gives the largest error; one scale per row (output channel) lowers it; one scale per group of 8 weights lowers it further, at the cost of 32 scales instead of 1.

Synthetic 8 × 32 weight matrix from a fixed seed, with rows of different spread and two outlier weights. Symmetric 4-bit absmax quantization. Relative error: ‖W − Ŵ‖² / ‖W‖². Overhead assumes one FP16 scale per group.

Per channel cuts the per-tensor error by almost four, and groups of 8 by another four, because each step confines the outliers to fewer neighbours.

Activations are harder. Their outliers sit in a few input channels (Dettmers et al., 2022), and when the multiply runs in low precision, those channels cannot get their own scales. A scale per output channel multiplies a finished output, so it can be applied after the integer multiply. A scale per input channel would change inside the sum, so it cannot be factored out. Activations therefore get one scale per tensor or per token, which the outliers stretch for everyone. SmoothQuant (Xiao et al., 2023) works around this.

Static and dynamic quantization

Weight scales are computed once, offline. Activation scales can be:

What can be quantized?

Three kinds of tensors can be stored in low precision. W4A16 means 4-bit weights and 16-bit activations, and W8A8 means 8 bits for both.

The dataflow diagram follows one decoding step under each scheme.

Where low precision lives during a decoding step

Weight-only quantization (W4A16) stores the weights in 4 bits and dequantizes them to BF16 just before each matrix multiply; activations and the KV cache stay in BF16. W8A8 also quantizes the activations, so the multiply itself runs on 8-bit tensor cores. KV-cache quantization stores keys and values in 8 bits and dequantizes them when attention reads them.

Schematic of one linear layer and the attention cache under three common schemes. The precisions are typical, not the only options: W4A16 is also served with FP4 weights, W8A8 with FP8, and KV caches with INT8.

In W4A16, a dequantization step feeds the weights to a 16-bit multiply. In W8A8, the multiply itself runs in 8 bits and its result is rescaled. With an 8-bit KV cache, the cache is converted on every write and read.

PTQ, QAT and QAD

The last question is how much the model takes part in its own quantization: not at all, by training, or by training with a teacher.

Post-training quantization (PTQ)

PTQ quantizes a finished model: compute the ranges (min-max, MSE or percentile), usually on a calibration set, and round.

Quantization-aware training (QAT)

QAT simulates quantization during training or fine-tuning, so that the model learns to live with it. Each quantized tensor goes through a fake quantization step in the forward pass:

W^=s⋅(Clip(Round(Ws)+z, qmin⁡, qmax⁡)⏞Quant−z)⏟DeQuant\hat{W} = \underbrace{s \cdot \Big(\overbrace{\text{Clip}\big(\text{Round}\big(\tfrac{W}{s}\big) + z,\ q_{\min},\ q_{\max}\big)}^{\text{Quant}} - z\Big)}_{\text{DeQuant}}

The loss sees the rounded weights W^\hat{W}, while the optimizer updates the full-precision weights WW. Round has zero gradient almost everywhere, so the straight-through estimator (STE) (Bengio et al., 2013) treats it as the identity inside the clipping range:

∂L∂W≈∂L∂W^⋅1[qmin⁡≤Ws+z≤qmax⁡]\frac{\partial \mathcal{L}}{\partial W} \approx \frac{\partial \mathcal{L}}{\partial \hat{W}} \cdot \mathbf{1}_{\left[q_{\min} \le \frac{W}{s} + z \le q_{\max}\right]}

Quantization-aware distillation (QAD)

QAD adds knowledge distillation (Hinton et al., 2015) to QAT: a full-precision teacher guides the quantized student.

LQAD=λ⋅Ltask(y^,y)+(1−λ)⋅LKD(pstudent,pteacher)\mathcal{L}_{\text{QAD}} = \lambda \cdot \mathcal{L}_{\text{task}}(\hat{y}, y) + (1 - \lambda) \cdot \mathcal{L}_{\text{KD}}(p_{\text{student}}, p_{\text{teacher}})

LKD\mathcal{L}_{\text{KD}} is usually the KL divergence between the two output distributions, and λ\lambda sets the balance. In self-distillation, as in LLM-QAT (Liu & others, 2023), the teacher is the full-precision model itself. Its full distribution over the next token carries more signal than a single correct label.

The workflow figure puts the three side by side.

Three ways to obtain a quantized model

Post-training quantization measures value ranges on a small calibration set and converts the trained model directly, without gradients. Quantization-aware training simulates quantization in the forward pass and updates the full-precision weights through the straight-through estimator. Quantization-aware distillation adds a frozen full-precision teacher whose outputs the quantized student learns to match.

Schematic workflows. Costs are typical orders of magnitude, not measurements.

QAT and QAD add a training loop to PTQ’s straight line. The loop buys accuracy, but costs data, compute and tuning, so most deployments start with PTQ.

  1. Bengio, Y., Léonard, N., & Courville, A. (2013). Estimating or Propagating Gradients Through Stochastic Neurons for Conditional Computation. arXiv Preprint arXiv:1308.3432. https://arxiv.org/abs/1308.3432
  2. Dettmers, T., Lewis, M., Belkada, Y., & Zettlemoyer, L. (2022). LLM.int8(): 8-bit Matrix Multiplication for Transformers at Scale. Advances in Neural Information Processing Systems. https://arxiv.org/abs/2208.07339 back: 1, 2
  3. Dettmers, T., Pagnoni, A., Holtzman, A., & Zettlemoyer, L. (2023). QLoRA: Efficient Finetuning of Quantized LLMs. Advances in Neural Information Processing Systems. https://arxiv.org/abs/2305.14314
  4. Hinton, G., Vinyals, O., & Dean, J. (2015). Distilling the Knowledge in a Neural Network. arXiv Preprint arXiv:1503.02531. https://arxiv.org/abs/1503.02531
  5. Lin, J., Tang, J., Tang, H., Yang, S., Dang, X., Gan, C., & Han, S. (2024). AWQ: Activation-aware Weight Quantization for LLM Compression and Acceleration. Proceedings of Machine Learning and Systems (MLSys). https://arxiv.org/abs/2306.00978
  6. Liu, Z., & others. (2023). LLM-QAT: Data-Free Quantization Aware Training for Large Language Models. arXiv Preprint arXiv:2305.17888. https://arxiv.org/abs/2305.17888
  7. Nagel, M., Fournarakis, M., Amjad, R. A., Bondarenko, Y., van Baalen, M., & Blankevoort, T. (2021). A White Paper on Neural Network Quantization. arXiv Preprint arXiv:2106.08295. https://arxiv.org/abs/2106.08295
  8. NVIDIA. (2023). NVIDIA H100 Tensor Core GPU. Product specifications. https://www.nvidia.com/en-us/data-center/h100/
  9. NVIDIA. (2025). Introducing NVFP4 for Efficient and Accurate Low-Precision Inference. NVIDIA Technical Blog. https://developer.nvidia.com/blog/introducing-nvfp4-for-efficient-and-accurate-low-precision-inference/
  10. Xiao, G., Lin, J., Seznec, M., Wu, H., Demouth, J., & Han, S. (2023). SmoothQuant: Accurate and Efficient Post-Training Quantization for Large Language Models. Proceedings of the 40th International Conference on Machine Learning (ICML). https://arxiv.org/abs/2211.10438

Advanced post-training quantization

At 8 bits, rounding to nearest with a good range is usually enough. At 4 bits, or with activation outliers, it is not. Each method below fixes a different weakness of plain rounding:

GPTQ

GPTQ (Frantar et al., 2023) quantizes one linear layer at a time, and judges the result by the layer’s outputs, not its weights. Given weights W∈RCout×Cin\mathbf{W} \in \mathbb{R}^{C_{\text{out}} \times C_{\text{in}}} and NN calibration inputs stacked as the columns of X∈RCin×N\mathbf{X} \in \mathbb{R}^{C_{\text{in}} \times N}, it solves

min⁡W^ ∥WX−W^X∥22\min_{\hat{\mathbf{W}}}\ \left\| \mathbf{W}\mathbf{X} - \hat{\mathbf{W}}\mathbf{X} \right\|_2^2

Inputs are correlated, so the rounding error on one weight can be cancelled by nudging the weights that multiply correlated inputs. GPTQ quantizes the matrix one column at a time, and after each column compensates by updating the columns not yet quantized.

The objective is quadratic, with Hessian H=2XX⊤\mathbf{H} = 2\mathbf{X}\mathbf{X}^\top. Let column jj be next, and FF the columns not yet quantized, jj included. Rounding column jj leaves an error wj−w^j\mathbf{w}_j - \hat{\mathbf{w}}_j, one value per row, and the best correction to FF is

δF=−wj−w^j[HF−1]jj (HF−1)j,F\boldsymbol{\delta}_F = -\frac{\mathbf{w}_j - \hat{\mathbf{w}}_j}{[\mathbf{H}_F^{-1}]_{jj}} \, (\mathbf{H}_F^{-1})_{j,F}

where HF−1\mathbf{H}_F^{-1} is the inverse Hessian restricted to FF. Each row spreads its error over its remaining weights, in proportions set by how the inputs correlate. This is the update of Optimal Brain Surgeon (Hassibi & Stork, 1993), adapted to quantization by Optimal Brain Compression (Frantar & Alistarh, 2022).

The GPTQ figure runs the algorithm on a small layer with correlated inputs, one column per step.

GPTQ spreads each column's error over the columns still to come

A synthetic 6 × 12 layer with correlated inputs, quantized to 3 bits one column at a time. After each column, GPTQ moves that column's error onto the columns not yet quantized, weighted by the inverse Hessian. Once all twelve columns are quantized, the relative output error is about 0.022 with GPTQ and 0.050 with round-to-nearest.

Synthetic layer from a fixed seed: 6 × 12 normal weights and 256 calibration inputs with strongly correlated neighbouring features. Per-row symmetric 3-bit grid, Hessian dampened by 1% of its mean diagonal. Error relative to the full-precision output.

The bottom heatmap shows how far GPTQ has moved each weight: the columns not yet quantized keep changing as errors are pushed onto them. After all twelve columns, GPTQ’s output error is less than half of round-to-nearest’s.

Every row is quantized in the same column order, so all rows share one inverse Hessian. Updates are applied in blocks of columns to keep the GPU busy, and a Cholesky decomposition keeps the inverse Hessian numerically stable. Together, these let GPTQ quantize 175B-parameter models to 3 or 4 bits in about four GPU hours (Frantar et al., 2023).

The algorithm, step by step

With blocks of kk columns and a dampening term λ\lambda that keeps H\mathbf{H} invertible:

H⁻¹ = (2XXᵀ + λI)⁻¹
U   = upper Cholesky factor of H⁻¹        (H⁻¹ = UᵀU)
for each block of k columns:
    for each column j in the block:
        q_j = quant(w_j)                   quantize the column
        e_j = (w_j − q_j) / U[j, j]        scaled quantization error
        W[:, j+1 : block end] −= e_j · U[j, j+1 : block end]
    W[:, after the block] −= E · U[block, after the block]

The inner update spreads each error within the block. The outer one applies the block’s accumulated errors EE to all later columns in a single matrix multiply.

SmoothQuant

GPTQ leaves activations alone, and for W8A8 they are the hard half. Their outliers sit in a few input channels that cannot get their own scales (granularity), so a per-tensor scale wide enough for the outliers leaves the other channels a few of the 256 levels.

SmoothQuant (Xiao et al., 2023) divides each activation channel by a smoothing factor sjs_j and multiplies the matching weight row by the same factor, which leaves the product unchanged:

Y=XW=(X⋅diag(s)−1)⋅(diag(s)⋅W)\mathbf{Y} = \mathbf{X}\mathbf{W} = \left(\mathbf{X} \cdot \text{diag}(\mathbf{s})^{-1}\right) \cdot \left(\text{diag}(\mathbf{s}) \cdot \mathbf{W}\right)

The factor for channel jj is

sj=max⁡(∣X:,j∣)αmax⁡(∣Wj,:∣)1−αs_j = \frac{\max\left(|\mathbf{X}_{:,j}|\right)^{\alpha}}{\max\left(|\mathbf{W}_{j,:}|\right)^{1-\alpha}}

The migration strength α\alpha sets how much difficulty moves. At α=0.5\alpha = 0.5, each activation channel and its weight row end up with the same maximum: the activations become smooth, and the weights get slightly wider, which they tolerate. The paper uses 0.5 by default and larger values for models with stronger outliers (Xiao et al., 2023). The factors are folded into the previous layer, so smoothing is free at run time.

The SmoothQuant figure applies this to synthetic activations with two outlier channels.

SmoothQuant migrates outliers from activations to weights

Synthetic activations with two outlier channels about 40 times larger than the rest, multiplied by well-behaved weights, all quantized to 8 bits per tensor. Smoothing with migration strength α = 0.5 divides each activation channel by s_j and multiplies the matching weight row by s_j: the product XW is unchanged, the per-channel maxima of activations and weights become equal, and the output error falls well below the unsmoothed baseline.

Synthetic data from a fixed seed: 64 tokens × 16 activation channels, two of them about 40× larger in every token, and a 16 × 8 weight matrix. Both operands quantized to INT8 with one scale per tensor. Error relative to the full-precision output.

At α=0.5\alpha = 0.5, each channel’s largest activation and largest weight match, and the output error is about seven times lower than without smoothing. Toward 0 the outliers stay in the activations, toward 1 they move into the weights.

Activation-aware weight quantization (AWQ)

The few channels with large activations also make some weights matter more: every error on them gets multiplied by a large input. AWQ (Lin et al., 2024) calls these salient weights, only 0.1–1% of the total.

Keeping them in FP16 would break the regular layout fast kernels need. Instead, AWQ scales each input channel by ss before quantization and divides the input by the same ss:

Q(w⋅s)⋅xs=Q(w⋅s)⋅x′Q(\mathbf{w} \cdot \mathbf{s}) \cdot \frac{\mathbf{x}}{\mathbf{s}} = Q(\mathbf{w} \cdot \mathbf{s}) \cdot \mathbf{x}'

A group’s step is set by its largest weight, so scaling up a channel that does not become the largest leaves the step, and the absolute rounding error, unchanged. The weight grows ss times, so its relative error Δw/w\Delta w / w shrinks by ss. Scale too far, and the group’s range widens for every other channel.

AWQ sets s=sxα\mathbf{s} = \mathbf{s}_{\mathbf{x}}^{\alpha}, where sx\mathbf{s}_{\mathbf{x}} is the average activation magnitude per channel, and grid-searches α∈[0,1]\alpha \in [0, 1] for the lowest output error on calibration data. Searching for scales, rather than reconstructing outputs as GPTQ does, also overfits the calibration set less (Lin et al., 2024).

In the paper’s ablation, OPT-6.7B (Zhang & others, 2022) with 3-bit weights in groups of 128 reaches a WikiText-2 (Merity et al., 2016) perplexity (lower is better) of 23.54 with round-to-nearest, against 10.86 in FP16. Multiplying the 1% salient channels by 2 brings it to 11.92, close to the 11.39 of keeping them in FP16 (Lin et al., 2024).

The AWQ figure starts at α=0\alpha = 0, plain round-to-nearest.

AWQ protects salient channels without mixed precision

A synthetic layer with 32 input channels, two of which carry activations about 12 times larger, quantized to 3 bits per output channel. Rounding to nearest gives a relative output error of 0.054; keeping the two salient input channels in FP16 gives 0.006 but mixes precisions; AWQ's per-channel scaling s = s_xᵅ reaches 0.017 at α = 0.3 with every weight on the 3-bit grid.

Synthetic data from a fixed seed: 128 tokens × 32 activation channels, two of them about 12× larger, and a 16 × 32 weight matrix. Symmetric 3-bit weights with one scale per output channel, scales normalized as in the reference implementation. Error relative to the full-precision output.

The best α\alpha cuts the output error to about a third. Weight error on the salient channels drops from 24% to 10%, while the others rise from 22% to 28%, a good trade because the salient inputs are 12 times larger. Keeping the salient channels in FP16 (dashed) is lower still, but here 2 of 32 channels (6%) are salient, far more than in a real model.

Rotations: spreading outliers across channels

SmoothQuant and AWQ rescale single channels. Rotations mix all channels, so that an outlier’s energy is shared by every channel instead of sitting in one. Any orthogonal matrix Q\mathbf{Q} (QQ⊤=I\mathbf{Q}\mathbf{Q}^\top = \mathbf{I}) can be inserted into a matrix multiply for free:

Y=XW=(XQ)(Q⊤W)\mathbf{Y} = \mathbf{X}\mathbf{W} = (\mathbf{X}\mathbf{Q})(\mathbf{Q}^\top\mathbf{W})

A rotation preserves each vector’s length but spreads it over the coordinates: two huge coordinates become many moderate ones, which a uniform grid handles well. QuIP (Chee et al., 2023) introduced the idea for weights as incoherence processing.

The usual choice is a Hadamard matrix. Its entries are all ±1/d\pm 1/\sqrt{d}, so it mixes every input into every output equally, and like an FFT it runs in O(dlog⁡d)O(d \log d). Flipping the signs of its rows at random gives a randomized Hadamard transform, which spreads outliers wherever they sit.

The rotation figure rotates activations with two outlier channels, then quantizes activations and weights to 4 bits.

A rotation spreads outliers over every channel

32 synthetic tokens with 64 activation channels, two of which are about 10 times larger. A randomized Hadamard rotation spreads those outliers over every channel without changing the layer's output, and the W4A4 output error falls to less than a third.

Synthetic data from a fixed seed: 32 tokens × 64 activation channels, two channels scaled up, and a 64 × 32 weight matrix. Activations get one scale per token and weights one per output channel, both symmetric. Error relative to the full-precision output. Hover a bar for its value.

After rotation, every channel has a similar range, and the 4-bit output error falls to less than a third. As the outliers grow, the unrotated error grows two to three times, while the rotated error stays flat.

QuaRot (Ashkboos et al., 2024) rotates a whole transformer. It relies on the computational invariance shown by SliceGPT (Ashkboos, Croci, et al., 2024): once the RMSNorm (B. Zhang & Sennrich, 2019) scales are folded into the next weights, the residual stream can be rotated and every weight that reads it counter-rotated, with no change to the output. Most rotations are folded into the weights offline. A few run online: one before the feed-forward down-projection, and others in attention, including one on queries and keys so that the cached keys are rotated too. Every matrix multiply then runs in 4 bits, KV cache included, and 4-bit Llama 2 70B (Touvron & others, 2023) loses at most 0.47 WikiText-2 perplexity (Ashkboos, Mohtashami, et al., 2024).

Random rotations are not equally good. SpinQuant (Liu et al., 2025) finds they can differ by up to 13 points of zero-shot accuracy, and learns them instead, closing up to 45% of QuaRot’s gap to full precision on Llama 3 8B. FlatQuant (Sun et al., 2025) replaces rotations with a learned affine transform per layer, kept cheap by a Kronecker factorization, and reports less than 1% accuracy loss for W4A4 on Llama 3 70B.

SINQ: activation awareness without calibration

AWQ needs calibration data to find the channels with large activations. SINQ (Müller et al., 2025) finds a proxy in the weights alone: in trained models, the weights that read a large input tend to have a small spread. In the Cout×CinC_{\text{out}} \times C_{\text{in}} layout, each input channel is a column of W\mathbf{W}, and across the models SINQ examines, the inverse of a column’s standard deviation predicts its average input magnitude (Müller et al., 2025).

Scaling columns alone would create new outliers within rows, so SINQ uses two scale vectors, one per row (s⃗\vec{s}) and one per column (t⃗\vec{t}):

W≈diag(s⃗) Wq diag(t⃗)\mathbf{W} \approx \text{diag}(\vec{s})\, \mathbf{W}_q\, \text{diag}(\vec{t})

where Wq\mathbf{W}_q is the quantized matrix, with its usual scale and zero point per row. An outlier WijW_{ij} can be absorbed by raising sis_i or tjt_j. To find the scales, SINQ iterates in the style of Sinkhorn-Knopp matrix balancing (Sinkhorn & Knopp, 1967), dividing each row and column by its standard deviation, and keeps the scales with the lowest imbalance:

I(W)=max⁡(max⁡iσirow, max⁡jσjcol)min⁡(min⁡iσirow, min⁡jσjcol)I(\mathbf{W}) = \frac{\max\left(\max_i \sigma_i^{\text{row}},\ \max_j \sigma_j^{\text{col}}\right)}{\min\left(\min_i \sigma_i^{\text{row}},\ \min_j \sigma_j^{\text{col}}\right)}

the ratio of the largest to the smallest row or column standard deviation. The balanced matrix is then rounded to nearest. At run time, t⃗\vec{t} multiplies the layer’s input like AWQ’s scale, so the overhead is one element-wise product.

The SINQ figure runs the iteration on a synthetic matrix whose column spreads follow the paper’s observation.

SINQ balances rows and columns before rounding

A synthetic 16 × 64 weight matrix whose rows and columns have very different spreads. A few Sinkhorn-style iterations rescale rows and columns until their standard deviations are balanced. Quantizing the balanced matrix to 3 bits, then undoing the scales, gives about five times less output error than quantizing the original matrix row by row.

Synthetic data from a fixed seed: a 16 × 64 weight matrix whose column spreads are inversely proportional to the input magnitudes, and 256 inputs. SINQ's Algorithm 1 with the reference implementation's step limits. Asymmetric round-to-nearest, one scale and shift per row. Errors relative to the full-precision weights and outputs. Hover a bar for its value.

Unscaled, the row and column spreads differ by 12×. Within a few iterations they flatten toward 1, the output error falls well below round-to-nearest’s, and the column scales track the input magnitudes without ever seeing an input.

The synthetic matrix makes the gain larger than on a real model. On the Qwen3 family (Yang & others, 2025) and others, at 3 and 4 bits, SINQ more than halves the perplexity gap to 16 bits left by other uncalibrated uniform quantizers (Müller et al., 2025). It processes each layer on its own, so it works on any architecture, and combines with calibrated methods such as AWQ.

Quantizing the KV cache

The KV cache is not just another activation. It is written once per token and read at every later step, its keys and values have different statistics, and at long contexts it can outweigh the model (KV cache requirements).

Keys per channel, values per token (KIVI)

KIVI (Liu et al., 2024) measures that keys have a few fixed channels with very large magnitudes in every token, while values have no outlier pattern. So it groups them differently:

Per-channel groups need several tokens, while generation adds one at a time, so KIVI keeps the most recent tokens in full precision until a group is complete.

The KIVI figure quantizes the keys of one synthetic attention head both ways.

Grouping keys per channel isolates their outlier channels

Synthetic keys for 64 tokens with 32 channels, three of which are large in every token. At 2 bits, grouping keys per token lets those channels set every token's scale, and attention scores carry several times more error than when each channel gets its own scale, as KIVI recommends.

Synthetic data from a fixed seed: one head with 64 cached tokens and 32 channels, three key channels large in every token, and 16 queries. Only the keys are quantized, to isolate their grouping. Asymmetric round-to-nearest; per-channel groups span 32 tokens. Error relative to the full-precision attention scores. Hover a cell for its value.

Per token, each scale stretches to the three large channels and every key is rounded coarsely. Per channel, the ordinary channels get scales fitted to their own range, and the attention-score error drops 6–9× at every bit width.

With this layout, KIVI stores the cache in 2 bits with almost no quality loss on Llama, Falcon (Almazrouei & others, 2023) and Mistral (Jiang & others, 2023) models. Peak memory, weights included, falls by 2.6×, allowing up to 4× larger batches and 2.35–3.47× higher throughput (Liu et al., 2024).

Rotation plus an unbiased residual (TurboQuant)

TurboQuant (Zandieh et al., 2025) rotates each vector instead, in three steps:

  1. Rotate. Store the vector’s length, and multiply the unit vector by a random rotation. Every coordinate then follows the same known distribution (close to a normal with variance 1/d1/d), whatever the input.
  2. Round to a fixed codebook. Since the distribution is known, its best codebook is computed once with the Lloyd-Max algorithm (Lloyd, 1982; Max, 1960). No calibration, no scale per group.
  3. Correct the bias. A quantizer that minimizes squared error shrinks inner products toward zero, and attention scores are inner products. TurboQuant spends one bit on the rounding residual r\mathbf{r}: it stores the signs of Sr\mathbf{S}\mathbf{r} for a random Gaussian matrix S\mathbf{S}, plus the residual’s length. This 1-bit quantized Johnson-Lindenstrauss (QJL) transform (Zandieh, Daliri, & Han, 2025) makes every inner-product estimate unbiased.

The TurboQuant figure shows the first two steps on one key, then repeats the whole procedure over 150 random rotations to show the third.

TurboQuant: rotate, round to a fixed codebook, correct the bias

A synthetic 64-dimensional key with four outlier channels. After a random rotation every coordinate looks alike, so one fixed codebook fits them all. Over 150 random rotations, an MSE-optimal 2-bit quantizer underestimates the key's inner product with a query by about 11% on average, while TurboQuant's 1-bit residual correction removes that bias.

Synthetic 64-dimensional key with four outlier channels and one query, from a fixed seed. Lloyd-Max codebook computed for the coordinate distribution of a random point on the sphere. The histogram repeats both quantizers over 150 independent random rotations and QJL matrices. Hover a bar for its value.

After rotation, every coordinate falls in the same narrow band, so one codebook fits them all. The MSE-optimal quantizer underestimates the inner product consistently, while TurboQuant is right on average, with a wider spread. Random errors partly cancel across the many keys a query attends to, but a bias shifts every score the same way and flattens the attention weights.

On real models, TurboQuant keeps full quality with 3.5 bits per channel and loses little at 2.5 (Zandieh, Daliri, Hadian, et al., 2025). The fractional budgets come from giving outlier channels more bits. The paper also proves its distortion is within a factor of about 2.7 of the best any quantizer can achieve.

How low can the cache go?

A 4-bit cache preserves accuracy, but a 2-bit one often degrades it, especially on long-context reasoning (Xia et al., 2025). Kitty ranks key channels by sensitivity and keeps a small fraction at 4 bits, cutting KV memory by nearly 8× with negligible accuracy loss on Qwen3 and Llama 3 (Xia et al., 2025).

Comparing the methods

These methods combine more often than they compete. GPTQ (Frantar et al., 2023) or AWQ (Lin et al., 2024) quantizes the weights, rotations or SmoothQuant (Xiao et al., 2023) make activations quantizable, and KIVI (Liu et al., 2024) or TurboQuant (Zandieh, Daliri, Hadian, et al., 2025) handles the cache. The table lists what each one needs.

MethodQuantizesCalibrationKey idea
GPTQWYesHessian error compensation
AWQWYesScale salient channels
SmoothQuantW, AYesMove outliers into W
QuaRotW, A, KVOptionalHadamard rotations
SpinQuantW, A, KVYesLearned rotations
SINQWNoRow and column scales
KIVIKVNoKeys per channel
TurboQuantKVNoRotation + 1-bit residual
Post-training quantization methods compared (W: weights, A: activations, KV: KV cache). SmoothQuant's α needs tuning, rotations add online transforms to the forward pass, and QuaRot uses calibration only when it quantizes weights with GPTQ.
  1. Almazrouei, E., & others. (2023). The Falcon Series of Open Language Models. arXiv Preprint arXiv:2311.16867. https://arxiv.org/abs/2311.16867
  2. Ashkboos, S., Croci, M. L., Nascimento, M. G. do, Hoefler, T., & Hensman, J. (2024). SliceGPT: Compress Large Language Models by Deleting Rows and Columns. International Conference on Learning Representations (ICLR). https://arxiv.org/abs/2401.15024
  3. Ashkboos, S., Mohtashami, A., Croci, M. L., Li, B., Cameron, P., Jaggi, M., Alistarh, D., Hoefler, T., & Hensman, J. (2024). QuaRot: Outlier-Free 4-Bit Inference in Rotated LLMs. arXiv Preprint arXiv:2404.00456. https://arxiv.org/abs/2404.00456 back: 1, 2
  4. Chee, J., Cai, Y., Kuleshov, V., & De Sa, C. (2023). QuIP: 2-Bit Quantization of Large Language Models With Guarantees. Advances in Neural Information Processing Systems. https://arxiv.org/abs/2307.13304
  5. Frantar, E., & Alistarh, D. (2022). Optimal Brain Compression: A Framework for Accurate Post-Training Quantization and Pruning. Advances in Neural Information Processing Systems. https://arxiv.org/abs/2208.11580
  6. Frantar, E., Ashkboos, S., Hoefler, T., & Alistarh, D. (2023). GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers. International Conference on Learning Representations (ICLR). https://arxiv.org/abs/2210.17323 back: 1, 2, 3, 4
  7. Hassibi, B., & Stork, D. G. (1993). Second Order Derivatives for Network Pruning: Optimal Brain Surgeon. Advances in Neural Information Processing Systems 5, 164–171.
  8. Jiang, A. Q., & others. (2023). Mistral 7B. arXiv Preprint arXiv:2310.06825. https://arxiv.org/abs/2310.06825
  9. Lin, J., Tang, J., Tang, H., Yang, S., Dang, X., Gan, C., & Han, S. (2024). AWQ: Activation-aware Weight Quantization for LLM Compression and Acceleration. Proceedings of Machine Learning and Systems (MLSys). https://arxiv.org/abs/2306.00978 back: 1, 2, 3, 4, 5
  10. Liu, Z., Yuan, J., Jin, H., Zhong, S., Xu, Z., Braverman, V., Chen, B., & Hu, X. (2024). KIVI: A Tuning-Free Asymmetric 2bit Quantization for KV Cache. Proceedings of the 41st International Conference on Machine Learning (ICML). https://arxiv.org/abs/2402.02750 back: 1, 2, 3, 4
  11. Liu, Z., Zhao, C., Fedorov, I., Soran, B., Choudhary, D., Krishnamoorthi, R., Chandra, V., Tian, Y., & Blankevoort, T. (2025). SpinQuant: LLM Quantization with Learned Rotations. International Conference on Learning Representations (ICLR). https://arxiv.org/abs/2405.16406
  12. Lloyd, S. P. (1982). Least Squares Quantization in PCM. IEEE Transactions on Information Theory, 28(2), 129–137. 10.1109/TIT.1982.1056489
  13. Max, J. (1960). Quantizing for Minimum Distortion. IRE Transactions on Information Theory, 6(1), 7–12. 10.1109/TIT.1960.1057548
  14. Merity, S., Xiong, C., Bradbury, J., & Socher, R. (2016). Pointer Sentinel Mixture Models. arXiv Preprint arXiv:1609.07843. https://arxiv.org/abs/1609.07843
  15. Müller, L. K., Bich, P., Zhuang, J., Çelik, A., Benfenati, L., & Cavigelli, L. (2025). SINQ: Sinkhorn-Normalized Quantization for Calibration-Free Low-Precision LLM Weights. arXiv Preprint arXiv:2509.22944. https://arxiv.org/abs/2509.22944 back: 1, 2, 3, 4
  16. Sinkhorn, R., & Knopp, P. (1967). Concerning Nonnegative Matrices and Doubly Stochastic Matrices. Pacific Journal of Mathematics, 21(2), 343–348. 10.2140/pjm.1967.21.343
  17. Sun, Y., Liu, R., Bai, H., Bao, H., Zhao, K., Li, Y., Hu, J., Yu, X., Hou, L., Yuan, C., Jiang, X., Liu, W., & Yao, J. (2025). FlatQuant: Flatness Matters for LLM Quantization. Proceedings of the 42nd International Conference on Machine Learning (ICML). https://arxiv.org/abs/2410.09426
  18. Touvron, H., & others. (2023). Llama 2: Open Foundation and Fine-Tuned Chat Models. arXiv Preprint arXiv:2307.09288. https://arxiv.org/abs/2307.09288
  19. Xia, H., Wu, X., Li, J., Wu, R., Wang, J., Wang, J., Li, C., Singhal, A., Shah, A. D., Ariyak, A., Zhuang, D., Zhou, Z., Athiwaratkun, B., Zheng, Z., & Song, S. L. (2025). Kitty: Accurate and Efficient 2-bit KV Cache Quantization with Dynamic Channel-wise Precision Boost. arXiv Preprint arXiv:2511.18643. https://arxiv.org/abs/2511.18643 back: 1, 2
  20. Xiao, G., Lin, J., Seznec, M., Wu, H., Demouth, J., & Han, S. (2023). SmoothQuant: Accurate and Efficient Post-Training Quantization for Large Language Models. Proceedings of the 40th International Conference on Machine Learning (ICML). https://arxiv.org/abs/2211.10438 back: 1, 2, 3, 4
  21. Yang, A., & others. (2025). Qwen3 Technical Report. arXiv Preprint arXiv:2505.09388. https://arxiv.org/abs/2505.09388
  22. Zandieh, A., Daliri, M., Hadian, M., & Mirrokni, V. (2025). TurboQuant: Online Vector Quantization with Near-optimal Distortion Rate. arXiv Preprint arXiv:2504.19874. https://arxiv.org/abs/2504.19874 back: 1, 2, 3, 4
  23. Zandieh, A., Daliri, M., & Han, I. (2025). QJL: 1-Bit Quantized JL Transform for KV Cache Quantization with Zero Overhead. Proceedings of the AAAI Conference on Artificial Intelligence, 39(24), 25805–25813. 10.1609/aaai.v39i24.34773
  24. Zhang, B., & Sennrich, R. (2019). Root Mean Square Layer Normalization. Advances in Neural Information Processing Systems. https://arxiv.org/abs/1910.07467
  25. Zhang, S., & others. (2022). OPT: Open Pre-trained Transformer Language Models. arXiv Preprint arXiv:2205.01068. https://arxiv.org/abs/2205.01068

Putting it together

Quantization works because decoding is limited by memory: fewer bytes per weight mean fewer GPUs, more room for the KV cache and faster decoding. The price is rounding error, and outliers make it expensive. Clipping gives them up, small blocks fence them in, SmoothQuant and AWQ rescale around them, rotations spread them out, and KIVI and Kitty give them their own scales or extra bits. GPTQ corrects whatever error remains.

The recipe below follows from these mechanisms, not from benchmarks, so check it against your own evaluation.

  1. Find your bottleneck. If the model does not fit, or single-stream generation is too slow, quantize the weights. If large batches or long prompts saturate the GPU’s arithmetic, quantize the activations too. If long contexts or large batches run out of memory, quantize the KV cache.
  2. Start with post-training quantization, calibrated on data that looks like your traffic.
  3. Evaluate on your task, not only on perplexity. Quantization error can be small on average and still concentrate on long contexts or multi-step reasoning.
  4. Escalate only when needed. If accuracy drops too far, try smaller groups or a microscaling format first, then quantization-aware training or distillation.
Fewer bits are not always faster

A format speeds things up only if your kernels and hardware support it. Weight-only 4-bit helps memory-bound decoding but adds dequantization work to compute-bound prefill. FP8 and FP4 arithmetic need tensor cores that implement them.

The surveys by Gholami et al. (Gholami et al., 2021) and Liu et al. (K. Liu et al., 2025) cover more methods, including the extreme low-bit ones left out here. The white paper by Nagel et al. (Nagel et al., 2021) goes deeper into the fundamentals, and the ApX course on practical LLM quantization (ApX Machine Learning, 2026) shows how to apply them.

  1. ApX Machine Learning. (2026). Practical Quantization for Large Language Models. Online course. https://apxml.com/courses/practical-llm-quantization
  2. Ashkboos, S., Mohtashami, A., Croci, M. L., Li, B., Cameron, P., Jaggi, M., Alistarh, D., Hoefler, T., & Hensman, J. (2024). QuaRot: Outlier-Free 4-Bit Inference in Rotated LLMs. arXiv Preprint arXiv:2404.00456. https://arxiv.org/abs/2404.00456
  3. Frantar, E., Ashkboos, S., Hoefler, T., & Alistarh, D. (2023). GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers. International Conference on Learning Representations (ICLR). https://arxiv.org/abs/2210.17323
  4. Gholami, A., Kim, S., Dong, Z., Yao, Z., Mahoney, M. W., & Keutzer, K. (2021). A Survey of Quantization Methods for Efficient Neural Network Inference. arXiv Preprint arXiv:2103.13630. https://arxiv.org/abs/2103.13630
  5. Lin, J., Tang, J., Tang, H., Yang, S., Dang, X., Gan, C., & Han, S. (2024). AWQ: Activation-aware Weight Quantization for LLM Compression and Acceleration. Proceedings of Machine Learning and Systems (MLSys). https://arxiv.org/abs/2306.00978
  6. Liu, K., Zheng, Q., Tao, K., Li, Z., Qin, H., Li, W., Guo, Y., Liu, X., Kong, L., Chen, G., Zhang, Y., & Yang, X. (2025). Low-bit Model Quantization for Deep Neural Networks: A Survey. arXiv Preprint arXiv:2505.05530. https://arxiv.org/abs/2505.05530
  7. Liu, Z., Yuan, J., Jin, H., Zhong, S., Xu, Z., Braverman, V., Chen, B., & Hu, X. (2024). KIVI: A Tuning-Free Asymmetric 2bit Quantization for KV Cache. Proceedings of the 41st International Conference on Machine Learning (ICML). https://arxiv.org/abs/2402.02750
  8. Liu, Z., Zhao, C., Fedorov, I., Soran, B., Choudhary, D., Krishnamoorthi, R., Chandra, V., Tian, Y., & Blankevoort, T. (2025). SpinQuant: LLM Quantization with Learned Rotations. International Conference on Learning Representations (ICLR). https://arxiv.org/abs/2405.16406
  9. Müller, L. K., Bich, P., Zhuang, J., Çelik, A., Benfenati, L., & Cavigelli, L. (2025). SINQ: Sinkhorn-Normalized Quantization for Calibration-Free Low-Precision LLM Weights. arXiv Preprint arXiv:2509.22944. https://arxiv.org/abs/2509.22944
  10. Nagel, M., Fournarakis, M., Amjad, R. A., Bondarenko, Y., van Baalen, M., & Blankevoort, T. (2021). A White Paper on Neural Network Quantization. arXiv Preprint arXiv:2106.08295. https://arxiv.org/abs/2106.08295
  11. Xia, H., Wu, X., Li, J., Wu, R., Wang, J., Wang, J., Li, C., Singhal, A., Shah, A. D., Ariyak, A., Zhuang, D., Zhou, Z., Athiwaratkun, B., Zheng, Z., & Song, S. L. (2025). Kitty: Accurate and Efficient 2-bit KV Cache Quantization with Dynamic Channel-wise Precision Boost. arXiv Preprint arXiv:2511.18643. https://arxiv.org/abs/2511.18643
  12. Xiao, G., Lin, J., Seznec, M., Wu, H., Demouth, J., & Han, S. (2023). SmoothQuant: Accurate and Efficient Post-Training Quantization for Large Language Models. Proceedings of the 40th International Conference on Machine Learning (ICML). https://arxiv.org/abs/2211.10438