You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This guide documents all quantization strategies available in AITER, their backend support, fused operations, and how to choose the right precision for your use case.
Quick Reference: Which Quantization Should I Use?
Use Case
Strategy
QuantType
Target Dtype
Why
Best accuracy (no quant)
None
QuantType.No
BF16
No quantization loss
FP8 inference (simple)
Per-tensor
QuantType.per_Tensor
FP8
Single scale, lowest overhead
FP8 inference (balanced)
Per-token
QuantType.per_Token
FP8
Per-row scales, good accuracy/perf
FP8 inference (high accuracy)
Block-scale (1x128)
QuantType.per_1x128
FP8
Per-block scales, best FP8 accuracy
MXFP4 (max compression)
Block-scale (1x32)
QuantType.per_1x32
FP4
4x compression, E8M0 scales
Outlier-aware
SmoothQuant
per-token + channel scale
FP8/INT8
Handles activation outliers
KV cache compression
Per-token/block cache
N/A
FP8/INT8
Reduces KV cache memory
Fused norm + quant
RMSNorm + FP8/FP4
N/A
FP8/FP4
Saves kernel launches
1. QuantType Enum
All quantization strategies in AITER are identified by the QuantType enum:
fromaiterimportQuantTypeQuantType.No# No quantization (pass-through)QuantType.per_Tensor# Single scale for entire tensorQuantType.per_Token# One scale per token (row)QuantType.per_1x32# Block-scale with 32-element groups (for MXFP4)QuantType.per_1x128# Block-scale with 128-element groups (for FP8)QuantType.per_128x128# Large 2D block quantization
Supported Data Types
Type
Format
Bits
Usage
FP8 (E4M3)
E4M3FNUZ (GFX942) / E4M3FN (GFX950)
8
Default quantized dtype
FP4 (MXFP4)
E2M1 packed as fp4x2 (2 values per byte)
4
Maximum compression
INT8
Symmetric integer
8
Legacy quantization
FP8 E8M0
Exponent-only float
8
Block scale storage for MXFP4
BF16/FP16
Standard floats
16
Input/output precision
FP32
Single precision
32
Scale computation, accumulation
2. Per-Tensor Quantization
Single scale factor for the entire tensor. Simplest strategy with lowest overhead.
Activation quantization during inference (most common)
When different tokens have different magnitude distributions
Pairs with per-tensor weight quantization: gemm_a8w8(act_quant, weight_quant, act_scale, weight_scale)
4. Block-Scale Quantization
Per-block scales for fine-grained quantization. Two block sizes are supported.
Per-1x128 (FP8 Block-Scale)
For each block of 128 elements along K:
scale[m, k//128] = max(|x[m, k:k+128]|) / dtype_max
x_quant[m, k:k+128] = round(x[m, k:k+128] / scale[m, k//128])
Per-1x32 (MXFP4 Block-Scale)
For each block of 32 elements along K:
scale[m, k//32] = max(|x[m, k:k+32]|) → E8M0 format
x_quant[m, k:k+32] = round(x[m, k:k+32] / scale[m, k//32]) → E2M1 packed
FP8 block-scale (per_1x128): Best accuracy for FP8 GEMM, pairs with gemm_a8w8_blockscale
MXFP4 block-scale (per_1x32): Maximum compression (4x), pairs with gemm_a4w4 on MI350
When per-tensor/per-token scales are too coarse for your accuracy requirements
5. SmoothQuant
Reduces per-channel activation outliers by pre-multiplying with a learned channel-wise scale before quantization. Moves quantization difficulty from activations to weights.
x_smooth = x * smooth_scale # per-channel scaling
x_quant = quantize(x_smooth) # now easier to quantize
w_quant = quantize(w / smooth_scale) # absorb inverse into weights
AITER provides factory functions that return the appropriate quantization implementation for each backend:
fromaiter.ops.quantimportget_torch_quant, get_hip_quant, get_triton_quant# Get per-token quant function for Triton backendquant_fn=get_triton_quant(QuantType.per_Token)
x_quant, scale=quant_fn(x)
# Get per-block quant function for HIP backendquant_fn=get_hip_quant(QuantType.per_1x32)
x_quant, scale=quant_fn(x)