AnyLearn
All lessons
AIadvanced

Outliers: Why Large Models Resist Naive Quantization

Round-to-nearest works on small models and falls apart on large ones, because beyond a certain scale transformers grow systematic activation outliers in a few fixed channels, a hundred times larger than everything else. This lesson shows arithmetically why one outlier destroys a tensor, then works through the three families of fix: decompose, smooth, and rotate.

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

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

Round to nearest, and where it stops working

The naive method is round-to-nearest: compute a scale from the observed range, divide, round, done. No calibration data, no optimisation, a few seconds of work.

It is entirely adequate in three cases. Weights at 8 bits, on models of any size. Weights at 4 bits on small models. And anything at 16 bits, where there is nothing to fix.

It fails in two, and the pattern of failure is the subject of this lesson. Weights at 4 bits on large models degrade noticeably, which the algorithms in the next lesson address. And activations at 8 bits collapse on large models, which no amount of clever rounding fixes.

That second failure is the strange one. Activations at 8 bits should be easy: 256 levels is generous for values that mostly sit within a small range. The reason it breaks is not about rounding at all. It is about what large transformers do to their own activation distributions.

Full lesson text

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

Show

1. Round to nearest, and where it stops working

The naive method is round-to-nearest: compute a scale from the observed range, divide, round, done. No calibration data, no optimisation, a few seconds of work.

It is entirely adequate in three cases. Weights at 8 bits, on models of any size. Weights at 4 bits on small models. And anything at 16 bits, where there is nothing to fix.

It fails in two, and the pattern of failure is the subject of this lesson. Weights at 4 bits on large models degrade noticeably, which the algorithms in the next lesson address. And activations at 8 bits collapse on large models, which no amount of clever rounding fixes.

That second failure is the strange one. Activations at 8 bits should be easy: 256 levels is generous for values that mostly sit within a small range. The reason it breaks is not about rounding at all. It is about what large transformers do to their own activation distributions.

2. The emergent outlier phenomenon

Dettmers and colleagues documented the effect while developing LLM.int8(), and the shape of it is consistent enough to plan around.

Beyond roughly 6.7 billion parameters, transformers develop systematic outlier features in their activations. Three properties make them pathological for quantization.

They are large. Reported magnitudes reach around a hundred times the typical activation value, with other work observing per-channel ranges twenty to a hundred times the majority.

They are concentrated. The outliers do not scatter randomly. They occupy a small number of fixed dimensions of the hidden state, the same dimensions across inputs.

And they are persistent. Those channels carry outlier values on almost every token, rather than on rare inputs you could treat as exceptions.

The useful summary is that variance across channels is enormous while variance across tokens within one channel is small. That asymmetry is not a defect to be trained away. It is the structure every serious activation quantization method is built around.

3. Why one outlier destroys a whole tensor

The damage is easy to see arithmetically, and doing so makes every later fix obvious.

Take a tensor whose values mostly sit between minus 1.5 and 1.5, and quantize symmetrically to 8 bits with 127 positive levels. The step size is 1.5 over 127, which is 0.0118. A value of 1.0 maps to level 85. Plenty of resolution.

Now introduce a single outlier of 100. The scale is set by the largest absolute value, so the step becomes 100 over 127, which is 0.787.

Re-quantize the ordinary values against that grid. A value of 1.0 maps to level 1. A value of 0.5 also maps to level 1. A value of 0.3 maps to level 0 and disappears entirely.

An 8-bit grid with 256 levels has, in effect, been reduced to about three usable levels for the values that carry most of the signal. One number consumed the entire dynamic range, and it did so through the scale, not through the rounding.

4. Why weights are the easy half

The same reasoning explains an asymmetry that governs the whole field: weights quantize far more readily than activations.

Weights are static. They are fixed after training, so you can inspect the actual distribution, choose scales offline, and spend as much computation as you like getting it right. Nothing about the input changes them.

Weights are also better behaved. Their per-channel distributions are roughly bell-shaped around zero without the extreme fixed-channel structure activations show, so per-channel or per-group scaling already handles most of the range problem.

Activations are neither. They depend on the input, so scales must either be computed at runtime, which costs a reduction over the tensor before every matrix multiply, or estimated from calibration data, which risks a mismatch when real traffic differs.

This is why W4A16 is routine and W4A4 is a research frontier, and why every technique in the rest of this lesson exists to make activations behave more like weights.

5. Fix one: decompose

The first response is the most direct. If a few channels are the problem, take them out of the quantized path.

LLM.int8() applies mixed-precision decomposition. It identifies the outlier dimensions, computes their contribution to the matrix multiply in 16-bit, computes everything else in 8-bit, and sums the two results. Because outliers occupy a small fraction of dimensions, almost all of the arithmetic still runs at 8 bits, and accuracy is preserved at essentially the 16-bit level.

The method is correct and its costs are structural rather than incidental. Splitting a matrix multiply into two paths with irregular, data-dependent column selection is unfriendly to hardware built for dense regular work. Kernels grow complex, memory access becomes scattered, and the realised speedup falls short of what the bit width suggests.

Decomposition is best understood as the correctness-first answer: it proved outliers were the cause, and it made 8-bit inference usable, while leaving the performance question to the approaches that followed.

6. Three ways to handle a spike

The three families differ in what they do to the outlier, and understanding that distinction is enough to choose between them.

Decomposition leaves the outlier where it is and routes around it. The tensor is split, the awkward channels are computed at high precision, and the results are added. The distribution is unchanged; the pipeline works around it.

Smoothing shrinks the outlier by dividing its channel down, and compensates by scaling the matching weight row up. The product is identical, but difficulty has moved from the activation side to the weight side, where per-channel scaling already handles it.

Rotation removes the outlier's privileged position entirely. Multiplying by an orthogonal matrix mixes every channel into every other, so the large value is spread across the whole hidden dimension instead of concentrating in one place.

Only the last one actually changes the distribution being quantized. That is why rotation is the family that opened 4-bit activations, where the other two still struggle.

flowchart TD
A["Activation tensor with a few huge channels"] --> B["Decompose: outlier channels in 16-bit, rest in 8-bit"]
A --> C["Smooth: divide activation channel, multiply weight row"]
A --> D["Rotate: orthogonal mixing spreads the spike"]
B --> E["Accuracy kept, kernels irregular"]
C --> F["Difficulty moved to the weights, enables W8A8"]
D --> G["No channel is special, enables 4-bit activations"]

7. Fix two: smooth the difficulty across

SmoothQuant, from Xiao and colleagues at ICML 2023, starts from an algebraic observation. In the product of an activation matrix and a weight matrix, you can divide activation channel j by any positive number and multiply the corresponding row of the weight matrix by the same number, and the result is unchanged.

So choose those numbers to make both sides easy. Divide the outlier channels down until their range resembles the others, and push the compensating factor into the weights, which tolerate a wider range because they are static and quantized per channel.

The scale for channel j is the maximum absolute activation in that channel raised to the power alpha, divided by the maximum absolute weight in the matching row raised to the power one minus alpha. Alpha controls the migration: zero leaves activations untouched, one moves all the difficulty to the weights, and 0.5 is the usual starting point.

The scales fold into the preceding layer's parameters offline, so at inference time the transformation is free. That is what makes W8A8 practical on hardware built for dense arithmetic.

8. Fix three: rotate the outlier away

Smoothing reduces the spike. Rotation removes the concept of a privileged channel altogether.

The idea, developed in work such as QuaRot, is to insert an orthogonal matrix and its inverse into the computation. Because the two cancel, the function the network computes is unchanged. But the values being quantized are now expressed in a rotated basis.

A rotation mixes every input channel into every output channel. A value a hundred times larger than its neighbours no longer sits alone in dimension 2047; its energy is distributed across the whole hidden dimension. The resulting distribution is closer to Gaussian and has a far smaller ratio between its largest and typical magnitudes, which is exactly what a uniform grid wants.

Randomised Hadamard transforms are the usual choice, because they can be applied in time proportional to n log n rather than n squared, and many rotations can be fused into adjacent weight matrices offline.

This is the family that made 4-bit activations tractable rather than merely conceivable.

9. Sensitivity is not uniform

One more piece of structure matters, and it is the reason serious formats are never a single bit width applied everywhere.

Different parts of a transformer tolerate quantization very differently. Attention projections and the layers at the very start and end of the network tend to be more sensitive than the wide feed-forward blocks in the middle, which contain most of the parameters and much of the redundancy.

That combination is fortunate. The sensitive tensors are a small share of total weight bytes, so raising their precision costs little, while the tolerant tensors are where the memory actually is.

The GGUF k-quant family in llama.cpp is built on exactly this. A file labelled Q4_K_M is not uniformly 4-bit. The K denotes the k-quant family, the M denotes the medium variant, and the scheme assigns higher precision to attention tensors while keeping feed-forward weights lower. The average lands near the nominal bit width while the damage concentrates where it matters least.

When you see a mixed-precision recipe, this is the observation it encodes.

10. Choosing among the three

The families are not competitors so much as answers to different questions, and modern pipelines combine them.

FamilyWhat it does to the outlierEnablesMain cost
DecomposeRoutes around it in higher precisionW8A8 with high fidelityIrregular kernels, weaker speedup
SmoothShrinks it, pays for it in the weightsW8A8 on dense hardwareOne hyperparameter to tune per model
RotateSpreads it across all channels4-bit activationsExtra transforms, more implementation work

A practical ordering. If you only need weight-only quantization, none of this is required: go straight to the algorithms in the next lesson. If you want W8A8 for compute-bound serving, smoothing is the standard route and is usually built into the toolchain. If you are pushing to 4-bit activations, rotation is what makes it work.

And across all three, the sensitivity structure argues for mixed precision rather than one bit width everywhere.

Check your understanding

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

  1. What characterises the emergent outliers that make large-model activation quantization hard?
    • They appear randomly across dimensions on rare inputs
    • They are large, confined to a small number of fixed hidden dimensions, and present on almost every token
    • They only occur during training, not inference
    • They are an artefact of low-precision weights
  2. A tensor whose values mostly lie within plus or minus 1.5 contains one value of 100. Quantized symmetrically to 8 bits, what happens to a typical value of 0.3?
    • It maps to level 25 with minor error
    • It is clipped to the maximum level
    • It rounds to level 0 and disappears, because the outlier set the step size to about 0.787
    • It is stored separately in 16-bit precision automatically
  3. Why are weights easier to quantize than activations?
    • Weights are stored in fewer dimensions
    • Activations are always sparse
    • Weights use floating point while activations use integers
    • Weights are static, so their distribution can be analysed offline, and they lack the extreme fixed-channel outlier structure activations show
  4. What does SmoothQuant do?
    • Divides each activation channel by a factor and multiplies the matching weight row by the same factor, leaving the product unchanged
    • Trains the model to stop producing outliers
    • Stores outlier channels in 16-bit and the rest in 8-bit
    • Applies a Hadamard transform to spread outliers across channels
  5. Why does rotating into an orthogonal basis help more than smoothing at very low bit widths?
    • It reduces the number of weights that must be stored
    • It shrinks outliers by a constant factor chosen per layer
    • It mixes every channel into every other, so no channel keeps a privileged large magnitude and the distribution becomes closer to Gaussian
    • It moves the computation onto integer tensor cores

Related lessons

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
AI
intermediate

Ten Domains, and a Profile That Is Not Flat

The framework scores ten cognitive domains at ten percent each. Running it produces something more useful than the headline totals of 27 percent for GPT-4 and around 57 for GPT-5: a jagged profile, where a model is at or near full marks on some domains and at zero on others. This lesson walks the domains, reads both profiles column by column, and shows what the jaggedness explains.

8 steps·~12 min