INT8 Quantization › Smooth Quantization
Language AI HandbookAll chapters INT8 Quantization › Smooth QuantizationOne section · Sections in this chapter8 / 15 ↓
Reading tools Definitions & inline links
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
The key insight behind smooth quantization is that while activations are hard to quantize (dynamic, contain outliers), weights are easy to quantize (static, relatively uniform). We can mathematically migrate the quantization difficulty from activations to weights through a channel-wise scaling transformation, making the problem tractable.
The intuition is straightforward. If one matrix is "spiky" with outliers and another is "smooth" and well-behaved, we can transfer some of the spikiness from the first to the second. As long as we do this in a mathematically consistent way that preserves the final computation, we have not changed the model's behavior, only redistributed the quantization difficulty to where it is easier to handle. Think of smooth quantization as a seesaw: we load more weight (quantization difficulty) onto the weight side, which can bear it, and unload the activation side, which was struggling under the strain.
The insight that makes this possible is that the product is unchanged if we multiply by some diagonal matrix and also multiply by . These operations are inverses and cancel out. But while they cancel mathematically, they can sharply change the magnitude distributions of both matrices, making each individually much easier to quantize. The question is just how to choose to optimally redistribute the difficulty.
The Mathematical Equivalence
Consider a linear layer computing , where is the activation input and is the weight matrix. We introduce a diagonal matrix with positive scaling factors, then insert between the two matrices:
where:
- : the output of the linear layer, unchanged by this transformation
- : the input activation tensor with outlier channels
- : the weight matrix with relatively uniform distribution
- : the diagonal smoothing matrix containing scaling factors for each input dimension
- : the smoothed activations, where each column is divided by
- : the adjusted weights, where each row is multiplied by
This transformation is mathematically exact since . We have not changed the computation, just how we factor it. The key mathematical property we exploit is that multiplying by a matrix and then its inverse produces the identity, so inserting between and changes nothing about the final result. We are free to group these factors however we like, and we choose to group with the activations and with the weights.
The transformation affects the data as follows: smoothed activations divide each column of by , which shrinks outlier channels by choosing large values. Meanwhile, adjusted weights multiply each row of by the same , increasing the magnitude of those rows to compensate. If channel has outlier activations, we choose a large . This shrinks the activations (making them easier to quantize) while enlarging the corresponding weights (which are already easy to quantize). We are transferring the outlier problem to a domain where it is more manageable.
Choosing the Smoothing Factors
How do we pick the values? If we make too large, we might shrink the activations so much that we lose precision in other ways, or we might inflate the weights to the point where they become hard to quantize. The optimal choice balances these competing concerns, and the SmoothQuant paper proposes a principled way to reach this balance.
The SmoothQuant paper proposes balancing the quantization difficulty between activations and weights using a migration strength parameter :
where:
- : the smoothing factor for the -th input channel
- : the maximum absolute value in the -th column of activations, measured across a calibration dataset
- : the maximum absolute value in the -th row of weights
- : the migration strength hyperparameter controlling how much difficulty shifts from activations to weights
This formula balances two competing goals. When , we have , which fully smooths the activations by dividing each channel by its maximum. This makes the activations perfectly balanced but potentially makes weights hard to quantize. When , we have , which leaves activations unchanged. The intermediate value gives the geometric mean, which ensures that after transformation, the maximum activation and maximum weight for each channel have roughly equal magnitude, spreading the quantization difficulty evenly.
To understand this formula intuitively, consider what "equal difficulty" means. After applying the transformation, the smoothed activation maximum for channel is , and the adjusted weight maximum is . For these to be equal:
Solving for :
This is exactly the case of the SmoothQuant formula, confirming that is the "equal difficulty" point. Values above 0.5 shift more difficulty to the weights, values below 0.5 leave more with the activations.
In practice, works well for most models, achieving roughly equal quantization ranges for both activations and weights after smoothing. However, some models may benefit from different values. Models with particularly severe activation outliers might use to more aggressively smooth the activations, while models with already-difficult-to-quantize weights might use to avoid making the weights worse.

Offline Computation and LayerNorm Fusion
A necessary practical advantage of smooth quantization is that the transformation can be computed entirely offline during a calibration phase. This means inference has no additional runtime cost compared to standard quantized inference. The calibration procedure works as follows:
First, run a small calibration dataset (typically a few hundred representative samples) through the model to collect activation statistics. During this calibration forward pass, we record the maximum absolute value seen in each channel across all calibration samples. Second, compute for each channel using these statistics, capturing how large the outliers tend to be. Third, calculate smoothing factors for each layer using the formula above. Fourth, apply the weight transformation and store the modified weights. Fifth, and most cleverly, fuse into the preceding layer's weights or normalization parameters.
Step 5 is important and deserves careful explanation. Rather than explicitly dividing activations by at runtime, we absorb this division into the bias of the previous layer or the scale/shift parameters of the preceding LayerNorm. This means inference has zero additional cost compared to standard quantized inference. The activation values arrive at the quantization step already "smoothed" because the previous layer was modified to produce smoothed outputs.
The fusion works because transformer architectures typically have a LayerNorm immediately before each linear layer. LayerNorm applies a learned scale () and shift () to each channel. We can incorporate the smoothing factor directly into these existing parameters. If the original LayerNorm scale for channel was and shift was , we replace them with and . The activations coming out of the modified LayerNorm are already "smoothed," and we never perform the division at runtime. This is mathematically equivalent to explicitly dividing at every forward pass but requires zero additional computation.
The offline nature of smooth quantization also means it is compatible with any existing INT8 quantization infrastructure. You do not need to modify the inference engine or write new kernels. Simply transform the weights and LayerNorm parameters before quantizing, then proceed with standard absmax or per-channel quantization. The resulting model can be deployed on any hardware that supports INT8 matrix multiplication.