Inference Optimisation advanced 8 min read 12 flashcards

Activation Outliers and Rotation-Based Quantisation

A handful of channels in every transformer carry activations a hundred times larger than the rest, which is why activation quantisation fails where weight quantisation succeeds, and why rotating the hidden state fixes it.

Weight-only quantisation is comparatively easy because weight distributions are well behaved: roughly Gaussian, similar across channels, and static. Activations are neither. Past a few billion parameters, transformers develop systematic outlier channels, a small set of hidden dimensions whose activations are one to two orders of magnitude larger than everything else, consistently across inputs.

This is fatal for per-tensor activation quantisation. The scale factor must cover the outlier's range, so the remaining 99.9% of values compress into a handful of the 256 available int8 levels, and the effective precision collapses to two or three bits. Weight quantisation succeeds while activation quantisation fails, and the reason is entirely distributional.

Migrating the difficulty

SmoothQuant's insight is that the difficulty can be moved. For a linear layer \(Y = XW\), insert a diagonal matrix \(s\):

\[Y = (X \, \mathrm{diag}(s)^{-1})(\mathrm{diag}(s) \, W)\]

The product is mathematically unchanged. Choosing \(s\) larger on outlier channels shrinks those activation channels and grows the corresponding weight rows. Since weights had headroom and activations did not, both sides end up quantisable, and the scaling folds into the preceding LayerNorm at no runtime cost.

SmoothQuant reported W8A8 quantisation with up to 1.56x speedup and 2x memory reduction at negligible accuracy loss, enabling a 530B model on a single node (Xiao et al., 2022, SmoothQuant, ICML 2023, arXiv:2211.10438).

The limitation: a diagonal rescale only redistributes magnitude between the two sides of one matmul. It does not remove outliers, and at 4 bits there is not enough headroom on either side to hide them.

Rotating them away

The stronger idea is to change the basis. Insert an orthogonal matrix \(Q\) and its inverse around a computation:

\[XW = (XQ)(Q^{\top}W)\]

If \(Q\) is a random rotation, in particular a randomised Hadamard transform, the outlier's energy is spread across all dimensions of \(XQ\). The result is a hidden state that is approximately isotropic and has no outlier channels at all, and because \(Q\) is orthogonal it can often be folded into adjacent weight matrices so it costs nothing at inference.

QuaRot applies this throughout the network, making it possible to run all matrix multiplications in 4 bits, with weights, activations and KV cache all quantised and no channels retained in higher precision. On LLaMA2-70B it reported at most 0.47 WikiText-2 perplexity loss and 99% of zero-shot performance retained, with 6- and 8-bit variants lossless and requiring no calibration data (Ashkboos et al., 2024, QuaRot, arXiv:2404.00456).

SpinQuant asked the obvious follow-up: if a random rotation helps, does an optimised one help more? It learns rotation matrices on the Stiefel manifold rather than sampling them, narrowing the 4-bit gap to full precision to 2.9 points on LLaMA-2 7B zero-shot reasoning, ahead of SmoothQuant by 25.0 points and LLM-QAT by 19.1, and closing up to 45.1% of QuaRot's remaining gap on LLaMA-3 8B (Liu et al., 2024, SpinQuant, ICLR 2025, arXiv:2405.16406).

Why anyone bothers, given weight-only works

Weight-only quantisation shrinks memory traffic but leaves arithmetic in bf16. Quantising activations too lets the matmul itself run on int8 or int4 tensor cores, which is where the raw FLOPS are. That matters in two regimes weight-only cannot help:

  • Prefill, which is compute bound rather than bandwidth bound.
  • Large-batch serving, where the weight read is amortised across many sequences and arithmetic dominates again.

Full 4-bit inference also quantises the KV cache, which is what actually limits long-context batch size.

When it breaks

Rotations are not free everywhere. A rotation that cannot be folded into an adjacent weight matrix has to run as an online Hadamard transform. It is \(O(d \log d)\) and cheap in theory, but it is an extra kernel launch on the critical path and needs a good implementation to stay cheap in practice.

RMSNorm compatibility is a precondition. Folding rotations through the network relies on the computational invariance of RMSNorm-style architectures. Models with learned per-channel LayerNorm affine parameters require extra care, and the invariance argument does not transfer for free.

Outliers move under fine-tuning. Outlier channels are a property of the trained weights. Fine-tune, merge adapters, or continue pretraining, and the calibration or learned rotation may no longer match. Requantise after any weight change; this is routinely forgotten in LoRA-merge pipelines.

Hardware support is the real constraint. Int4 tensor-core throughput exists on recent accelerators and not on older ones. A 4-bit method whose kernels fall back to dequantise-then-bf16 gives you the memory win and none of the compute win.

Check yourself

12 flashcards for this concept

Click a card to reveal the answer.

Drill the whole track