A served model's weights are read from memory on every token. The cheapest way to
make inference smaller and faster is therefore not to change the architecture at all, but to
store each weight in fewer bits.
The trick is a tiny linear map: pick a scale
Step 1 — fix the integer grid. With
Step 2 — map a real weight onto the grid. Given a weight
Step 3 — recover an approximate weight. To use the integer in a matmul we
invert the map. Undo the shift, then undo the scaling — this dequantizes back
to a near-copy
It is only near: rounding in Step 2 throws away everything finer than one level, so
Step 4 — count the memory. A weight stored in fp16 costs
INT8 halves the model; INT4 quarters it. (A small per-group
Step 5 — the outlier catch. A naive scale stretches the grid to cover the
single largest-magnitude weight. If most weights sit near
Step 6 — quantize carefully. The fix is not one global
It is tempting to treat quantization as a free lunch — smaller and faster, no downside. It isn't. Rounding every weight to a handful of integer levels throws away real information, and if that is done carelessly — one global scale, every layer squeezed to the same low bit-width — the model's outputs can noticeably degrade: garbled reasoning, worse factual accuracy, or a model that quietly gets easy questions wrong. The damage isn't spread evenly either; some layers (often the first and last, or ones carrying large outlier activations) are far more sensitive to coarse rounding than the rest.
That is exactly why real quantization pipelines rarely quantize everything to the same low precision. Mixed-precision quantization keeps the handful of sensitive weights or layers at fp16 (or INT8) while pushing the bulk of the model down to INT4 — trading a smaller memory win for keeping the accuracy that matters. Treat "we quantized the model" as a spectrum, not a single decision: the real questions are always how much, where, and how carefully calibrated.
The quantizer above is weight-only: the stored weights are integers, but they are dequantized to 16-bit on the fly and the matmul runs in 16-bit. That alone wins because inference is memory-bandwidth-bound — each decoded token must read every weight once, so halving the bytes nearly halves the time spent moving them, even though the arithmetic is unchanged.
Activation quantization goes further and stores the activations in low precision too, so the matmul itself runs in integer arithmetic (e.g. INT8 × INT8). That can use faster integer tensor cores, but activations carry their own, larger outliers, so it is harder to do without losing accuracy. The common sweet spot for serving is therefore weight-only INT8/INT4: most of the bandwidth win, little of the risk.
The dots are a spread of continuous fp16 weights; the ticks below are the