Reduce model size and inference cost through quantization. Covers INT8, INT4 and mixed-precision quantization, post-training vs. quantization-aware training, GGUF formats, and the patterns that shrink models by 4x with minimal accuracy loss.
Quantization reduces the precision of neural network weights and activations from floating-point formats (like FP32 or FP16) to lower-bit integers (INT8, INT4, etc.). It matters when deploying models in production environments where memory usage, inference latency, and computational efficiency are critical. This process is most impactful for edge devices, mobile applications, and large-scale inference clusters.
Quantization transforms model parameters from high-precision floating-point numbers to fixed-point integers. The transformation involves scaling factors that map the original range of values to a quantized range. For example, an FP32 weight in the range [-1.0, 1.0] might be mapped to INT8 values in the range [-128, 127].
The process requires careful handling of data ranges and scaling factors. Without proper calibration, quantized models can suffer from significant accuracy degradation.
PTQ applies quantization to a pre-trained model without retraining. It typically uses static scaling factors computed during calibration on a representative dataset. This method works best with models that already have stable activation distributions.
Example workflow:
python -m torch.quantization.prepare --model=model.pth --output=quantized_model.pth
PTQ does not support dynamic range adjustments during inference. It relies entirely on the calibration data to determine scaling factors for each layer or group of parameters.
QAT modifies training to simulate quantization effects, allowing the model to adapt to reduced precision during learning. This approach often produces better results than PTQ because it incorporates quantization noise into the training process.
The key difference is that QAT introduces fake quantization operations into the computational graph during training, so gradients are computed assuming quantized weights and activations.
PyTorch provides native support for quantization through its torch.quantization module. To convert a model to quantized form:
import torch
import torch.quantization
model = torch.load('model.pth')
model.eval()
# Prepare for quantization
model.qconfig = torch.quantization.get_default_qconfig('fbgemm')
prepared_model = torch.quantization.prepare(model)
# Calibrate with sample data
with torch.no_grad():
for data in calibration_dataloader:
prepared_model(data)
# Convert to quantized model
quantized_model = torch.quantization.convert(prepared_model)
The qconfig parameter controls how quantization is applied. Common choices include 'fbgemm' for CPU inference and 'qnnpack' for mobile devices.
TensorFlow Lite supports both dynamic and full integer quantization:
tflite_convert \
--saved_model_dir=model_dir \
--output_file=model.tflite \
--optimizations='optimize_for_size'
The --optimizations='optimize_for_size' flag enables full integer quantization. This approach does not require explicit calibration steps.
ONNX models can be quantized using the onnxruntime package:
python -m onnxruntime.quantization.quantize_dynamic \
--model_path=model.onnx \
--output_path=quantized_model.onnx \
--weight_type=UInt8
This command performs dynamic quantization, which computes scaling factors at runtime rather than during static calibration.
Quantization accuracy depends heavily on how well the scaling factors represent the actual data distribution. The calibration process involves running a subset of validation data through the model to compute per-layer scales.
Failure mode: Using an unrepresentative calibration set leads to poor quantization results. For example, if you calibrate on images from one domain but deploy in another, the quantized model may perform significantly worse than expected.
Quantization parameters often include:
activation_bits: Number of bits for activation tensorsweight_bits: Number of bits for weight tensorssymmetric: Whether to use symmetric or asymmetric quantizationper_channel: Whether to compute scales per channel or per tensorWhen quantizing models, ensure that:
Example error message from PyTorch quantization:
RuntimeError: Quantization failed due to invalid scaling factor for layer conv1
Quantization typically reduces model size by a factor of 4 for INT8 vs FP32. This reduction is crucial for memory-constrained environments like mobile phones or embedded systems.
Example size comparison:
# Original model size
ls -lh model_fp32.pth
# Output: 1.2G model_fp32.pth
# Quantized model size
ls -lh model_int8.pth
# Output: 300M model_int8.pth
Quantization can improve inference performance by enabling vectorized operations on integer data types. However, this improvement depends on hardware support for integer arithmetic.
Some devices may not benefit from INT8 quantization if they lack optimized integer kernels, resulting in no performance gain or even slower execution.
Before deploying quantized models, validate that accuracy remains within acceptable bounds:
def evaluate_quantized_model(model, test_dataloader):
model.eval()
correct = 0
total = 0
with torch.no_grad():
for inputs, labels in test_dataloader:
outputs = model(inputs)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
accuracy = 100 * correct / total
return accuracy
One of the most subtle issues is silent precision loss. Quantized models may appear to work correctly but show degraded performance in production. This occurs when quantization introduces small rounding errors that accumulate during inference.
Some hardware platforms do not support certain quantization schemes. For example, a model quantized to INT4 may run slowly on GPUs that lack native INT4 support, forcing the system to perform conversions at runtime.
If calibration data differs significantly from real-world usage patterns, the quantized model will perform poorly in production. This mismatch is particularly common when calibration datasets are too small or not representative of actual deployment conditions.
Quantization can change memory layout requirements. Some quantized models require specific alignment for optimal performance, which may not be preserved during model serialization or loading.
Instead of applying the same scaling factor across all elements in a tensor, channel-wise quantization computes separate scales for each output channel. This approach typically provides better accuracy for convolutional layers.
Example configuration:
quantization_config:
method: "channel_wise"
weight_bits: 8
activation_bits: 8
Dynamic quantization applies quantization to activations at runtime, while weights remain in full precision. This technique reduces memory usage without requiring calibration.
Monitor accuracy degradation during quantization:
def compare_models(original_model, quantized_model, test_data):
original_model.eval()
quantized_model.eval()
with torch.no_grad():
orig_output = original_model(test_data)
quant_output = quantized_model(test_data)
# Compute difference between outputs
diff = torch.abs(orig_output - quant_output)
max_diff = torch.max(diff)
mean_diff = torch.mean(diff)
return {'max_diff': max_diff.item(), 'mean_diff': mean_diff.item()}
Add logging to track quantization parameters:
import logging
logger = logging.getLogger('quantization')
for name, module in model.named_modules():
if hasattr(module, 'qconfig'):
logger.info(f"Module {name} uses qconfig: {module.qconfig}")
Quantized models may fail to load if their quantization metadata is corrupted:
# Error when loading quantized model
RuntimeError: Failed to load quantized model due to incompatible tensor format
Ensure that quantization parameters are preserved during model serialization and that the loading environment supports the quantization scheme used.
If quantization does not improve performance, check:
Always validate quantized models against their full-precision counterparts before deployment. The goal is to maintain accuracy within acceptable bounds while achieving desired efficiency gains.
Use representative calibration data that matches production usage patterns. Avoid overfitting to calibration data by using diverse, realistic examples.
Monitor model performance in production to detect unexpected behavior from quantization artifacts.
This page was rewritten on 15 October 2026. It replaced a templated version that was not specific to its own title. How these pages are written and checked. If anything here is wrong, tell us at [email protected] and we will correct it.
We use cookies for analytics (Google Analytics) and advertising (Google AdSense) to improve your experience and support free content. Privacy Policy