本文是《高效推理与压缩(算法侧):解码、投机、量化与 KV》系列的第 6 篇(共六篇)。上一篇:KV cache 压缩:量化、驱逐与稀疏 attention。
前五篇改的是表示(量化)、过程(解码、投机)与缓存(KV),模型的参数数量与结构没有变。最后一条线改参数的数量:删掉一部分权重、一部分 head、一部分层,让模型本身变小。剪枝是最老的压缩方法(LeCun 等 1989 的 Optimal Brain Damage),在 CNN 时代成熟,在 LLM 上重新变得重要——因为”一个 70B 怎么变成一个能用的 8B”这个问题有了新的答案:不是从头训一个 8B,而是从 70B 剪出来再蒸馏,用十分之一的 token 达到相近的效果。
剪枝与前几篇的根本区别是:剪掉的东西不能靠更好的舍入找回来,必须靠训练恢复。所以剪枝几乎总是”剪枝 + 蒸馏”的组合(L5 第七篇的方法在这里是工具),它的算力账是”剪枝 + 恢复的 token 数”与”从头训一个同样大小的模型的 token 数”的比较。这也让它成为小模型配方的一部分——2024–2025 年发布的小模型(Llama 3.2 1B / 3B、Minitron、Gemma 3 1B、Qwen 的小尺寸)里,有一部分是从大模型剪出来的。
本篇要回答的核心问题是:
剪掉 25% 的层,困惑度只升 0.3,为什么下游任务掉一半?蒸馏能恢复多少?
一、总览:剪什么、怎么恢复
1. 一张对照表
| 方法 | 剪什么 | 粒度 | 硬件兑现 | 恢复 | 典型结果 |
|---|---|---|---|---|---|
| 非结构化剪枝(幅度、Wanda、SparseGPT) | 单个权重置零 | 元素 | 需要稀疏 kernel;GPU 上一般不兑现 | 可不训(50%);更高需训 | 50% 稀疏困惑度 +0.5 到 +2(不训) |
| 2:4 半结构化 | 每 4 个权重留 2 个 | 4 元素块 | Ampere+ Tensor Core 原生,GEMM 约 1.5–1.8× | 需训恢复到接近无损 | 理论 2× 算力,实际 1.3–1.6× |
| 层裁剪(深度) | 整个 Transformer block | 层 | 完全兑现:层数 ÷ | 必须训 | 剪 25% 层困惑度 +0.3–1,任务掉一半(不训) |
| 宽度剪枝 | attention head、FFN 中间维、hidden 维 | 结构 | 完全兑现:矩阵变小 | 必须训 | Minitron:15B → 8B / 4B |
| MoE 专家剪枝 | 整个专家 | 专家 | 完全兑现 | 需训 | 剪掉少用的专家 |
| 从头训小模型 | — | — | — | 全部训练 | Llama 3.2 1B:9T token |
| 剪枝 + 蒸馏(Minitron 路线) | 深度 + 宽度 | 结构 | 完全兑现 | 蒸馏 ~100B token | 比从头训省 40× token,效果相当或更好 |
前两行是稀疏化——参数矩阵的形状不变,一部分元素为零,需要硬件支持稀疏计算才能变快;后面几行是结构化——矩阵真的变小,任何硬件都变快。LLM 部署上结构化剪枝更实用,非结构化剪枝的主要价值是它的数学(OBS)在 GPTQ 与结构化方法里的重用。
2. 先说答案
剪掉 25% 的层困惑度只升 0.3,是因为 Transformer 的中后层做的是残差流上的小修正——每层的输出与输入的余弦相似度在中后层常在 0.9 以上(Gromov 等 2024、Men 等 2024 的测量),删掉一层,残差流几乎不变,下一个 token 的平均预测几乎不变,困惑度几乎不变。下游任务掉一半,是因为任务准确率依赖的是少数关键位置上的精确计算——一道数学题的中间步骤、一个多跳推理的连接——这些计算恰好是被删的层负责的”小修正”累积起来的结果,且任务评测里大量的题目(尤其多选题)依赖模型对格式与指令的精确遵循,这是后训练在深层写进去的、最脆弱的能力。上一篇第六章讲的”困惑度是平均、任务看关键 token”在这里以最极端的形式出现:删层对平均的影响与对关键计算的影响相差一个量级。
蒸馏能恢复多少:几十 B token 的蒸馏可以把困惑度恢复到接近原模型的水平,下游任务恢复大部分(Minitron 的 15B → 8B 在 94B token 蒸馏后 MMLU 与从头训的 8B 相当或更好),但不是全部——剪掉 25% 的层,恢复后的模型仍略低于原模型,且恢复最慢的是推理类任务。第三、六章展开。
3. 本文的章节安排
| 章 | 主题 | 内容 |
|---|---|---|
| 二 | 非结构化剪枝 | OBS 的剪枝形式(与 GPTQ 同一套推导);SparseGPT;Wanda 的权重 × 激活;50% 的免费与 2:4 的条件 |
| 三 | 层裁剪 | 为什么中后层”多余”:残差流的余弦相似度;Block Influence;剪哪些层;困惑度与任务的脱节 |
| 四 | 宽度剪枝 | head、FFN 维、hidden 维的重要性估计;Sheared LLaMA 的可学习 mask;Minitron 的激活重要性 |
| 五 | MoE 与其他结构 | 专家剪枝与合并;attention head 剪枝的特殊性 |
| 六 | 恢复:为什么必须蒸馏 | 剪枝后的分布偏移;SFT 恢复 vs 蒸馏恢复;Minitron 的流水线与算力账 |
| 七 | 小模型配方对照 | Llama 3.2、Minitron、Gemma 3、Qwen2.5 小尺寸、SmolLM、MobileLLM:从头 vs 剪枝,深而窄 vs 浅而宽 |
| 八 | 剪枝与量化的叠加 | 两种误差如何叠;顺序 |
| 九 | 动手(建议) | 层裁剪 + 蒸馏恢复的曲线 |
| 十 | 本文小结与系列总结 | 六篇的总表;”70B 怎么变成能用的 8B” |
二、非结构化剪枝
1. OBS 的剪枝形式
第三篇第四章从拉格朗日推出了 OBS:把第 \(q\) 个权重置零,其余权重的最优补偿是 \(\delta^* = -\frac{w_q}{[H^{-1}]_{qq}} H^{-1}_{:, q}\),造成的最小输出误差是
\[\mathcal{E}_q = \frac{w_q^2}{[H^{-1}]_{qq}}\]这就是剪枝的重要性得分:\(\mathcal{E}_q\) 小的权重先剪。它比单纯的幅度 \(\lvert w_q \rvert\) 多了一个 \([H^{-1}]_{qq}\)——输入通道 \(q\) 的”不可替代性”:如果通道 \(q\) 与其他通道高度相关(\(H\) 非对角元大),\([H^{-1}]_{qq}\) 大,剪掉它的误差小,因为其他通道能补偿。
2. SparseGPT
SparseGPT(Frantar & Alistarh 2023)把 GPTQ 的工程改造用在剪枝上:逐列处理,每列内按 \(\mathcal{E}\) 选要剪的权重(达到目标稀疏度),剪掉后用 OBS 更新其余未处理的列,Cholesky 加速。175B 模型几小时内剪到 50% 稀疏,困惑度 OPT-175B 从 8.34 到 8.21(几乎无损——大模型的冗余度高),Llama-2-70B 50% 稀疏困惑度 +0.5 左右。它同时支持 2:4 模式(每 4 个连续权重里剪 2 个,按 \(\mathcal{E}\) 选)。
3. Wanda:不需要 Hessian
Wanda(Sun 等 2023)的观察:LLM 里权重的重要性主要由它乘的激活有多大决定(上一篇 AWQ 的同一个观察)。重要性得分 \(\lvert w_{ij} \rvert \cdot \lVert X_j \rVert_2\)(权重幅度 × 对应输入通道的激活范数),在每一行内比较、剪掉最小的。不需要 \(H\)、不需要更新其余权重、几分钟完成。50% 稀疏下与 SparseGPT 接近(Llama-2-70B 困惑度差 0.1 以内),2:4 下略差。
它说明的事:对 LLM,”哪些权重重要”的一阶答案是”乘大激活的那些”,二阶的补偿(OBS)在 50% 稀疏度上只多贡献一点。更高的稀疏度(60–70%)上 SparseGPT 的优势扩大,但两者都开始明显退化——非结构化剪枝在 LLM 上的”免费区间”大约到 50%。
4. 硬件兑现的条件
非结构化的 50% 稀疏在 GPU 上不变快:稠密 GEMM 的 Tensor Core 不识别零,稀疏 GEMM 的 kernel 在 50% 稀疏度下比稠密慢(索引开销)。它省的是存储(如果用压缩格式)而不是算力,且存储上量化的性价比高得多。
2:4 半结构化是硬件兑现的形式:Ampere 及之后的 Tensor Core 原生支持”每 4 个元素中恰好 2 个非零”的稀疏矩阵乘,理论算力翻倍,实际 GEMM 加速 1.3–1.8×(索引与 dequant 的开销,且只在 compute-bound 区间有效——decode 的 memory-bound 区间里权重字节只减少到约 5/8:2 个值 + 2 个 2-bit 索引对 4 个值)。2:4 的约束比无结构 50% 更严(每个 4 元素块内必须恰好剪 2 个,不能按全局重要性自由选),困惑度损失更大,需要训练恢复到接近无损(NVIDIA 的推荐流程是”剪枝 → 继续训练”)。
在 LLM 部署里,2:4 主要用于 prefill 与训练(compute-bound),对 decode 帮助有限;且它与量化叠加时(2:4 + INT8)的 kernel 支持与收益都要单独验证。
三、层裁剪
1. 为什么中后层”多余”
Transformer 是残差结构:\(h_{l+1} = h_l + f_l(h_l)\)。如果 \(f_l(h_l)\) 相对于 \(h_l\) 很小,删掉第 \(l\) 层(\(h_{l+1} := h_l\))对残差流的影响就小。测量每层输入与输出的余弦相似度 \(\cos(h_l, h_{l+1})\),多个独立的工作(Gromov 等 2024 “The Unreasonable Ineffectiveness of the Deeper Layers”;Men 等 2024 ShortGPT)在 Llama-2 / Qwen / Mistral 上得到一致的图景:
- 前几层(尤其第一层)相似度低(0.3–0.6)——它们把 token embedding 变成上下文表示,改动大;
- 中后层相似度高(0.85–0.95)——每层是残差流上的小修正;
- 最后一层相似度又降低——它把表示映射到 logits 空间。
所以”多余”的是中后层。删掉最后一层是灾难(困惑度飙升),删掉倒数第 5 到第 25 层中的任何一层,困惑度只升一点。
2. Block Influence 与剪哪些层
ShortGPT 定义了 Block Influence:\(\text{BI}_l = 1 - \mathbb{E}_{x}\big[\cos(h_l^{(x)}, h_{l+1}^{(x)})\big]\),在校准集上对每层测量,BI 低的层先剪。Gromov 等用另一个度量——删掉第 \(l\) 到 \(l + n\) 连续 \(n\) 层后 \(h_l\) 与 \(h_{l+n+1}\) 的角距离——找出最适合删的连续块(连续删比分散删对后面的层影响更可预测)。两者都指向中后段:Llama-2-70B 删掉约第 50–70 层中的 20 层(25%),MMLU 几乎不变(Gromov 的发现——但注意下一节),困惑度升 0.3–0.5。
剪多少层:Gromov 等发现有一个”悬崖”——删到某个比例(Llama-2-70B 约 40–45%,13B 约 30%)之前 MMLU 几乎平坦,之后骤降到随机。困惑度则是平滑上升的。这个悬崖的存在本身说明 MMLU 测的是与困惑度不同的东西。
3. 困惑度与任务的脱节
回到核心问题。Gromov 等报告删 25% 层 MMLU 几乎不变,但同一批工作与后续(Kim 等 2024 Shortened LLaMA;Siddiqui 等 2024 的系统评估)发现生成类任务(GSM8K、代码、开放问答、指令遵循)在同样的剪枝下掉得多得多——GSM8K 可以从 50 掉到 10 以下,”掉一半”是常态。
机制有三层:
多选与生成的差别。MMLU 是多选,模型只需要在 A/B/C/D 中让正确选项的 logit 最大——一个”大致对”的残差流就够了。GSM8K 需要生成 100–300 个 token 的正确推理链,每一步都要精确,错一步全错;删层引入的每步小误差在链上级联。
被删的层做什么。中后层的”小修正”不是随机噪声,它们是模型做多步组合的地方——把浅层提取的事实组合成结论、把上下文中的多个信息对齐。困惑度主要由”下一个 token 是什么”的局部预测决定(多数 token 是可预测的延续),组合能力只影响少数关键 token;任务准确率恰好由这些 token 决定。
后训练能力的脆弱性。指令遵循、格式、拒绝等能力是 SFT / RLHF 在预训练模型的表示上”写”进去的相对浅的改动,集中在深层。删层直接破坏它们——剪枝后的模型常常不再遵循 chat template 的格式、不知道何时停止。这部分在困惑度(在预训练文本上测)里完全看不到。
所以层裁剪的正确评测是:困惑度作为”没崩”的确认,生成任务与指令遵循作为真正的度量——上一篇第七章的组合在这里同样适用,且更重要。
四、宽度剪枝
1. 三个可剪的维度
| 维度 | 剪什么 | 参数变化 | 注意 |
|---|---|---|---|
| attention head | 整个 head(Q、K、V、O 对应的行 / 列) | \(4 d^2 \times (\text{头数比})\) | GQA 下要按组剪(一个 KV 头对应的所有 Q 头一起);不同层的 head 数可以不同 |
| FFN 中间维 \(d_{ff}\) | up / gate 的输出列与 down 的输入行 | \(3 d \cdot d_{ff} \times (\text{比例})\) | 最容易剪的维度——FFN 是参数大头,且中间维的神经元独立性高 |
| hidden 维 \(d\) | 残差流的维度(所有层的所有矩阵的一维) | 全模型线性 | 最难——所有层共享,且 LayerNorm、embedding、lm_head 都要跟着改 |
宽度剪枝的重要性估计:对每个 head / 神经元 / 维度,测量它对输出的贡献。Minitron(Muralidharan 等 2024)用激活的统计量:head 的重要性是它输出的 \(L_2\) 范数在校准集上的均值;FFN 神经元是它的激活值的均值;hidden 维是 LayerNorm 输出该维的均值。不需要梯度,几分钟完成,结果与更贵的方法接近。
2. Sheared LLaMA:可学习的 mask
Sheared LLaMA(Xia 等 2024)用另一条路:给每个 head、每个 FFN 神经元、每个 hidden 维、每层一个可学习的 mask 变量(hard concrete 分布的参数化,让 mask 接近 0/1),在剪枝目标(目标形状)的拉格朗日约束下训练几千步,让模型自己决定剪什么;然后固定 mask、删掉被 mask 的部分、继续预训练恢复。它的一个发现是动态 batch 加载——恢复训练时按各领域的 loss 恢复速度调整数据配比(loss 恢复慢的领域多给)——比固定配比好。Llama-2-7B → 2.7B 与 1.3B,用 50B token 恢复,比同规模从头训的模型(用 1T+ token)在多数任务上更好。
3. Minitron:深度与宽度的组合
Minitron 系统地比较了各种剪枝轴的组合(Nemotron-4 15B → 8B → 4B):
- 只剪深度恢复后最差——一致于第三章:层做的是组合,删了不容易补回。
- 只剪宽度(FFN + hidden + head)恢复后最好。
- 深度 + 宽度在同参数量下介于两者之间;但深度剪枝让延迟下降更多(层数决定串行深度,宽度决定每层的 GEMM 大小,小 batch 下延迟主要由层数决定)。
所以选择依赖目标:追求精度剪宽度,追求延迟剪一部分深度。Llama 3.1 Minitron 4B 的两个版本(Width 与 Depth)正是这两种选择,Width 版本在多数 benchmark 上高 1–3 个点,Depth 版本快约 1.8×。
五、MoE 与其他结构
1. 专家剪枝
MoE 的专家在训练后有明显的使用不均——某些专家被路由到的频率是其他的几倍到几十倍(负载均衡 loss 只在训练时约束,且约束的是 batch 内的均衡,不同领域的数据激活不同专家)。剪掉低频专家(或对特定部署领域低频的专家)是自然的:Mixtral 8×7B 剪到 8×4 或 8×2 在通用任务上退化明显,但在领域特定的部署上(只用代码、只用某语言)可以几乎无损(Lu 等 2024 的分析)。专家合并(把相似的专家平均成一个)比直接删更稳。
MoE 剪枝的特殊之处:路由器要一起调整(删掉专家后 softmax 的归一化变了),且 top-\(k\) 中如果 \(k\) 不变,剩余专家的负载上升。
2. attention head 剪枝的特殊性
Michel 等 2019 的经典发现:”大部分 head 可以在推理时被删掉而不影响 BERT 的性能”——在 LLM 上依然大致成立,但有几类 head 不能删:retrieval head(Wu 等 2024 发现的少数负责从上下文精确复制信息的 head,删掉它们 needle 任务崩掉而困惑度不变)、induction head(in-context learning 的机制)、以及承担 attention sink 功能的 head。这些 head 的重要性在校准集上的激活范数里看不出来(它们只在特定任务上活跃),是宽度剪枝里最容易误删的部分——又一个”困惑度看不到”的例子。剪 head 之前用 needle 一类任务做一次筛查是必要的。
六、恢复:为什么必须蒸馏
1. 剪枝后的分布偏移
剪枝后的模型是一个”受伤”的模型:它的每层输出与原模型有系统性的偏差,这个偏差在层间累积、在生成中级联。不训练的剪枝只在很轻的剪枝(非结构化 50%、删几层)下可用;结构化剪枝到 50% 参数几乎总是需要训练。
2. SFT 恢复 vs 蒸馏恢复
两种恢复方式:继续预训练(在预训练数据上用交叉熵训)与蒸馏(让剪枝后的模型匹配原模型的 logits 分布,L5 第七篇)。Minitron 的对照:同样 94B token,蒸馏比继续预训练在 MMLU 上高 3–4 个点、在 GSM8K 上高更多。原因在 L5 第七篇讲过:蒸馏的目标是每个位置的完整分布(几十 bit 的信号),交叉熵只有正确 token(几 bit);且”恢复到原模型”比”重新学习”是更明确的任务。Minitron 还加了中间层的蒸馏损失(让剪枝模型的隐状态匹配原模型对应层的隐状态,需要一个线性映射处理维度不同)——在剪得很重时有帮助,剪得轻时可以省。
蒸馏恢复的成本是每步多一次教师前向。教师是原模型(15B),学生是 8B,教师前向约是学生前向 + 反向的 \(15 / (3 \times 8) \approx 0.6\) 倍——总算力约 1.6 倍于纯训练。
3. Minitron 的流水线与算力账
完整流水线:
- 重要性估计:在 1024 条校准样本上前向一次,收集每层、每 head、每 FFN 神经元、每 hidden 维的激活统计。分钟级。
- 剪枝:按目标形状(比如 15B → 8B:层 32 → 32,hidden 6144 → 4096,FFN 24576 → 16384,head 48 → 32)删掉重要性最低的。
- 轻量搜索:几种候选形状各用 ~2B token 短训,选最好的。
- 蒸馏恢复:94B token,教师为原 15B 模型,logits KL + 可选的中间层损失。
算力账(Minitron 论文的数字):Nemotron-4 15B 从头训用了 8T token;8B 剪枝 + 蒸馏用 94B token(约 1.2%);4B 从 8B 再剪 + 蒸馏用 94B token。8B 的结果与从头训的同规模模型相当或更好(MMLU 与 Nemotron-3 8B 比高约 10 个点——不过 Nemotron-3 是老一代数据),训练 token 省 40 倍。这个账的前提是大模型已经存在——剪枝的 token 节省是相对于”再训一个小模型”而言的,大模型的 8T token 是沉没成本。
Llama 3.1 Minitron 4B(从 Llama-3.1-8B 剪)与 Mistral-NeMo-Minitron 8B(从 12B 剪)延续了这条路线,Mistral-NeMo-Minitron 8B 在多个 benchmark 上超过了从头训的 Llama-3.1-8B。
4. 恢复不了的部分
蒸馏恢复后的模型接近但低于原模型,且差距在推理类任务上最大。它也低于一个”用同样多 token 从头训、但用更好的数据”的小模型的上限——剪枝 + 蒸馏赢的是 token 效率,不是精度上限。以及一个实践问题:恢复后的模型需要重新做后训练(SFT / DPO),因为剪枝破坏的指令遵循能力不会被预训练数据上的蒸馏完全恢复;Minitron 与 Llama 3.2 都在恢复后重新对齐。
七、小模型配方对照
1. 从头训还是剪出来
| 模型 | 规模 | 来源 | 训练 token | 备注 |
|---|---|---|---|---|
| Llama 3.2 1B / 3B | 1.23B / 3.21B | 从 Llama 3.1 8B 剪枝(宽度)+ 用 8B 与 70B 的 logits 蒸馏 | 蒸馏阶段 ~9T token(预训练规模) | 官方描述:结构化剪枝初始化 + 蒸馏;深度 16 / 28 层 |
| Minitron 8B / 4B | 8B / 4B | 从 Nemotron-4 15B 剪枝 + 蒸馏 | 94B / 94B | 40× token 节省的原始报告 |
| Llama 3.1 Minitron 4B | 4.5B | 从 Llama 3.1 8B 剪 | 94B | Width 与 Depth 两版 |
| Gemma 3 1B | 1B | 从头训,用大模型蒸馏(logits) | 2T | Google 的小模型一直是”从头 + 蒸馏” |
| Qwen2.5 0.5B / 1.5B / 3B | — | 从头训 | 18T(全系列同数据) | 同数据、同配方、不同规模 |
| SmolLM2 135M / 360M / 1.7B | — | 从头训,精选数据 | 2T / 4T / 11T | Hugging Face;数据配比是核心(FineWeb-Edu、Cosmopedia 合成) |
| MobileLLM 125M / 350M | — | 从头训 | 1T | Meta;深而窄的结构研究 |
| Phi-3-mini / Phi-4-mini | 3.8B | 从头训,大量合成数据 | 3.3T / 5T | 数据质量路线 |
两条路都有:剪枝 + 蒸馏(Llama 3.2、Minitron)在有大模型的前提下 token 效率高;从头 + 蒸馏(Gemma、Qwen、SmolLM)控制力更强(结构可以为小模型专门设计),代价是全部训练 token。Llama 3.2 的做法值得注意:它用剪枝做初始化,然后用预训练规模的 token 做蒸馏——不是 Minitron 的”94B 恢复”,而是”9T 蒸馏”,剪枝在这里的作用是给一个比随机好的起点。
2. 深而窄还是浅而宽
MobileLLM(Liu 等 2024)在 125M–350M 上系统地测了:同参数量下,深而窄(更多层、更小的 hidden)比浅而宽好——30 层 × 512 维优于 12 层 × 768 维,差几个点。解释是层数决定了模型能做的”顺序计算步数”,小模型的瓶颈在这里而不在每层的宽度。它还发现 embedding 共享(tied embedding,04 系列第九篇)与 GQA 在小模型上都有效——小模型的 embedding 占参数比例大(125M 模型 32K 词表的 embedding 是 25%),共享省下的参数可以加层。
这与第四章 Minitron 的”剪深度恢复最差”不矛盾:剪深度差是因为删掉已训好的层破坏了组合能力;从头设计时深一点好是因为给模型更多的顺序步数。两者都说层是小模型最宝贵的资源。但 Llama 3.2 1B 只有 16 层(宽 2048),Qwen2.5-0.5B 有 24 层(宽 896)——各家的选择并不一致,延迟(层数决定串行深度)是反向的考虑。
3. 数据是另一半
小模型对数据质量比大模型更敏感(容量小,装不下噪声)。SmolLM 与 Phi 系列的核心是数据:教育类网页的分类器过滤(FineWeb-Edu)、合成教科书(Cosmopedia、Phi 的合成数据)、代码与数学的高比例。同样是 1.7B、2T token,数据配比可以差出 5–10 个 MMLU 点。这是 04 系列第十一篇的内容在小模型上的放大——剪枝与蒸馏解决的是”怎么得到一个小模型”,数据决定的是”这个小模型能有多好”。
八、剪枝与量化的叠加
1. 两种误差
剪枝的误差是”结构性缺失”——某些计算不再存在;量化的误差是”数值噪声”——所有计算都在但略有偏差。两者叠加时不是简单相加:剪枝后的模型更”紧”(每个剩余参数承担更多),对量化噪声更敏感——同样的 W4 在剪枝后模型上的困惑度增量常比在原模型上大 1.5–2 倍。
2. 顺序
先剪枝(+ 恢复)再量化是标准顺序:剪枝需要训练恢复,训练在全精度下做;量化是最后一步的 PTQ。如果要 QAT(上一篇),可以把 QAT 并入恢复训练的末段——Llama 3.2 的 QAT 版本正是”剪枝 → 蒸馏 → SFT + QAT → DPO(LoRA)”的顺序。
2:4 稀疏与量化的叠加(稀疏 + INT8,NVIDIA 的推荐组合)在硬件上有原生支持(Ampere 的 Sparse Tensor Core 支持 INT8),是 compute-bound 场景下算力 4 倍的理论路径,但恢复训练要同时处理两种误差,实践中不常见。
九、动手(建议)
一张 24 GB 的卡,Qwen2.5-1.5B-Instruct(28 层)或 Llama-3.2-3B-Instruct(28 层):
- 测量:在 256 条校准文本上前向,记录每层输入 / 输出的余弦相似度(Block Influence),画出随层的曲线。预期:前几层低、中后段高、最后一层降。
- 剪枝:按 BI 删掉 4 层(14%)与 7 层(25%),两种策略——BI 最低的 \(n\) 层(可能分散)与 Gromov 式的连续 \(n\) 层。用
transformers直接删model.layers中的对应项并更新 config。 - 不恢复的评测:WikiText 困惑度;MMLU(5-shot);GSM8K(8-shot);IFEval;一个 needle 任务(8K)。预期:困惑度小升、MMLU 小降、GSM8K 与 IFEval 大降。
- 恢复:用 L5 第一篇的 SFT 脚本改成蒸馏(教师为原模型,logits KL;
trl的GKDTrainer设lmbda=0、beta=0即前向 KL logits 级),在 1–2B token 的混合文本上训(24 GB 卡上一两天)。每 200M token 评一次上述任务,画恢复曲线。 - 对照:同样的 token 用交叉熵(继续预训练)恢复,与蒸馏比。
该看的:困惑度与 GSM8K 的退化比例(预期相差一个量级);连续删与分散删的差别;蒸馏与交叉熵恢复曲线的差;恢复到 1B token 时各任务恢复了几成、哪个任务恢复最慢。不引用任何未跑过的数字。
十、本文小结与系列总结
1. 本文小结
| 项 | 规则 / 公式 | 备注 |
|---|---|---|
| OBS 剪枝 | 重要性 \(\mathcal{E}_q = w_q^2 / [H^{-1}]_{qq}\);补偿 \(\delta^* = -\frac{w_q}{[H^{-1}]_{qq}} H^{-1}_{:,q}\) | 与 GPTQ 同一套推导;SparseGPT 用它逐列剪 |
| Wanda | \(\lvert w_{ij} \rvert \cdot \lVert X_j \rVert\),逐行比较 | 一阶、分钟级;50% 与 SparseGPT 接近 |
| 稀疏兑现 | 非结构化 GPU 上不变快;2:4 Tensor Core 1.3–1.8×,需训恢复 | decode 字节只到 5/8;主要用于 prefill / 训练 |
| 层裁剪 | 中后层 \(\cos(h_l, h_{l+1}) > 0.85\);BI 低的先删;连续删 | 悬崖:70B 约 40%,13B 约 30% |
| 脱节 | 困惑度 = 平均局部预测;任务 = 关键位置的多步组合 + 后训练能力 | 删 25% 层:PPL +0.3,GSM8K 可掉一半,格式遵循破坏 |
| 宽度 | head(GQA 按组)、FFN 维(最易)、hidden 维(最难);激活统计估重要性 | Minitron:剪宽度精度好,剪深度延迟好 |
| 不能删的 head | retrieval / induction / sink head——校准集激活看不出 | 剪 head 前跑 needle |
| 恢复 | 必须训;蒸馏 > 继续预训练(+3–4 MMLU);教师前向 +60% 算力 | 恢复后需重做后训练 |
| 算力账 | Minitron 15B → 8B:94B token vs 从头 8T,省 40× | 前提:大模型是沉没成本 |
| 小模型 | 剪枝 + 蒸馏(Llama 3.2、Minitron)vs 从头 + 蒸馏(Gemma、Qwen、SmolLM);深而窄;tied embedding;数据质量决定上限 | |
| 叠加 | 先剪(+ 恢复)再量化;剪后对量化更敏感(1.5–2×) | QAT 可并入恢复末段 |
核心问题的答案:删 25% 的层困惑度只升 0.3,因为中后层是残差流上的小修正(输入输出余弦相似度 0.85–0.95),删掉它们对”下一个 token 的平均预测”影响很小,而困惑度就是这个平均;下游任务掉一半,因为任务准确率由少数关键位置的精确多步计算决定——正是这些层累积完成的组合——且生成任务的每步误差在链上级联,后训练写进深层的格式与指令遵循能力被直接破坏。蒸馏能恢复大部分:几十 B token 的 logits 蒸馏(教师为原模型)把困惑度恢复到接近原值、MMLU 恢复到与从头训的同规模模型相当,但推理类任务恢复最慢、最终仍低于原模型;且需要重新做后训练。剪枝 + 蒸馏赢的是 token 效率(40 倍),不是精度上限。
2. 系列总结:六篇的一张表
| 篇 | 方法 | 改什么 | 分布是否改变 | 收益 | 收益区间 | 代价 | 退化集中在 |
|---|---|---|---|---|---|---|---|
| 一 | 采样与截断 | 从分布里怎么取 | 有意改变 | — | — | — | 参数错配:pass@1 vs pass@k |
| 一 | 约束解码 | token mask | 逐 token 约束 ≠ 条件分布 | 格式 100% 合法 | 全部 | schema 远离自然格式时降质量 | 内容质量 |
| 二 | 投机解码 | 每次前向产出的 token 数 | 不变 | 2–6× 延迟 | \(B \cdot N_{tree} \lesssim \text{ridge}\) | 草稿训练;kernel;大 batch 为负 | 无(宽松验证除外) |
| 三 | PTQ W4A16 | 权重字节 ÷ 4 | 小(PPL +0.1–0.3) | decode 2.5–3.5× | memory-bound | prefill / 大 batch 变慢 | 推理、长上下文、多语言 |
| 三 | W8A8 / FP8 | 字节 ÷ 2,算力 × 2 | 极小 | 全区间 | 全部 | 需 SmoothQuant(INT8) | 几乎无 |
| 三 | W4A4(旋转) | 字节 ÷ 4,算力 × 4 | 小–中(PPL +0.2–0.5) | 全区间 | 需低比特 Tensor Core | 在线 Hadamard;kernel | 同 W4A16 略重 |
| 四 | QAT | 训练参与 | 比 PTQ 小一半 | 同上 | 同上 | 几百–几千 GPU 小时 | 同上更轻 |
| 四 | 2 bit / 三值 | 极低比特 | 中 / 需从头训 | 70B 进 24 GB | — | 查表 kernel;从头训 | 全面 |
| 五 | KV FP8 | KV 字节 ÷ 2 | 极小 | 长上下文 decode | 全部 | 无 | 无 |
| 五 | KV INT4 | KV 字节 ÷ 4(实际 3.2) | 小 | 同上 | < 64K 稳妥 | 元数据 25%;kernel | 超长精确检索、推理链累积 |
| 五 | KV 驱逐 | KV 数量 ÷ k | 任务依赖,可大 | 任意 | 问题已知(SnapKV) | 不可逆 | needle、多跳、问题未知 |
| 五 | 训练时稀疏 | 每步读的 KV | 不变(模型就这样训) | 读取 ÷ 5–10 | 全部 | 重训;kernel | 无 |
| 六 | 2:4 稀疏 | 参数 ÷ 2(形状不变) | 中,需训 | GEMM 1.3–1.8× | compute-bound | 训恢复 | 全面 |
| 六 | 层 / 宽度剪枝 + 蒸馏 | 参数数量与结构 | 大,恢复后小 | 参数 ÷ 2–4 | 全部 | ~100B token 蒸馏;重做后训练 | 推理、指令遵循 |
三条线索走到终点。推导线:拒绝采样的分布等式与 TV 距离、量化误差的 \(\Delta^2/12\) 与 OBS 的拉格朗日、STE 的有偏梯度、KV 离群的通道结构、层的余弦相似度——每种方法在最小化什么、假设了什么,都能写出来。成本线:每种方法改了成本公式的哪一项、收益止于哪个区间(Roofline 的 ridge、上下文长度的交叉点、任务形态的边界)——动手前能估出来。评测线:困惑度是平均、任务看关键 token;逐 token KL 是直接度量;退化集中在推理、长上下文、多语言、指令细节;协议一致、多次采样——每种方法”无损”的声明都要问在哪个指标、哪类任务、什么协议下。
“一个 70B 怎么变成一个能用的 8B”:如果只需要 70B 跑得便宜——FP8 权重 + FP8 KV(无损,字节减半,一张 H100),需要更低延迟再加 EAGLE-3 草稿(3 倍);需要单张消费卡——W4A16 GPTQ / AWQ(40 GB,测推理与长上下文的退化)+ INT4 KV。如果真的需要一个 8B——剪宽度(Minitron 式,激活重要性)到 8B,用 70B 做教师蒸馏 ~100B token,重新 SFT / DPO,再按上面的方法量化部署;预期比从头训的 8B 相当或更好,token 省一个量级以上;推理类任务是最后恢复的,用 GSM8K / MATH 而不是 MMLU 判断”能用”。每一步都改变了分布,每一步都在自己的评测集上验证——这是这六篇唯一不会过时的结论。
回到总纲:《高效推理与压缩(算法侧):解码、投机、量化与 KV》。
本文由 arganzheng 创作,采用 CC BY 4.0 许可协议。在保留原文作者、署名以及完整原文链接(https://arganzheng.life/pruning-depth-scaling-and-small-model-recipes.html)的前提下,欢迎各种形式的转载、翻译或商业引用。
COMMENTS
评论存放在 GitHub Discussions, 用 GitHub 账号登录即可发表,支持 Markdown。 想针对正文某句话说?选中那段文字,点浮出的「评论」即可划线评论;觉得哪里写错了,发表时勾上「同时提交 Issue」。 有人回复你时 GitHub 会按你的通知设置发邮件,不用守在这里。