3. 教师模型选型
做知识蒸馏,第一步就是选老师。老师选不好,后面全白干。
我见过不少团队,一上来就无脑上 BERT-large,结果蒸馏出来的学生模型还不如直接训练一个小模型。为什么?因为老师教的东西本身就有问题,或者老师太强了,学生根本学不会。
这一章,我们就来聊聊怎么选老师,以及选好之后怎么把预训练权重加载进来。
3.1 三大主流教师模型家族
目前 NLP 蒸馏领域,教师模型基本就三个流派:BERT、RoBERTa、。它们各有各的脾气。
| 模型家族 | 核心特点 | 适合蒸馏的场景 | 我个人习惯 |
|---|---|---|---|
| BERT | 双向编码器,MLM + NSP 预训练 | 分类、NER、QA 等理解型任务 | 中小规模任务首选,稳定 |
| RoBERTa | 去掉 NSP,动态 Mask,更大 batch | 需要更强语义理解的任务 | 效果比 BERT 好 1-2 个点 |
| 系列 | 单向自回归,生成式预训练 | 文本生成、对话、摘要 | 生成任务首选,但蒸馏难度大 |
核心原则:教师模型的任务类型必须与学生模型的目标任务一致。你拿 去蒸馏一个分类模型,效果大概率不如 BERT。
3.2 选型标准:五个维度
选老师不是拍脑袋。我总结了五个关键维度,你照着这个清单去选,基本不会踩坑。
- 任务匹配度——理解任务选 BERT/RoBERTa,生成任务选 。这是铁律。
- 模型容量——教师参数量一般是学生的 3-10 倍。太小了学不到东西,太大了学生跟不上。
- 预训练数据域——教师用的预训练数据跟你的下游任务越接近越好。比如做医疗 NLP,用 BioBERT 比用原始 BERT 强很多。
- 推理速度——蒸馏过程中需要教师反复推理。如果教师太慢,整个训练周期会拉得很长。
- 社区生态——HuggingFace 上有没有现成权重?有没有成熟的蒸馏工具?这直接决定你的开发效率。
我的经验:如果你刚开始做蒸馏,先用 BERT-base 当老师。它够用、够快、社区支持最好。等流程跑通了,再换更大的模型。
3.3 预训练权重加载实战
选好模型之后,下一步就是加载权重。这一步看似简单,但坑不少。
3.3.1 从 HuggingFace 加载
现在最主流的方式就是通过 transformers 库加载。代码很简单:
from transformers import AutoModel, AutoTokenizer
# 加载 BERT-base 教师模型
teacher_model = AutoModel.from_pretrained("bert-base-uncased")
teacher_tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
# 加载 RoBERTa-large
teacher_model = AutoModel.from_pretrained("roberta-large")
teacher_tokenizer = AutoTokenizer.from_pretrained("roberta-large")
# 加载
teacher_model = AutoModel.from_pretrained("")
teacher_tokenizer = AutoTokenizer.from_pretrained("")
注意: 系列加载时,记得设置 pad_ = eos_,否则 batch 推理时会报错。我曾经在这个坑里卡了半天。
3.3.2 加载自定义权重
有时候你需要加载自己微调过的模型。比如你在医疗数据上微调了一个 BERT,现在想用它当老师。
# 加载本地微调后的教师模型
teacher_model = AutoModel.from_pretrained("./my_finetuned_bert")
teacher_tokenizer = AutoTokenizer.from_pretrained("./my_finetuned_bert")
这里有个关键点:微调后的模型可能修改了分类头。蒸馏时我们通常只需要取 teacher_model.base_model 或者指定输出 hidden states。
3.3.3 冻结教师模型
蒸馏过程中,教师模型是 不参与梯度更新 的。一定要记得冻结:
for param in teacher_model.parameters():
param.requires_grad = False
teacher_model.eval() # 切换到评估模式
为什么?因为教师的作用是提供软标签和中间层特征。如果教师也在更新,那蒸馏就变成了联合训练,效果反而会变差。
3.4 教师模型选型决策流程图
下面这张图是我自己总结的选型流程,每次做新项目我都会过一遍:
3.5 常见问题与避坑指南
我曾经踩过的坑:
- 教师模型太大导致 OOM:蒸馏时教师和学生同时加载,显存占用翻倍。我建议先用
teacher_model.half()转半精度,或者用 CPU 推理教师。 - 分词器不匹配:教师和学生用不同的分词器,导致 对齐出错。一定要确保蒸馏时用同一个分词器。
- 忘记冻结教师:有一次我忘了设
requires_grad=False,训练了 10 个小时才发现教师参数也在变。白白浪费了算力。
我的建议:如果你不确定选哪个模型,直接跑一个快速对比实验。用 10% 的数据,分别用 BERT-base 和 RoBERTa-base 做教师,蒸馏一个小学生模型,看哪个效果更好。这个时间投入绝对值得。
3.6 小结
教师模型选型是蒸馏流程的基石。记住三个要点:
- 任务类型决定模型家族
- 容量和数据域决定具体版本
- 加载权重后务必冻结并切换到 eval 模式