Overview of AQT (Accurate Quantized Training)
mainwhat you serve is what you train. It provides specialized libraries for both JAX and Flax to enable quantized training and inference.repository·main·Indexed 18 days ago
https://github.com/google/aqtA JAX-based software library for tensor operation quantization, designed to enable high-quality int8 quantization in both training and serving to minimize training-serving bias. AQT provides low-level quantization primitives for JAX (such as quantized_dot and quantized_sum) and high-level Flax modules including DenseAqt, ConvAqt, EmbedAqt, LayerNormAqt, and MultiHeadDotProductAttentionAqt.
what you serve is what you train. It provides specialized libraries for both JAX and Flax to enable quantized training and inference.Jax and Flax provide "what you serve is what you train" quantization for convolution and matmul operations. For detailed usage of the quantization API, refer to the main JAX documentation in the jax/ directory.Conv layers and the Dense layer. The training process uses linear learning rate warmup and a cosine learning rate schedule.This directory contains the configuration files used to reproduce results from the paper Pareto-Optimal Quantized ResNet Is Mostly 4-bit.
When using these configurations, the following hyperparameters were used to achieve the reported results:
num_epochs: 250lr_scheduler: LRScheduler.COSINEstep_lr_coeff: 0.2step_lr_intervals: 6The leaderboard configurations summarize quantization results for various transformer model setups. These configurations include:
bfloat16.8bit, 4bit, and 2bit quantization.8bit and 4bit quantization.For models utilizing activation quantization, experiments are conducted using two different bounding strategies:
AQT achieves high quality by using per-example (for activations) and per-output-channel (for weights) scaling. This isolates the impact of outliers to a single row or column, allowing for tighter calibration.
Internally, a simple INT8 AQT matmul follows these steps:
int32 accumulator, then de-quantizes the result using the scales.To get hardware acceleration (like on TPUs) in JAX, AQT relies on jnp.matmul with preferred_element_type=jnp.int32, which maps to lax.dot_general and XLA's DotGeneral op.
import jax.numpy as jnp
def matmul_true_int8(lhs, rhs):
assert lhs.dtype == jnp.int8
assert rhs.dtype == jnp.int8
# Uses int32 accumulator for hardware acceleration
result = jnp.matmul(lhs, rhs, preferred_element_type=jnp.int32)
assert result.dtype == jnp.int32
return result
def aqt_matmul_int8(a, w):
max_int8 = 127
def quant_int8(x):
return jnp.clip(jnp.round(x), -max_int8, max_int8).astype(jnp.int8)
# Calibration: per-example and per-channel scales
a_s = max_int8 / jnp.max(jnp.abs(a), axis=1, keepdims=True)
w_s = max_int8 / jnp.max(jnp.abs(w), axis=0, keepdims=True)
# int8 matmul with int32 accumulator, then de-quantize
result = matmul_true_int8(quant_int8(a * a_s), quant_int8(w * w_s)) / (a_s * w_s)
return resultIn many models, a transformation $T$ is applied to weights before a matmul (e.g., matmul(a, T(w))).
Standard quantization might compute matmul(a, T(Q(w))), which saves checkpoint size but doesn't accelerate the matmul because $T$ likely returns floating-point values.
To achieve both checkpoint compression AND hardware acceleration, AQT aims to store the fully transformed and quantized weight $w_q = Q(T(w))$ in the checkpoint. This allows serving to use matmul(a, w_q) directly.
AQT provides a specialized matmul_aqt function that handles this: matmul_aqt(..., T(w)) = matmul(..., Q(T(w))). Note that $Q(T(w))$ is not visible outside of matmul_aqt because the function uses a custom gradient definition.
AQT provides two primary ways to apply quantization to Flax modules:
flax.linen.intercept_methods to intercept Flax module methods at runtime. This allows you to apply quantization by execution scope via a context manager, leaving the original module code untouched.Functionally, the Intercept API is designed to produce the same results as the Injection API, but offers better usability for existing models where you do not want to refactor the source code.
In the WMT Machine Translation example, AQT-style quantization is supported for all Matmul layers. This includes:
DenseGeneral layersDense layerQuantization configurations (such as 4-bit weights and auto-activation) are typically passed via the --hparams_config_dict flag in the train.py script.
jax.numpy.einsum or flax.linen.DenseGeneral) call lax.dot_general as their core computation. To quantize a model, you substitute lax.dot_general with a quantized variant provided by AQT. JAX-based libraries like Flax and Pax provide APIs to perform this substitution when creating layers.To install the AQT package with support for JAX legacy components, use pip. It is recommended to upgrade pip before installation.
# Upgrade pip.
pip install --user --upgrade pip
# Install AQT package
pip install aqtp[jax_legacy]report_utils.py to generate concise experiment reports containing aggregated metrics and metadata. Detailed instructions can be found in the utils/ directory documentation.