1. 蒸馏技术全景:知识蒸馏的起源、核心思想与三大范式
知识蒸馏这个概念,最早是 Hinton 在 2015 年那篇经典论文里正式提出的。但我个人觉得,它的思想其实更早就有雏形——说白了,就是让一个小模型去模仿一个大模型的行为。我在 2017 年第一次接触这个方向时,团队正愁怎么把 BERT 塞进手机端,蒸馏几乎是当时唯一可行的路。
1.1 起源:为什么需要蒸馏?
你想想看,一个 BERT-Large 有 3.4 亿参数,跑一次推理要几百毫秒。放到线上服务,延迟根本扛不住。但直接用小模型从头训练,效果又差一大截。蒸馏要解决的就是这个矛盾:把大模型的“知识”迁移到小模型里。
我记得当时我们试过直接用小 BERT 做 fine-tune,F1 掉了将近 8 个点。后来换成蒸馏方案,只掉了 2 个点,模型体积却缩小了 10 倍。嗯,这个差距让我彻底信了蒸馏的价值。
1.2 核心思想:Teacher-Student 范式
蒸馏的框架其实很简洁,就三个角色:
- Teacher(教师模型):大模型,参数多,效果好,但推理慢。通常是预训练好的 BERT、GPT 这类。
- Student(学生模型):小模型,参数少,速度快,但效果差。需要从 Teacher 那里学。
- 蒸馏损失(Distillation Loss):衡量 Student 输出和 Teacher 输出之间差距的指标。常用 KL 散度。
训练时,Student 不仅要拟合真实标签(硬目标),还要拟合 Teacher 的 softmax 输出(软目标)。软目标里包含了 Teacher 对各类别的“置信度分布”,这才是蒸馏的精髓。
1.3 三大蒸馏范式对比
蒸馏发展到现在,主流范式有三种。我在不同项目里都踩过坑,下面这张表可以帮你快速对比:
| 范式 | Teacher 状态 | 训练方式 | 典型场景 | 我踩过的坑 |
|---|---|---|---|---|
| 离线蒸馏 | 固定,预训练好 | Teacher 先训好,Student 单独训 | 大部分工业落地场景 | Teacher 太强,Student 学不动,需要调温度 |
| 在线蒸馏 | 动态更新 | Teacher 和 Student 同时训练 | 多任务学习、数据流场景 | 两个模型互相影响,收敛不稳定 |
| 自蒸馏 | Student 自己当 Teacher | 同一模型不同阶段互相学习 | 没有大模型资源时 | 效果提升有限,容易过拟合 |
离线蒸馏
这是最经典的做法。先训好一个 Teacher,然后冻结它。Student 在训练时,同时计算两个 loss:一个是对真实标签的交叉熵,另一个是对 Teacher 输出的 KL 散度。我建议新手从离线蒸馏入手,稳定、可控、好调试。
在线蒸馏
Teacher 和 Student 一起训练,Teacher 也在不断更新。这种做法的好处是 Teacher 能适应 Student 的能力,但坏处是训练成本翻倍。我在一个对话系统项目里试过,效果确实比离线好一点,但训练时间多了 60%。
自蒸馏
没有 Teacher 怎么办?让 Student 自己当自己的 Teacher。通常是先训一个模型,然后用它的输出去指导下一轮训练。说白了就是“自己教自己”。我见过一些团队在资源受限时用这个 trick,效果比直接训好 1-2 个点。
1.4 蒸馏流程全景图
下面这张图展示了三种蒸馏范式的核心流程。你可以看到,离线蒸馏是单向的,在线蒸馏是双向交互的,自蒸馏是循环的。
1.5 蒸馏的适用场景与选型建议
不是所有场景都适合蒸馏。我总结了几条经验:
- Teacher 必须比 Student 强:如果 Teacher 本身效果就一般,蒸馏出来的 Student 只会更差。我曾经犯过这个错,拿一个 85 分的 Teacher 去教 Student,结果 Student 只有 80 分。
- 任务越复杂,蒸馏收益越大:在简单的二分类任务上,蒸馏可能只提升 0.5 个点。但在序列标注、阅读理解这类任务上,提升能达到 3-5 个点。
- 数据量不能太少:蒸馏需要足够的数据让 Student 学到 Teacher 的分布。少于 1 万条样本时,我建议直接用 Student 从头训。
1.6 本章小结
蒸馏的核心就三句话:
- 用大模型(Teacher)教小模型(Student)
- 软目标比硬标签更有信息量
- 离线、在线、自蒸馏三种范式各有适用场景
嗯,这一章先帮你把蒸馏的全景搭起来。后面我们会深入到每个范式的代码实现、调参技巧和性能优化。你先把这三个范式的区别记牢,后面实战时就知道该选哪个了。