Automatically generated from handwritten notes — quantization_second_part.pdf

Efficient AI · Quantization notes

Quantization, Part II

Applying quantization to neural networks: PTQ and QAT, second-order weight quantization, activation-aware scaling, fake quantization, and hardware-supported low-precision formats.

Roadmap
  1. PTQ, QAT, and what gets quantized
  2. GPTQ and second-order compensation
  3. Activation-aware Weight Quantization
  4. SmoothQuant
  5. Quantization-aware training
  6. Hardware-supported formats

1. Quantization paradigms

The previous notes developed the basic mechanics of quantization. We now ask how those ideas are applied to LLMs and other neural networks. There are two broad workflows.

PTQ

Post-training quantization

Start with a trained model and quantize it without retraining or fine-tuning.

QAT

Quantization-aware training

Simulate quantization during training so the model can adapt to the errors introduced by low precision.

What gets quantized?

Scheme Examples What happens
Weight-only W8, W4 Weights are stored at low precision; activations remain in a floating-point format.
Weight + activation W8A8, W4A4 Both operands of a matrix multiplication use low precision.

In a weight-only kernel, low-bit weights may be dequantized inside the kernel and combined with BF16/FP16 activations. For an integer weight-and-activation kernel, the data path is different:

INT8 weights
+
INT8 activations
→
integer multiply
and accumulate
→
INT32
accumulator
→
rescale and
requantize / convert
Accumulator versus activation The INT32 value is an accumulator, not yet the final output activation. A kernel may requantize it to INT8, convert it to FP16/BF16, or retain a wider intermediate depending on the following operation.

2. GPTQ: second-order weight quantization

GPTQ applies ideas related to Optimal Brain Surgeon to post-training weight quantization. Instead of rounding every weight independently, it quantizes one coordinate and adjusts the remaining coordinates to compensate for the induced error.

From the ideal problem to a local objective

Let:

The ideal discrete problem is

\[ \min_{\widehat W\in\mathcal Q}\mathcal L(X,\widehat W). \]

Searching the complete grid is intractable, and repeatedly evaluating the full model is expensive. GPTQ therefore uses a local layer-reconstruction objective:

\[ \mathcal L(X,\widehat W) = \frac12\left\|X\widehat W-XW\right\|_2^2. \]

For $X\in\mathbb R^{n\times d_{\mathrm{in}}}$ and $W\in\mathbb R^{d_{\mathrm{in}}\times d_{\mathrm{out}}}$, this separates over output dimensions—that is, over columns of $W$:

\[ \mathcal L(X,\widehat W) = \sum_j \frac12 \left\| X\widehat w_{:,j}-Xw_{:,j} \right\|_2^2. \]

The input-side Hessian is, up to an optional factor of two,

\[ H=X^\top X. \]

Saliency and compensation

Define the perturbation using the convention $\delta W=\widehat W-W$. If coordinate $i$ is fixed to its quantized value, then

\[ \delta w_i=\operatorname{Quant}(w_i)-w_i. \]

Under the local quadratic model, the minimum loss increase caused by fixing this coordinate is

\[ S_i = \frac{\delta w_i^2}{2[H^{-1}]_{ii}}, \qquad \delta w = \frac{\delta w_i}{[H^{-1}]_{ii}}H^{-1}e_i. \]

$S_i$ is the coordinate’s saliency. It measures the smallest quadratic loss increase after optimally compensating with all other coordinates. A greedy method prefers coordinates with lower saliency.

Sign convention If quantization error is instead defined as $w_i-\operatorname{Quant}(w_i)$, the compensating update is written with a minus sign. The mathematics is unchanged as long as the convention is used consistently.

How the cost is reduced

Factoring a dense $d\times d$ Hessian costs $O(d^3)$. Repeating that factorization after each of $d$ decisions would lead to an $O(d^4)$ procedure. GPTQ avoids this naive cost through several distinct optimizations:

Efficient second-order quantization
  1. Factor the input-side Hessian once and share it across output columns.
  2. Use rank-one exclusion/inverse updates rather than refactorizing after every coordinate.
  3. Process coordinates in a predetermined order instead of running an expensive global greedy search.
  4. Batch corrections into matrix operations through lazy updates.

Across the coordinates, the factorization and inverse-update work is $O(d^3)$. SparseGPT adapts related second-order machinery to pruning; GPTQ uses it to quantize weights.

3. Activation-aware Weight Quantization

GPTQ compensates after a weight is moved to a fixed grid. AWQ takes a complementary view: activation statistics reveal which weight channels are sensitive, and an exact rescaling can protect those channels before quantization.

Why activations reveal sensitive weights

Consider a diagonal approximation to the local quadratic loss. For a perturbation $\delta w_i$,

\[ S_i \approx \frac12H_{ii}\delta w_i^2. \]

For squared layer-reconstruction error, $H_{ii}\propto\|X_{:,i}\|_2^2$. Hence

\[ S_i \propto \delta w_i^2H_{ii} \propto \delta w_i^2\|X_{:,i}\|_2^2. \]
Key observation. A weight error on an input channel with large activations has a larger effect on the layer output. Activation magnitude is therefore a useful heuristic for identifying salient weight channels.

Protecting salient channels without mixed precision

One option is to keep salient channels at higher precision. That creates an irregular mixed-precision matrix and is difficult to execute efficiently with standard GEMM kernels. AWQ instead preserves a uniform bit width and rescales channels.

For a positive scale vector $s$, rewrite the exact product as

\[ XW = \left(X\operatorname{diag}(s)^{-1}\right) \left(\operatorname{diag}(s)W\right). \]
Activations
$X_{:,i}\rightarrow X_{:,i}/s_i$
×
Weights
$W_{i,:}\rightarrow s_iW_{i,:}$

Before quantization this transformation is lossless. The benefit comes from changing how quantization error is distributed.

When does scaling help?

Consider a scalar contribution $xw$. Scale $w$ to $sw$, quantize it, and compensate by multiplying with $x/s$.

Scale changes the step

If $\Delta'=s\Delta$, then

\[ \frac{x}{s} \left(sw\pm\frac{\Delta'}2\right) = xw\pm\frac{x\Delta}{2}. \]

No reduction in output error.

Scale leaves the step fixed

If other values set the range and $\Delta'=\Delta$, then

\[ \frac{x}{s} \left(sw\pm\frac{\Delta}{2}\right) = xw\pm\frac{x\Delta}{2s}. \]

Error is reduced by a factor of $s$.

The scale can be selected through layer reconstruction:

\[ s^\star = \arg\min_s \left\lVert XW - X\operatorname{diag}(s)^{-1} Q\!\left(\operatorname{diag}(s)W\right) \right\rVert_2^2. \]

At lecture level, AWQ parameterizes the scales as

\[ s_i=s_{X,i}^{\alpha}, \qquad s_{X,i} = \operatorname{mean}\left(|X_{:,i}|\right), \]

and searches over the migration parameter $\alpha$.

4. SmoothQuant

AWQ uses activation statistics to improve weight-only quantization. SmoothQuant targets weight-and-activation quantization, where activation outliers are often the main difficulty.

Per-channel activation quantization along the inner dimension would isolate those outliers, but that granularity does not map efficiently to standard matrix-multiplication kernels. SmoothQuant instead moves part of the dynamic range from activations into weights:

\[ XW = \left(X\operatorname{diag}(s)^{-1}\right) \left(\operatorname{diag}(s)W\right). \]

A commonly used channel scale has the form

\[ s_j = \frac{ \left(\max|X_{:,j}|\right)^\alpha }{ \left(\max|W_{j,:}|\right)^{1-\alpha} }, \]

where $\alpha$ controls the migration strength: larger $\alpha$ moves more quantization difficulty from activations to weights.

Conceptually, we would like to choose

\[ \alpha^\star = \arg\min_\alpha \left\lVert XW - Q\!\left(X\operatorname{diag}(s)^{-1}\right) Q\!\left(\operatorname{diag}(s)W\right) \right\rVert_2^2. \]
Calibration in practice The expression above explains the trade-off. SmoothQuant usually treats $\alpha$ as a calibration hyperparameter and tunes it empirically rather than solving this exact optimization independently for every layer.
Method Main signal Main intervention
GPTQ Second-order curvature Compensate other weights after quantizing a coordinate
AWQ Activation magnitude Protect salient weight channels through scaling
SmoothQuant Activation and weight ranges Move dynamic range from activations into weights

5. Quantization-aware training

PTQ leaves the trained weights fixed, so any quality loss must be controlled entirely through calibration and the quantization method. QAT lets the model adapt while seeing simulated quantization noise.

Fake quantization

Insert fake-quantization operators wherever weights or activations will be quantized:

\[ \widehat X=Q^{-1}(Q(X)), \qquad \widehat W=Q^{-1}(Q(W)). \]

$Q$ maps a floating-point value to a quantized code, while $Q^{-1}$ dequantizes that code back to a representable floating-point value. The surrounding computation graph therefore remains floating-point, but its forward values lie on the intended quantization grid.

full-precision
master value
→
$Q$
quantize
→
$Q^{-1}$
dequantize
→
fake-quantized
forward value

The straight-through estimator

Rounding creates a staircase function whose true derivative is zero almost everywhere and undefined at thresholds. QAT replaces that derivative with a useful surrogate. For a clipped fake quantizer, a common STE is

\[ y=Q(x), \qquad \frac{\partial\widehat y}{\partial x} \approx \begin{cases} 1, & x\text{ is inside the representable range},\\ 0, & x\text{ is outside the representable range}. \end{cases} \]

Ignoring clipping gives the simpler identity STE, which treats the derivative as $1$ everywhere.

6. Hardware-supported formats

A low-precision representation is useful only when the hardware can consume it efficiently. Modern accelerators support several floating and microscaled formats.

Conventional floating point and FP8

FP32
full precision
FP16
half precision
BF16
half precision

Two common FP8 encodings are:

FP8 E4M3

Four exponent bits and three explicit mantissa bits.

FP8 E5M2

Five exponent bits and two explicit mantissa bits.

Format versus scaling recipe E4M3 and E5M2 define individual FP8 values. A scaled-FP8 recipe additionally attaches scales per tensor, channel, or block. A tensor-level FP32 scale is one possible recipe; it is not intrinsically part of the bare FP8 encoding.

MXFP8 and NVFP4

Format Data Scale granularity Scale format
MXFP8 FP8 values One shared scale per group of 32 values E8M0
NVFP4 FP4 E2M1 values One shared scale per group of 16 values FP8 E4M3, plus a tensor-level FP32 scale

What does hardware support mean?

Hardware support means that the accelerator exposes primitives which understand both the low-precision tensors and their scale metadata, conceptually:

\[ \operatorname{MM} \left( \text{tensor}_1, \text{tensor}_2, \text{scale}_1, \text{scale}_2 \right). \]

Fusing scale handling into the low-precision matrix-multiplication primitive minimizes or absorbs most conversion and scaling overhead. It does not mean that scale metadata and scale arithmetic have literally zero cost.

Tiling and training

Scale layout matters during training. A forward linear layer uses $W$, while backpropagation also requires products involving $W^\top$:

\[ y=Wx, \qquad \nabla_x\mathcal L=W^\top\nabla_y\mathcal L. \]

A one-dimensional scale layout optimized for $W$ may become awkward after transposition. Two-dimensional scale tiles can be more symmetric with respect to transposition and are therefore useful in training. Exact tile shapes and transpose support remain hardware- and implementation-specific.

Takeaway. Quantization quality is only one part of the design. A useful scheme must also choose scale granularity, data layout, and number formats that map to efficient hardware primitives in both the forward and backward passes.

Previous: Quantization basics. Source: handwritten lecture notes.