这个系列前几篇都在讲「感官」:输入以什么形态进来音视频怎么对时想好的话怎么说出口。今天换个话题,讲「教养」——模型怎么学会分辨哪个回答更好

其实强化学习在前几篇里已经悄悄出场过两次:Qwen2.5-Omni 用 DPO 治 Talker 的幻听,MiniCPM-V 用 RLAIF-V 治看图说瞎话。今天把这条线讲透:从 PPO 到 DPO、GRPO、GSPO,这串字母到底在解决什么问题。

先说清为什么需要它。预训练教会模型接话,SFT 教会模型照着范文答题——这两步都有「标准答案」可抄。但很多要紧的事没有标准答案:同一个问题的两个回答,哪个更有帮助?哪个没撒谎?推理题的一万种解法里,哪种更靠谱?这类信号只有一种形态:试错,然后被打分。这就是强化学习的主场。

一、把强化学习装进一句话

强化学习的教科书三件套,映射到 LLM 上非常直白:「策略」就是模型本身,「动作」就是吐出下一个 token,一整句吐完,「环境」给一个分(可能来自打分模型,也可能来自规则判卷)。

模型(策略)逐 token 往外吐打分器(环境)奖励模型 / 规则判卷一整句回答一个总分 r(整句的)更新却要落到每一个 token 上:↑?↑?↓?↑?↓?↑?↑?↓?整句 1 个分 ÷ 300 个 token = ?——功劳怎么摊?全文主线朴素策略梯度的答案:分高就整句全调大——太粗糙,于是有了后面的故事
RL 三件套映射到 LLM,以及贯穿全文的那道题:整句一个分,更新却要落到每个 token 上

最朴素的更新办法叫策略梯度:得分高的回答,把生成它的每个 token 的概率都调大一点;得分低的整句调小。听上去合理,但请注意一个别扭的地方——分是整句的,更新是逐 token 的。一句 300 个 token 的回答得了高分,功劳是第 17 个 token 的还是第 250 个的?这道「功劳分配」题,就是接下来所有算法的分歧点,请全程带着它。

二、PPO:经典重装旅

ChatGPT 起点的 RLHF 三部曲(InstructGPT 定型):先 SFT,再训一个奖励模型(人类对回答排序,模型从排序里学会打分),最后用 PPO 让策略在奖励模型的打分下自我改进。

策略模型 π在训练的主角回答 y(一整句)奖励模型 RM从人类排序学会打分 → r价值模型 critic估计「本来该得几分」→ V优势 A = 实际 − 期望参考模型 π_ref冻结的出发点按 A 调每个 token 的概率(clip:小步快跑)KL 锁链:别离出发点太远(防奖励破解)四个大模型同时在场:贵,但每一环都有它存在的理由
PPO 时代的四个角色:策略生成,奖励模型打分,价值模型分功,参考模型拉住缰绳

PPO 的两道核心保险,各配一个直觉:

  • 小步快跑(裁剪)。每次更新前算一个「新旧策略比率」——新策略生成这个 token 的概率是旧策略的几倍。比率被裁剪在一个窄区间内,一步迈太大就按住。旧策略采的数据只能小心地用,不然容易摔跤;
  • KL 锁链(参考模型)。策略随时和一个冻结的参考模型比对,跑太远就拉回来。这是在防奖励破解——打分器总有漏洞,放任不管,模型会学出一堆讨好打分器的怪话。

那「功劳分配」呢?靠一个价值模型(critic)逐位置估「这个局面本来该得几分」,拿实际减去它就是优势 A——比预期好该奖、比预期差该罚。至于 A 具体怎么从奖励模型和 critic 手里算出来,等 clip 讲完就拆开看——它俩的分工,是 PPO 最容易搞混的一处。

把裁剪写成公式,核心就一行(省掉了期望和求和号):

L_CLIP = min( r·A ,  clip(r, 1−ε, 1+ε)·A )
  r = π_new(token) / π_old(token)     ← 新旧概率比:这一步的概率涨了几倍
  A = 实际回报 − critic 预测           ← 优势:比「本来该得的」好还是差

带一个数走一遍。某个 token,旧策略给它 0.10 的概率,新策略抬到 0.15,比率 r = 1.5;取 ε=0.2,裁剪区间就是 [0.8, 1.2]:

  • 这一步该奖(A=+2):min(1.5×2, 1.2×2) = min(3.0, 2.4) = 2.4——涨太猛,被 clip 按到 1.2 倍封顶;
  • 这一步该罚(A=−2):min(1.5×(−2), 1.2×(−2)) = min(−3.0, −2.4) = −3.0——这次 clip 没拦,该扣多少扣多少。

这个 min 的不对称正是 PPO 的精髓:只往「过度自信」的方向踩刹车——好事不许一步占太多,坏事该扣就扣足。

L=0r裁剪后目标 L1−ε (0.8)1.01+ε (1.2)↑ 封顶:不许一步涨太多优势为正 A>0(该奖)封顶 ↓优势为负 A<0(该罚)clip 只在「会因这一步偏离太远」的方向踩刹车:A>0 右侧封顶、A<0 错误方向(r>1)不封顶,罚到底
PPO 裁剪目标:优势为正时在 1+ε 处封顶(不许涨太多),优势为负时不设下限(该罚罚足)

现在拆开优势 A,看它到底怎么算。 PPO 里其实有两个打分模型,常被混为一谈,分工却清清楚楚:

  • 奖励模型 RM:等一整句说完,才给一个标量总分——「这个回答整体值几分」。真实信号只此一个,而且极稀疏:一整句就一个数,落在最后一个 token 上。
  • 价值模型 critic:边生成边给每个 token 估一个预期前景 V——「站在这个位置往后看,最终大概能收多少分」。

每个 token 的即时奖励由此拼出(KL 缰绳也落在这里):

中间每个 token:  rₜ = − β·log( π_θ/π_ref )          ← 只有 KL 惩罚,别跑偏
最后一个 token:  r_T = RM 总分 − β·log( π_θ/π_ref )   ← 额外领到 RM 的整句分

「实际回报」就是从当前位置往后,把这些 rₜ 一路累加(终点那笔 RM 大分也算进去)。优势则是拿它和 critic 的预期一比:

优势 Aₜ ≈ 实际回报(往后累加,含终点 RM 分)  −  critic 预期 V(sₜ)

一句话说透三者:RM 在终点给一个真分,critic 把这个稀疏的终点分「摊」成每一步的预期,优势 = 实际 − 预期——告诉每个 token「你这一步让最终结果比原本预计的更好还是更差」。而 critic 自己也在同步训练,目标就是让 V 逼近实际回报,跟着 RM 的分数慢慢学会预测前景。(严格说这一步用 GAE 做了带权平滑,在偏差与方差间取衡,但内核就是「实际 − 预期」。)

t₁t₂t₃t₄t₅t₆一句话逐 token 生成 →奖励模型 RM整句 +1.0(唯一真分)整句读完才打这一个分critic 每步预期 V(把终点的稀疏分摊成每一步)↓0.60.60.70.70.80.9优势 A = 实际回报(≈1.0)− critic 预期 V ↓+0.4+0.4+0.3+0.3+0.2+0.1RM 给终点一个真分(稀疏)· critic 每步估预期(摊开它)· 优势=实际−预期,就是每个 token 的真功劳这里 A 越靠终点越小——critic 离终点越近、预测越准,实际与预期的差自然越小
两个打分模型分工:RM 在终点给整句一个总分,critic 给每个 token 一个预期,优势 = 实际回报 − critic 预期

代价也在这:策略、参考、奖励、价值,四个大模型同时在场,又贵又难调(critic 本身就不好训)。这为后面所有的简化埋下了伏笔。

三、DPO:掀桌子的极简派

DPO 论文的标题就带着挑衅:《你的语言模型,偷偷就是个奖励模型》。它的洞察是:在 KL 约束下,最优策略和奖励函数之间有一个闭式的对应关系——既然如此,何必先训奖励模型、再跑昂贵的采样循环?直接在偏好数据上优化策略就行。

✓ 更好的回答 y⁺✕ 更差的回答 y⁻DPO 损失一步交叉熵抬高 y⁺ 的相对概率 ↑压低 y⁻ 的相对概率 ↓「相对」是相对冻结的参考模型 π_ref;β 控制拉扯力度——允许离出发点多远没有奖励模型、没有采样循环:一对偏好,直接变成一次梯度
DPO:没有奖励模型、没有采样循环,一对偏好直接变成一次推拉

它的损失函数说穿了是一个推拉动作:拿到一对回答(更好的 y⁺,更差的 y⁻),把 y⁺ 相对参考模型的概率抬高,把 y⁻ 压低,系数 β 控制拉扯的力度(也就是允许离参考模型多远)。整个过程就是一次监督学习式的训练,四个模型的舞台瞬间只剩两个(策略 + 冻结的参考)。

把这套推拉写成公式。 出发点是那个闭式对应——KL 约束下的最优策略可以反解出奖励:

r(x,y) = β · log( π_θ(y|x) / π_ref(y|x) ) + 常数
         └──── 奖励其实藏在策略里,不用另训 ────┘

奖励不必单独学,它就等于「策略相对参考模型偏移了多少」。代进标准的偏好损失,奖励模型整个消失,只剩策略自己:

L_DPO = − log σ( Δ )
  Δ = β·[ log(π_θ(y⁺)/π_ref(y⁺)) − log(π_θ(y⁻)/π_ref(y⁻)) ]
      └──── 好句子比坏句子多「偏移」了多少 ────┘

σ 是 sigmoid。带数走一遍(β 取典型的 0.1):

  • 训练前没偏好,Δ=0 → loss = −log σ(0) = −log 0.5 = 0.69,梯度最大,使劲推;
  • 学好了,Δ=+3 → σ(3)=0.95loss = 0.05,几乎满足,梯度趋近 0,不再折腾;
  • 若模型搞反了、反而更偏好差答案,Δ=−2 → σ(−2)=0.12loss = 2.1,惩罚巨大,猛拉回来。
← 搞反区(更偏好差答案)Δ损失 −log σ(Δ)−4−20+2+4Δ=−2:loss 2.1(搞反,猛罚)Δ=0:0.69(无偏好,梯度最大)Δ=+3:0.05(学对了,松手)梯度自带权重 σ(−Δ):错得越离谱拉得越猛,已经对了就松手——这是 DPO 比朴素对比稳的关键
DPO 损失随「好坏偏移差 Δ」变化:搞反了(Δ<0)损失陡增猛罚,学对了(Δ 越大)损失趋零松手

妙就妙在梯度自带一个自适应权重 σ(−Δ):错得越离谱、拉得越猛,已经对了就松手。这是 DPO 比朴素「抬一个、压一个」稳的关键。

那道功劳分配题呢?DPO 的答案是根本不摊:它不给回答打分,比较直接发生在整句的对数似然上——好句子的每个 token 被同一股力一起抬,坏句子的每个 token 一起压(论文称之为隐式奖励,定义在序列级)。记住这个「整句打包」的味道,第五节它会换一副面孔再次出现。

便宜、稳定、好复现,DPO 因此成了工业界的宠儿——而且落地的理由说得很坦白:

  • Llama 3 的后训练用 SFT + 拒绝采样 + DPO,论文明说选这条简单路线是因为复杂的强化学习「不稳定且难以扩展」;
  • Qwen2.5-Omni 给 Talker 做了一轮 DPO:用「输入 + 一好一坏两段语音」的三元组训练,专治预训练数据噪声带来的幻听和重复——语音也能做偏好对;
  • MiniCPM-V 的 RLAIF-V 更进一步,连人类标注都省了:让开源模型当裁判,分治式地检查回答里的每个断言、拼出偏好对,再用 DPO 优化——开源反馈也能把幻觉率打下来。

局限也直白:DPO 是离线的,学的是「这两个候选里谁更好」,没有探索,天花板取决于偏好数据本身的质量和覆盖。想让模型自己闯出新解法——比如做数学题——还得回到在线试错的路上。

四、GRPO:砍掉裁判的轻装兵

回到在线 RL,最扎眼的开销是 critic:它和策略一样大,还难训。DeepSeek 在 DeepSeekMath 里给出的答案是 GRPO:不请裁判了,让同一道题的一组回答互相当彼此的基准

规则判分:答案对 +1,错 0同一道题回答 1回答 2回答 3回答 41 分0 分0 分1 分A = +0.5 ↑A = −0.5 ↓A = −0.5 ↓A = +0.5 ↑(组平均 0.5)优势 = 自己的分 − 组内平均(再除以组内标准差):跟同学比,critic 下岗R1 再加一条格式分:思考过程必须写进 think 标签
GRPO:同一道题采样一组回答,组内平均就是基线——跟同学比,不请裁判

做法:同一道题采样 G 个回答,各自拿分,然后减去组内平均、除以组内标准差——高于平均的算优势为正,低于平均的为负。「本来该得几分」不再需要一个大模型来估计,一组同学的平均分就是天然的参照。critic 下岗,显存减半。

组内标准化写成公式,很短:

Aᵢ = ( rᵢ − mean(r₁…r_G) ) / std(r₁…r_G)

同一道题采 4 个回答,规则判分得 [1, 0, 0, 1]:均值 0.5、标准差 0.5,于是优势

A = [ +1, −1, −1, +1 ]    ← 对的往上推、错的往下压,基线自己算出来

「本来该得几分」由一组同学的均值顶替,一个和策略同样大的 critic 就这么省了。完整目标其实还是 PPO 那套 clip,只换了两处:优势用组内的 Aᵢ,KL 从奖励挪进损失——

J_GRPO = 1/G Σᵢ (1/|oᵢ|) Σₜ min( rᵢ,ₜ·Aᵢ , clip(rᵢ,ₜ, 1−ε, 1+ε)·Aᵢ ) − β·KL
                          └─ 比率 rᵢ,ₜ 逐 token,优势 Aᵢ 却整句共享 ─┘

盯住最后那行注释:打分是整句一个 Aᵢ,更新却是每个 token 一个 rᵢ,ₜ,两者单位对不上。这个错位,下一节 GSPO 专门来修。

GRPO 真正大放异彩,是和可验证奖励(RLVR)组队之后。数学和代码这类任务不需要打分模型:答案对不对,规则一判便知。DeepSeek-R1 的奖励就两条——答案正确性(判对才给分)与格式合规(把思考过程写进 <think> 标签);他们还刻意不用逐步打分的过程奖励模型,理由是模型迟早学会讨好它(奖励破解)。就在这套朴素信号下,R1-Zero 从基座模型直接开始纯 RL 训练,长思维链自己长了出来,训练中途甚至出现了论文里那句著名的「aha moment」——模型突然学会回头检查自己的推理。

但功劳分配那道题,GRPO 只答了一半:组内相对分解决了「该得几分」,可这个分还是整句的,而更新用的新旧比率仍是逐 token 的。GSPO 的论文指出了后果:token 级的重要性采样在这种用法下是失效的,它引入的噪声随回答变长不断累积、又被裁剪机制放大——序列一长、模型一大(尤其 MoE),训练就容易崩,以至于 MoE 上要靠 Routing Replay 这类补丁续命。

五、GSPO:把单位对齐到整句

Qwen 团队的 GSPO 把这最后一块补齐,思路一句话:奖励是整句的,重要性比率也应该是整句的。它把新旧策略的比率定义在序列似然上(做了长度归一化),裁剪也在序列级进行——一句话要么整体被接受,要么整体被按住,不再让几百个 token 各自掷骰子。

序列比率写成公式,和 GRPO 并排一比就懂:

GRPO(逐 token):  rᵢ,ₜ = π_θ(tokenₜ) / π_old(tokenₜ)               每个 token 一个比率
GSPO(整句):      sᵢ   = ( π_θ(整句 yᵢ) / π_old(整句 yᵢ) )^(1/|yᵢ|)   整句一个,再开 |yᵢ| 次方

那个 1/|yᵢ| 次方是长度归一化——把整句似然比几何平均回「每 token」的尺度,长短句才可比。

为什么这一下就稳?带个数:一个 100-token 的回答,每个 token 的比率在 1.0 上下小抖(0.9~1.1)。

  • GRPO 逐 token:100 个比率各自进 clip,只要几个 token 抖到 1.5 被裁,就搅乱整次更新;回答越长,抖动累积越凶;
  • GSPO 整句:把 100 个比率乘起来再开 100 次方(几何平均),正负抖动相互抵消,结果紧贴 1.0——一句话掷一个骰子,而不是一百个各掷各的。

目标函数也随之清爽,Σₜ 那层逐 token 求和没了:

J_GSPO = 1/G Σᵢ min( sᵢ·Aᵢ , clip(sᵢ, 1−ε, 1+ε)·Aᵢ )

计分是整句(Aᵢ),结算也是整句(sᵢ),单位终于对齐。

GRPO:每个 token 各有一个新旧比率——几百个骰子各掷各的×1.02×0.97×1.10×0.93×1.05×0.96×1.08噪声随长度累积越长越飘,再被裁剪放大——长序列 / MoE 容易崩(要靠 Routing Replay 这类补丁续命)GSPO:整句一个比率——一次掷一个大骰子整句似然比(做长度归一化)序列级裁剪与更新计分单位=更新单位,训练稳了;MoE 不再需要补丁(Qwen3 采用)功劳分配四种答案:PPO 雇 critic 分功 · DPO 整句似然直接比 · GRPO 同学互比 · GSPO 整句结算
GRPO 的 token 级比率噪声随长度累积;GSPO 整句一个比率,单位终于对齐

论文报告的效果:训练比 GRPO 更稳、更高效,MoE 不再需要 Routing Replay,这些收益进入了 Qwen3。

到这里可以把主线收拢了。同一道「整句的分怎么摊给 token」,四种答案:PPO 花大价钱雇 critic 逐 token 分功;DPO 绕开打分,在整句似然上直接对比——最早交卷的「句子级」答案;GRPO 用组平均省掉裁判,但计分和更新的单位错着位;GSPO 把单位对齐——整句计分,整句结算,和 DPO 在「以句为单位」这件事上殊途同归。

六、一张地图

在线试错奖励模型价值模型信号形态代表落地
PPO整句打分,critic 逐 token 分功InstructGPT / ChatGPT
DPO不要(离线)不要(隐式)不要成对偏好Llama 3、Omni Talker、MiniCPM-V
GRPO可换规则判分不要组内相对分(token 级更新)DeepSeekMath、DeepSeek-R1
GSPO可换规则判分不要组内相对分(序列级更新)Qwen3

这张表之外还有一串亲戚,各占一句话:RLOO 和 GRPO 想法相近,用「留一法」拿组内其他人当基线;DAPO 开源了一整包让 GRPO 更好训的工程手筋;KTO 更进一步,连成对偏好都不要,单条「好/坏」标注就能训。方向都一样:更便宜、更稳的偏好信号。

七、写在最后

三句话收束:

  1. SFT 教模型「像谁」,RL 教模型「哪个更好」——前者抄范文,后者试错加打分;
  2. 这串字母的演化,是一条不断做减法的路:PPO 四个模型,DPO 砍到两个,GRPO 砍掉裁判,GSPO 把最后的单位错配也抹平;
  3. 但减法背后那道题从没变过:整句的分,怎么摊给每个 token——雇人分(PPO 的 critic)、不打分直接比(DPO)、同学比(GRPO 的组基线)、整句算(GSPO),四种答案,各领一个时代。

下次看到模型报告里轻描淡写的一句「post-trained with RL」,你知道那背后是四个模型的舞台,还是一组同学的内卷。

参考