Quantization

Model weights are stored in 16 bits, but they don't need 16 bits — most of that precision is describing differences too small to matter. Quantization throws those bits away, storing each weight in 8, 4, or even fewer, for a model that's smaller and, on the memory-bound side of the roofline, faster. The whole art is doing it without wrecking the accuracy — and a few oversized weights make that surprisingly hard.

1 Spare bits

A trained weight like 0.0143729 is stored in 16-bit floating point, but the model barely cares about the trailing digits — round it to 0.014 and the network behaves almost identically. Multiply that slack across billions of weights and you have a lot of bits doing nothing. Quantization reclaims them, representing each weight with a small integer instead of a float.

FP32 — continuous values INT8 — snap to a small grid of levels outlier — needs care fewer bits = less memory + faster, at the cost of rounding error (worst at outliers)
Quantization stores weights in fewer bits by snapping continuous values onto a small grid of levels. It shrinks the model and speeds up memory-bound work, but every value picks up rounding error — and a few large outliers, if not handled separately, can dominate that error and hurt quality.

The payoff is twofold. The model shrinks — int8 halves it, int4 quarters it — so it fits on smaller or fewer GPUs. And because decode is memory-bound (Chapter 22), moving fewer bytes per weight directly speeds it up: halving the weight size roughly doubles the achievable decode throughput. Smaller and faster, for the price of a little precision.

Precision is mostly slack. Neural-network weights tolerate rounding in a way exact computations don't. That tolerance is what quantization spends — and there's far more of it available than 16 bits suggest.

2 Rounding to a grid

Quantizing to B bits means snapping every weight to one of 2^B evenly spaced levels. You pick a scale that maps the floating-point range onto the integer range, round each weight to the nearest integer, and store that:

q = round(w / scale)  ·  ŵ = q · scale
scale = max|w| ÷ (2^(B−1) − 1). The reconstruction ŵ differs from w by the rounding error.

With 8 bits you have 256 levels — fine enough that the rounding error is tiny and the model is all but unchanged. With 4 bits you have 16 levels, and the spacing between them starts to matter. The error you introduce is exactly the gap between each weight and its nearest level, so everything comes down to placing those levels well.

3 One scale isn't enough

The naive approach uses a single scale for the entire weight matrix — per-tensor quantization. It's simple, but it forces every weight, large and small, onto the same grid. If one part of the matrix has a much wider range than another, the levels get stretched to cover the widest part, leaving the rest of the weights crammed coarsely between a few of them.

The fix is to use more scales. Per-channel quantization gives each row (or column) its own scale, so a quiet channel gets a fine grid and a loud one gets a coarse grid, each appropriate to its range. Group-wise quantization goes further, a separate scale for every block of, say, 128 weights — the modern default, because the handful of extra scale values costs almost nothing and the error drops sharply.

More scales, less error — for almost free. A scale is one number per group; storing it adds a fraction of a bit per weight. In exchange, every group gets a grid sized to its own weights, which is most of what makes 4-bit quantization viable at all.

4 The outlier problem

Here's what actually breaks low-bit quantization: outliers. A small number of weights — and, even more troublesome, a small number of activation channels — have magnitudes many times larger than everything else. Because the scale is set by the maximum, a single outlier stretches the grid so wide that all the ordinary weights collapse onto just a couple of levels. One weight ruins the precision of thousands.

The methods you hear about — GPTQ, AWQ, and friends — are mostly clever ways to handle outliers. Some keep the salient weights in higher precision while quantizing the rest; AWQ scales weights by how much their activations matter, protecting the ones that do; GPTQ adjusts the remaining weights to compensate for the error introduced. All of them exist because, without outlier handling, four-bit quantization falls apart.

A few weights hold the precision hostage. Outliers are why "just round it to 4 bits" doesn't work, and why a whole research literature grew up around quantization. Protect the outliers and the rest quantizes beautifully; ignore them and the model degrades fast.

5 Quality vs size

Put the curve together and a clear story emerges. Int8 is, for most models, effectively lossless — half the size, no measurable quality drop, an easy win. Int4 with group-wise scales and proper outlier handling loses very little and is the workhorse of local model serving. Push below four bits — three, two — and quality starts dropping off a cliff that no amount of cleverness fully arrests.

So quantization isn't a free lunch all the way down; it's a steep trade-off curve, and the sweet spot for inference today sits around 4 bits. The same arithmetic applies to the KV cache (Chapter 13) and even to training in lower precision — but the principle is always the one the playground makes visible: find the bits that aren't carrying information, and only those.

Int8 is free; int4 is cheap; below that, you pay. The quality-versus-size curve is gentle down to about four bits and steep below it. Knowing where that knee is — for your model and your tolerance — is the whole decision.

6 Reading the playground

A real weight tensor — a realistic distribution with a few genuine outliers — is quantized live at the bit-width and method you choose, and the reconstruction error is measured directly. The numbers are exact arithmetic on the tensor in front of you.

The weight histogram with the quantization grid laid over it. An outlier under per-tensor stretches the grid so the bulk falls between just a few levels.

Choose the bits and the method, toggle outlier protection, and watch the reconstruction error and the compression ratio respond.

The error-versus-bits curve for each method — the gentle slope to 4 bits, the cliff below.

The reading is the setup. The playground is the point.

Quantize the tensor 2,048 real weights · gaussian bulk + a few outliers
Bits
Method
Step 1 · weights on the quantization grid histogram of the bulk; level lines for the per-tensor grid
reconstruction error
effective bits / weight
compression
levels
Step 2 · error vs bits measured on this tensor, per method

Reconstruction error by bit-width

Per-tensor (orange) is wrecked by the outlier at low bits; group-wise (teal) holds. Note the gentle slope to 4 bits and the cliff below.

per-tensorper-channelgroup-wise

The bytes you keep

int8 ≈ ½ the size, near-lossless. int4 ≈ ¼ the size, the inference workhorse. Below 4 bits the error climbs faster than the size falls.