一个 70B 的模型,光是权重(16 位存)就要占 140 GB 显存——而一块 4090 只有 24 GB。 上一章《LoRA 与高效微调》只调适配器、基座没小;这一章换个方向:把它变小。 想让它在本地跑起来,只有三条路:换一个小模型(蒸馏)、 让每个数占更少的位(量化)、删掉一部分(剪枝)。
| 手段 | 砍掉的是什么 | 最擅长省 | 代价 |
|---|---|---|---|
| 蒸馏 | 整个网络结构:大模型教出一个小模型 | 推理算力 + 显存(永久) | 学生天花板就是老师 |
| 量化 | 每个数字的位数(16 位 → 4 位) | 显存带宽 + 容量(≈4 倍) | 精度有下限,INT4 之后很难再压 |
| 剪枝 | 一部分参数本身(置零或整块删除) | 理论参数量(换不来实际提速) | 稀疏收益在通用 GPU 上兑现不了 |
把一本厚书变薄,三种做法:
蒸馏 = 请专家重写成一本精简版;
量化 = 一个字不改,换更小的字号印刷;
剪枝 = 把书里某些行整段涂黑。
这个类比管到「存储和带宽」为止:量化连一个数都没改,
剪枝涂黑的行仍然占纸面——GPU 读的时候也不会跳过。
图 · 一本厚书的四种命运
四本书占的纸面 = 模型真正占的显存。涂黑的那本一点纸都没省下来。
假设你在训练一个识别动物的模型。一张猫的图片,老师模型给出的不是"猫", 而是一整个概率分布。这个分布里藏着关键信息。
| 监督方式 | 学生看到的目标 | 学到了什么 |
|---|---|---|
| 硬标签 普通训练 |
猫 = 1,其余全是 0 | 只知道"这是猫"。不知道猫和狗之间有什么关系 |
| 软标签 知识蒸馏 |
猫 0.70 狗 0.25 车 0.05 | 还学到了"这东西长得有点像狗,但完全不像车" |
那个 0.25 就是所谓的暗知识(dark knowledge): 概率高对应特征空间里两个类别挨得近——老师给出的「猫 0.70 像狗、0.05 像车」, 就是「猫和狗近、和车远」的相对大小,硬标签表达不了这个。
互动 · 温度如何把暗知识「放大」出来
图 · 温度 T 一升,分布就变平
T = 1 时非目标类贴着地(全在 0.000x 量级);T = 2~10 时「猫和狗像」被放大到看得见;T = 100 时所有类别挤到 0.2 附近,关系反而没了。
训练好的老师通常过度自信:正确答案 0.998,其余全在 0.000x——这点差异学生的梯度感受不到, 所以要除以一个 T 把它放大。但 T 太大会把分布抹平成直线,「猫和狗像」变成「什么都差不多」。 常见区间 T = 2 ~ 10;蒸馏时用大 T,推理时调回 1。
量化的做法很简单:给每个数分配一把刻度尺,把连续值四舍五入到最近的刻度上。 问题在于尺子怎么定。
下面这个互动是这一章的主图:位数是左边那个滑块,离群通道是右边三个按钮。
刻度记作 Δ(数学那节也叫 Δ,和这里的「刻度」是同一个东西)。 存的整数 wq = round(w / Δ),还原值 ŵ = wq · Δ。 Δ 由这一层里最大的那个数决定——一个离群值就能让整把尺子变粗。
「离群通道」是权重矩阵里的一整行或一整列,数值比正常维度大上百倍。
互动 · INT 量化(round + clip + 反量化)
把位数拖到 4,依次点三个按钮,盯住四个数字:
① 不处理 → 普通参数全被四舍五入到 0,但离群通道完好。
② 直接截断 → 普通参数精度提高几十倍,但那 3 个离群通道被毁,误差几乎等于它本身的值。
③ 保护离群通道 → 两边都保住。这就是 LLM.int8() 的混合精度(把少数离群通道留 16 位、其余压 8 位的方法):
不是放弃离群值,而是单独照顾它们。
AWQ 走另一条路:把重要通道的权重放大 s 倍、对应激活缩小 1/s,乘积不变,
但那些权重的相对量化误差变小了。
看「整体 MSE」那一栏:直接截断反而比不处理更差——3 个离群通道的平方误差 盖住了 1997 个参数的进步。所以量化要分开看「绝大多数参数」和「少数关键通道」: 真实评测不看平均误差,看下游任务掉了几个点。
互动 · 三种策略,分开看两类参数
普通参数(1997 个)的信噪比 —— 越高越好
离群通道(3 个)的 RMS 误差 —— 越低越好
| 对比项 | 权重 | 激活 |
|---|---|---|
| 分布形状 | 温和,接近钟形 | 有极端的离群通道,某些维度比正常值大 100 倍 |
| 什么时候能看到 | 训练完就固定了 | 依赖输入,某个词就能触发一个尖峰 |
| 量化难度 | INT8 几乎无损,INT4 基本可用 | INT8 就要小心,INT4 通常要特殊处理 |
| 典型解法 | GPTQ(误差补偿)、AWQ(保护重要通道) | SmoothQuant:把激活的量化难度「搬」一部分到权重上 |
大模型里的这些离群维度真实存在、而且对模型能力至关重要——直接砍掉确实好量化了,但模型也变笨了。
所以不能「消除」离群值,只能「绕开」它们。
保护哪些通道,得拿真实输入跑统计(这份数据叫校准集)。
模型大到一定程度后,权重反而更好量化、激活更难:隐藏维度越宽, 离群值又集中在固定几个维度,一个离群维度摊到的邻居越多,对整层刻度的影响就越被稀释。
剪枝最大的反直觉:把参数量砍到只剩 10%,模型在 GPU 上跑起来速度一模一样,甚至更慢。
互动 · 两种剪枝,同样的稀疏度,完全不同的结果
GPU 的矩阵乘法是密集计算:一次读一整块连续内存,对每一格都做乘加,根本不会「跳过」零。
非结构化剪枝把零撒得到处都是,矩阵还是那么大、全部算一遍——计算量一点没少。
结构化剪枝删掉整行整列,形状真的变小,计算量才减少;代价是一删就是一大片,精度掉得多。
彩票假设(2019):随机初始化的网络里存在一个只有 10%~20% 参数的子网络, 从头训练就能达到原网络的水平。但找到它得先把大网络完整训练一遍—— 省的是未来的推理成本,不是当下的训练算力。
三条路记在同一个账本上:显存 = 参数个数 × 每个数占几位 ÷ 8。 蒸馏改参数个数,量化改位数,剪枝改真正非零的个数 (只有结构化剪枝真省显存,非结构化只是把格子变零)。
互动 · 位数往下降,显存和误差谁先崩
显存是线性的,误差是指数的。16→8 位误差 0.003% → 0.71%,模型毫无感觉;
8→4 位 13%,还扛得住;4→2 位 84%,当场失灵。
这就是「INT4 之后越来越难」的原因,也是分组量化(每小段各配一把尺子)的动机——
和第 3 节「③保护离群通道」同一个目的:别让离群值把整把尺子带偏。
图解 · 三个旋钮各自拧短了哪一条边
每块方块占纸的面积 = 它真正占的显存。只有最左和最右两块真的变小了。 中间那块只是被打了很多洞(第 4 节的非结构化剪枝)—— 外框没变,硬件就还是按整个外框搬。
图 · 三类家族树
| 方法 | 让学生模仿什么 | 特点 |
|---|---|---|
| 响应蒸馏 Response KD |
老师最后一层的输出概率 | 最经典、最通用(Hinton 2015) |
| 特征蒸馏 Feature KD |
中间某几层的特征图 / 隐藏状态 | 信号更丰富;要解决「维度不一样」的问题 |
| 关系蒸馏 Relation KD |
样本之间、层之间的关系结构 | 更灵活,实现更绕 |
| 自蒸馏 | 老师早期版本 / 深层教自己的浅层 | 不需要额外的老师模型 |
| 在线蒸馏 | 师生同时训练、互相促进 | 省内存;但两个都在动,稳定性难保证 |
| LLM 蒸馏 DeepSeek-R1 → Qwen 等 |
老师生成的完整推理过程(思维链) | 2025 主流:把推理能力从长链条学过来 |
| 方法 | 思想 | 精度档位 |
|---|---|---|
| PTQ 训练后量化 |
拿校准集跑一遍统计,直接转 | INT8 基本无损;INT4 需要更精细的方法 |
| QAT 量化感知训练 |
前向里模拟量化误差,让模型适应 | 质量最好,能压到很低位数 |
| GPTQ | 逐层误差补偿:量化一个权重时,调其他权重补它的误差 | INT4 权重的事实标准之一 |
| AWQ | 找出重要通道(激活大的),放大保护,其余正常量化 | INT4,推理实现简单 |
| SmoothQuant | 用数学等价变换,把激活的量化难度转移到权重上 | W8A8(权重和激活都 8 位) |
| NF4 QLoRA |
用正态分布的分位数做非均匀量化(切点中段密、两端疏) | 4 bit 微调,把 65B 模型塞进单卡 |
| GGUF llama.cpp |
实用的量化文件格式与工具链,支持 |
本地部署事实标准,Q4_K_M 最常被推荐 |
| 方法 | 砍什么 | 真能加速吗 |
|---|---|---|
| 幅度剪枝 | 绝对值最小的权重 | 不能。零是散着的 |
| SparseGPT | 一次性对超大模型做非结构化剪枝 | 不能(没有专用硬件) |
| Wanda | 按 |权重| × ‖x‖ 排序,比只看权重更准,不用重训 | 不能 |
| 结构化剪枝 | 整个通道 / 整个注意力头 / 整层 | 能。矩阵形状真的变小了 |
| 层丢弃 LayerDrop |
训练时随机跳过整层,推理时可以安全删掉几层 | 能,而且和别的手段正交 |
| 手段 | 天花板在哪 | 什么时候别用 |
|---|---|---|
| 蒸馏 | 学生不可能超过老师;训老师本身就是最大的开销 | 手上只有弱模型时 |
| 量化 | 精度有下限,INT4 之后收益急剧变难 | 数值精度极度敏感时(部分科学计算、RL 的 logprob) |
| 剪枝 | 结构化剪枝精度掉得快;非结构化剪枝加速收益兑现不了 | 没有专用稀疏硬件,或不能接受重训成本时 |
量化还会让输出分布变形。普通对话里不明显,但在 RL(阶段 5 后半)里致命: RL 要拿模型的 logprob(每个词的对数概率)算重要性比率,而量化误差是固定偏移、不是均值为零的噪声, 累加几十步比率就越滚越偏。
| 环节 | 关系 |
|---|---|
| 显存账本(阶段 6) | 量化省的是权重和优化器状态的显存,要算「这张卡能不能跑」先看那一章 |
| 推理与 KV Cache(阶段 6) | 长上下文场景下,KV Cache(生成时缓存的历史键值,省得每个 token 重算)会超过权重, 所以 KV Cache 量化往往比权重量化更关键 |
| 微调(相邻章) | QLoRA = 4 bit 基座 + LoRA 适配器:前者省显存,后者省可训练参数 |
| 服务化与吞吐(阶段 6) | 量化降低每 token 的显存带宽消耗,而推理瓶颈通常就在带宽上 |
部署模型显存不够,按这个顺序试:
① KV Cache 量化(最易忽略,长上下文收益最大)→
② 权重量化到 INT8(几乎无损)→
③ 权重压到 INT4(配 GPTQ / AWQ)→
④ 换更小的模型
第 ④ 条尤其别跳过——原生小模型通常比被压到变形的模型更好用。
蒸馏、量化、剪枝看上去是三件不相干的事。它们其实在回答同一个问题。
第 2 节:把「蒸馏温度 T」从 1 拖到 10——「狗」的概率从贴地涨到肉眼可见,而「车」「树」更低。 第 3 节:把位数拖到 4,依次点那三个按钮,看两个读数怎么此消彼长。
| 暗线 | 这一章的回答 |
|---|---|
| A 信息流动 | 形状变没变,决定它快不快(数学那节最后那张方块图):蒸馏换掉整个模型、 结构化剪枝删掉整行整列,形状真变小;量化和非结构化剪枝只是把数变小、格子变零,硬件照搬全量。 |
| B 什么被牺牲了 | 牺牲的是分辨率,不是功能:量化换容量、剪枝换规则性、蒸馏换尺寸。共同代价是模型更容易在边缘情况上出错。 |
| D 跑在什么上 | 带宽受限的那一类。每吐一个 token 都要把全部权重从显存读一遍(7B FP16 每次 14 GB), 而对应计算量只有约 1 FLOP/byte(每搬 1 字节只做 1 次运算:算力在等数据), 算力全程坐着等。量化减少的正是搬运字节。两笔账在 《硬件与算力账本》。 |
它接住了《LoRA 与高效微调》的适配器,留给《微调实战决策树》去选。
蒸馏是让学生模仿老师给出的整套概率(软标签),量化是权重好办、激活难办,
剪枝是压掉 90% 参数也换不来 10 倍速度。
部署时:先量化,再考虑换更小的模型,最后才想剪枝。
上面讲的都是「够用」的版本。想往下挖,这里有三个入口—— 它们不是必修内容,是给想再往前走一步的读者准备的。