端侧模型知识蒸馏实战:把大模型的本事教给手机小模型
上次我们用 INT8 量化把 MobileNetV2 从 14 MB 压到 3.5 MB(见端侧模型 INT8 量化实战 )。但量化是事后减肥:模型该多大还多大,该多笨还多笨。今天聊另一种压缩思路——知识蒸馏(Knowledge Distillation),它发生在训练阶段:让小模型拜大模型为师,直接把大模型脑子里的判断力继承下来。
一句话概括:量化管体积,蒸馏管智商。两者不冲突,先蒸馏再量化,是端侧部署的标准组合拳。
蒸馏在学什么:软标签与温度
2015 年 Hinton 提出蒸馏时发现一个反直觉现象:训练好的大模型(教师)除了输出"这是猫"的硬结论,其 softmax 概率分布里还藏着"猫和老虎像、猫和卡车不像"这类暗知识。普通训练只让模型看硬标签(0 或 1),把这类信息全扔了。
蒸馏的做法是:把教师模型的输出除以一个温度 T 再做 softmax,得到"放软"的概率分布,作为学生的训练目标。T 越大分布越平,暗知识暴露得越多;T=1 时就退化回普通输出。损失函数是软目标 KL 散度与硬标签交叉熵的加权和,权重 alpha 控制两者比例。
实战:ResNet18 当老师,MobileNetV2 当学生
CIFAR-10 完整可跑代码(PyTorch):
|
|
两个细节值得注意:KL 散度是在除以 T 之后的 logits 上算的,梯度会缩水 T 倍,所以要乘回 T * T 恢复梯度量级;教师全程 no_grad,只推理不出梯度,显存占用很低,手机显存不够也跑得动。
效果与组合拳
以 CIFAR-10 为例(参考量级,具体数值取决于你的数据):从零硬训的 MobileNetV2 约 85%-90% 准确率,跟蒸馏后的学生通常能再涨 1-3 个点,逼近 ResNet18 的水平,而体积只有教师的四分之一、推理更快。数据越少、任务越难,蒸馏收益越明显——这正是端侧小模型偏爱蒸馏的原因。
蒸馏完再走一遍 INT8 量化流程 ,14 MB 的学生模型压到 3.5 MB,且因为学生输出分布更平滑,量化掉点通常比直接量化教师更小。
大模型场景同样适用:DistilBERT 用蒸馏把 BERT-base 从 1.1 亿参数减到 6600 万,保留约 97% 的性能(官方数据)。注意它的输入是文本,说明蒸馏对模态不挑,图像、语音、文本流程通用。
开源工具箱
| 项目 | GitHub | 适用场景 |
|---|---|---|
| torchdistill | yoshitomo-matsubara/torchdistill | 通用蒸馏框架,KD、FitNets、attention transfer 等论文方法现成可用 |
| timm | huggingface/pytorch-image-models | 训练脚本原生支持 --teacher-model,一行参数开启蒸馏 |
| MMRazor | open-mmlab/mmrazor | OpenMMLab 出品,剪枝加蒸馏一体化,适合结构压缩一起做 |
| Transformers | huggingface/transformers | DistilBERT 官方训练脚本,文本模型蒸馏的样板 |
| TF Model Optimization | tensorflow/model-optimization | TF 侧量化感知训练加蒸馏的官方方案 |
选型建议:PyTorch 图像任务先试 timm,够简单;要复现论文方法用 torchdistill;检测、分割这类复杂任务,MMRazor 覆盖面最全。
踩坑清单
- 教师别太强:教师与学生能力差距过大时学生学不动,梯度里全是噪声。CIFAR-10 这种小任务,ResNet18 教 MobileNetV2 刚好,没必要上 ResNet152。
T和alpha要一起调:常用区间T=3-8、alpha=0.5-0.9。T太大分布太平,暗知识稀释成噪声;太小退化回硬标签训练。- 教师必须先微调好:直接用 ImageNet 预训练教师换任务,前几轮软标签不准,收敛慢。
- 学生小 batch 注意 BN:学生网络浅、BN 统计不稳时,攒大 batch 或用累积梯度。
- 蒸馏本质是免费监督信号:软标签相当于额外告诉学生"类别之间存在相似性",和 dropout、数据增强不冲突,可以叠加。
端侧部署的压缩三件套——蒸馏(训练期)、剪枝(结构)、量化(存储)——蒸馏是唯一能提升小模型精度的环节。先拜师,再瘦身,最后上设备,这条路比单吊量化稳健得多。