1. 蒸馏基础:知识蒸馏的起源与核心思想、教师-学生网络架构、软标签与温度系数 T
知识蒸馏这个概念,我第一次接触是在 2018 年。当时我在做一个移动端图像分类模型,模型太大,手机跑不动。压缩、剪枝、量化都试了,效果总差那么一口气。后来读到 Hinton 那篇经典论文,才恍然大悟——原来可以让大模型「教」小模型。
说白了,知识蒸馏的核心思想就一句话:让一个复杂的大模型(教师)把自己的「知识」迁移给一个轻量的小模型(学生)。你想想看,这就像老工程师带新人,不是把全部手册丢给他背,而是把经验、直觉、判断力传给他。
1.1 知识蒸馏的起源
2015 年,Geoffrey Hinton 和他的团队在 NIPS 上发表了《Distilling the Knowledge in a Neural Network》。这篇论文提出了一个观点:大模型的「暗知识」藏在软标签里。
传统训练只关注正确类别,但大模型其实知道「猫」和「老虎」更像,「猫」和「汽车」完全不像。这种类别间的相似性关系,就是所谓的「暗知识」。
核心洞察: 教师模型输出的概率分布,比硬标签(0 或 1)包含更丰富的信息。学生模型通过学习这种分布,能学到类别间的相似性结构。
我记得当时在项目中第一次尝试蒸馏,效果并不理想。后来才发现,问题出在温度系数上——这个超参数直接影响蒸馏效果,调不好就白干。
1.2 教师-学生网络架构
教师-学生架构是蒸馏的基础框架。结构其实很简单,我画了一张图帮你理解:
这张图展示了完整的蒸馏流程。教师模型(大)和学生模型(小)接收同样的输入。教师输出软标签,学生也输出软标签。两者之间的差异用 KL 散度计算,这就是蒸馏损失。同时,学生还要跟真实标签计算交叉熵损失。两个损失加权求和,就是总损失。
我的经验: 教师模型在蒸馏过程中是冻结的,不参与梯度更新。你只需要加载预训练好的教师权重,用它生成软标签就行。我曾经犯过让教师也参与训练的错,结果学生学到的全是噪声。
1.3 软标签与温度系数 T
软标签是蒸馏的核心。硬标签长什么样?[0, 0, 1, 0, 0],只有一个 1,其他全是 0。软标签呢?[0.05, 0.02, 0.85, 0.03, 0.05],每个类别都有概率值。
但问题来了:模型输出的概率分布往往太「尖锐」。比如正确类别的概率是 0.99,其他类别都是 0.001 左右。这种分布几乎跟硬标签没区别,暗知识全丢了。
温度系数 T 就是用来解决这个问题的。公式如下:
softmax(z_i / T) = exp(z_i / T) / Σ_j exp(z_j / T)
当 T=1 时,就是标准的 softmax。T 越大,概率分布越平滑;T 越小,分布越尖锐。
| 温度 T | 分布特点 | 适用场景 |
|---|---|---|
| T → 0 | 接近 one-hot,信息丢失 | 不推荐用于蒸馏 |
| T = 1 | 标准 softmax,分布较尖锐 | 常规分类任务 |
| T = 2~5 | 分布平滑,暗知识丰富 | 蒸馏训练(推荐) |
| T → ∞ | 均匀分布,信息稀释 | 不推荐 |
我建议你从 T=3 开始调。有一次我在 CIFAR-100 上做蒸馏,T=3 时学生准确率比 T=1 高了 3 个百分点。但 T 太大也不行,我记得有一次设到 T=10,学生直接学废了,准确率掉到跟随机猜差不多。
避坑指南: 我曾经在蒸馏时犯过一个低级错误——教师和学生用了不同的温度。教师用 T=3 生成软标签,学生用 T=1 计算蒸馏损失。结果两个分布根本对不上,损失一直不收敛。记住:教师和学生必须用相同的温度 T。
1.4 蒸馏的完整损失函数
蒸馏的总损失由两部分组成:
L_total = α * L_distill + (1 - α) * L_student
其中:
L_distill = KL_div(softmax(teacher_logits / T), softmax(student_logits / T)) * T²
L_student = CrossEntropy(student_logits, hard_labels)
注意那个 T² 系数。为什么要乘 T²?因为梯度会随着 T 增大而缩小,乘 T² 是为了保持梯度尺度一致。这个细节很多人会忽略,但很重要。
参数建议:
- α(蒸馏权重):0.7~0.9,教师越强,α 可以越大
- T(温度):2~5,从 3 开始调
- β = 1 - α(学生权重):0.1~0.3,保留硬标签监督
嗯,这里要注意:α 不是越大越好。如果教师模型本身有偏差,α 太大反而会把偏差传给学生。我一般先设 α=0.7,看学生收敛情况再调。
1.5 蒸馏的三种常见模式
根据教师和学生的关系,蒸馏可以分为三种模式:
- 离线蒸馏: 教师提前训练好,固定权重。学生只学教师的输出。这是最常用的方式,计算成本低。
- 在线蒸馏: 教师和学生同时训练。教师也在不断更新,学生跟着学。适合教师模型本身也在迭代的场景。
- 自蒸馏: 自己教自己。同一个模型,先用大模型训练,再用自己的输出教小版本。我在做模型压缩时经常用这招。
我个人习惯用离线蒸馏。原因很简单:稳定。教师固定了,学生学到的知识是确定的,不会出现「教师今天教 A,明天教 B」的情况。
小技巧: 如果你做自蒸馏,可以先用完整模型训练 50 个 epoch,保存 checkpoint。然后用这个 checkpoint 做教师,蒸馏一个更小的版本。我试过,效果比直接训练小模型好 2~5 个点。
蒸馏基础就这些。说白了,核心就是三件事:教师-学生架构、软标签、温度系数 T。把这三件事搞明白,蒸馏就算入门了。后面我们会深入特征迁移、部署优化,一步步把蒸馏做到生产级。