AnyLearn
All lessons
AIadvanced

What Quantization Actually Does to a Number

Decoding is memory-bandwidth-bound, so fewer bits per weight means more tokens per second, not fewer. This lesson builds the mechanism from the arithmetic up: the affine mapping, a worked example done by hand, why group size costs fractional bits, the difference between W4A16 and W8A8, and which formats the hardware actually accelerates.

Updated · AI-authored, review-gated · how lessons are made

Not signed in: your progress and quiz score won't be saved.
Progress1 / 10

Why this is the highest-leverage lever

Generating one token from a transformer requires reading every weight from memory once. Not once per batch item, once per forward pass. At batch size one the arithmetic units are idle most of the time, waiting on memory.

That makes decoding memory-bandwidth-bound, and it gives quantization an unusual property. Compression normally costs speed: you trade cycles to save space. Here it buys both. Fewer bytes per weight means fewer bytes to move, which means more tokens per second.

Put numbers on it. A 70-billion-parameter model at 16 bits per weight is 140 GB. On a GPU with roughly 3 TB/s of memory bandwidth, the ceiling is about 21 tokens per second, before any compute at all.

The same model at 4 bits is around 36 GB, and the ceiling rises to about 82 tokens per second. Same hardware, same model, roughly four times the throughput ceiling, and it now fits where it previously did not.

Full lesson text

All 10 steps on one page, for reading, reference, and search.

Show

1. Why this is the highest-leverage lever

Generating one token from a transformer requires reading every weight from memory once. Not once per batch item, once per forward pass. At batch size one the arithmetic units are idle most of the time, waiting on memory.

That makes decoding memory-bandwidth-bound, and it gives quantization an unusual property. Compression normally costs speed: you trade cycles to save space. Here it buys both. Fewer bytes per weight means fewer bytes to move, which means more tokens per second.

Put numbers on it. A 70-billion-parameter model at 16 bits per weight is 140 GB. On a GPU with roughly 3 TB/s of memory bandwidth, the ceiling is about 21 tokens per second, before any compute at all.

The same model at 4 bits is around 36 GB, and the ceiling rises to about 82 tokens per second. Same hardware, same model, roughly four times the throughput ceiling, and it now fits where it previously did not.

2. The affine mapping

Quantization maps a continuous range onto a small set of integers. The standard form is affine.

To quantize: q equals round of x divided by s, plus z, clamped to the representable range. To recover: x_hat equals s times the quantity q minus z.

Here s is the scale, a positive floating point number giving the spacing between adjacent levels, and z is the zero point, an integer offset that lets the grid represent an asymmetric range.

Two variants matter. Symmetric quantization sets z to zero and derives the scale from the largest absolute value: s equals absmax divided by the largest positive level. The grid is centred on zero, which is a good fit for neural network weights, and dequantization is a single multiply.

Asymmetric quantization derives the scale from the full range, s equals max minus min divided by the number of levels minus one, and picks z so that real zero maps exactly onto a grid point. That costs an extra subtraction but wastes no levels when the distribution is one-sided, as after a ReLU.

3. Doing it by hand

Take eight weights and quantize them symmetrically to 4 bits, using levels minus 7 through 7.

The values: 0.12, -0.35, 0.87, -1.42, 0.05, 0.63, -0.21, 1.10. The largest absolute value is 1.42, so the scale is 1.42 divided by 7, which is 0.202857.

Divide each weight by the scale and round.

WeightLevelDequantizedError
+0.12+1+0.20290.0829
-0.35-2-0.40570.0557
+0.87+4+0.81140.0586
-1.42-7-1.42000.0000
+0.0500.00000.0500
+0.63+3+0.60860.0214
-0.21-1-0.20290.0071
+1.10+5+1.01430.0857

Root mean squared error: 0.0545.

Two things to notice. The value that set the scale is reproduced exactly, and everything else absorbs the error. And 0.05 collapsed to zero, because it fell below half a step. Small weights near a large one do not survive.

4. Granularity, and the bits you pay for metadata

The previous example used one scale for eight weights. Real implementations choose a granularity, and it is the single most consequential knob after bit width.

Per-tensor uses one scale for an entire weight matrix. Cheapest in metadata, worst in accuracy, because one extreme value sets the step size for millions of weights.

Per-channel uses one scale per output channel, typically a row or column. Standard for weights, since each output neuron gets its own range.

Per-group subdivides further, one scale per contiguous block of 32, 64 or 128 weights. This is what makes 4-bit weight quantization viable, because an unusually large weight now only damages its own group.

Metadata is not free. With a 16-bit scale and a 4-bit zero point per group, the true cost per weight is 4 plus 16 over the group size plus 4 over the group size. At group size 128 that is 4.156 bits. At 64 it is 4.313. At 32 it is 4.625, which is a sixteen percent overhead over the nominal 4 bits.

5. Weight-only versus weight-and-activation

The notation WxAy names the bit width of weights and of activations. It tells you what a scheme actually buys.

W16A16 is the unquantized baseline, usually bfloat16 or float16.

W4A16 is weight-only quantization. Weights are stored at 4 bits and dequantized back to 16 bits inside the kernel, immediately before the matrix multiply. The arithmetic still happens in 16-bit. You gain memory and bandwidth, and therefore decode speed, but no arithmetic throughput. This is what GPTQ, AWQ and most GGUF files give you.

W8A8 quantizes both. Now the matrix multiply itself can run on integer or 8-bit-float tensor cores, so you gain arithmetic throughput too. That matters for prefill and for large batches, which are compute-bound rather than bandwidth-bound.

W4A4 is the aggressive frontier and requires the outlier handling the next lesson covers.

The practical consequence: if your workload is single-stream chat, weight-only is enough. If you are serving high-concurrency traffic or processing long prompts, activation quantization is where the remaining gain lives.

6. Where the dequantization happens

The difference between weight-only and full quantization is a question of where in the pipeline values return to high precision.

In a W4A16 path, the packed 4-bit weights are read from memory, unpacked and multiplied by their group scales inside the kernel, and the matrix multiply runs in 16-bit. The bandwidth saving is real because only 4-bit data crossed the memory bus. The compute saving is zero because the multiply is unchanged.

In a W8A8 path, activations are quantized on the fly, the multiply runs natively on 8-bit tensor cores, and the integer accumulator is rescaled once at the end. Both bus and arithmetic units benefit.

The diagram makes the asymmetry visible. Weight-only narrows one arrow. Full quantization narrows the arrow and swaps the engine.

This is also why a 4-bit model can be slower than an 8-bit one at high batch sizes: the dequantization work is per-weight, and once you are compute-bound rather than bandwidth-bound, it is pure overhead.

flowchart LR
A["Packed 4-bit weights in memory"] --> B["Unpack and apply group scales"]
B --> C["16-bit matrix multiply"]
C --> D["16-bit output"]
E["8-bit weights in memory"] --> F["8-bit tensor core multiply"]
G["Activations quantized on the fly"] --> F
F --> H["Integer accumulator"]
H --> I["Rescale once to 16-bit output"]

7. Integer grids are not the only grids

Uniform integer levels are the obvious choice, and often the wrong one, because weight distributions are not uniform. They are roughly bell-shaped around zero, so uniform spacing wastes levels in the sparse tails and starves the dense centre.

NF4, introduced with QLoRA by Dettmers and colleagues, addresses this directly. It is a 4-bit NormalFloat type built by quantile quantization: the 16 levels are placed so that a normally distributed input lands in each bin equally often. For weights that really are near-Gaussian, this is information-theoretically optimal, and it beats uniform INT4 at the same bit width for free.

Floating point grids are the other family. FP8 comes in two encodings: E4M3, with four exponent and three mantissa bits, representing roughly plus or minus 448; and E5M2, with more range, roughly plus or minus 57344, and less precision. The convention is E4M3 for weights and activations, E5M2 where the wider dynamic range of gradients is needed.

Floating point grids spend their resolution proportionally, which suits values spanning several orders of magnitude.

8. Microscaling, and what the hardware accelerates

A format only pays off if silicon executes it. That constraint has shaped the recent generation of 4-bit formats.

Microscaling formats combine a low-precision element type with a shared scale over a small block, putting group-wise quantization directly into the number format rather than into software around it.

MXFP4 encodes blocks of 32 elements with an 8-bit exponent-only scale, of type E8M0. NVFP4 uses blocks of 16 with an E4M3 scale, trading more metadata for finer granularity and better accuracy.

NVIDIA's Blackwell generation supports FP4 natively in its fifth-generation tensor cores, alongside FP16 and FP8, with accumulation in higher precision. Where earlier 4-bit work was weight-only, unpacked into 16-bit before the multiply, hardware here executes the low-precision multiply directly.

The lesson generalises beyond any one vendor. Check what your target accelerates natively before selecting a format. A scheme with better paper accuracy that must be emulated in software will usually lose to a slightly worse one the hardware runs directly.

9. Sizing a real model

Put the arithmetic together for a 70-billion-parameter model, counting only weights.

At 16 bits: 70 billion times 2 bytes is 140 GB. That needs at least two 80 GB accelerators, so you pay for tensor parallelism and the interconnect it demands.

At 8 bits: 70 GB. One 80 GB accelerator holds the weights, leaving roughly 10 GB for KV cache and activations, which is tight but workable.

At 4 bits with group size 128: 70 billion times 4.156 bits over 8 is about 36.4 GB. Now more than half the device is free for KV cache, which is what actually determines how many concurrent requests you can serve.

That last point is the one people miss. Quantizing weights does not only make the model fit. It converts saved weight memory into KV cache capacity, and KV cache capacity is concurrency. The throughput gain from serving four times as many simultaneous sequences usually dwarfs the per-token bandwidth gain.

10. What quantization is not

Three neighbouring techniques get confused with quantization, and keeping them separate keeps the decisions clean.

Pruning removes weights, setting them to zero and ideally skipping them. Quantization keeps every weight and stores each one less precisely. Pruning changes the shape of the computation; quantization changes its precision.

Distillation trains a smaller model to imitate a larger one. It produces a genuinely different model with different parameters. Quantization produces the same model at lower fidelity, with no training required in the post-training case.

Low-rank factorisation approximates a weight matrix by a product of thinner matrices. That changes the parameter count. Quantization leaves the count untouched.

The practical significance is that these compose. You can distil, then quantize the student. You can prune, then quantize what remains. And their failure modes differ: a quantized model degrades smoothly and predictably in most cases, while an over-pruned one tends to fail abruptly.

Check your understanding

The lesson ends with a 5-question quiz. Take it in the player above to see your score.

  1. Why does quantization usually increase decoding speed rather than cost it?
    • Because integer arithmetic is always faster than floating point
    • Because decoding is memory-bandwidth-bound, so fewer bytes per weight means fewer bytes to move per token
    • Because quantized models have fewer parameters
    • Because the compiler can vectorise integer code more aggressively
  2. Weights are quantized to 4 bits with a 16-bit scale and a 4-bit zero point per group of 128. What is the true cost per weight?
    • Exactly 4 bits, since metadata is stored separately
    • 8 bits, because the scale doubles the storage
    • About 4.156 bits, since the scale and zero point are amortised across 128 weights
    • About 4.625 bits
  3. A model is served as W4A16. What does that buy?
    • Memory and bandwidth savings, and therefore decode speed, but no arithmetic throughput gain
    • Both memory savings and native 4-bit tensor core arithmetic
    • Faster prefill but slower decoding
    • A reduction in the number of parameters
  4. What makes NF4 different from uniform INT4 at the same bit width?
    • It uses 5 bits internally and truncates
    • It requires quantization-aware training to work
    • It stores the sign separately from the magnitude
    • Its levels are placed by quantile so that normally distributed weights fall into each bin equally often
  5. Beyond making the model fit, why does quantizing weights raise serving throughput so much?
    • It reduces the number of layers that must be executed
    • The freed memory becomes KV cache, which raises how many sequences can be served concurrently
    • It allows the model to skip attention entirely at low precision
    • It shortens the context window requirement

Related lessons

AI
advanced

Finding the Next One: Fusion Beyond Attention

The pattern that made attention slow recurs across the stack, and once you know what to look for it is easy to find. This lesson applies the diagnosis to normalisation layers, optimizer steps, loss functions and inference decoding, covers why fused attention silently stops applying when a model deviates slightly from standard, and gives the profiling routine that decides where to look first.

10 steps·~15 min
AI
intermediate

What This Teaches About Measuring Anything

The exchange is a case study with transferable rules. A conclusion resting on failures needs a failure taxonomy. Every instance must be verified solvable before anyone is scored against it. Output format is a confound whenever answers get long. And when two explanations fit the same data, the productive move is to find the prediction on which they differ, then test it.

8 steps·~12 min
AI
intermediate

The Rebuttal: Three Ways to Score Zero Without Failing

The response disputed none of the data and argued the experiment measured something other than reasoning. Models had to print move lists exceeding their output limits, and said so in the transcripts. Some instances had no solution and were scored as failures anyway. And asking for a program instead of a move list produced high accuracy on instances reported as total collapse.

8 steps·~12 min
AI
intermediate

The Experiment: Puzzles With a Difficulty Dial

Apple researchers built an evaluation designed to fix a real problem with benchmarks: puzzles where difficulty turns up smoothly while the logic stays identical, and every step can be checked. They found accuracy collapsing to zero past a threshold, and not improving when the solution algorithm was handed to the model. This lesson covers the design and why it was a good one.

8 steps·~12 min