量化推理 — 交互式学习指南

基于手算示例,逐步理解对称/非对称/Per-Channel/INT4 量化原理

§2 对称量化 (Symmetric INT8)

2.1 数学公式

量化: q = round(x / scale), clamp(q, -127, 127) 反量化: x' = q × scale 其中: scale = max(|x|) / 127

零点固定为 0——0.0 在浮点和量化空间都对应 0

2.2 手算示例:权重 [0.03, -0.05, 0.12, -0.08, 0.01]

Step 1: max(|x|) = 0.12

Step 2: scale = 0.12 / 127 = 0.000945

Step 3: 量化 (÷ scale → round)

原值计算INT8反量化误差
0.03round( 31.7) 32 0.0302+0.0002
-0.05round(-52.9)-53-0.0501-0.0001
0.12round(127.0)127 0.12000
-0.08round(-84.7)-85-0.0803-0.0003
0.01round( 10.6) 11 0.0104+0.0004

2.3 Outlier 的影响

999 个值在 [-0.5, 0.5],1 个 outlier = 5.0

无 outlier

scale = 0.5/127 = 0.00394
值 0.01 → q ≈ 3
值 0.05 → q ≈ 13
值 0.10 → q ≈ 25

有 outlier (5.0)

scale = 5.0/127 = 0.0394 (×10)
值 0.01 → q = 0 ← 完全丢失
值 0.05 → q = 1
值 0.10 → q = 3
1 个 outlier 放大 scale 10 倍,256 级精度只用了不到 4 级。
解决方案:LLM.int8() 对 outlier 维度单独保留 FP16,其余 INT8。

§3 非对称量化 (Asymmetric UINT8)

3.1 数学公式

量化: q = round(x / scale) + zero_point, clamp(q, 0, 255) 反量化: x' = (q - zero_point) × scale 其中: scale = (x_max - x_min) / 255 zero_point = round(-x_min / scale)

zero_point 将数据范围精准映射到 [0, 255],无浪费

3.2 手算示例:ReLU 激活值 [0.0, 0.35, 1.20, 0.08, 2.50]

Step 1: x_min = 0.0, x_max = 2.50

Step 2: scale = 2.50/255 = 0.00980, zero_point = 0

原值计算UINT8反量化误差
0.00round(0.0)+0 00.00000
0.35round(35.7)+0 360.3528+0.0028
1.20round(122.4)+01221.1960-0.004
0.08round(8.2)+0 80.0784-0.0016
2.50round(255.1)+02552.50000

3.3 同一组数据:对称 vs 非对称

原值对称量化 (不适合)非对称量化 (适合)
q → 反量化误差q → 反量化误差
0.00 0→0.00000 0→0.00000
0.35 18→0.3544Δ0.0044 36→0.3528Δ0.0028
1.20 61→1.2011Δ0.0011122→1.1960Δ0.0040
0.08 4→0.0788Δ0.0012 8→0.0784Δ0.0016
2.50127→2.50000255→2.50000
对称浪费 50% 范围(负数区间 [-2.5,0) 用不上),非对称 scale 减半 → 精度翻倍

§4 Per-Tensor vs Per-Channel

4.1 粒度对比

方式粒度scale 数 (4096²)存储开销精度
Per-Tensor整个矩阵 1 个 scale14 B受 outlier 通道影响
Per-Channel每行独立 scale409616 KB各通道自主最优

4.2 手算示例:2×3 矩阵

通道 0 (小值): [ 0.05, -0.02, 0.10] 通道 1 (大值): [ 1.20, -0.80, -2.50]

Per-Tensor

scale = 2.50/127 = 0.01969

通道 0:
0.05→3 → 0.059 Δ+0.009 (18%!)
-0.02→-1 → -0.020 Δ0
0.10→5 → 0.098 Δ-0.002
RMSE = 0.0054

通道 1:
1.20→61 → 1.201 Δ+0.001
-0.80→-41 → -0.807 Δ-0.007
-2.50→-127 → -2.501 Δ-0.001
RMSE = 0.0038

Per-Channel

通道 0: scale₀ = 0.10/127 = 0.000787
0.05→64 → 0.0504 Δ+0.0004
-0.02→-25 → -0.0197 Δ+0.0003
0.10→127 → 0.1000 Δ0
RMSE = 0.0003

通道 1: scale₁ = 2.50/127 = 0.01969
(与 per-tensor 相同)
RMSE = 0.0038

通道 0 精度提升 18×
额外开销仅 8 bytes

§6 INT4 量化

6.1 INT4 vs INT8

离散值精度7B HBM
INT8256≈ 0.4%~7 GB
INT416≈ 6.25%~3.5 GB

6.2 手算示例:INT4 Per-Tensor vs Group-Wise

8 个权重,INT4 范围 [-7, 7],16 个离散级别

前 4 个 (小值): [0.15, -0.08, 0.03, 0.12] 后 4 个 (大值): [2.10, -1.80, 1.50, -0.95]

Per-Tensor INT4

scale = 2.10/7 = 0.30

前 4 个:
0.15→1 → 0.30 (原值 0.15,偏差极大)
-0.08→0 → 0
0.03→0 → 0
0.12→0 → 0
全部塌缩到 0-1!
RMSE = 0.126

后 4 个:
2.10→7 ✓
RMSE = 0.039

Group-Wise INT4

Group 0: scale₀ = 0.15/7 = 0.0214
0.15→7 → 0.150
-0.08→-4 → -0.086 ✓
0.03→1 → 0.021 ✓
0.12→6 → 0.128 ✓
RMSE = 0.011

Group 1: scale₁ = 2.10/7 = 0.30
(与 per-tensor 相同)
RMSE = 0.039

精度恢复!
开销: 2 scale × 4B = 8B
Group-wise 用 ~3% 额外存储,换回 per-channel 级别的精度。INT4 必须搭配 group-wise。

§7 量化加速原理

7.1 显存节省 (7B 模型)

FP32
28GB
FP16
14GB
INT8
7GB
INT4
3.5GB

7.2 HBM 带宽节省

推理时需从 HBM 读取全部权重。910B3 HBM 带宽 1538 GB/s。

精度权重大小读取时间加速
FP1614 GB9.1 ms
INT87 GB4.6 ms
INT43.5 GB2.3 ms
更多交互式实验请打开 quantization_viz.html | Python 演示:python3 quantization_demo.py