On-Policy蒸馏未必真蒸馏:OPSA无需监督的泛化优化
最近在跟进大模型推理与强化学习相关工作时被一个问题反复触动很多团队把“用大模型生成数据再拿小模型做监督微调”直接称为“蒸馏”并且只关心训练 loss 有没有降下去。可一旦把老师模型撤掉或者切换到一个新的任务分布学生模型的表现往往没有想象中稳定。这让我重新去读论文《On-Policy 蒸馏是否真在蒸馏》以及它提出的无需监督的 OPSA 方法。这篇论文的切入点非常小但讨论的问题却很基础我们以为自己在做知识蒸馏但 on-policy 的训练方式最后蒸馏到的到底是“知识”还是一种对老师行为分布的拟合假象本文会从知识蒸馏的经典定义出发逐步拆解这个问题为什么存在再结合 OPSA 方法的设计思路做分析最后给出一个可以自己动手验证的概念性实验框架。适合正在做大模型微调、强化学习策略训练、或者准备把大模型能力迁移到小模型上的开发者阅读。1. 为什么突然开始讨论“On-Policy 蒸馏到底蒸了什么”1.1 从“蒸馏一本书”到“怎么蒸馏 Skill”最近社区里经常能看到“蒸馏一本书”“怎么蒸馏 Skill”这一类说法。表面上看它们是比喻但背后反映了知识蒸馏正在从早期单纯压缩模型变成一种更通用的能力迁移手段。“蒸馏一本书”这个比喻很形象教师模型像一本权威教材学生模型通过学习教材中的解答过程来获得知识。但问题也随之而来——一本书不可能覆盖所有可能遇到的题目一个教师模型也不可能覆盖所有状态空间。如果学生只把教材里的例题背下来了那考试题目稍加变形它就不会做了。这也是“怎么蒸馏 Skill”这个问题的真正难点。Skill 是一种能够在新状态、新场景下泛化的能力而不仅仅是记住输入与输出的映射。Hinton 等人早期提出的知识蒸馏Knowledge DistillationKD更多是让小模型去拟合大模型在已有数据集上的输出分布它擅长的是“压缩”。但当你希望把一个策略模型的能力迁移给另一个策略模型尤其是训练过程中学生还在不断产生新数据时传统 KD 的很多隐含假设就失效了。1.2 从人工标注到模型反馈蒸馏的需求升级传统监督学习中的数据分布是固定的训练集和测试集虽然不同但理论上来自同一个分布。蒸馏任务中教师模型在固定数据集上给出 soft label学生模型去匹配这些 soft label这套流程在 CV 和 NLP 的分类任务里已经被验证过很多年。但到了强化学习场景或者更具体一点到了大语言模型通过强化学习做推理优化的场景数据不再是静态的。学生策略会不断探索产生新的状态和新的轨迹教师模型再对这些 on-policy 数据给出评价或标签。训练数据的分布会随着学生策略的变化而变化。这就是 On-Policy 蒸馏面临的核心场景。这里有一个很容易被忽略的循环学生策略变化后能访问到的状态空间也会变化教师模型对这些新状态给出的反馈可能和学生原本应该学习的方向存在偏差。如果你只是简单地把教师输出当作监督信号并且不断用学生自己采样的数据来训练那学生最终学到的东西未必等于教师模型真正具备的知识。2. 从传统知识蒸馏到 On-Policy核心概念与操作区别2.1 经典知识蒸馏的基本框架为了后面讨论方便我们先给出经典知识蒸馏的最小形式。假设有一个教师模型 T一个学生模型 S输入 x 来自数据分布 D教师输出一个概率分布 T(x)学生输出一个概率分布 S(x)。训练目标通常是最小化两个分布的 KL 散度L_KD E_{x ~ D}[ KL( T(x) || S(x) ) ]在分类任务中教师输出的概率分布带有“软标签”特性。比如一张图片到底是猫还是狗教师可能输出 0.8 的猫、0.15 的狗、0.05 的狐狸这个分布比硬标签“猫1”包含更多信息。学生通过学习这个分布不仅能学到最终答案还能学到类别之间的相似性。这段描述揭示了传统蒸馏的两个关键假设输入分布 D 是固定的学生不需要自己去探索未知状态。教师模型有能力对 D 中的每个输入给出可靠输出。在这两个假设成立时蒸馏可以看作一个分布式匹配问题学生只需要让条件分布逼近教师即可。2.2 On-Policy 蒸馏中的公式为什么不再“干净”On-Policy 蒸馏与传统蒸馏最大的区别在于训练数据 D 会根据学生策略的变化而变化。常见的 On-Policy 蒸馏 / On-Policy 强化学习目标在抽象层面可以写成下面这种形式L E_{τ ~ π_S}[ 根据教师信号 f(T, τ) 更新学生 π_S ]这里的 τ 是学生策略采样出来的轨迹π_S 是学生策略f(T, τ) 是教师模型给出的某种反馈可能是 KL 散度、奖励值、偏好排序等等。这个形式和传统 KD 相比多了一个“在线数据生成”环节。学生策略一边采样一边学习学习后策略改变下一轮采样分布又跟着改变。于是数据分布是策略的函数策略是数据分布的优化结果形成了一个闭环。这种设置本身没有错很多强化学习算法都依赖这个闭环来不断提升策略。但问题是当研究者把“策略梯度优化”包装成“蒸馏”时需要重新审视它到底在优化什么。如果是传统蒸馏我们在优化一个静态分布匹配问题如果是 On-Policy 蒸馏我们在优化一个动态系统而动态系统容易出现“路径依赖”和“分布偏移”。维度传统知识蒸馏On-Policy 蒸馏数据来源固定数据集学生策略在线采样教师作用对静态输入给输出分布对新状态给反馈核心假设输入分布固定训练分布随策略变化主要风险分布外泛化差分布漂移、捷径学习典型应用图像分类、文本分类RL、LLM 推理优化2.3 “On-Policy”在这里到底指什么在强化学习里On-Policy 通常指“用来更新策略的数据必须由当前策略采样产生”。与之相对的是 Off-Policy可以使用旧策略产生的历史数据来更新新策略。这篇论文讨论的 On-Policy 蒸馏场景更接近一种特殊的策略优化学生策略先和环境交互产生轨迹教师模型对这些轨迹提供指导然后学生用这些轨迹和指导来更新自己。这里涉及的“学生策略”可以是强化学习智能体也可以是一个正在生成推理路径的大语言模型。用大模型推理来举例会更清晰。假设我们有一个很强的教师模型希望学生模型学会更长链条的数学推理。我们让学生模型先尝试做一道题如果做错了再让教师模型给出正确答案然后用正确答案来微调学生模型。这个过程就是在用学生模型自己采样出来的错误轨迹结合教师的修正信号来学习。它听起来像是蒸馏但因为它依赖学生自身的采样分布所以本质上更接近 On-Policy 的学习过程。3. On-Policy 蒸馏真的在蒸馏吗论文提出的关键质疑3.1 表面公式相似的陷阱很多 On-Policy 蒸馏工作的训练目标可以写成“最大化教师模型偏好动作的概率”或者“最小化学生模型与教师模型在访问状态上的 KL 散度”。从公式表面看这和传统蒸馏几乎一样都是让学生的输出分布靠近教师。论文提出的质疑恰恰在这个“表面相似”上。作者指出仅仅最小化 KL 散度只能保证学生模型在教师分布覆盖比较高的区域和教师保持一致并不能说明学生掌握了教师模型在那些未覆盖区域的判断能力。用更通俗的例子来说一位老师擅长教数学学生每次练习时都只做老师课上传授过的题型。学生在这些题型上的表现越来越接近老师甚至可以完全复述老师的解题步骤。此时如果只看 KL 散度你会认为蒸馏很成功。但如果你换一批新题型学生的表现可能立刻崩溃。原因是学生只是在训练分布内记住了教师的行为而不是学到了教师的抽象解题策略。论文在这里提出了一个尖锐的问题如果你的训练数据是由学生自己采样产生的而这个学生在早期又很弱那么它采样到的状态空间一定很窄。在这个窄分布上拟合教师模型最终得到的是不是一种“自我实现的谎言”——学生只学会了在自己能达到的状态里表现好而没有形成真正的泛化能力3.2 真正的“知识”转移应该如何度量这个问题直接导向另一个问题我们应该用什么指标来判断一次 On-Policy 蒸馏是否成功传统 KD 时代大家习惯看学生模型在评估集上的准确率。如果学生准确率提升就认为蒸馏有效。但在策略学习场景评估集往往很难覆盖真实世界状态尤其是开放式的推理任务中合法状态几乎是无限的。论文的研究思路中值得关注的一点是作者没有只停留在“loss 降了没有”这个表面层次而是尝试回答“学生到底学到的是教师的知识还是只是学会了如何与教师的偏见保持一致”。要回答这个问题需要在蒸馏过程中设计一些“教师没有提供过明确监督”的状态检查学生在这些状态下的行为是否仍然合理。这种思路让我联想到一个词行为覆盖度。一个成功的 Skill 蒸馏不应该只在教师偏好区域上表现良好还应该让学生的行为在更广泛的状态空间上保持合理的覆盖。如果学生在训练过程中只敢访问自己熟悉的少数状态那么即使教师给再多的反馈学生也无法探索出真正稳健的策略。3.3 论文的核心目标不是否定 On-Policy而是重新定义“蒸馏”需要特别强调的是这篇论文并不是说 On-Policy 蒸馏完全无效也不是建议大家回到 Off-Policy 蒸馏。它试图说明的是如果我们用 On-Policy 的方式去训练同时又声称在做蒸馏就必须对“蒸馏”的定义给出更严格的标准。仅仅把教师模型当做一个评分器让学生在其产生的数据分布上做优势估计这更像强化学习而真正意义上的蒸馏还应该确保学生的行为模式已经内化即使暂时关闭教师模型的监督信号学生依然能在相关状态中表现出被迁移的技能。论文给出的启示是方法名称不重要重要的是训练目标和评估指标是否一致。如果你的目标是让模型在测试时脱离教师也能表现良好那么在训练过程中就不能只依赖教师标签来度量好坏。这正好引出了本文的主角——OPSA 方法。4. OPSA无需监督信号的蒸馏优化思路4.1 OPSA 要解决的问题是什么OPSA 这个名称听起来像是一个优化算法但从论文摘要所能读到的信息来看它更像是一套“无需监督信号”的蒸馏评估与优化框架。传统蒸馏需要教师输出作为监督信号。教师告诉学生“这道题应该这么做”学生基于这些回答来调整参数。OPSA 要解决的问题是如果我们去掉教师逐条回答的监督信号还能不能判断学生是否真的学会了某种技能能不能继续优化学生“无需监督”并不是说完全不需要任何参考信息而是指不需要传统意义上的逐样本标签。OPSA 的设计出发点很可能是学生策略从环境中获得反馈或者从自身行为一致性中获得信号从而判断自己是否已经掌握了教师想转移的技能。这种思路在强化学习中其实有对应物无监督探索、内在奖励、自监督一致性。把这几样东西组合到一起就有可能构建一个不依赖强监督标签的蒸馏优化目标。4.2 一个抽象理解从“老师判卷”变成“学生自检”传统蒸馏模式下老师判卷学生根据试卷分数修改答案。OPSA 想改成一种更接近“学生自检”的模式学生做完题后不是只看老师给多少分而是通过一系列约束来检查自己是否真的理解了这道题的考点。这种约束可以是行为一致性。比如学生对一道题给出一个推理步骤如果改变其中某个无关变量的表述学生仍然应该得到一致的推理方向。如果一个模型只在训练数据里见过“苹果和香蕉”这种表达换一种说法就不会了那说明它没有掌握背后的比较逻辑。在策略学习中类似的约束可以来自状态空间的扰动。我们希望对输入状态做不影响任务语义的变换学生策略的输出应该保持稳定。如果学生模型对语义不变的状态变换非常敏感那么它学的很可能只是一堆表面规则而不是可迁移的 Skill。4.3 从论文角度看 OPSA 的三个关键词如果要概括 OPSA 的设计特点可以从论文的公开信息中提取三个关键词无需监督、自一致性、蒸馏评估。第一无需监督。这意味着 OPSA 的训练目标里不需要教师对每条轨迹给出明确的正确答案。这样既减少了标注成本也避免了教师模型在分布外区域给出不可靠标签的问题。第二自一致性。它既是一种优化目标也是一种评估准则。学生模型产生的策略应当在不同上下文中保持决策一致性。一个真正内化了知识的学生不应当因为输入状态的微小表面扰动而完全改变行为。第三蒸馏评估。OPSA 不满足于“loss 下降”或者“生成结果相似”而是会构造一些教师未覆盖区域去检测学生策略的鲁棒性和泛化性。只有当学生在这些区域也表现出稳定的决策能力时才认为蒸馏真正成功。4.4 为什么这种方法在推理模型时代更有价值过去做知识蒸馏主要对象是图像分类模型和语言理解模型。现在大家越来越关注推理模型的推理能力比如数学问题、代码问题、复杂规划问题。推理能力很难用“输出字面接近”来衡量因为正确答案只有一个但失败的中间步骤可以有无数种。在这种背景下教师模型给出的监督信号往往只覆盖到最终正确路径上的状态。学生如果只盯着这些状态学习就会忽略大量可能的失败分支。OPSA 这种不需要教师逐条标注的方法更适合用来构建覆盖失败模式的训练目标因为它让学生从自身的探索反馈中学习而不是依赖于教师对每个失败分支给出正确答案。5. 论文实验结论如何解读从指标设计到实现启发5.1 训练损失降了不代表学生学到了教师行为读论文时我建议你先放下训练曲线直接看作者比较了哪些“非传统指标”。如果一篇蒸馏论文只用“检测准确率”来证明蒸馏成功那么它无法回答“学生是否学到泛化技能”这个问题。论文着重分析的结论之一很可能是在 On-Policy 设置下学生模型的训练损失可以降得很低KL 散度也可以收敛到很小但这些都是“训练轨迹上”的指标。教师行为矩阵在这些轨迹上的拟合度高并不等于学生行为矩阵在完整状态空间上接近教师行为。把它换成工程语言你拿学生模型上线后发现它在某些边缘场景表现不佳这不是因为它没有能力而是因为你在训练时根本没有构造过这类边缘场景的采样路径。On-Policy 采样会天然偏向高概率区域低概率但有风险的状态在训练中很少出现。5.2 “复制成功路径”与“学到技能”的差别一个非常有趣的解读角度是On-Policy 蒸馏最容易让学生陷入“复制成功路径”的陷阱。在学习过程中学生很快发现某些动作会获得教师较高认可于是它会提高这些动作的概率。久而久之学生的采样轨迹开始收敛到少数几条路径它不再尝试其他可能同样有效甚至更有泛化性的路径。这种模式下学生确实复现了教师的成功路径但它没有学到教师为什么会选择这条路径。教师模型可能因为避免某些高风险区域才选择绕路而学生模型只学到了绕路这一行为没有学到背后的风险判断。OPSA 的意义在于它尝试通过无监督的一致性判断让学生理解“行为背后的约束条件”。如果一条路径只是在特定初始状态下成功而在另一个状态泛化失效那就不能说完成了 Skill 蒸馏。6. 实战概念验证用简单环境复现思想论文本身的公式和实验环境可能比较学术。为了让你更直观地理解上面的讨论这里提供一个概念性验证框架。它不是论文代码的完整复现而是一个可以独立运行的思路演示项目。6.1 准备一个简单的格子世界环境为了观察 On-Policy 蒸馏中出现的问题我们可以设计一个最简单的离散格子世界。假设状态空间是 5×5 的格子智能体从左下角出发目标是到达右上角。每一步可以选择上下左右四个动作。教师模型是一个已经过训练的专家它知道如何从任意可达格子到达目标。学生模型初始化后对路径一无所知。我们用 On-Policy 蒸馏来训练学生。先看工程结构onpolicy_distill_demo/ ├── env.py ├── teacher.py ├── student.py ├── train_distill.py └── eval_opsa.py这里为了快速演示不需要引入完整的强化学习框架只用一个带参数的策略表和一个简单的仿真器。6.2 环境与策略的极简实现环境部分我们使用 Python 类表达不依赖额外库。先来看定义状态转移的代码# 文件路径onpolicy_distill_demo/env.py import numpy as np class GridEnv: 一个 5x5 的网格世界状态编号 0~24。 动作: 0上, 1下, 2左, 3右。 起点固定为 0终点固定为最高编号状态。 def __init__(self, size5): self.size size self.state 0 self.goal size * size - 1 self.actions [0, 1, 2, 3] def reset(self): self.state 0 return self.state def step(self, action): r, c divmod(self.state, self.size) if action 0: r max(0, r - 1) elif action 1: r min(self.size - 1, r 1) elif action 2: c max(0, c - 1) elif action 3: c min(self.size - 1, c 1) self.state r * self.size c done (self.state self.goal) reward 1.0 if done else 0.0 return self.state, reward, done策略表使用随机初始化的 softmax 分布表示。教师策略可以预先定义为“每一步都朝终点方向移动”的规则后面再给教师附加一些随机扰动模拟真实模型的不完美。# 文件路径onpolicy_distill_demo/teacher.py import numpy as np from env import GridEnv def make_teacher_policy(size5): 构造一个专家策略表。 在每个格子优先选择让曼哈顿距离减少的动作。 env GridEnv(size) goal_r, goal_c divmod(env.goal, size) policy {} for state in range(size * size): r, c divmod(state, size) best [] best_dist float(inf) # 上 nr, nc max(0, r - 1), c d abs(nr - goal_r) abs(nc - goal_c) best.append((d, 0)) # 下 nr, nc min(size - 1, r 1), c d abs(nr - goal_r) abs(nc - goal_c) best.append((d, 1)) # 左 nr, nc r, max(0, c - 1) d abs(nr - goal_r) abs(nc - goal_c) best.append((d, 2)) # 右 nr, nc r, min(size - 1, c 1) d abs(nr - goal_r) abs(nc - goal_c) best.append((d, 3)) min_d min([t[0] for t in best]) best_actions [t[1] for t in best if t[0] min_d] probs np.zeros(4) for a in best_actions: probs[a] 1.0 / len(best_actions) policy[state] probs return policy6.3 关键评估代码判断 On-Policy 蒸馏是否真在蒸馏接下来是核心评估逻辑。我们在训练过程中记录学生策略访问过的状态、教师在那些状态上的动作、以及学生在“教师理论上会到达但学生很少访问”的状态上的表现。# 文件路径onpolicy_distill_demo/eval_opsa.py import numpy as np from env import GridEnv from teacher import make_teacher_policy def get_state_action_counts(policy, env, episodes200): 按照给定策略采样统计每个状态被访问的频率。 counts np.zeros(env.size * env.size, dtypeint) for _ in range(episodes): state env.reset() done False while not done: counts[state] 1 probs policy[state] action int(np.random.choice([0, 1, 2, 3], pprobs)) state, _, done env.step(action) return counts def alignment_on_visited_states(student_policy, teacher_policy, counts, threshold5): 在学生高频访问的状态上计算动作对齐率。 total 0 hit 0 for state in range(env.size * env.size): if counts[state] threshold: continue student_action int(np.argmax(student_policy[state])) teacher_action int(np.argmax(teacher_policy[state])) total 1 if student_action teacher_action: hit 1 return hit / max(total, 1) def coverage_of_teacher_reachable_states(student_policy, teacher_policy, env): 教师可达但学生几乎不访问的状态占比用于观察学生是否发生分布坍缩。 visited_states set() state env.reset() done False while not done: visited_states.add(state) probs student_policy[state] action int(np.random.choice([0, 1, 2, 3], pprobs)) state, _, done env.step(action) teacher_states set() for state in range(env.size * env.size): # 判断教师策略能否在这个状态引导到终点并不容易 # 这里用简化条件凡是教师认为存在最短方向的状态都算。 if np.max(teacher_policy[state]) 0.5: teacher_states.add(state) missing teacher_states - visited_states return len(missing) / max(len(teacher_states), 1)这两个指标非常直观。第一个指标表示在学生通常能遇到的区域学生和教师的动作是否一致第二个指标表示在学生采样很少到达的区域它和教师之间的覆盖差距有多大。6.4 On-Policy 蒸馏训练循环现在模拟一次简单的 On-Policy 蒸馏训练。这里用“教师动作作为硬标签”来更新学生策略模拟很多实际项目中把教师回答当作监督信号的做法。# 文件路径onpolicy_distill_demo/train_distill.py import numpy as np from env import GridEnv from teacher import make_teacher_policy # 构造环境与教师 env GridEnv(size5) teacher make_teacher_policy(size5) # 学生策略初始化为接近均匀分布 n_state env.size * env.size student {} for state in range(n_state): student[state] np.full(4, 0.25) def update_with_teacher_label(state, teacher_action, lr0.1): 把教师选择的动作视为硬标签在策略表上做一次增量更新。 student[state] lr * teacher[state] student[state] / student[state].sum() # 平滑避免概率归零 student[state] 0.1 / 4 0.9 * student[state] student[state] / student[state].sum() for epoch in range(20): state env.reset() done False step 0 while not done and step 50: # 学生采样 probs student[state] action int(np.random.choice([0, 1, 2, 3], pprobs)) next_state, _, done env.step(action) # 蒸馏更新用教师对当前状态的偏好来更新学生 update_with_teacher_label(state, action) state next_state step 1 if epoch % 5 0: print(fepoch {epoch}, finish_step{step})在这个训练循环里学生每次走到一个状态都会采样一个动作然后根据教师的偏好来更新策略。它看起来非常接近 On-Policy 蒸馏的标准用法。但这样的更新有一个明显问题如果学生早期总是走一条固定的短路径那么教师在这些路径状态上的偏好会被反复强化而学生从未涉足的状态虽然教师在那些状态也能给出很好的指导但学生根本没有机会采到因此也不会被更新。6.5 结果判读常见的“假蒸馏”现象运行训练脚本后你会看到学生很快就能从起点到达终点并且 loss 也会下降。但如果调用上面的 eval_opsa.py往往会发现 coverage_of_teacher_reachable_states 指标偏低说明有大量教师可达状态学生很少访问。这正是论文讨论的核心问题在极简环境中的体现训练目标是最大化教师标签的拟合但因为数据来自学生自己的路径学生策略一旦陷入局部最优数据分布就越来越窄训练信号也失去多样性。此时你可能会观察到下面几种典型的“假蒸馏”特征现象可能原因反映的问题训练 loss 持续下降学生只在自己熟悉的路径上拟合分布坍缩高频状态对齐率很高记住了课堂例题缺乏泛化低频状态对齐率很低教师信号在这些区域没被采样覆盖度不足去掉教师模型后测试失败学生依赖教师软标签未内化知识只是拟合不是蒸馏6.6 OPSA 思路下的改进方向前面说过OPSA 的核心思想是引入无需逐条教师标签的自一致性约束。在一个表格策略的世界里我们可以做一个简单版本的实现在每组更新之后检查语义等价的相邻状态是否产生一致的最佳动作。如果发现不一致就给策略一个平滑项让相近状态的策略差异不要过大。下面用代码示意这种“自一致性正则”的基本思想# 文件路径onpolicy_distill_demo/opsa_smooth.py import numpy as np def enforce_local_consistency(student, env, alpha0.05): 对格子世界中相邻状态做策略平滑。 这里没有使用教师标签只利用环境结构本身给出的相邻关系。 size env.size for state in range(size * size): r, c divmod(state, size) neighbors [] if r 0: neighbors.append(state - size) if r size - 1: neighbors.append(state size) if c 0: neighbors.append(state - 1) if c size - 1: neighbors.append(state 1) for nb in neighbors: # 让当前状态与邻居状态的动作分布不要差异过大 mixed 0.5 * student[state] 0.5 * student[nb] student[state] (1 - alpha) * student[state] alpha * mixed student[nb] (1 - alpha) * student[nb] alpha * mixed # 重新归一化 for state in range(size * size): student[state] / student[state].sum()这种平滑不是标准的 OPSA 算法但它能帮助你理解“无需监督”的更新长什么样我们不再需要教师为每一个状态标动作而是通过环境的空间结构和策略自身的一致性来判断学生是否学得太孤立。如果把这种一致性约束加到前面训练循环的每个 epoch 之后学生虽然在训练初期学得更慢但最终对低访问状态的覆盖度通常会更好。原因很简单平滑项让学生策略在状态空间中没有被奖励信号驱动到的区域依然能与已学习区域保持一定的行为连续性。7. 常见误区和 FAQ7.1 KL loss 很低就代表蒸馏成功吗不成立。KL 散度是在当前学生采样分布上计算的如果学生采样分布很窄KL 降低只能说明它在熟悉状态和教师更接近了。真正的蒸馏成功需要看学生是否掌握了教师在不同状态间的决策规则最好是用那些教师没有出现在训练数据里的状态去验证。7.2 on-policy 方法只能用在强化学习里吗不是。大语言模型的推理优化中很多做法都是学生先自己采样一部分推理路径再由教师模型判断对错并给出修正。这个过程本质上就是 On-Policy 学习。因此这篇论文提出的问题和结论同样适用于大语言模型蒸馏场景。7.3 OPSA 的“无需监督”是不是完全不用老师从名称和摘要来看OPSA 强调不需要逐条监督信号。更准确的理解是不再把教师对每个样本的输出作为必须拟合的硬标签而是通过自一致性、行为约束或环境反馈来优化学生。教师仍然可以在初始化、数据生成、结果校验等环节发挥作用。7.4 我是不是应该立刻放弃传统的 On-Policy 蒸馏不建议。传统 On-Policy 蒸馏在很多任务上仍然有效尤其是训练初期教师模型的强监督信号可以帮助学生快速进入正确的学习区域。你需要做的是在训练中增加覆盖度评估在训练后期逐步减少对教师标签的依赖让学生的探索能力接手训练过程。8. 工程实践建议8.1 给你的训练流程加一张“行为覆盖度报表”在生产训练中不要只记录 total loss 和 accuracy。建议每个 epoch 额外记录以下内容学生采样轨迹去重后的状态数、教师在每个状态上的预测置信度、学生动作与教师动作的一致率、学生在教师低置信区域的行为统计。这张报表可以回答一个关键问题学生是在学习教师的知识还是在走捷径拟合教师的数据分布不用等到模型上线训练过程中就能提前发现崩溃信号。8.2 让数据分布保持足够的多样性无论采用 OPSA 还是传统教师蒸馏最需要避免的都是数据分布坍缩。在实践中可以混合多种来源的数据一部分来自学生自己采样一部分来自教师采样一部分来自真实用户场景再补一部分随机探索数据。这样即使用 On-Policy 方法更新模型也不会因为学生早期策略太弱而让训练分布过度集中。8.3 用“撤掉教师”的测试来做上线前的最终验证如果你希望模型真正学会某种 Skill而不是只在教师存在时表现好那么最有效的验证方式是训练完成后在推理阶段完全撤掉教师模型只使用学生模型和任务环境本身。观察学生能否稳定完成目标特别是在没有额外纠正的情况下能否从错误中恢复。这个测试虽然简单却能在很大程度上避免“训练时很漂亮、上线后立刻崩”的工程事故。8.4 记录失败模式而不是只记录成功路径很多蒸馏项目会把训练重点放在教师能正确解决的样本上但真正决定模型上限的往往是那些学生容易失败、教师也不一定可靠的边界样本。建议在训练数据里固定加入一段“失败模式集”定期用当前学生模型去跑这些样本记录它的错误类型再决定下一步数据生成策略。9. 关于 On-Policy 蒸馏这件事我现在更倾向于怎么判断如果你问我一个 On-Policy 蒸馏过程什么时候才算真正成功我的答案会很简单不是看训练曲线多漂亮也不是看它与教师模型的 KL 散度多小而是看当教师模型不在场时学生模型能不能在更广的状态空间里维持合理表现。这个标准比任何公式都更贴近真实部署需求。论文和 OPSA 方法给我们的最大价值不是制造一个“传统蒸馏失效了”的焦虑而是提醒我们方法命名会影响我们对问题的理解。当我们把强化学习过程的高层目标解释为蒸馏时就必须用蒸馏的标准去评估它——知识是否真的被迁移而不是只在数据分布重合的地方达成共识。如果你正在做类似的大模型数据蒸馏实验不妨把这篇 P 讨论的问题整理成一张检查表采样状态覆盖了多少教师信号是否覆盖了所有关键分支学生对教师没有给出标准答案的状态做出了什么选择把这些问题答清楚之后你或许会发现一些原本被平均指标掩盖的问题其实非常严重。