你大概遇到过这种局面:手上有个大模型效果不错,但推理成本和延迟压不下来,想用蒸馏把能力搬到小模型上,翻了几篇论文却发现方法名一堆、损失函数各不相同,不知道该从哪下手。这篇按「先定问题、再挑方案、最后验证」的顺序把知识蒸馏串一遍,重点讲清楚每种解法适合什么条件、什么情况下不适用,以及怎么用站内资料把结论核对成自己的判断。
先想清楚蒸馏到底在解决哪类问题
动手做蒸馏之前,先花十分钟回答一个问题:你要解决的到底是「模型不够准」,还是「模型跑不动」。这两个答案对应完全不同的技术路线,选错了后面全是白工。
- 蒸馏在做什么
- 把一个或多个教师模型的输出分布当成监督信号,让学生模型去拟合这套分布,而不是只拟合非黑即白的硬标签
- 为什么分布比硬标签信息多
- 硬标签只告诉你正确答案是哪个,分布还告诉你教师认为哪些选项是「次优但接近」的,这类相对关系本身就是额外监督
- 蒸馏最擅长的场景
- 任务边界清晰、但人工标注贵、或者标签本身带噪声的场合
- 不解决什么
- 不解决显存吃紧、不解决推理算力不够、也不解决教师本身就判断错误的样本
先分清你要的是压缩还是加速
| 你的瓶颈 | 该动的地方 | 为什么 |
|---|---|---|
| 模型体积大、装不进目标环境 | 蒸馏,换一个更小的学生结构 | 蒸馏改的是模型本身,参数量和结构都变了 |
| 模型能装下但推理太慢、显存占用高 | 量化,降低数值精度 | 量化改的是权重和激活的表示精度,结构基本不动 |
| 两者都紧张 | 先蒸馏再量化,组合使用 | 这不是二选一的关系,实际工程里经常串起来做 |
| 只是想省点标注钱 | 蒸馏 + 少量标注 | 把教师当标注器,比纯人工便宜,但要看教师质量 |
很多人一上来就把蒸馏当成万能压缩手段,结果做完发现推理速度没怎么变。原因很简单:换个更小的模型确实能同时降体积和降算力,但如果你的瓶颈只出在数值精度和访存上,量化才是直接对症的那一刀。判断标准是看你的目标机器卡在哪一步,去站内的资料库页面对一下目标硬件的参数再决定。
这几类情况先别急着上蒸馏
- 教师模型在某类样本上本身就是错的:蒸馏只是把这个错误以更平滑、更自信的方式传给学生,学生不会自己纠正
- 线上数据分布和训练数据差得远:教师在自己没见过的分布上判断本来就虚,学生照着学只会一起跑偏
- 目标任务需要严格可解释的决策链路:蒸馏出来的学生学到的是分布,未必能还原教师的推理过程
- 你连教师在这类样本上的错误率都没测过:先去站内的检测页面把教师的表现摸清楚,再谈要不要蒸馏
- 确认瓶颈类型写清楚目标环境的硬约束是显存、算力还是体积,判断标准是哪一个指标先撞墙,撞墙的那个才决定技术路线
- 摸清教师底细在你要蒸馏的那类样本上单独跑一遍教师,记录它错在哪、错得有多自信,错得越自信的样本越危险
- 对比数据分布把线上真实请求的样本和训练集做一次粗略分布比对,差得远就先补数据,别指望蒸馏自动兜住
- 决定路线组合按上面的对照表选蒸馏、量化还是两者串起来,去站内的工具目录页确认有哪些现成实现可用
蒸馏放大的从来不是模型的正确率,而是教师对世界的理解方式——包括它理解错的那部分。
知识长什么样:响应、特征还是关系
蒸馏这件事,第一步不是挑算法,而是先问一句:你到底能从教师那边拿到什么。拿到的东西不同,能选的路线就完全不同。业内通常把可蒸馏的知识分成三类——输出层概率、中间层特征、样本或层之间的关系结构。这三类没有绝对高下之分,只有「你手上有什么材料」和「你愿意付多少工程成本」的匹配问题。
| 知识类型 | 学生学什么 | 对教师结构的要求 | 主要代价 |
|---|---|---|---|
| 基于响应 | 输出层的概率分布(软标签) | 无,黑盒也能做 | 信息量受输出维度限制 |
| 基于特征 | 中间层的表示 | 要能读到教师内部,层要对得上 | 维度不匹配,得加映射层或注意力对齐 |
| 基于关系 | 样本之间、层之间的关系结构 | 要能算成对或成组的相似度 | 构造关系矩阵有额外开销,超参更多 |
基于响应是最省事的一类:教师只把最后的概率吐出来,学生去拟合这个分布,而不是去拟合硬标签。好处是对教师是黑盒还是白盒完全不敏感,接口级就能接。代价也很明显——学生能学到的信息上限,被输出维度卡死了。分类任务里输出维度就是类别数,类别不多的时候,那点软标签承载的「暗知识」其实相当有限。
基于特征走的是另一条路:让学生中间层的表示去靠近教师中间层的表示。理论上信息更丰富,实践中通常也确实更容易把学生带起来,尤其是教师和学生容量差距大的时候。但这条路有个绕不开的麻烦——教师和学生的层数、通道数、特征图尺寸往往对不上,你得额外插一个映射层把两边拉齐,或者用注意力对齐的方式,让两边关注的空间区域先对齐再算差异。这些都是要写进训练代码、要调、会引入新超参的东西。
基于关系既不盯单个样本的输出,也不盯某一层的激活,而是盯「结构」:样本和样本之间的相似度矩阵长什么样,层和层之间的依赖关系长什么样。它的好处是对教师和学生的结构差异最宽容,两边宽度差多少、层数差多少,只要能算出关系就能对齐。代价是关系矩阵本身要算,样本数或层数一多,内存和时间都会涨,而且关系到底用哪种度量,是个需要试的选择。
- 先盘材料:教师是只能调接口,还是能拿到权重和中间激活?只能调接口就别考虑特征和关系路线。
- 再看维度:能拿到中间层的话,先比一比两边的通道数和分辨率差多少,差得离谱就准备加映射层。
- 差得多就走关系:教师和学生结构差太大时,强行逐层对齐往往不如对齐关系结构稳。
- 小数据优先软标签:标注少、类别也不多时,基于响应往往够用,没必要为了几个点去搭对齐模块。
- 别一次上全套:先把响应做通当基线,再决定要不要加特征或关系,不然出问题时分不清是哪一块的锅。
需要提醒的是,「特征一定比响应好」这个说法并不总成立。当教师和学生的容量差距很小、或者任务本身类别就少的时候,特征对齐带来的收益可能被它引入的调参成本吃掉。反过来,当教师是第三方闭源接口、你根本拿不到中间层时,讨论特征和关系就是纸上谈兵,老老实实做输出层对齐才是唯一可行的。具体到不同模型和不同中转渠道,能拿到哪些产物、当前各家的价格与可用状态,这些数字会变,建议直接到 站内价格与模型库页面(/pricing) 和 中转站检测页面(/relay-check) 核对当时的实际情况再动手。
下一步确定路线之后,接着要解决的是「教师和学生容量差多少算合适」,站内指南中心有对应的选型与配比讨论。→训练过程里最容易翻车的几个点
蒸馏训练翻车,大多不是模型结构的问题,而是几个超参和流程细节没对齐。下面这三个点最常见:损失权重、训练节奏、数据增强。它们有个共同特征——用常规训练的直觉去设,前期看着正常,中后期才开始出问题,等你发现时已经浪费了一轮训练。
- 硬标签损失
- 学生对着真实标签算的那部分损失,负责把学生拉回正确答案
- 蒸馏损失
- 学生模仿教师输出分布的那部分损失,负责把教师的暗知识传过去
- 损失权重
- 两项损失之间的比例系数,调的就是「听标签」还是「听教师」的优先级
权重:先跑通,再往上加
权重给小了,学生基本只学标签,教师信息进不去,蒸了个寂寞;给大了,学生会被教师的错误判断带偏——教师在某些样本上本来就不确定或答错,学生却被要求全盘照抄。判断信号很直接:看学生在这类样本上的表现有没有比不用教师时更差,如果更差,说明权重压过了标签的纠正作用。
- 先用小权重跑通让蒸馏损失只作为辅助项存在,确认整条链路能正常收敛、不报错、不震荡
- 逐步往上抬每次只动一个量级,抬完在同一批验证样本上对比,看学生相对纯标签训练的差距是缩小还是扩大
- 定位被带偏的样本把教师置信度低或判断明显可疑的样本单独拎出来看学生的输出,如果这些样本上学生明显退化,就把权重降回去
- 定下区间再调别的权重不稳定之前不要动学习率、轮次,否则两个变量同时变,说不清是谁的问题
节奏:轮次要更长,学习率要更温和
蒸馏常需要比常规训练更多的轮次和更小的学习率。直接把普通训练那套超参搬过来,典型现象是学生前期涨得很快——因为它在快速吸收教师的输出分布,但后期就卡住不动了,验证指标上不去也下不来。原因通常是学习率偏大,学生在教师分布附近来回跳,没法稳定收敛到那个更平滑的解。
| 现象 | 可能原因 | 先动哪个 |
|---|---|---|
| 前期涨得快,中后期平掉 | 学习率偏大,学生围着教师分布震荡 | 先降学习率,轮次同步拉长 |
| 一直没起色,和纯标签训练差不多 | 蒸馏损失权重太小,教师信息没进来 | 先小幅加权重,观察验证集 |
| 训练损失降但验证变差 | 轮次过多,学生在拟合教师的噪声 | 提前停,或加正则 |
| 损失忽高忽低 | 权重和学习率同时过大 | 两个都降,先稳一个 |
注意这个表只是排查顺序,不是结论。每家的数据分布、教师质量、学生容量都不一样,实际数值要去站内相关的模型与价格资料库页面核对,看同类模型在相似任务上的常规配置区间,别凭感觉拍。
数据增强:在蒸馏里会被放大
- 学生看到的不只是增强后的输入,还有教师对这批增强样本的判断,增强的偏差会连同教师的判断一起被学进去
- 增强策略如果和教师擅长的输入分布不匹配,教师给出的软标签质量会下降,学生等于在学噪声
- 常规训练里增强只是扩数据,蒸馏里它同时改变了监督信号的来源,影响面更大
- 判断方法:固定一套增强,分别用教师和学生在同一批增强样本上看表现,差距大的那部分就是风险区
- 先小范围开增强,确认教师在这些样本上的判断质量,再逐步放开,不要一次上满
蒸馏里调超参,一次只动一个,动完必须能说清是哪个环节变了。
验证蒸馏效果:别只看一个指标
学生模型在测试集上跑出一个平均分,很多人到这里就收工了。但平均分是最不挑毛病的指标:它会把少数类别的崩盘和多数类别的微涨混在一起,看起来还挺体面。真正值得看的是同一测试集上学生和教师的差距分布——差距落在哪些类别、哪些输入长度、哪些业务切片上。
| 观察维度 | 怎么切 | 说明什么 |
|---|---|---|
| 类别 | 按业务标签分组算学生与教师的差距 | 是整体弱,还是某几类被牺牲掉 |
| 输入长度 | 按短/中/长分桶对比 | 长输入往往是蒸馏塌陷重灾区 |
| 语言或口吻 | 按正式/口语、中英混杂分桶 | 风格类能力最容易在蒸馏中丢失 |
| 置信度区间 | 按教师高置信与低置信样本分开看 | 低置信区差距大属正常,高置信区大就要查 |
先看差距分布还有一层好处:它能告诉你该不该继续做蒸馏。如果差距集中在极少数冷门类别,且这些类别在线上请求里占比很小,那可以考虑接受;反过来,如果差距摊在核心类别上,平均分再漂亮也不该上线。这条判断标准不适用于那种必须全类别一致达标的合规场景,那时只能按最差类别的表现来卡。
遗忘检查:变好的代价是什么
- 准备一份通用能力小测集,内容与蒸馏任务无关,比如基础推理、指令跟随、常见问答
- 在学生模型蒸馏前后各跑一次,比较同一批题目的通过情况,而不是比总分的绝对值
- 重点看原本就会做、蒸馏后做错的题,这类回退比新题不会做更危险
- 如果通用能力明显退化,先怀疑训练数据配比和训练轮数,而不是怀疑学生模型容量不够
- 用大模型蒸馏小模型时遗忘最明显,因为教师能力远超学生容量,学生容易把容量全押在任务上
通用能力小测集不用很大,但要覆盖你实际业务之外的高频场景。有些团队嫌麻烦,只用蒸馏任务自己的验证集看效果,那永远发现不了遗忘。另一种不适用的情况:如果学生模型只在一个封闭管线里做单一职责,从不处理开放输入,那通用能力退化的优先级可以往后放,但记忆和简单推理这类底座能力仍要抽查。
- 取真实请求样本从线上日志或线上流量抽样里随机抽一批真实输入,覆盖不同来源和时段,不要用训练集里的样本,也不要用人工构造的干净样本。
- 同批对比学生与教师同一批输入分别跑学生和教师,记录输出差异。人工只看分歧样本,一致的样本直接跳过,能省掉大半人工。
- 给分歧分等级分成「不可接受」「可接受但需优化」「风格差异」三档,统计各档占比。不可接受档占比是上线与否的核心依据。
- 核对线上指标小流量灰度后,把线上真实指标与离线抽样结果对照。对不上就回到训练集与线上分布的差异上找原因,别急着调模型。
抽样对比不需要全量跑,但样本要真。样本来源、抽样比例和判断口径最好固定下来,每次蒸馏迭代都用同一套,否则前后两版没法比。想把各家的评测口径和线上追踪方法对齐,可以到站内的评测与指南页面看整理好的对照方法,再决定自己这套抽样怎么定。
哪些情况下蒸馏不是最优解
先别急着拉训练任务。蒸馏是拿一个学生模型去模仿教师模型的输出分布,这件事本身有成本:要造数据、要清洗、要训、要评测、要维护两条链路。如果需求只是「把每天那点调用花销压下来」,而业务对首字延迟和并发抖动没什么硬要求,那多半用不着训模型——换成更便宜的模型、或者按请求难度做分流,改动量小得多,出问题也能立刻回滚。
| 你的真实约束 | 先考虑的动作 | 什么时候蒸馏才更合适 |
|---|---|---|
| 只想降调用成本,延迟无所谓 | 换更便宜的档位、按任务分流、缓存高频结果 | 已有明确的效果下限,且便宜档位达不到这个下限 |
| 对延迟、吞吐有硬要求 | 换更小更快的模型或走本地部署 | 小模型单靠选型补不回效果,且有稳定的教师可模仿 |
| 任务靠多步推理、链路长 | 先做数据筛选和语料优化 | 任务偏格式化、分类、抽取这类映射型工作 |
| 数据来源和授权没理清 | 先查服务条款和使用范围 | 已确认输出可被用于训练,且留存方式合规 |
换模型和分流这件事的基本判断,可以到 /compute/finetune 对照着看:那里把「要不要微调、要不要自训」的决策条件拆得比较细,蒸馏可以理解成其中更重的一支。判断顺序建议是:先确认现有调用里有多少是重复的、有多少是简单任务;再看便宜档位在这些任务上的实际通过率;只有当便宜档位稳定卡在某个能力上、且这个能力是刚需时,才轮到蒸馏出场。
- 先量化需求统计当前请求里简单任务和复杂任务的比例,以及重复请求占比。如果重复率高、简单任务占比高,先做缓存和分流,通常就能解决大部分成本问题。
- 再验证替代方案把候选的便宜模型或小模型接进灰度流量,用业务侧的真实通过标准去跑,而不是只看通用评测。若通过率已经够用,直接定稿,不必进入蒸馏流程。
- 最后才比蒸馏只有当替代方案在关键子集上稳定不达标、且这个子集不可拆走时,才评估蒸馏。评估时要算上数据构造、训练、评测、长期维护四项人力,别只算推理时的单价差额。
另一个常见误判是:任务本身需要长链推理,却指望学生模型把教师的思考过程也一起学会。实际训练里,学生更容易对齐的是输出的外壳——格式、语气、分点习惯、常见模板,而中间那些「先拆解、再验证、再回头改」的步骤很难靠输出层面的模仿被稳定学到。判断依据很简单:把教师模型在同类题上的中间步骤去掉、只留最终答案,再让学生学一遍,如果效果掉得不多,说明这任务本来就不靠推理链;如果掉得厉害,说明推理过程才是价值所在,那么该做的是数据筛选——挑那些步骤清晰、结论可验证的样本,把噪声样本剔掉,而不是硬做输出对齐。
- 样本里最终答案对、但过程是编的,这类数据留着会让模型学到错误的中间路径,优先删。
- 答案对、过程也严谨的样本才是高价值数据,宁可少而干净,不要多而混乱。
- 同一个问题的多份回答里过程和结论互相矛盾的,先别用来训练,先人工定一个基准答案。
- 只对齐格式不对齐过程的训练目标,适合抽取、分类、改写这类映射型任务,不适合多步计算和需要查证的任务。
- 推理类任务可以考虑拆成「先教会分步、再教会收敛」两段,而不是一次端到端对齐。
最后是授权问题,这一步经常被放到最后,但它其实是前置条件。用某家模型的输出当训练数据,能不能商用、能不能再分发,取决于那家模型的服务条款和使用政策,不同厂商、不同接口、不同套餐的约定可能不一样。核对思路可以参考 /tools/quality-check:先确认数据来源和获取方式,再逐条对照条款里关于输出使用、衍生物、再训练的表述,把结论落到文档里留档;条款里表述模糊的地方,不要自己往宽松方向解释,按最保守的方式处理。
这个方向接下来会往哪走
过去做蒸馏,主流思路是「教师给答案,学生抄答案」:教师对一批样本输出概率分布或标签,学生在同样输入上去拟合这些输出。这条路简单、好复现,但天花板也明显——学生只学会了「结果长什么样」,没学会「结果是怎么一步步推出来的」。所以接下来一个很自然的方向,是把监督信号从最终输出往中间过程挪。
具体说,就是让教师把推理链、中间草稿、工具调用的先后顺序和参数,也当成监督数据留给学生。学生模仿的不再只是「答案对不对」,还包括「遇到这类问题时先做什么、后做什么、什么时候该去调工具」。这种做法的代价是数据构造更贵,教师轨迹得专门采集和清洗;如果你手上的任务本身就是一步到位的分类或回归,没有中间过程可模仿,那这个方向对你的收益就有限,不必硬套。
| 迁移维度 | 教师侧提供什么 | 学生侧要注意什么 |
|---|---|---|
| 输出模仿 | 最终答案或概率分布 | 实现简单,但学不到过程 |
| 过程模仿 | 推理步骤、工具调用轨迹 | 教师轨迹质量参差,要先清洗 |
| 跨模态迁移 | 文本教师的能力映射到多模态学生 | 模态对齐做不好,蒸馏反而掉点 |
| 能力解耦 | 把某一种能力单独抽出来当教师 | 拆分粒度和再组合方式决定成败 |
跨模态和能力解耦是另一条线。前者是把文本教师学到的东西迁到能看图、听声的学生上;后者是把「推理」「检索」「格式遵循」这类能力拆开,各自蒸馏再拼回去。这两个方向听起来美好,但落地时最大的坑是「对齐」:模态之间有语义鸿沟,能力拆开之后怎么再组合回一个不自相矛盾的整体,目前还没有省事的答案。相关术语和概念边界,可以先去 前沿概念词典(/ai-dict/category/frontier) 混个脸熟,再决定要不要往自己的任务里套。
- 先确认有没有过程可模仿看你的教师输出里是否包含推理步骤或工具调用记录。如果从头到尾只有最终标签,那这条路线暂时用不上。
- 再确认组合对象问自己学生模型后面要不要接量化或剪枝。要接,就得把蒸馏放进整条流水线里一起调,而不是先单独调好蒸馏再叠加。
- 组合流水线要重新验证单独蒸馏出来的效果结论,换成「蒸馏+量化」或「蒸馏+剪枝」之后往往不成立,必须在目标组合下重跑一轮,别直接沿用小实验的结论。
- 记录每次组合的配置至少把教师来源、学生结构、组合顺序记成一张表,否则出问题时分不清是蒸馏的锅还是量化剪枝的锅。
常见问题
知识蒸馏和模型蒸馏是一回事吗?
日常口语里经常混用,严格说知识蒸馏强调的是「用教师的输出分布当监督信号」这套训练方法,模型蒸馏是更宽的说法,包含结构压缩、层数裁剪等做法,选方案时先明确你要的是训练方法还是整体压缩流程。
蒸馏出来的小模型能直接商用吗?
取决于教师模型的授权条款和你的训练数据来源,有些许可只允许个人使用,用它的输出训练学生并商用可能越界。具体条款要逐条读,拿不准就去站内许可证相关页面核对边界,别只看模型是不是「开源」。
蒸馏和量化该先做哪个?
如果只是想让现有模型跑得更省资源,先做量化,改动小、可回退;如果目标是把能力搬到结构完全不同的小模型上,先做蒸馏,再对蒸馏结果做量化。两者叠加时效果要重新测一遍,不能直接相乘。
教师模型选多大合适?
不是越大越好。教师和学生容量差距过大时学生学不动,建议先试一个中间规模的教师,看学生的收敛曲线和最终差距,再决定要不要换更大的教师,省下的算力可能比直接上大教师更值。