大模型数学速成(15):量化——从 FP16 到 INT4 的尺度
第 10 篇 GQA 和 第 11 篇 KV Cache 从结构上省显存;推理时还有一条更「硬」的路——用更少比特存同一个数。这就是 量化(Quantization)。
本篇只讲数学直觉:实数如何落在整数网格上、scale / zero-point 是什么、粒度与误差从哪来。不写安装教程,公开格式名(如 GGUF)仅作索引。
这是「大模型数学速成」续篇第 15 篇。建议先读第 10–11 篇(显存动机)与 第 02 篇矩阵乘。下一篇讲 LoRA。
一、为什么要量化?
大模型的权重与激活本质上是大量浮点数。推理时瓶颈经常是:
| 压力 | 含义 |
|---|---|
| 显存 / 内存容量 | 装不下整模,或 Concurrent 请求装不下 KV |
| 带宽 | 算力够,但读权重/读 Cache 太慢(「算得动、搬不动」) |
若把 FP16(2 字节)换成 INT4(0.5 字节),同样参数量体积约变为 1/4——在误差可接受时,这是极高杠杆。
本篇范围:以权重量化为主,兼提 KV Cache 量化;训练中的量化感知训练(QAT)只点名、不展开。
二、均匀量化:尺子上的刻度
最常见的思路:均匀量化——把一段实数区间均匀切成 $2^b$ 格($b$ 为比特数),每个实数落到最近的整数码。
对称情形(零点在中间,示意)可写成:
\[q = \mathrm{clamp}\Big(\mathrm{round}\big(\frac{x}{s}\big),\; q_{\min},\; q_{\max}\Big)\]
\[\hat{x} = s \cdot q\]
| 符号 | 含义 |
|---|---|
| $x$ | 原始浮点(权重或激活) |
| $s$ | scale(尺度),一格代表多大的实数步长 |
| $q$ | 整型码,如 INT8 的 $-128..127$ 或 $0..255$ |
| $\hat{x}$ | 反量化后的近似值 |
非对称时常再引入 zero-point $z$:
\[\hat{x} \approx s \cdot (q - z)\]
$z$ 把「整数 0」对齐到实数轴上的某个偏置——分布整体偏移时更省误差。
生活类比
用一把只有整数刻度的尺子量连续长度:
- $s$ = 每一小格代表几毫米;
- $z$ = 尺子零刻度是不是对准了「真实的 0」。
量出来的永远是「格数 × 格宽」,和真实长度有四舍五入误差。
三、手算:把 4 个数压成「假 INT8」
设一组权重(虚构):
\[\mathbf{w} = [0.10,\ 0.40,\ -0.20,\ 0.80]\]
取对称范围 $[-a,a]$,其中 $a = \max |w_i| = 0.80$。
若用 8 级示意(实际 INT8 是 256 级,这里为了手算缩成 8 级,概念相同):
\[s = \frac{2a}{7} \approx 0.2286\]
\[q_i = \mathrm{round}(w_i / s),\quad \hat{w}_i = s\cdot q_i\]
| $w$ | $w/s$ | $q$ | $\hat{w}$ | 误差 |
|---|---|---|---|---|
| 0.10 | 0.44 | 0 | 0.00 | 0.10 |
| 0.40 | 1.75 | 2 | 0.46 | 0.06 |
| -0.20 | -0.87 | -1 | -0.23 | 0.03 |
| 0.80 | 3.50 | 4 | 0.91 | 0.11 |
比特越少、格越粗,$s$ 越大,误差越大——这就是 INT4 比 INT8 更「省」也更「糙」 的来源。
四、粒度:scale 绑在多大一块上?
同一个 $s$ 管多少个数,叫量化粒度:
| 粒度 | 含义 | 精度 vs 开销 |
|---|---|---|
| per-tensor | 整层/整张量一个 $s$ | 最省元数据,误差常最大 |
| per-channel / per-row | 每个输出通道一套 $s$ | 常见于权重量化,效果较好 |
| per-group | 每 $g$ 个元素一套 $s$(如 32/64/128) | 4-bit 时很常见,细粒度换精度 |
group 越小,scale 越「贴身」,误差越小,但要多存一些 scale 本身——工程上在体积与精度间折中。
1 | per-tensor: [==== 一整块共用 s ====] |
五、INT8 vs INT4(量级直觉)
以「每个参数」粗算存储(忽略 scale 开销与特殊布局):
| 格式 | 约字节/参数 | 相对 FP16 |
|---|---|---|
| FP16 / BF16 | 2 | 100% |
| INT8 | 1 | ~50% |
| INT4 | 0.5 | ~25% |
典型公开实践(不绑未公开配置):推理侧大量采用 4-bit 权重量化;激活有的仍用更高精度,有的做动态量化。是否「能接受」取决于任务、层敏感度与校准数据。
离群值(outlier)
若某个通道出现绝对值特别大的权重/激活,per-tensor 的 $s$ 会被它撑大,其余小数全被挤到粗糙网格——这是量化掉点的常见元凶。细粒度 scale、混合精度(敏感层保留更高比特)都是对策方向。
六、权重 vs KV Cache:两处省显存
| 对象 | 存在哪 | 量化在省什么 |
|---|---|---|
| 权重 $W$ | 模型参数 | 装模体积、读权重带宽 |
| KV Cache | 随序列增长的运行时状态 | 长上下文、多并发时的显存(接第 10–11 篇) |
可以只量化权重、只量化 Cache,或两者都做——数学都是 scale + 整数码,约束与误差特性不同:权重离线标定一次即可;Cache 随 decode 动态写入,常更谨慎。
GQA 减少的是 K/V 头数量;量化减少的是 每个元素的比特。两者正交,经常叠用。
七、校准(calibration)一句话
Post-Training Quantization(PTQ) 常在一小批代表性数据上跑前向,统计激活范围,再定 scale——叫校准。
没有校准、乱设范围,等于尺子刻度乱标。
Quantization-Aware Training(QAT) 则在训练中模拟量化噪声,一般更贵、有时更稳——知道有这条路即可。
八、公开名词索引(不展开安装)
读引擎文档时可能看到(均为公开生态常见词,非内部名):
| 名词 | 你只需知道 |
|---|---|
| GGUF 等容器 | 常承载量化后的权重与元数据 |
| GPTQ / AWQ 等 | 不同的权重量化/校准算法族 |
| bitsandbytes 等 | 训练/推理库里的量化实现之一 |
选型属于「推理工程」路线;本系列停在公式与误差直觉。
九、和矩阵乘的关系
第 02 篇 的 $y = Wx$ 在量化推理里往往变成:
- 读入整型权重码与 scale
- 在硬件友好的整数或混合精度域做乘加
- 用 scale 把结果变回(或保持在)推理用的浮点域
数学对象仍是线性变换;变的是 $W$ 的存储与近似。LoRA(下一篇)会在「冻住的大 $W$」旁加小矩阵——常与 4-bit 基座一起出现(QLoRA 思路)。
十、小结
| 概念 | 要点 |
|---|---|
| 动机 | 容量 + 带宽 |
| 核心式 | $\hat{x} \approx s\cdot(q-z)$ |
| 粒度 | tensor / channel / group |
| INT4 vs INT8 | 更省、更糙;靠细粒度 scale 补 |
| 权重 vs KV | 两处独立杠杆,可叠加 GQA |
| 校准 | 定 scale 的数据步骤 |
大模型数学速成续篇第 15 篇完。下一篇 LoRA:低秩适配在算什么——不改动巨大的 $W$,只训练 $BA$。
系列导航
| 篇号 | 标题 | 状态 |
|---|---|---|
| 14 | 采样:Temperature / top-k / top-p | ✅ |
| 15 | 量化:从 FP16 到 INT4(本篇) | ✅ |
| 16 | LoRA:低秩适配 | ✅ |
完整大纲见工作区 docs/MATH_SERIES_OUTLINE_V2.md。









