权重量化方法:scale、零点与分组粒度
一句话定义
现代 LLM 权重量化采用"分组 + weight-only"范式:把权重按小块(如每 128 个数)各配一组 scale/零点存储为 4-bit,推理时在 kernel 内反量化回 FP16 做矩阵乘。
为什么重要
这是 2023 年后生产端 LLM 量化的默认形态——vLLM/llama.cpp/TensorRT-LLM 的 "awq"、"gptq"、"Q4_K" 全部建立在这套机制上。理解 scale 与分组粒度,才能读懂所有量化参数的含义并自己判断质量上限。
前置知识
- kp-005(仿射量化与噪声模型)。
核心概念
- 分组量化(group-wise):per-tensor 一组 scale 误差大;per-channel(按输出通道)次之;per-group(每 32/64/128 个连续权重一组)是 4-bit 的标配,用少量额外存储换小步长。
- zero-point(非对称):允许把网格零点偏移到组内最小值处,适合不对称分布;对称量化省存储但组内分布偏斜时吃亏。
- weight-only(W4A16):只量化权重,激活保持 FP16。LLM decode 是访存密集的,读权重的字节省了 4 倍即近线性加速;而激活存在离群值,强行低比特激活(W4A4)误差失控——这是"权重量化而非全量化"成为主流的根本原因。
- 反量化矩阵乘(dequant-fused GEMM):kernel 把 4-bit 权重解码为 FP16 后走常规矩阵乘,计算本身不省 FLOPs,省的是读取。
原理与机制
反量化矩阵乘让"存储格式"与"计算格式"解耦:显存里只存 4-bit 整数与每组 scale/零点,kernel 读入后还原为 FP16 再参与矩阵乘。收益因此全部来自读取字节减少与显存余量,计算 FLOPs 不变——这正是它对访存密集的 decode 收益最大、对计算密集的 prefill 收益有限的根本原因;而分组粒度决定 s 的大小,是误差的第一杠杆。
公式与模型
一层线性层的推理等价形式:
Q 是 4-bit 整数矩阵,s_g/z_g 是每组的 scale/零点,⊗ 表示按组广播。误差由组内动态范围决定:步长 s_g = (max_g − min_g)/(2^4 − 1)。分组越细,max_g 越贴近局部分布,s_g 越小,噪声方差(≈s²/12)越小。
存储开销对比(每权重):FP16 16bit vs W4G128 ≈ 4 + 16/128 = 4.125bit——scale 的代价只有 0.125bit/权重,却把组内步长缩小一个量级。
直观类比
一本书全文统一四舍五入到整数页会丢信息;按"每段一个舍入规则"就能既压存储又保内容——分组量化就是按段舍入。
实例或案例
观察一个真实现象:Llama 系模型在个别通道的激活幅度是中位数的 20–100 倍(离群值)。若对这些层做 W8A8 全量化,误差集中在这些通道导致输出崩坏;而 W4A16 把激活留在 FP16,仅压权重,实测困惑度增幅可控。SmoothQuant 的思路则是把激活的尺度"平滑"搬运到权重上再全量化,说明同一问题的不同处理路线。
常见误区
- "4-bit 权重 = 计算量减为 1/4":反量化后仍是 FP16 矩阵乘,FLOPs 不变;收益来自带宽与显存。
- "分组越细越好":scale 存储与 kernel 访问模式有代价,g=128 是实践平衡点,g=16 收益边际递减。
- "weight-only 量化让 prefill 也快 4 倍":prefill 是计算密集的,收益主要来自显存余量间接提升并发,而非单次 prefill 提速。
自测题
- W4-G128 下每权重平均占多少比特?
要点:4 + 16/128 = 4.125 bit(对称无零点时)。
- 为什么 LLM 主流是 W4A16 而不是 W4A4?
要点:激活离群值使低比特激活误差失控;decode 瓶颈在读权重,只压权重即可拿到主要收益。
- 反量化矩阵乘省的是什么资源?
要点:显存占用与读取字节(带宽),不是 FLOPs。
与其他知识点的关系
kp-007/kp-008 决定"Q 与 scale 怎么求得更优";kp-009 是选档实操;kp-025/kp-026 是该机制在 ONNX/GGUF 的载体格式。
延伸阅读
《SmoothQuant》(Xiao 等,2023)第 3 节对激活离群值的量化分析。