分布视角 · SFT / RL / OPDblog-to-html · 2026-05-11
原文
Distributional Lens · Post-Training

把 SFT / RL / On-Policy Distillation 看成对同一个分布的三种塑形

一个语言模型其实就是一个序列上的分布。Post-training 在做的事,是把这个分布往某个目标推。 SFT、RL、OPD 的差别,不在「学不学得到」,而在目标分布是什么,以及梯度被允许从哪儿出发。 nrehiew 这篇 blog 的核心论点是:真正承重的不是显式 KL 惩罚,而是「on-policy 数据」。

原文阅读 ≈ 12 分钟 本页 8 段 · 多个对照图 nrehiew.github.io 原推文
TL;DR

SFT 把模型拉向外部数据集,RL 沿当前策略上奖励最高的方向更新,OPD 用学生自己的样本但跟着教师的分布走。 前者会按整个分布均匀施力,因此容易把无关能力一起冲掉;后两者只在「模型自己访问过的区域」上动,自带一种隐式 KL 约束

在最小代码编辑实验里,OPD 的两个学生(一个从 SFT 教师、一个从 RL 教师蒸馏)表现几乎一模一样, 甚至都略超过 RL 教师本身。说明真正在起作用的是"数据从学生分布采样"这一性质,而不是教师的好坏。 把 SFT / RL / OPD 并排看,on-policy 数据才是 post-training 真正的承重梁

0.45 → 0.06
归一化 Levenshtein 距离
SFT 教师 → OPD 学生:从大改特改回到「最小编辑」
0.286 → 0.297
LiveCodeBench v6
OPD 学生的通用代码能力比 SFT 教师还高,遗忘被吸收掉了
≈ 0%
OPD-SFT 与 OPD-RL 两个学生
核心指标几乎完全一致 —— 教师不重要,数据来源才重要
3 轴
下一代算法要同时满足:
蒸馏的密度 · RL 的无偏 · on-policy 的就近
01 · 心智模型

语言模型 = 一种分布;训练算法 = 怎么把分布往目标推

nrehiew 提出一个统一的视角:先别看损失函数长什么样,而是问「目标分布是什么?它有多直接?」 这一节先把这个模板立起来,后面的所有差异都可以套进它。

作者明确说这不是一个严谨的数学定义,更像一个有用的思考模板。在这个视角下: SFT 把当前分布拉向「数据集定义的那个分布」;RL 没有一个事先指定的外部分布, 但每一步都试图朝「期望奖励更高的方向」挪一点;OPD 介于两者之间 —— 样本由学生自己生成,但梯度让学生去匹配教师的分布。

模板里最关键的一个问题是 —— gradient 是从哪儿出发的? SFT 的梯度均匀地铺在外部数据集的 token 上,不管这些 token 是不是任务核心; RL 和 OPD 的梯度则只在模型当前访问的区域上动。这就是后面所有「为什么 RL 少遗忘」讨论的几何源头。

同一个模型,三种被拉的方式

想象当前模型分布 π 是一条曲线,覆盖了它已经学到的所有能力(数学、代码、写作……不同的「山头」)。 训练 = 拿一只手去推这条曲线,让它的某个山头变高。

SFT 的手是直的,从外部按住目标 token,不管模型现在长什么样; RL 的手在曲线自己的高地里推,只动模型采得到的区域; OPD 的手也在曲线自己的高地里,但推力来自教师 logits 的形状,不是来自外部奖励。

读到这里要 get 到:算法的差别不在「学不学得到任务」,而在从哪推、推多远、付出什么代价

能力 A 能力 B(要学的新任务) 能力 C π · 当前模型 已经学到的能力 target · 目标分布 训练想达到的形状 有用更新 ↑ 附带挤压 ↓ — 不变 —
灰色山头:当前模型分布 π,每个山头是一类已经学会的能力。 红色虚线山头:训练想推到的目标形状 —— 想把能力 B这个山头大幅拔高。 红色实箭头:在目标山头上施加的"有用拉力"。灰色虚箭头:附带把无关山头压低(潜在遗忘)。
02 · 三种塑形

SFT、RL、OPD 各自拿什么当目标,又施加了什么样的力

把三种方法并排放在同一张图上对比。每张卡片同时回答三个问题: 「目标分布是谁定义的?数据是哪儿来的?梯度怎么被约束?」 切换 Tab 就可以一个一个看。

Method 01 · Supervised Fine-Tuning

目标分布提前固定,模型被「直接拉过去」

数据集在训练开始前就已经存在 —— 人写的、强模型生成的,都行。 然后用交叉熵让模型尽量贴近数据集的 token 分布。 起点是哪个分布完全不影响最终目标方向,因为 NLL 损失对起点不敏感。

这也是 SFT「灾难性遗忘」最自然的源头:数据集分布如果离原模型很远, 模型没有理由优先选「附近的解」,它只会被往示范 token 上拽。 梯度在整个分布上均匀施力,不区分 token 是任务关键的运算符,还是「therefore」「we can see that」这类风格 token。

target
外部固定分布(数据集)
data
外部 trajectory
gradient
每个 token 上都有压力
擅长
冷启动、格式变更
软肋
对原有能力的连带挤压
几何形象
一只外部的手直接按住
π · model target dataset distribution
蓝色虚线:数据集定义的目标。蓝色箭头:每个 token 上施加的「拉力」。 注意低概率山头同样被向上推,这是与任务无关的连带压力,最终表现为 catastrophic forgetting。
Method 02 · Online RL

模型从自己里采样,被「沿着奖励梯度往前挪」

没有一个外部的目标分布。模型自己生成轨迹,奖励函数打分,然后用 Policy Gradient 增加期望奖励。 梯度只能从「当前策略采得到的样本」上发出,所以更新天然集中在模型已经访问的高概率区域。

这种局部性正是 RL「不太遗忘」的物理来源。前提是奖励有意义 —— RLVR 有可验证奖励,奖励方向≈质量方向;RLHF 用奖励模型,方向更有偏,因此需要 KL 惩罚和 trust region 兜底。

target
沿期望奖励的最近优策略
data
on-policy 自采样
gradient
只在自己采得到的区域
擅长
数学 / 代码 / RLVR
软肋
credit assignment、稀疏奖励
几何形象
在自己的高地里轻推
π · current π · updated
金色点:当前策略下采到的 rollout。 圆圈:奖励较高的样本。 箭头:只从这些样本出发的梯度。 更新后的虚线轮廓:高奖励区被抬高,其余区域几乎不动 —— 这就是 on-policy 的「局部性」。
Method 03 · On-Policy Distillation

样本来自学生自己,但梯度让学生贴向老师的分布

OPD 是 SFT 和 RL 中间的那一档:像 SFT 那样有一个明确的「老师信号」,但像 RL 那样数据来自学生本身。 每一步先 on-policy 采样,再用 reverse KL 把学生的 logits 朝老师的 logits 拉。 粗略类比:RL 用 advantage 加权 completion,OPD 用「学生/老师 log ratio」加权。

一种新变体是 On-Policy Self Distillation (OPSD):教师 = 学生,但教师在算 log 概率时可以看到参考答案作为前缀。 因为两者本质同一个模型,大部分 token 上 KL 都很小; 真正张开的是 style / pivot token(如 wait / alright),这反而和任务核心不同步。

target
教师分布(reverse KL)
data
on-policy 学生采样
gradient
token 级 KL,有偏但更密
擅长
写作 / 知识 / 专家融合
软肋
style token 过更新、需 clip
几何形象
自己的高地,外部的形状
student π teacher distribution ↑ KL gradient
紫色面+虚线:教师分布(主峰更高、小峰更平 —— reverse KL 的 mode-seeking 形状)。 紫色点:学生从自己分布上采到的点。箭头:在这些点上,KL 把学生 logits 朝老师同一 x 处拉。 梯度既来自学生自身的可达区域,又被赋予了老师那侧的「形状信号」。
03 · OPSD 的尴尬

当学生 = 老师,最大的 KL 反而出现在「style token」上

OPSD 用同一个模型当学生和老师,老师比学生多看到一个「参考答案前缀」。 作者做了 per-token KL 分析后发现:在所有 thinking 配置下,风格 token 的 KL 显著高于数学 token。 如果不加 clip,模型会被这些与任务无关的 token 过度拉扯,最终崩掉。

per-token KL:风格 token vs 数学 token

下面这两组是作者图示中的典型 token 类别。bar 长度按相对 KL 强度对照(论文里是相对量级)。 Style 这一侧远高于 Math 这一侧 —— 意味着如果朴素地走梯度,每一步更新都会被 style token 主导

Style / Pivot tokens · 高 KL

老师有「答案前缀」这一上下文优势,最容易在这些 transition 词上跟学生分歧
"wait"
≈ 1.0
"alright"
≈ 0.92
"therefore"
≈ 0.83
"so"
≈ 0.75
"actually"
≈ 0.70

Math / Content tokens · 低 KL

学生和老师都倾向给这些 token 高且接近的概率,KL 自然就小
"power"
≈ 0.23
"exponent"
≈ 0.18
"logarithm"
≈ 0.16
"="
≈ 0.12
"integral"
≈ 0.10
关键直觉:OPSD 的训练信号其实和 RLHF 是一个家族 —— 两者都依赖于一个「有偏但密集」的信号。 所以两者都需要 KL 惩罚、trust region、token-level clipping 这类机制来防止模型在错的方向上跑太远。 相比之下,RLVR 的可验证奖励偏差更小,反而可以放松 KL 约束(用 GRPO 替代 PPO)。
04 · 出乎意料的实验

OPD 学生几乎不在乎老师是谁 —— 两种老师都炼出几乎一样的学生

作者沿用前作的「最小代码编辑」任务:给模型一段被人为损坏的函数, 只允许修改 bug 相关的几行。SFT 教师泛化差、伤害通用代码能力;RL 教师泛化好、不掉 LCB。 作者本来以为 OPD 学生会跟教师一致 —— 结果完全不是。

Model Pass@1 ↑ Norm. Levenshtein ↓ Added CC ↓ LiveCodeBench v6 ↑
教师 · Teachers
SFT teacher 0.775 0.450 0.450 0.286
RL teacher 0.792 0.063 0.206 0.320
学生 · On-Policy Distillation
OPD · 从 SFT 教师蒸馏 0.800 0.059 0.206 0.297
OPD · 从 RL 教师蒸馏 0.787 0.055 0.228 0.314
读法:↑ 越高越好,↓ 越低越好。Norm. Levenshtein 量化「改了多少」 —— SFT 教师 0.45 是大改特改; Added CC 是新增的圈复杂度,SFT 教师同样飙到 0.45。OPD 两个学生在这两列上都几乎完全一致。
FINDING 01

两个 OPD 学生几乎一模一样

OPD-SFT(0.800 / 0.059 / 0.206)和 OPD-RL(0.787 / 0.055 / 0.228)的差距, 比两种教师之间的差距小一个量级。教师的好坏几乎被「on-policy 采样」这个步骤抹平了。

FINDING 02

两个学生都打过 RL 教师

OPD-SFT 在 Pass@1 上 0.800 > 0.792,OPD-RL 的 Levenshtein 0.055 < 0.063。 这跟 Agarwal 等人在 GSM8K 上观察到的「学生超过老师」一致 —— OPD 的监督本身就比单纯模仿教师轨迹更针对学生的状态。

FINDING 03

SFT 教师的遗忘被学生吸收掉了

SFT 教师在 LCB 上 0.286(明显掉了),但从它蒸馏出来的 OPD 学生反而是 0.297, 甚至比教师还高。即使教师本身已经退化,学生也没有继承这份退化。结论:教师提供信号,状态分布属于学生。

这意味着什么:如果是要培养一个专家模型再融合进主线模型, 可以用"暴力 SFT"把专家训得很强(哪怕它本身在通用能力上有退化), 然后通过 OPD 把这份专家能力反过来注入一个仍然保留通用能力的学生。 这给「专家融合式后训练」开了一条可行路径。
05 · 为什么 RL 会少遗忘

三种常见解释 —— 作者只完全买账其中一种

关于「为什么 RL 比 SFT 少遗忘」,社区里至少有三种说法。 作者认为前两种都有一部分对,但都解释不清 OPD 的现象。 他真正相信的是第三种:on-policy 数据本身就是隐式 KL 约束

解释 01

"SFT 是 forward KL、RL 是 reverse KL"

SFT 的交叉熵在固定数据集上等价于最小化 forward KL;Chen et al. (2025) 证明 RL 可被看作 reverse KL 最小化。 forward KL 是 mode-covering,会牺牲已有的 mode 去覆盖新数据。

作者的批评:这论证依赖于显式 KL 惩罚。但实证上即便 KL 惩罚被弱化或去掉,RL 也仍然不太遗忘 —— 所以「KL 方向」不是真正的发动机。

部分正确,但解释不到根
解释 02

"SFT 的 token 级梯度均匀又密集"

每个示范 token 都被无差别推高概率 —— 不管是数学符号还是「therefore」。 Diao et al. 发现 SFT 上大量 token 都是低概率 + 低熵:模型本来很自信,却被迫去拟合一个发散的 ground-truth, 代价是冲掉现有的表示。

RL 有数据相关的隐式正则(Lai et al. 2025):方差大的样本组得到更小的 advantage; Mukherjee 等人观察到 RL 只更新了一个稀疏的子网络。

实证扎实,但是否普适尚未验证
作者偏好 · Shenfeld et al.

真正的发动机:on-policy 数据 = 隐式 KL 约束

想象一个最朴素的 RL:REINFORCE + 0/1 奖励。这时奖励就是个 filter, 得到 reward = 1 的样本本质上和拒绝采样产生的样本一样。

把 RL 的目标定义为「所有 completion reward 都是 1 的最优策略」。 因为我们只从当前策略采样,所有可达的最优策略里,离我们最近的那一个就成了实际的训练目标。 每一步策略梯度,都把我们朝"最近的、可解的最优解"挪一点。

on-policy 数据本身约束了"挪到哪里"

几何直觉:on-policy 把目标限制在"够得到的最优解"里

所有让任务做对的策略形成一个集合 P*。一般的 SFT 目标可以选 P* 里的任意一个 —— 哪怕它离当前 π 很远。 而 on-policy 训练,因为每一步只能从 π 自己里采样,能挪到的位置自然被局限在 π 的邻域

所以训练过程倾向于走向「π 在 P* 中的最近投影 π*」。这就是 RL 不太遗忘的几何源头 —— 它不需要 KL 惩罚,采样过程本身已经把"可达范围"卡住了

这也解释了为什么 OPD 从 SFT 教师蒸馏也能少遗忘:教师 logits 提供方向信号,但状态分布始终是学生的, 所以更新仍然被约束在学生附近的可达区域里。

当前策略 π(起点) 最优策略集合 P* "最近"的最优策略 π*(实际去的地方) 外部目标(SFT 可能要去的位置)
P* · 所有最优策略 on-policy 可达邻域 π* π SFT 外部目标
06 · 学生为什么能超过老师

监督打在学生自己会犯的错上 —— 为什么 OPD 学生能反超老师

实验里 OPD 学生在 Pass@1 上反超了 RL 教师本身。蒸馏一般不会超过老师,这事反直觉。 作者没给严格证明,但给了两条解释,并补一张曲线说明这件好事的代价是什么。

HYPOTHESIS 01

监督打在学生自己会犯的错上(on-policy)

传统离线蒸馏只在教师自己生成的轨迹上学。问题是:学生真实犯的错,教师轨迹里可能根本没出现过 —— 等于没被监督到。

OPD 反过来:让学生先自己生成一段 prefix,教师在这段 prefix 上给意见。 监督直接发生在学生"真正会去的状态"上,所以错在哪、就被纠在哪。

HYPOTHESIS 02

OPD 学的是老师的"整张分布",不只是老师吐出的那一个 token

先打个底:模型每生成一个 token,softmax 出来其实是覆盖整个词表的一张概率分布。我们平时看到的"老师输出 X"只是这张分布的最高峰(argmax)。下面三张图直接对比看:

a b c d e vocab tokens →
老师每步的真实输出
整张概率分布
a b c d e vocab tokens →
普通 SFT / token 蒸馏
学生只学到 argmax
a b c d e vocab tokens →
OPD(reverse KL)
学生学整张分布形状

普通 token 蒸馏只学最高那一根;OPD 用 reverse KL,让学生把整张分布对齐到老师 —— 老师在第二、第三峰各有多少概率、哪些位置老师其实自己就拿不准(多 bar 都不矮),学生统统学下来。

学生因此继承的是老师的判断力,不只是"答案"。所以哪怕老师采样出来的某个具体样本不算最佳(采样有运气成分),学生自己采样反而能更稳地落到分布里好的那部分 —— 这就是 Pass@1 反超老师的来源。

↑ reward RL · 平滑上升 OPD · 突跳 ↑ entropy(多样性 / 不确定性) RL · 缓慢下降 OPD · 同步崩塌 同一步:reward 突跳 ⇄ entropy 崩塌 training steps →

代价:reward 突跳的那一步,OPD 的熵同步坍塌

原文实测了 OPD 和 RL 训练全程的 reward / entropy 曲线,这是结论: RL 的 reward 平稳爬升、熵缓慢温和下降;OPD 的 reward 近乎阶跃地拉升,同一步上熵直接断崖崩塌到非常低的水平 —— 远低于 RL。

为什么 OPD 的熵反而比 RL 更低?因为 reverse KL 是 mode-seeking 的(Gu et al. 2023)—— 它要求学生的整张分布对齐老师,会主动把概率压到老师的少数几个峰值上,其它合理备选 token 的概率被压到接近 0。RL 哪怕弱化了 KL 约束,因为 on-policy 采样的"近优解"性质,分布形状本身没被那么剧烈地改写。

对应到指标:Pass@1 提升,但 Pass@k(k>1)和多样性会被 mode collapse 拖累。Pass@1 强 ≠ 全面更强,评估时要单独看多样性指标。

07 · 完整 pipeline

Pretrain → SFT → RL → OPD:每个领域都在「挑最适合它的教师」

近一年开源 / 半开源模型逐渐收敛到一个范式:用 SFT 立基础格式,用 RL 在可验证领域里冲分, 最后用 OPD 把不同领域的「专家教师」融合到同一个学生里 —— 学生最后不再走 RL。 GLM 5、DeepSeek V4、MiMo-V2 Flash 都走这套。

Stage 1
Pretrain
Stage 2
SFT
Stage 3
RL · 训练专家
Stage 4
OPD · 融合
核心问题转移了:SFT 是必须的(不做 SFT 没法做 RL;Chu et al. 2025); RL 也是必须的,但只用于训练专家教师; 最后一步是把每个领域的专家通过 OPD 蒸馏进同一个 student,最终模型本身不经过 RL。 所以新的问题变成了:该用什么训出最好的「专家教师」?
领域 最佳教师训练方法 理由
Math · Code RL · RLVR 有可验证奖励,方向无偏,正合 RL 长项
Creative Writing Self-Distillation 奖励信号噪声大,用 LLM judge 反而是有偏代理
Knowledge-heavy benchmarks Distillation 系 同上 —— 知识题用 RL 反而容易跑偏
BrowseComp 等开放任务 SFT 等 这是少数几个最终合并模型反而弱于教师的领域

有趣的观察:在 RL 这一列上,最终合并模型几乎总是优于专家教师; 只有 self-distilled 专家所在的领域,合并模型可能反而退步。原因尚不明确,但本身就是 OPD 作为"承重梁"的一个反证。

08 · 接下来

下一代算法应该长什么样:密度 × 无偏 × on-policy

Brown (2026) 提出 RL 之所以 Pareto-optimal,是因为在「capability ↑ vs KL 移动 ↑」这条曲线上很高效。 nrehiew 用 OPD 把这个框架补完:真正决定 KL 预算的是 on-policy 数据,而不是显式 KL 惩罚。 所以未来的最优算法,需要同时满足三个性质 —— 而目前任何已知方法都只占两个。

Three Properties · Pick Three

"形状像蒸馏一样致密、信号像 RL 一样无偏、数据像两者一样 on-policy"

作者承认他不知道具体算法长什么样。但问题的形状是清楚的:每一根轴都解决一个已知的缺陷, 目前还没有任何一种已知方法把三根轴同时占满。

AXIS · DENSITY

每个 token 都有信号

RLVR 的 outcome reward 一回合只给 O(1) bit 信息(Schulman et al. 2025)。 Logits 蒸馏密度高,但引入偏差。 未来算法需要密度,但代价不能是偏差。

AXIS · UNBIASED

信号方向不能歪

RLVR 因为奖励可验证,偏差几乎为零。 OPD 教师 logits 是高偏代理,需要靠 clipping 兜底。 最佳算法应该在保持密度的同时把偏差压下去。

AXIS · ON-POLICY

状态分布属于学生自己

on-policy 数据是隐式 KL 约束的源头,避免了模型为了拟合遥远目标而摧毁原有能力。 RL 和 OPD 都有这一性质,它是承重梁

方向已经清楚,但还没有人写出具体的 loss。 Process Reward Model(Lightman et al.)试图增加密度但训练成本高、扩展难; token 级蒸馏(OPD / OPSD)增加了密度但带来偏差,必须配 clip。 作者的最后一句话很坦诚:「这个算法具体长什么样,我也不知道」。
把 RL 当成「特殊」的算法,会让人误判努力方向。真正承重的是 on-policy 数据, 而不是显式 KL 惩罚 —— 任何想取代 RL 的算法,必须先保留这一点,再去加密度、再去减偏差。
— nrehiew · SFT, RL, and On-Policy Distillation Through a Distributional Lens (2026)