1. 从1% Token这个数字说起:OPD到底在省什么
第一次看到"1% Token就够了"这个说法,我的反应是怀疑。做过大模型蒸馏的人都知道,蒸馏本质上是在让学生模型去拟合教师模型的输出分布,而输出分布的信息密度远高于硬标签。传统做法要么用海量无标注数据做黑盒蒸馏,要么用教师模型的logits做白盒蒸馏,无论哪种,数据量都是绕不过去的成本项。1%这个数字如果成立,意味着整个蒸馏的数据成本结构被改写了。
先把OPD这个概念拆开。OPD是On-Policy Distillation的缩写,核心思路是让学生模型自己生成样本,再由教师模型对这些样本给出监督信号。这和传统的off-policy蒸馏有本质区别:off-policy是拿一批固定数据,教师先算好答案,学生去学;on-policy是学生边走边问,教师实时纠正。这个区别听起来只是流程差异,但实际影响的是数据分布匹配问题。
传统蒸馏有个隐藏的坑:教师模型在训练数据分布上表现很好,但学生模型在实际推理时会走到教师没见过的状态空间里去。off-policy蒸馏只覆盖了固定数据集的分布,学生一旦偏离这个分布,就失去了教师的指导。而on-policy蒸馏让学生自己探索,教师针对学生实际走到的位置给反馈,监督信号和学生当前策略是匹配的。这就是为什么OPD能用更少的数据达到更好的效果——不是数据变少了,而是每一份数据的利用率变高了。
那1%是怎么来的?我的理解是,在on-policy框架下,学生模型生成的样本天然带有"当前策略的分布信息",教师对这些样本的纠正直接作用于学生最需要改进的地方。传统方法可能需要100万条数据才能覆盖的分布,OPD用1万条就能覆盖到关键区域,因为采样是定向的,不是盲目的。这就像补课:off-policy是给你一本习题集从头做到尾,on-policy是老师看你做题,哪道错了讲哪道,效率自然不在一个量级。
不过这里要泼一盆冷水。1% Token这个数字是有前提的,不是所有场景都能复现。它依赖于几个条件:教师模型和学生模型的能力差距不能太大,否则学生生成的样本质量太差,教师纠正的成本会飙升;任务本身要有一定的结构性,纯开放域生成任务里on-policy的方差会很大;还有就是教师模型的推理成本要可控,因为on-policy意味着教师要在训练过程中反复调用。这些条件在后面会展开讲。
2. On-Policy Distillation的工作机制:学生提问,教师批改
2.1 和off-policy蒸馏的本质差异
要理解OPD,得先搞清楚传统蒸馏为什么"费数据"。off-policy蒸馏的流程是:准备一个固定数据集,教师模型对每条数据生成软标签(logits或概率分布),学生模型去拟合这些软标签。这个流程的问题在于,数据集是静态的,教师给出的监督信号也是静态的。学生模型在训练过程中参数不断变化,但它看到的监督信号始终是针对那批固定数据的。
打个比方,这就像用一本五年前的教材备考,教材内容没变,但考试大纲每年都在调整。学生学的是旧分布上的知识,到了新分布上就抓瞎。更具体地说,off-policy蒸馏中,学生模型在某个中间层产生的表示,和教师模型在同一输入下的表示,可能因为参数初始化、训练动态等原因产生偏移。这个偏移在固定数据集上不明显,但在推理时会累积放大。
OPD的做法是打破这个静态循环。每一轮训练,学生模型先对一批prompt生成自己的回答,然后教师模型对这些回答进行评分或给出修正后的分布,学生再根据教师的反馈更新参数。关键点在于:学生生成的样本反映了它当前的策略分布,教师的反馈直接作用于这个分布上的薄弱环节。
这个机制带来的第一个好处是数据效率。传统方法要覆盖一个分布,需要大量样本;OPD只需要覆盖学生当前策略附近的区域,因为学生不会跑到离自己策略太远的地方去。第二个好处是训练稳定性。off-policy蒸馏中,学生和教师的分布差异可能很大,导致梯度方向不稳定;OPD中,学生生成的样本和教师评估的样本是同一批,分布差异被控制在可接受范围内。
2.2 教师模型在OPD中扮演的角色变化
在off-policy蒸馏里,教师模型是个"离线标注器"——训练前跑一遍,生成软标签,然后就退场了。在OPD里,教师模型是个"在线裁判"——训练过程中持续参与,对学生的每个输出给出反馈。这个角色变化带来的成本是:教师模型的推理开销从一次性变成持续性。
这就引出一个工程上的核心矛盾:on-policy蒸馏效果好,但教师调用成本高。蚂蚁和MBZUAI的这个工作,核心贡献之一就是解决了这个矛盾。他们的思路不是降低教师调用频率,而是提高每次教师调用的信息密度。具体来说,不是让学生生成一堆样本然后教师逐个打分,而是设计了一种更高效的交互机制,让教师的每次反馈都能覆盖更大的策略空间。
我推测这里可能用到了类似"重要性采样"或"优势估计"的技术。学生生成的样本不是均匀采样的,而是根据当前策略的置信度或不确定性来加权。教师对那些学生"拿不准"的样本给出更细致的反馈,对那些学生已经掌握的样本只给粗略信号。这样,同样的教师调用次数,覆盖的有效信息量大幅提升。
另一个可能的技术点是"教师模型的输出压缩"。教师模型的logits维度可能很大(比如词表大小几万),直接传给学生做蒸馏,通信和计算成本都很高。如果能把教师的输出压缩成一个低维表示,或者只传递top-k的logits,就能在保持监督信号质量的同时降低开销。这个思路在近期的蒸馏工作中比较常见,OPD框架下应该也有类似优化。
2.3 1% Token背后的采样策略
回到1%这个数字。如果OPD只是简单地让学生生成样本、教师打分,数据量不可能降到1%。一定还有额外的采样优化。我的判断是,这里用到了基于不确定性的主动采样。
具体逻辑是:学生模型对一批prompt生成多个候选回答,然后计算每个回答的置信度或熵。对于那些学生"很确定"的回答,说明当前策略已经覆盖了这个区域,不需要教师介入;对于那些学生"不确定"的回答,说明当前策略在这个区域有缺陷,需要教师重点纠正。只把不确定的样本送给教师,教师调用量自然大幅下降。
这个策略的有效性取决于一个假设:学生模型的不确定性和它的实际错误率是相关的。这个假设在大多数情况下成立,但也有例外。比如学生模型可能在某些简单问题上过度自信(低熵但错误),在某些复杂问题上过度谨慎(高熵但正确)。如果采样策略没有处理好这些例外,1%的Token可能覆盖不到关键错误区域。
蚂蚁和MBZUAI的工作应该在这方面做了改进。可能的做法是结合多种不确定性度量:熵、边际概率、以及学生模型和教师模型在少量标注数据上的表现差异。用这些信号综合判断哪些样本值得送给教师,而不是单纯依赖熵。
3. 复现OPD蒸馏的实操路径:从环境准备到训练循环
3.1 基础环境与模型选型
如果你想自己复现OPD蒸馏,第一步是确定教师模型和学生模型。教师模型的选择原则是:能力要明显强于学生,但差距不能太大。差距太大,学生生成的样本质量太差,教师纠正起来事倍功半;差距太小,蒸馏的收益不明显。我的经验是,教师模型比学生模型大3到5倍参数量比较合适。比如学生用1B到3B的模型,教师用7B到14B的模型。
框架方面,目前主流的训练框架都能支持on-policy蒸馏,但需要自己实现采样和教师调用的逻辑。HuggingFace的TRL库有蒸馏相关的接口,但主要是off-policy的。如果要实现完整的OPD,可能需要基于PyTorch或JAX自己写训练循环。蚂蚁和MBZUAI的工作如果开源了代码,直接拿来改是最省事的;如果没有,可以参考他们的论文细节自己搭。
硬件方面,on-policy蒸馏对显存的要求比off-policy高,因为训练过程中要同时加载学生模型和教师模型。如果教师模型太大,可以考虑用LoRA或量化来降低显存占用。但要注意,教师模型的量化可能会影响监督信号的质量,需要做消融实验确认。
3.2 训练循环的核心步骤
OPD的训练循环可以拆成四个步骤,每个步骤都有坑:
第一步:学生模型生成样本。对一批prompt,用学生模型做自回归生成。这里的关键是采样参数的选择。温度太高,生成的样本太随机,教师纠正起来没有针对性;温度太低,生成的样本太单一,覆盖不到策略空间的边缘。我的经验是温度设在0.7到1.0之间,top-p设在0.9左右。另外,生成的样本长度要控制,太短的样本信息量不足,太长的样本教师处理成本高。
第二步:教师模型评估样本。把学生生成的样本送给教师模型,获取教师对每个token的logits或概率分布。这一步的计算量最大,因为教师模型要对每个样本做一次前向传播。如果样本数量多,可以考虑用vLLM或TensorRT-LLM做推理加速。但要注意,这些推理框架的输出格式可能和训练框架不兼容,需要做转换。
第三步:计算蒸馏损失。蒸馏损失通常是学生分布和教师分布之间的KL散度。但on-policy场景下,直接算KL散度可能有问题,因为学生生成的样本可能不在教师的高概率区域。这时候可以考虑用反向KL散度,或者用重要性采样来修正。蚂蚁的工作里应该用了某种修正机制,具体细节需要看论文。
第四步:更新学生模型参数。根据蒸馏损失的梯度更新学生模型。这里要注意学习率的设置,on-policy蒸馏的梯度方差比off-policy大,学习率通常要设小一点,或者用梯度裁剪来稳定训练。
3.3 教师调用的成本控制
教师调用是OPD蒸馏中最贵的环节。控制成本的方法有几个:
- 批量调用:把多个样本攒成一批送给教师,而不是逐个调用。批量大小受显存限制,但能显著提升吞吐。
- 缓存机制:如果某些prompt在训练过程中反复出现,可以缓存教师对这些prompt的评估结果,避免重复计算。
- 早停策略:如果学生模型对某个样本的置信度已经很高,可以跳过教师评估,直接用学生自己的预测作为监督信号。
- 教师模型蒸馏:如果教师模型太大,可以先把它蒸馏成一个中等大小的"助教"模型,再用助教模型来指导学生学习。这样虽然多了一步,但总体成本可能更低。
这些方法在实际使用中需要组合。我的经验是,批量调用和缓存机制是必做的,早停策略要看任务特点,教师模型蒸馏适合教师模型特别大的场景。
4. 蒸馏过程中最容易踩的五个坑
4.1 学生模型生成质量太差导致教师信号无效
这是on-policy蒸馏最常见的问题。如果学生模型太弱,生成的样本可能完全是乱码或无关内容,教师模型对这些样本的评估没有意义。判断标准是:学生生成的样本中,至少有30%以上是语义通顺、和prompt相关的。如果低于这个比例,说明学生模型的基础能力不够,需要先做一轮off-policy蒸馏或监督微调,把学生模型的基础能力提上来,再开始on-policy蒸馏。
4.2 教师和学生分布差异过大导致梯度爆炸
on-policy蒸馏中,学生生成的样本分布和教师模型的训练分布可能有较大差异。如果直接用KL散度做损失,梯度可能会很大,导致训练不稳定。解决方法是对损失做裁剪,或者用温度参数来平滑分布。具体来说,可以在softmax之前除以一个温度系数T,T越大分布越平滑,梯度越小。T的取值需要实验确定,一般从2.0开始试。
4.3 采样策略偏差导致关键错误区域被忽略
前面提到,基于不确定性的采样策略有个假设:学生的不确定性和错误率相关。如果这个假设不成立,采样就会偏向那些学生"不确定但正确"的样本,而忽略那些学生"确定但错误"的样本。解决方法是在采样策略中加入多样性约束,比如强制覆盖不同的prompt类型或不同的生成长度。另外,可以定期用一小批标注数据做验证,检查学生模型在哪些区域表现差,然后针对性地调整采样权重。
4.4 教师调用延迟导致训练吞吐下降
on-policy蒸馏的训练循环中,教师调用是串行的:学生生成完才能调用教师,教师返回后才能更新学生。如果教师调用延迟高,整个训练循环就会被拖慢。解决方法是用异步训练:学生生成和教师评估在不同的进程或不同的GPU上进行,通过队列来协调。这样虽然增加了工程复杂度,但能显著提升吞吐。
4.5 蒸馏后的模型在分布外数据上表现下降
蒸馏的本质是让学生模型拟合教师模型的输出分布。如果教师模型在某些分布外数据上表现不好,学生模型也会继承这个缺陷。更严重的是,on-policy蒸馏可能放大学生模型的"盲区",因为学生只在教师覆盖的区域得到指导,教师没覆盖的区域学生可能越走越偏。解决方法是在蒸馏数据中混入一定比例的通用数据,或者在损失中加入正则项,防止学生模型过度拟合教师的输出分布。
5. 1% Token的适用边界与效果验证
5.1 什么任务适合用OPD蒸馏
OPD蒸馏不是万能的。从我的经验看,它最适合以下几类任务:
- 有明确对错标准的任务:比如数学推理、代码生成、结构化信息抽取。这类任务的教师信号清晰,学生生成的样本容易评估。
- 教师模型明显强于学生模型的任务:如果教师和学生能力接近,蒸馏的收益有限,on-policy的额外成本不划算。
- 推理成本敏感的场景:如果最终部署的模型需要低延迟、低成本,用OPD蒸馏出一个小模型是合理的选择。
不适合的任务包括:纯开放域对话(教师信号模糊)、创意生成(对错标准不明确)、以及教师模型本身就不擅长的任务。
5.2 如何验证1% Token是否真的够用
验证方法很简单:做消融实验。用不同比例的Token(1%、5%、10%、50%、100%)分别做OPD蒸馏,然后在同一套评测集上比较学生模型的表现。如果1%的Token就能达到100% Token的95%以上效果,说明这个比例是合理的。如果差距很大,说明采样策略或蒸馏损失有问题,需要调整。
评测集的选择也很关键。不能只用教师模型擅长的评测集,还要加入一些分布外的评测集,检查学生模型的泛化能力。另外,评测指标不能只看准确率,还要看推理延迟、显存占用等工程指标,因为蒸馏的最终目的是得到一个更实用的模型。
5.3 从1%到更少:还能再压缩吗
1%已经很低了,但理论上还有压缩空间。进一步压缩的方向有几个:
- 更好的采样策略:用强化学习来学习采样策略,而不是用启发式规则。让模型自己学会哪些样本值得送给教师。
- 教师信号的压缩:不传递完整的logits,只传递关键信息,比如top-k的token和对应的概率。这样能降低通信成本。
- 课程学习:先从简单的样本开始蒸馏,逐步增加难度。这样学生模型能在早期快速提升,后期只需要少量难样本就能达到好效果。
不过要注意,压缩到极致可能会牺牲鲁棒性。1%的Token可能已经接近某个临界点,再往下压,学生模型在某些边缘情况下的表现会急剧下降。这个临界点在哪里,需要根据具体任务做实验确定。
6. 工程落地时的几个实用技巧
6.1 教师模型的推理加速
教师模型的推理速度直接决定训练吞吐。除了前面提到的vLLM和TensorRT-LLM,还有一些小技巧:
- KV缓存复用:如果多个样本共享相同的prompt前缀,可以复用KV缓存,避免重复计算。
- 动态批处理:根据样本长度动态调整批大小,短样本用大批,长样本用小批,提升GPU利用率。
- 混合精度:教师模型用FP16或BF16推理,速度能提升一倍左右,精度损失可接受。
6.2 学生模型的初始化策略
学生模型的初始化对蒸馏效果影响很大。如果从随机初始化开始,学生生成的样本质量太差,教师纠正成本高。我的建议是先用off-policy蒸馏或监督微调做一个"预热",让学生模型达到基本可用的水平,再开始on-policy蒸馏。预热阶段的数据量不用太大,几万条就够,目的是让学生模型学会基本的语言模式和任务格式。
6.3 训练过程中的监控指标
on-policy蒸馏的训练过程比off-policy更难监控,因为损失函数的绝对值没有直接意义。我通常会监控以下几个指标:
- 学生生成样本的教师评分:如果教师评分持续上升,说明学生模型在进步。
- 学生和教师的KL散度:如果KL散度持续下降,说明学生模型在逼近教师模型。
- 学生模型在验证集上的表现:这是最直接的指标,但要注意验证集不能和蒸馏数据重叠。
- 教师调用次数和训练步数的比例:这个比例反映了采样策略的效率,比例越低说明采样越精准。
6.4 蒸馏后的模型微调
蒸馏完成后,学生模型可能在某些特定任务上还有提升空间。这时候可以用少量标注数据做一轮监督微调,把蒸馏学到的通用能力适配到具体任务上。微调的学习率要设小一点,避免破坏蒸馏学到的知识。另外,微调数据要和蒸馏数据的分布有差异,否则微调的效果不明显。
7. 我对OPD蒸馏的几点个人判断
OPD蒸馏的核心价值不在于"1% Token"这个数字本身,而在于它揭示了一个方向:蒸馏的效率可以通过改变数据生成方式来提升,而不只是靠增加数据量或模型规模。这个思路对整个模型压缩领域都有启发。
从工程角度看,OPD蒸馏目前的主要瓶颈是教师调用的成本。如果教师模型的推理成本能进一步降低,或者采样策略能进一步精准,Token比例还有下降空间。但要注意,效率提升不是线性的,越往极端走,边际收益越小,工程复杂度越高。
另外,OPD蒸馏对教师模型的依赖很强。如果教师模型本身有缺陷,学生模型会继承这些缺陷,而且on-policy的机制可能放大这些缺陷。所以,在做蒸馏之前,先确保教师模型在目标任务上的表现是可靠的。
最后说一个实际体会:蒸馏不是万能药。如果学生模型和教师模型的能力差距太大,或者任务本身太复杂,蒸馏的效果可能不如直接训练一个中等大小的模型。选择蒸馏之前,先算一笔账:蒸馏的工程成本、教师调用成本、以及最终模型的收益,是否划算。这个账算清楚了,再决定要不要上OPD。