×

Search anything:

INT8 Quantization

Understanding how to do calculations in INT8 instead of FP32 and still get same results is a core optimization in DL. DL is highly insensitive to local errors.

INT8 Quantization is a technique to run DL models by computing arithmetic using INT8 inputs (instead of FP32) with INT8 outputs. This reduces the memory bandwidth by 4X and improves computation by up to 3X (using AVX512 VNNI instructions).

For AVX details, see chapter on “Matrix Multiplication” and “Convolution”.

By default, weights are in FP32 and computation is in FP32 as well. These are converted to INT8. The new pre-training model is a quantized INT8 model.

There are 3 basic approaches to Quantization (preparing INT8 model):

Method Description Notes
Post-Training Quantization (PTQ) Converts FP32 model to INT8 after training Less accuracy, Fast training, Only calibration.
Quantization-Aware Training (QAT) Simulates INT8 during training for better accuracy Higher accuracy, Full training needed
Dynamic Quantization Only weights are INT8, activations remain FP32 Less benefit of INT8 speedup

Core concepts:

  • FP32 input mapped to INT8 range
  • Core operations: quantize, dequantize, clip
  • Symmetric Quantization
  • Asymmetric Quantization

FP32 input is mapped to INT8 range

Note: The distribution of numbers remains the same. Numbers can fall out of the INT8 range after conversion is clipped to the max or min INT8 value.

This involves 2 core metrics:

  • Scale factor S
  • Zero-point Z

Quant/ Dequant operations

2 core operations using S and Z (X is input):

  • Quantizeoperation: Convert FP32/INT32 inputs to INT8: Xq = round(X/S) + Z
    • Output is clipped to fit in INT8 range [-128, 127] or [0, 255]
  • Dequantizeoperation: Convert INT8 to FP32/INT32: Xd = (Xq - Z) * S
    • Output is clipped to the actual min / max of the input
    • Actual min / max is maintained through the model.
Op Type Description Used For
Quantize Per-Tensor A single scale and zero-point are shared across all elements in the tensor. Simple quantization when data distribution is uniform across the tensor.
Dequantize Per-Tensor Dequantizes the entire tensor using a global scale and zero-point. Complementary to Quantize Per-Tensor.
Quantize Per-Channel Each channel in the tensor gets its own scale and zero-point, allowing finer control. Quantizing tensors with varying channel distributions (e.g., CNN weights).
Dequantize Per-Channel Dequantizes each channel using a unique scale and zero-point. Complementary to Quantize Per-Channel.
Quantize Per-Block Quantization applied on a block of the tensor, often used when processing large batches or operations. Used in optimizations like block-level quantization to manage large tensor blocks.
Dequantize Per-Block Dequantizes each block using a unique scale and zero-point, similar to per-channel but at a block level. Complementary to Quantize Per-Block.
Clip Clips the input values to be within a specified range (e.g., [-128, 127] for INT8). Ensures that values are within the representable range for INT8.

S and Z is computed as:

Symmetric Quantization

If input has range [Xmin, Xmax] where the middle element is 0, then:

Scale = \(\frac{\mathbf{MAX\ }\left( \left| \mathbf{X}_{\mathbf{\min}} \right|\mathbf{,\ \ \ }\left| \mathbf{X}_{\mathbf{\max}} \right| \right)}{\mathbf{2}^{\mathbf{N - 1}}\mathbf{- 1}}\) or \(\frac{\mathbf{MAX\ }\left( \left| \mathbf{X}_{\mathbf{\min}} \right|\mathbf{,\ \ \ }\left| \mathbf{X}_{\mathbf{\max}} \right| \right)}{\mathbf{q}_{\mathbf{\max}}}\)

Zero point = 0 (always)

Main points:

  • INT8 range is [-127, 127] (Input is mapped to this range)
  • Use when input data is centered around zero (not + or – skewed)
  • Efficient computation as zero-point addition is avoided.
  • In relative symmetric input, gives better accuracy as it captures small values better (example, weights in CNN)

Asymmetric Quantization

S = \(\frac{\mathbf{X}_{\mathbf{MAX}}\mathbf{-}\mathbf{X}_{\mathbf{MIN}}}{\mathbf{2}^{\mathbf{N}}\mathbf{- 1}}\mathbf{\ \ or\ }\frac{\mathbf{X}_{\mathbf{MAX}}\mathbf{-}\mathbf{X}_{\mathbf{MIN}}}{\mathbf{q}_{\mathbf{MAX}}\mathbf{-}\mathbf{q}_{\mathbf{MIN}}}\mathbf{\ }\)

Z = ROUND(\(\mathbf{\ }\frac{\mathbf{- \ Xmin}}{\mathbf{S}}\) ) or ROUND( \(\mathbf{q}_{\mathbf{MIN}}\mathbf{-}\frac{\mathbf{Xmin}}{\mathbf{S}}\) )

Main points:

  • INT8 range is [-128, 127] (if signed output is needed) or [0, 255]
  • Captures full dynamic range of input.
  • Better accuracy for highly skewed input (ReLU output)
Feature Symmetric Quantization Asymmetric Quantization
INT8 range [-127, 127] [0, 255] or [-128, 127]
Zero-point (Z) Always 0 Computed (Z ≠ 0)
Use case Balanced distributions Skewed distributions
Compute efficiency Faster Extra computation (addition of zero point)
Accuracy Better for symmetric input Better for skewed input

There are 2 main methods of preparing an INT8 model:

  • PTQ
  • QAT

Post Training Quantization (PTQ)

Main steps:

  • Take a pre-trained FP32 model.
  • For weights, calculate the range and compute the scale and zero point accordingly using symmetric quantization.
  • For activations, run inference on a subset of the training dataset (called calibration dataset) and measure the range of activations. Clip the outliers using histogram-based calibration and compute the scale and zero point according using asymmetric quantization. This step is called calibration.
  • Run inference using the computed scale and zero point.
    • If accuracy is low, update the calibration step.
    • As PTQ is sensitive, first Conv layer must run in FP32 and specific ops like SoftMax should run in FP32. Fuse specific ops like Conv + BatchNorm + ReLU.
  • If accuracy remains low, QAT must be used.

Quantization-Aware Training (QAT)

Main steps:

  • Take the FP32 model.
  • Before each op which needs to be quantized (like Conv), add a Fake Quantization op (that is Quantize -> Dequantize one after another). This introduces INT8 quantization noise in training process.
  • In forward pass, ops like Conv run in the default FP32 precision.
  • In backward pass, the loss gradient is bypassed through the Fake Quantization. This is called straight-through estimator STE. Weights are updated as usual.
  • At the end of the training process, the Fake Quantization nodes hold the scale and zero point.
Fake Quantization operators are added in the forward to introduce training loss which get optimized and reduced in the backward pass.

Calibration

  • Process: clip original weights -> then quantization (avoid outlier + increase representation) -> improves accuracy.
  • Manually choose percentile of weights to consider.
  • Minimize mean squared error (MSE) between original and quantized weight.
  • Minimizing entropy (KL-divergence) between original and quantized value.

3 variants:

  • Smooth Quant
  • Weight Only
  • Activation Aware Quantization

Smooth Quant

Rescale weights and activations to smooth their dynamic ranges, preventing large values in activations from dominating and causing clipping.

  • Improves INT8 quantization accuracy especially in transformer models.
  • Avoids outlier activation issues without retraining.
  • Compatible with post-training quantization (PTQ).

Weight Only

Only weight is quantized to FP8/INT8.

  • Reduces model size.
  • No need for activation calibration or retraining.
  • Allows high-speed inference on GPUs with fast FP16 compute units.
  • Doesn't reduce activation memory footprint (which matters for long-context LLMs).
  • May degrade accuracy if quantization noise in weights is too high.

Activation-Aware Quantization (AAQ)

Takes into account the distribution of activations during calibration or training to minimize quantization error.

  • Helps preserve model accuracy.
  • Often paired with per-channel scaling and min-max clipping.
  • Used in Quantization-Aware Training (QAT) or calibration-based PTQ.
INT8 Quantization
Share this