> For the complete documentation index, see [llms.txt](https://yeasy.gitbook.io/llm_internals/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://yeasy.gitbook.io/llm_internals/di-san-bu-fen-tui-li-yu-bu-shu-pian/10_inference_optimization/10.5_pruning_distillation.md).

# 10.5 剪枝与知识蒸馏：模型瘦身的两条路

上一节的量化压的是每个数的位宽，参数量一个也没少。本节换一条路，直接减少参数的数量。**剪枝**（Pruning）删掉已训练模型中贡献小的参数或结构；**知识蒸馏**（Knowledge Distillation）用大模型的输出分布训练一个更小的模型。两者要回答的问题相同：删掉或缩小之后，10.1.2 那笔每步读取的字节数是否真的变少，质量靠什么补回来。

## 10.5.1 剪枝

**两种形态。** **非结构化剪枝**把单个权重置零，矩阵形状不变。**结构化剪枝**删掉整个注意力头、MLP 的中间通道、隐藏维度或整层，矩阵真正变小。介于两者之间的是**半结构化稀疏**，如 2:4：每 4 个相邻权重恰好保留 2 个。

**按什么删。** 三种代表性准则，信息量依次增加。

* **幅值剪枝**：删 $|w|$ 最小的权重。不看数据，对 LLM 效果差，原因与 10.4.4 的离群通道相同：小权重若乘在大激活上，贡献并不小。
* [**Wanda**](https://arxiv.org/abs/2306.11695)：重要性取 $|W\_{ij}| \cdot \lVert X\_j \rVert\_2$，即权重幅值乘以对应输入特征在校准数据上的范数，并在每个输出内部比较而不是全层比较。不重训，也不更新保留下来的权重。
* [**SparseGPT**](https://arxiv.org/abs/2301.00774)：把剪枝写成逐层的稀疏回归，删掉一部分权重后，用 Hessian 逆更新其余权重来补偿输出误差。这与 10.4.4 的 GPTQ 同源，两者可以联合使用。

SparseGPT 报告：OPT-175B 与 BLOOM-176B 可在 4.5 小时内一次性剪到 50%–60% 的非结构化稀疏，困惑度几乎不变。这个结论有规模限定，论文同时指出大模型更容易压缩，较小的模型在同样稀疏度下损失明显。

### 稀疏为什么不一定快

非结构化稀疏首先是一个压缩与质量保持的结果，不自动带来加速。

**稠密内核下没有收益。** 零也要从显存读出，也要参与乘法。不换存储格式和内核，50% 稀疏的模型每步读取的字节与稠密模型一样多。

**稀疏格式有索引开销。** 以 CSR 类格式存 FP16 权重，每个非零值要附一个列号。列号按 16 位计，50% 稀疏时每个原始权重平均占 `0.5 × (16 + 16) = 16` 位，与稠密相同；75% 稀疏时 8 位，90% 稀疏时 3.2 位。稀疏度不够高，连存储都省不下来，不规则访存还会拖慢内核。

**2:4 是硬件认可的折中。** 每组 4 个权重存 2 个值，外加每个值 2 位的组内位置。FP16 下一组是 `2 × 16 + 2 × 2 = 36` 位，平均每个权重 9 位，压缩 1.78 倍，不是直觉上的 2 倍。[NVIDIA 的论文](https://arxiv.org/abs/2104.08378)给出同样的账（64 位变 36 位，约省 44%），并报告 Ampere 的稀疏 Tensor Core 对矩阵乘最高约 2 倍加速。代价是掩码受约束，同样 50% 的稀疏度，2:4 的质量损失大于非结构化。表 10-13 汇总三种形态。

| 形态       | 删什么        | 每权重位数（FP16，50% 稀疏） | 加速靠什么           | 质量损失       |
| -------- | ---------- | -----------------: | --------------- | ---------- |
| 非结构化     | 任意单个权重     |     16（CSR，16 位列号） | 专用稀疏内核，高稀疏度才有收益 | 最小         |
| 2:4 半结构化 | 每 4 个留 2 个 |                  9 | 硬件稀疏矩阵乘单元       | 居中         |
| 结构化      | 头、通道、层     |          8（矩阵直接变小） | 不需要特殊支持         | 最大，通常要重训恢复 |

表 10-13：三种剪枝形态的存储、加速条件与质量对比。

### LLM 的结构化剪枝

结构化剪枝得到的仍是一个稠密的小模型，所有推理引擎都能直接运行，10.1.2 的权重字节按比例下降。代价是损失大，必须接一段训练来恢复，通行做法是剪后蒸馏。

[Minitron](https://arxiv.org/abs/2407.14679) 给出了完整流程：先用少量校准数据，依据激活计算每一层、每个注意力头、每个 MLP 神经元和每个隐藏维度的重要性并排序；再按目标尺寸沿深度（层数）和宽度（头、MLP 中间维、隐藏维）裁剪；最后以原模型为教师蒸馏重训。论文从 15B 模型得到 8B 与 4B 模型，每个模型所需训练词元最多比从头训练少 40 倍；并发现宽度剪枝优于深度剪枝，但这一优势要在重训之后才显现。Meta 对 [Llama 3.2 1B 与 3B](https://ai.meta.com/blog/llama-3-2-connect-2024-vision-edge-mobile-devices/) 的说明是同一条路线：从 Llama 3.1 8B 一次性结构化剪枝，再以 Llama 3.1 8B 与 70B 的 logits 为词元级目标做蒸馏来恢复性能。

深度方向还有一个经验发现：[删掉靠后的一段连续层](https://arxiv.org/abs/2403.17887)，再做少量微调修复，一些开放权重模型在常见问答基准上删到接近一半的层才明显退化。边界在于评测口径：该结论来自问答基准，不能直接推广到需要多步推理的任务。

## 10.5.2 知识蒸馏

**知识蒸馏**让小模型（学生）学习大模型（教师）的输出概率分布，而不只是数据里的正确答案。教师给出的是整个词表上的分布：哪些候选词元次优但合理，哪些完全不可能。这些候选词元之间的相对可能性称“暗知识”（dark knowledge），硬标签里没有。

**温度软化。** [Hinton 等人](https://arxiv.org/abs/1503.02531)（2015）把教师与学生的 logits 都除以温度 $T > 1$ 再做 Softmax，让被压扁的小概率显现出来。以 logits `[4, 2, 0]` 为例：

|      温度 | 第 1 项 | 第 2 项 | 第 3 项 |
| ------: | ----: | ----: | ----: |
| `T = 1` | 0.867 | 0.117 | 0.016 |
| `T = 2` | 0.665 | 0.245 | 0.090 |
| `T = 4` | 0.506 | 0.307 | 0.186 |

表 10-14：同一组 logits 在不同温度下的 Softmax 概率。

`T = 1` 时第 2、3 项合计只有 0.13，对损失的贡献很小；`T = 4` 时两者的相对大小清楚可见，学生能学到“第 2 项比第 3 项更合理”。蒸馏损失通常是硬标签与软标签的加权和：

$$\mathcal{L}*{\text{KD}} = (1-\alpha),\underbrace{\text{CE}(y,, p\_S)}*{\text{硬标签}} + \alpha, T^2,\underbrace{\text{KL}!\left(p\_T^{(T)} ,|, p\_S^{(T)}\right)}\_{\text{软标签}}$$

其中 $p^{(T)}$ 是温度为 $T$ 的软化分布。系数 $T^{2}$ 的来历是：软目标产生的梯度幅值按 $1/T^{2}$ 缩小，乘回 $T^{2}$ 才能让两项的相对权重不随温度变化。

按信号来源，蒸馏分三类：

* **响应蒸馏**（response-based）：匹配教师的输出分布，即上式，最常用。
* **特征蒸馏**（feature-based）：额外匹配中间层的隐状态或注意力图。
* **序列级蒸馏**（sequence-level）：让学生学习教师生成的整条序列，出自 [Kim 与 Rush](https://arxiv.org/abs/1606.07947)（2016）。

DistilBERT 是早期的代表案例：相对 BERT-base，参数少 40%，推理快 60%，保留 97% 的语言理解性能。

### LLM 蒸馏的工程形态

生成式模型的蒸馏有几处不同于分类任务。

**分布太大，只能存一部分。** 词元级蒸馏要在每个位置拿到教师的词表分布。Llama 3 的词表有 128,256 项，FP16 下每个词元 256.5 KB，10 亿词元就是约 257 TB。离线保存教师输出时通常只留概率最高的 k 项；在线蒸馏让教师与学生同时前向，省了存储，多了教师的推理成本。

**前向 KL 还是反向 KL。** 上式的 $\text{KL}(p\_T | p\_S)$ 是前向 KL：教师有概率的地方学生都要覆盖。学生容量不足时，它会把概率摊到教师的各个模式之间，生成教师不会说的内容。反向 KL $\text{KL}(p\_S | p\_T)$ 只惩罚学生把概率放在教师认为不可能的地方，学生会集中到少数主要模式上。[MiniLLM](https://arxiv.org/abs/2306.08543) 据此主张生成式模型的蒸馏用反向 KL。

**在学生自己的轨迹上学。** 用固定语料蒸馏时，学生训练时看到的前缀来自数据，推理时的前缀来自自己，两者分布不一致，即曝光偏差。**在线策略蒸馏**（on-policy distillation）让学生先采样，再由教师对这些序列逐词元给出分布作为监督；[GKD](https://arxiv.org/abs/2306.13649) 是这一做法的代表，并允许在前向 KL、反向 KL 之间选择。

**词表不一致。** 词元级蒸馏要求教师与学生共用词表。词表不同，或教师只开放文本接口时，只能做序列级蒸馏：用教师生成的文本做监督微调。它拿不到分布，信息量小于词元级蒸馏。

**容量差距。** 教师不是越强越好。[Mirzadeh 等](https://arxiv.org/abs/1902.03393)的实验表明，师生差距过大时学生的表现反而下降，可以用中等规模的模型逐级传递。教师的错误和偏见也会原样传给学生。

蒸馏也不只是事后压缩，它已进入预训练：[Gemma 2](https://arxiv.org/abs/2408.00118) 的技术报告说明，其 2B 与 9B 模型用知识蒸馏取代下一词元预测来训练。

## 10.5.3 怎样选择与组合

三种手段改变的量不同，可以叠加，见表 10-15。

| 手段          | 改变的量    | 需要的训练                     | 对 decode 每步读取字节的影响 | 主要风险         |
| ----------- | ------- | ------------------------- | ------------------ | ------------ |
| 量化          | 每个参数的位数 | 无，或少量校准                   | 按位宽比例下降            | 离群值、长尾能力回归   |
| 非结构化、2:4 剪枝 | 非零参数的个数 | 无，或少量校准                   | 依赖稀疏格式与内核          | 没有内核支持则不提速   |
| 结构化剪枝加蒸馏    | 矩阵形状与层数 | 十亿到千亿词元（Minitron 为 940 亿） | 按参数量比例下降           | 训练成本、推理类任务退化 |
| 从头蒸馏小模型     | 整个模型    | 完整预训练                     | 按参数量比例下降           | 成本最高，受容量差距限制 |

表 10-15：量化、剪枝与蒸馏的对比。

常见的顺序是先结构化剪枝并蒸馏恢复，得到稠密小模型，再量化。SparseGPT 论文也展示了 50% 稀疏与 4 位量化的联合。失效情形集中在三处：把非结构化稀疏度当作加速比；只用困惑度验收剪枝或蒸馏的结果，漏掉推理、代码等能力的回归；蒸馏数据的分布与业务不一致。

蒸馏得到的小模型还有一个用途：给大模型当草稿模型。这类方法不改目标模型的任何权重，见 [10.6 节](/llm_internals/di-san-bu-fen-tui-li-yu-bu-shu-pian/10_inference_optimization/10.6_speculative_decoding.md)。
