关键词:On-Policy Distillation、OPD、Reverse KL、Mode-Seeking、GRPO、RLVR、Tinker、蒸馏
写在前面
前面几篇文章分别讲了 DPO(用偏好对训练)、GRPO(用组内相对优势训练)、RLVR(用规则验证器给奖励)。这些方法都在回答同一个问题:当我们不想完整跑传统 RLHF 那一整套(训练 RM、跑 PPO)时,训练信号还能从哪里来?DPO 的答案是偏好对,RLVR 的答案是验证器,而这篇文章要讲的OPD(On-Policy Distillation,在线策略蒸馏)给出了第三种答案:用一个更强的 Teacher 模型,在 Student 自己生成的轨迹上,逐 token 给出密集反馈。
这个方法最早由 Agarwal 等人在 GKD(Generalized Knowledge Distillation)工作中系统化,2025 年因为 Thinking Machines Lab(Kevin Lu 等)的工程化博客和 Qwen3 的复现结果而被广泛关注,现在已经成为在 GRPO/RLVR 之外训练小模型、特别是训练"专才模型"的重要选项。
一、OPD 要解决什么问题
1.1 三种训练范式的对比
在讲 OPD 具体怎么做之前,先把它放在三种范式的对比里看清楚它的位置:
| 范式 | 训练轨迹从哪来 | 反馈密度 | 典型问题 |
|---|---|---|---|
| SFT / 离线蒸馏(SeqKD) | Teacher 写好的答案 | 密集(每个 token 都有监督) | 分布偏移:训练时看 Teacher 的轨迹,推理时却要接着自己生成的内容往下写 |
| RL(GRPO/RLVR) | Student 自己探索 | 稀疏(通常只有结果级的 0/1 奖励) | 样本效率低:一个 2000 token 的解题过程,可能只有最后一个 token 才带来学习信号 |
| OPD | Student 自己生成 | 密集(Teacher 对每个 token 都能给出反馈) | 需要一个可靠的、思维模式相近的 Teacher |
传统监督微调的问题在于训练时和推理时看到的分布不一样:训练时,模型看到的都是 Teacher 写好的"标准答案"前缀;但推理时,它必须接着自己刚刚生成的内容继续写下去。一旦某一步生成得不够好,后续的生成就会在一个训练时从未见过的分布区域里越走越偏,这就是经典的分布偏移(也叫 exposure bias)问题。
标准 RL(比如 GRPO)恰好解决了分布偏移——因为训练轨迹本来就是 Student 自己生成的,训练分布和推理分布是一致的。但 RL 的代价是奖励太稀疏:不管生成了多少个 token,一整条轨迹通常只换来一个标量奖励(答对给 1 分、答错给 0 分),模型很难知道这上千个 token 里究竟哪几步是关键。
OPD 的思路是把这两者的优点结合起来:让 Student 按自己的策略生成轨迹(保留 on-policy 的优势),同时让一个更强的 Teacher 沿着这条轨迹逐 token 给出密集反馈(保留监督信号的密度优势)。用一句话概括就是:OPD 同时拿到了 RL 的 on-policy 分布和蒸馏的密集监督。
1.2 核心三步流程
OPD 的核心流程只有三步:
- Student 自主 rollout:Student 模型按照自己当前的策略,对给定 prompt 生成一段完整回复。这个过程完全由 Student 独立完成,不受任何外部干预——它就是在做正常的推理;
- Teacher 逐 token 给出反馈:Teacher 不重写答案,而是沿着 Student 走出来的这条轨迹,在每一步前缀上计算"如果是我,这个位置的下一个 token 概率分布应该长什么样",并据此判断 Student 实际选出的这个 token 合不合理;
- 反馈作为密集信号回传:Teacher 对每个 token 的判断被转化成密集的、逐 token 的训练信号,回传给 Student 用于更新参数。
把这套流程映射回强化学习的语言:Student 模型就是策略(policy);每一个被选中输出的 token 是一次动作(action);Teacher 对该 token 给出的 log-prob(或者由此计算出的 KL)就是反馈信号。可以把这套体系理解成一种特殊的 RL——奖励函数不是训练出来的 RM,也不是规则验证器,而是一个已经训练好的更强模型。
二、为什么选择 Reverse KL
2.1 目标函数
OPD 可以使用多种散度作为损失函数来给 Student 的轨迹打分,但 Thinking Machines Lab 的工程实践选择了最简单也最有效的一种:逐 token 的反向 KL 散度(per-token reverse KL)——衡量在给定相同历史前缀的条件下,Student 分布πθ\pi_\thetaπθ和 Teacher 分布πteacher\pi_{teacher}πteacher之间的差异:
DKL(πθ(⋅∣st) ∥ πteacher(⋅∣st))=∑aπθ(a∣st)logπθ(a∣st)πteacher(a∣st) D_{KL}\big(\pi_\theta(\cdot|s_t) \,\|\, \pi_{teacher}(\cdot|s_t)\big) = \sum_{a} \pi_\theta(a|s_t) \log\frac{\pi_\theta(a|s_t)}{\pi_{teacher}(a|s_t)}DKL(πθ(⋅∣st)∥πteacher(⋅∣st))=a∑πθ(a∣st)logπteacher(a∣st)πθ(a∣st)
这里的下标顺序很关键:是DKL(πθ∥πteacher)D_{KL}(\pi_\theta \| \pi_{teacher})DKL(πθ∥πteacher),而不是DKL(πteacher∥πθ)D_{KL}(\pi_{teacher} \| \pi_\theta)DKL(πteacher∥πθ)——期望是相对于Student 自己的采样分布来算的,这也是为什么它被称为"reverse"(相对于传统蒸馏里更常用的 forward KL 而言)。训练目标是让这个散度最小化,促使 Student 在每一个它自己真实走到的状态上,都去逼近 Teacher 在同样状态下的行为。
2.2 Reverse KL 的两个关键性质
选择 reverse KL 而不是 forward KL,是因为它有两个非常契合 OPD 场景的性质:
性质一:不可被"投机取巧"(unhackable)。和大多数实践中的奖励模型不同,reverse KL 作为奖励很难被"作弊"——因为从 Teacher 的视角看,低 KL 永远对应着 Student 表现出了 Teacher 认可的高概率行为,不存在"钻空子拿高分但实际没做对"的空间。这一点和前面提到的 verifier 抗作弊原则是一致的:目标函数本身的结构决定了它不容易被绕过。
性质二:“模式寻找”(mode-seeking)。当 Teacher 分布是多峰的(比如同一个问题有多种合理解法)时,forward KL 具有"模式覆盖(mass-covering)“倾向——为了不遗漏任何一个峰,Student 会把概率质量分散到所有峰之间,甚至包括峰与峰之间那些实际上没有意义的"幻觉区域”;而 reverse KL 具有"模式寻找(mode-seeking / zero-forcing)"倾向——Student 会集中学习某一个具体的峰(通常是 Teacher 更确信的那个),完全放弃其他备选模式。对于语言生成这种需要给出一个具体、连贯输出的任务,mode-seeking 通常是更合适的选择——半个模式加半个另一个模式拼起来的输出,在离散的 token 序列里往往是没有意义的乱码。
2.3 一个额外的工程红利:不需要跑完整条轨迹
因为 reverse KL 是逐 token 定义的,不需要等一整条轨迹采样完成才能计算奖励,所以可以直接用更短的、甚至是不完整的轨迹片段来训练——这在工程上能省下不少计算资源。而且查询 Teacher 的 log 概率只需要 Teacher 做一次前向传播,真正负责生成轨迹的是更小、更便宜的 Student 模型;整个流程也不再需要单独训练一个奖励模型或标注模型。
2.4 一个信息论视角:为什么密集反馈更高效
Thinking Machines Lab 给出了一个很直观的信息论解释:标准 RL 每一条轨迹(episode)大约只能传递O(1)O(1)O(1)bit 的信息量——不管这条轨迹生成了多少 token,最终能用来更新模型的本质上就是"这条轨迹好不好"这一个比特左右的判断。而蒸馏(distillation)每条轨迹能传递大约O(N)O(N)O(N)bit 的信息量,其中NNN是 token 数——因为 Teacher 对轨迹中的每一个 token 都给出了一次独立的判断。这个数量级上的差异,直接解释了为什么在样本效率上,OPD 常常能用远少于纯 RL 的训练量,达到相近甚至更好的效果。
可视化地看,如果把 Teacher 给每个 token 的 reverse KL 惩罚大小用颜色深浅标注出来,会发现惩罚并不是均匀分布的——大多数 token 上 Teacher 和 Student 的分布高度一致(惩罚接近零),真正被显著惩罚的往往是那些"关键转折点":引出错误推理方向的起始短语、开启一条错误分支的连接词等,直觉上正对应着推理链条里的"分叉 token(forking token)"。反而最终答案 token 本身即便是错的,也常常不会被显著惩罚——因为给定前面已经写错的全部推理过程,那个错误答案在条件概率上其实是完全"可预测"的,真正需要纠正的是更早的分叉点。
三、OPD 与 GRPO / RLVR 的关键区别
理解 OPD 最好的方式是把它放进前几篇文章已经建立的坐标系里对比。区别集中在两个维度:
第一个维度:训练轨迹由谁生成。SFT / SeqKD 用的是 Teacher 写好的答案;GRPO 用的是 Student 自己的探索;OPD 同样用 Student 自己的轨迹——这一点上 OPD 和 GRPO 是一致的,都规避了传统蒸馏的分布偏移问题。
第二个维度:反馈有多密。GRPO / RLVR 通常是结果级奖励——一个 2000 token 的解题过程,只有最后一个 token 附带的那个 0 或 1;OPD 则几乎每个 token 都有反馈信号,因为 Teacher 对每一步都能给出 log 概率。这也是为什么 OPD 常被形容为"把 Teacher 变成一个密集奖励函数"。
从蒸馏方法自身的演化脉络看,也能看到同样的模式:早期方法(SFT 阶段的蒸馏)里 Teacher 是纯粹的数据生产者,Student 只是模仿 Teacher 走过的轨迹;而 OPD 里 Teacher 的角色变成了奖励提供者,Student 在自己真正会走到的状态上被纠偏。OPD 的动机正是要消除分布偏移:既然 Student 推理时看到的永远是自己生成的上下文,那么训练时也应该直接在这些区域给出信号,而不是只在 Teacher 走过的路径上铺设数据。
一个常见的进一步问题是:OPD 是否可以和 GRPO/RLVR同时使用?答案是肯定的,而且这是当前工程实践中很主流的做法。因为 OPD 本质上是在给策略梯度目标加一个 KL 正则项,所以它天然可以叠加在任何优势估计器之上——不管底层用的是 GRPO、PPO 还是别的 estimator,都可以在优势计算里额外减去一个由 Teacher 给出的 token 级 reverse KL 惩罚:
A^t=At−λopd⋅DKL(πteacher ∥ πθ)t \hat{A}_t = A_t - \lambda_{opd} \cdot D_{KL}\big(\pi_{teacher} \,\|\, \pi_\theta\big)_tA^t=At−λopd⋅DKL(πteacher∥πθ)t
其中AtA_tAt是底层 estimator(比如 GRPO 的组内归一化优势)算出的原始优势,λopd\lambda_{opd}λopd是 OPD 惩罚项的权重系数。这意味着 OPD 并不是一个和 GRPO 互斥的独立算法,而更像是一个可以叠加在任意策略优化方法之上的正交模块——工程上通常实现为对已有的 RL 训练脚本做一处很小的改动:把原本用于 KL 正则的参考模型,换成一个能力更强的 Teacher 模型即可。
四、工程实现
4.1 最小实现骨架
一个最简 OPD 训练步骤的核心逻辑大致如下:
importtorchimporttorch.nn.functionalasFdefopd_training_step(student_model,teacher_model,tokenizer,prompts,max_new_tokens=512,temperature=0.8):"""一个 OPD 训练步:student 生成 -> teacher 逐token评分 -> reverse KL loss"""# 阶段 1:Student 自主 rollout(不受外部干预)withtorch.no_grad():input_ids=tokenizer(prompts,return_tensors="pt",padding=True).input_ids output_ids=student_model.generate(input_ids,max_new_tokens=max_new_tokens,temperature=temperature,do_sample=True,)# 阶段 2:在 student 生成的完整序列上,分别计算 student 和 teacher 的逐 token 分布student_logits=student_model(output_ids).logits[:,:-1,:]withtorch.no_grad():teacher_logits=teacher_model(output_ids).logits[:,:-1,:]student_logprobs=F.log_softmax(student_logits,dim=-1)teacher_logprobs=F.log_softmax(teacher_logits,dim=-1)# 阶段 3:逐 token 的 reverse KL —— D_KL(student || teacher)# 只在 student 实际选出的 token 上生效的简化实现(token级奖励近似)student_probs=student_logprobs.exp()reverse_kl=(student_probs*(student_logprobs-teacher_logprobs)).sum(dim=-1)# reverse KL 越小越好,转化为 loss 直接最小化loss=reverse_kl.mean()loss.backward()return{"loss":loss.item(),"mean_kl":reverse_kl.mean().item()}真实的工程实现(比如 Tinker 的 cookbook)通常在 RL 训练脚本的基础上做很小的改动——因为标准 RL 实现里本来就有"用参考模型算 KL 正则"这一步,OPD 只是把这个参考模型换成了一个能力更强的 Teacher,再把这个 reverse KL 当作(或叠加成)奖励信号本身,而不仅仅是一个正则项。
4.2 与 GRPO 训练框架整合的配置示例
在已经支持 GRPO 的训练框架里接入 OPD,一般只需要在训练配置里新增一个蒸馏相关的模块,声明 Teacher 模型路径、损失函数形式,以及是否与策略梯度损失联合训练:
distillation:enabled:Trueteacher_models:teacher_model:model_path:'Qwen/Qwen3-32B'# HF 路径或本地路径distillation_loss:loss_mode:'k3'# 可选 k1 / k3 / forward_kl_topk 等不同 KL 估计方式use_policy_gradient:True# 是否与 GRPO 的策略梯度 loss 联合训练topk:64# teacher 只传 top-k logits,节省显存与通信开销其中topk参数值得一提:完整传输 Teacher 在整个词表上的 logits 通信开销很大,工程上通常只传输概率质量最集中的 top-k 个 token 的 logits,用截断后的分布近似完整的 KL 计算,这是一个精度和效率之间的常见权衡。
4.3 实测效果
Thinking Machines Lab 使用 Tinker 训练 API 复现了 Qwen3 报告中的结果:在数学推理这类基准上,先用 SFT 在公开推理数据集(如 OpenThoughts)上冷启动,再叠加 OPD 从一个更强的 Teacher 蒸馏,能够达到和完整走一遍 RL 流程相当甚至更好的效果,而所需的计算成本只是完整 RL 的一小部分。这也是 Qwen3 系列在训练 hybrid reasoning 模型和专才模型(specialist distillation)时采用的关键技术之一。
五、局限性与前沿动态
5.1 Teacher-Student 的思维模式一致性
一个反直觉但被反复验证的现象是:换一个参数量更大、benchmark 分数更高的 Teacher,蒸馏效果不一定更好,甚至可能直接把训练"训崩"。研究发现 OPD 能否成功,很大程度上取决于 Teacher 和 Student 之间的思维模式一致性(Thinking-Pattern Consistency)——如果两者初始状态下的 token 重叠率(在同一个 prefix 下两者高概率候选 token 的重合程度)过低,蒸馏就容易失效。举例来说,一个 base 模型 Student 向"经过 GRPO 强化训练后的同源 base 模型"学习,通常比向一个推理风格完全不同的模型学习效果更好——因为前者的推理模式和 Student 天然更接近,Teacher 给出的密集监督信号更容易被 Student “消化”。这也是为什么很多实践中会选择"用 RL 先训出一个强 Teacher,再用这个 Teacher 对同源的小模型做 OPD"这种两阶段流程,而不是随便挑一个市面上最强的模型当 Teacher。
5.2 长序列上的稳定性问题
把 OPD 直接应用到长思维链推理任务时,还会遇到一些工程层面的挑战:序列越长,逐 token 的 KL 累积误差就越容易放大;不同任务难度下,固定的散度形式和固定的惩罚系数不一定都合适。近期的一些研究方向包括:根据 Teacher 的置信度动态在 forward KL 和 reverse KL 之间切换(熵感知 OPD)、只在"局部可教"的位置提供密集监督而在教师置信度崩塌的区域及时截断(动态释放规则)、以及把密集的 token 级 KL 监督和验证器给出的稀疏结果级奖励结合起来联合训练,取两者之长。
5.3 与自蒸馏的结合
除了依赖外部更强 Teacher 的经典设定,OPD 的思想也被扩展到了无需外部 Teacher 的自蒸馏(self-distillation)场景——比如让同一个模型在不同上下文条件下扮演 Teacher 和 Student 两个角色,或者利用同一组内(GRPO 意义上的组)其他成功的 rollout 作为隐式 Teacher,为失败的 rollout 提供密集纠偏信号。这类方法进一步降低了 OPD 对外部强模型的依赖,让蒸馏式的密集监督也能在没有更强 Teacher 可用的场景下发挥作用。
六、全文脉络回顾
把 OPD 放回本系列的整体版图里看:
- OPD 解决的核心问题是标准 RL 反馈过于稀疏、传统离线蒸馏又存在训练-推理分布偏移这两个问题的交集——它让 Student 按自己的策略生成轨迹(保留 on-policy 特性),同时让 Teacher 逐 token 给出密集反馈(保留监督密度);
- 核心机制可以概括为三步:Student 自主 rollout,Teacher 沿轨迹逐 token 评分,评分转化为密集信号回传;损失函数上,选择per-token reverse KL是因为它具有不可被投机利用、以及在语言生成任务上更合适的"模式寻找"这两个关键性质;
- 信息论的视角说明了为什么 OPD 通常比纯 RL 样本效率更高:标准 RL 每条轨迹只传递大约O(1)O(1)O(1)bit 信息,而密集 token 级监督能传递大约O(N)O(N)O(N)bit;
- 工程上,OPD 并不是 GRPO/RLVR 的替代品,而是一个可以叠加在任意优势估计器之上的正交模块——只需把优势计算里额外加入一个由 Teacher 给出的 reverse KL 惩罚项,就可以让 GRPO、PPO 等任意策略优化方法同时获得密集监督的收益;
- OPD 的效果高度依赖Teacher 与 Student 的思维模式一致性,盲目换用更强但风格迥异的 Teacher 反而可能让训练崩溃,这也是当前研究和工程实践共同关注的核心变量。
从 DPO 到 GRPO/RLVR 再到 OPD,这条脉络反映了同一个大方向:LLM 后训练正在从"完整走一遍传统 RLHF 流水线"逐渐演化成"针对具体场景挑选最合适的训练信号来源"——偏好对、规则验证器、更强的 Teacher 模型,乃至它们的组合,共同构成了当前后训练工具箱里越来越丰富的选项。
参考:Agarwal R, Vieillard N, Zhou Y, et al. “On-Policy Distillation of Language Models: Learning from Self-Generated Mistakes”(GKD), ICLR 2024;Lu K, Thinking Machines Lab. “On-Policy Distillation”, Thinking Machines Lab: Connectionism, 2025;Gu et al. “MiniLLM: Knowledge Distillation of Large Language Models”, 2023;Li Y, Zuo Y, He B, et al. “Rethinking On-Policy Distillation of Large Language Models: Phenomenology, Mechanism, and Recipe”, arXiv 2026