Posted on ::

我是在做 Agent 的过程中重新看这条训练链路的。

平时调用模型、接工具、配参数并不难,真正容易卡住的是继续往下追问:SFT 到底在优化什么?PPO 为什么需要 KL 约束?GRPO 去掉了 Critic 之后,优势值从哪里来?DPO 少了奖励模型,为什么还能做偏好优化?

这些问题如果只记结论,很快就会混在一起。于是我从预训练之后的几种方法重新梳理了一遍:先看 SFT,再看策略梯度和优势函数,最后把 REINFORCE、RLOO、REMAX、PPO、GRPO、REINFORCE++ 和 DPO 放回同一条演进线上。

这篇文章不是论文复述。公式只保留理解算法所需要的部分,重点放在三个问题上:

  • 每种方法拿什么作为“好坏”的判断;
  • 它用什么方式估计优势值;
  • 它为了解决前一种方法的问题,又引入了什么成本。

这是工程视角的学习笔记。推导以直觉和关键公式为主,严格证明请以原论文为准。

一、预训练之后,模型还缺什么

预训练让模型掌握了大量语言、知识和模式,但它并不天然知道:

  • 用户的指令应该如何遵循;
  • 什么样的回答更符合人类偏好;
  • 数学题、代码题应该怎样完成并验证;
  • 输出格式、安全边界和产品约束是什么。

后训练通常从下面这条链路开始:

模型结构设计
    -> 预训练
    -> Base LLM
    -> SFT
    -> 偏好数据 / 奖励模型
    -> RLHF、RLVR 或 DPO
    -> 评测、压缩、部署

实际项目里并不是严格走一遍就结束。更常见的方式是先用 SFT 冷启动,再做偏好优化或强化学习,把训练过程中发现的好答案和坏案例重新整理到下一轮数据里。

1.1 SFT 和 RL 的区别

维度SFTRL(RLHF / RLVR)
数据指令、输入、标准回答偏好排序、奖励分数或可验证结果
目标最大化专家答案的似然最大化期望奖励
反馈粒度token 级通常是完整回答或轨迹级
样本来源固定的离线数据模型在线生成的数据
主要作用学习格式、风格和基本行为在多个可行答案中继续选择更好的答案
优点稳定、简单、成本低能利用相对质量和探索结果
风险过拟合、暴露偏差、分布偏移reward hacking、熵崩塌、训练不稳定

简单说,SFT 解决的是“应该怎么回答”,RL 解决的是“多个回答里哪个更好”。

这不是说 SFT 只能死记硬背,也不是说 RL 一定能带来泛化。它们处理的是不同的监督信号:SFT 有明确的示范答案,RL 只有奖励或偏好反馈。

二、SFT:用示范答案塑造行为

2.1 SFT 在做什么

SFT(Supervised Fine-Tuning)是在预训练模型的基础上,用标注好的输入输出样本继续训练。

一个样本可以写成:

输入:介绍一下量子力学
回答:量子力学是研究微观粒子运动规律的物理学分支……

训练时,模型看到输入和回答前缀,预测下一个 token。目标是让标准回答的概率变大。

如果一条样本包含输入 x 和标准回答 y* = (y1, y2, ..., yT),常见的 SFT 损失是:

L_SFT(θ) = - Σ_t log πθ(y_t | x, y_<t)

其中 y_<t 表示第 t 个 token 之前的回答内容。实际训练中通常只对回答部分计算损失,输入部分不参与监督。

2.2 数据质量决定上限

SFT 数据通常包含三部分:

字段含义示例
Instruction任务说明将以下英文翻译成中文
Input任务输入,可选一段英文
Output期望的高质量回答翻译结果

数据量不一定要特别大,但质量很敏感。指令是否清楚、回答是否正确、格式是否一致,都会直接反映到模型行为上。

几千到几万条高质量数据,往往就能让模型明显改变风格或学会一项具体技能;但如果数据里混入大量错误答案、重复模板和互相冲突的规则,继续增加数量只会放大问题。

2.3 SFT 的优点和局限

SFT 的优点很明确:

  • 训练稳定,优化过程和普通监督学习类似;
  • 工程链路简单,不需要在线采样和奖励模型;
  • 对格式、风格和领域术语的适配速度快;
  • 单模型训练,算力和显存压力相对较低。

局限也很明确:

问题具体表现
泛化有限学会了示范答案的分布,换一种问法可能表现下降
暴露偏差训练时一直看到正确前缀,推理时一旦生成错误 token,后续会在错误上下文中继续生成
分布偏移训练数据来自专家,推理数据来自模型自己的生成结果
缺少探索模型只被告知应该模仿什么,没有经历生成、评价和修正
标注依赖数据错误会直接进入模型行为

因此,SFT 很适合做基础能力注入、格式对齐、领域适配和冷启动,但不一定适合单独解决开放式偏好、多步推理和复杂安全约束。

2.4 什么时候使用 SFT

适合使用 SFT 的场景:

  • 翻译、摘要、信息抽取、SQL 生成;
  • JSON、Markdown 或固定模板输出;
  • 领域术语和业务知识适配;
  • 模仿某种写作风格或对话语气;
  • 需要快速验证一个训练方案。

如果任务的关键不在于复现某个答案,而在于从多个答案中挑出更好的一个,就需要引入偏好优化或强化学习。

三、把 SFT 放到强化学习里看

3.1 策略梯度

在强化学习中,语言模型可以看成策略 πθ:

  • 状态 s_t:已经生成的 token 序列;
  • 动作 a_t:下一个 token;
  • 策略 πθ(a_t | s_t):模型对下一个 token 的概率分布;
  • 奖励 r:奖励模型、规则或验证器给出的分数。

策略梯度的简化形式是:

∇θ J(θ) = E[∇θ log πθ(a | s) · A(s, a)]

这里有两部分:

  • ∇θ log πθ(a | s) 决定参数更新的方向;
  • A(s, a) 是优势值,决定这次更新应该有多大。

优势值为正,说明这个动作比基准更好,应当提高它的概率;优势值为负,说明它表现更差,应当降低它的概率。

SFT 的梯度可以写成:

-∇θ log πθ(y* | x)

它只告诉模型“把标准答案的概率提高”,并没有显式告诉模型“这次回答比另一个回答好多少”。

3.2 SFT 的隐式奖励

为了把 SFT 和策略梯度放到同一套表达里,可以把固定的专家数据看成来自一个数据分布,再用重要性采样改写梯度。

直觉上,传统 SFT 相当于设置了一个非常严格的隐式奖励:

r(x, y) = 1        if y == y*
           0        otherwise

也就是说,只有生成结果和标准答案完全一致时才算正确。换一个表达、换一个同义词,甚至只改一个标点,都不会获得“部分正确”的反馈。

进一步看,SFT 的更新还会受到模型当前概率的影响,可以理解为带有类似下面的权重:

1 / πθ(y | x)

这并不是说实际的 SFT 代码会显式计算这个奖励,而是从策略梯度角度观察它的隐式效果。这个视角有助于解释 SFT 的两个问题:

  1. 奖励极其稀疏,无法区分“答对一部分”和“完全答错”;
  2. 模型越不确定的正确样本,隐含的更新权重反而可能越大。

因此,SFT 能很好地把模型推向示范数据,却不擅长表达“答案之间的相对好坏”。

3.3 从绝对分数到相对优势

如果一个回答拿到 80 分,单看这个数字并不能说明它到底好不好。它可能是很高的分数,也可能只是因为这道题很难,所有答案都只有几十分。

更有用的问题是:

这个回答比当前策略通常生成的回答好多少?

这就是优势函数的直觉。理想的奖励应该尽量满足:

  • 有一定密度,能够区分部分正确和完全错误;
  • 更新稳定,不因为一个低概率样本就产生巨大梯度;
  • 更关注相对质量,而不是脱离上下文的绝对分数。

后面的算法差异,主要就是围绕“如何估计这个优势值”展开的。

四、强化学习的几个基本概念

4.1 MDP

马尔可夫决策过程(MDP)通常包含以下要素:

概念符号在语言模型中的对应
状态s_t输入和已经生成的 token
动作a_t下一个 token
策略πθ(a_t | s_t)语言模型
奖励r_t奖励模型、规则或验证器的反馈
轨迹τ一次完整回答

语言模型从输入开始,每生成一个 token 就进入新的状态,直到生成结束。对于很多 LLM 后训练任务,奖励是在完整回答生成后一次性给出的,所以它更接近稀疏的序列级奖励。

4.2 回报、价值和优势

从时间步 t 开始的折扣回报是:

G_t = r_t + γr_{t+1} + γ²r_{t+2} + ...

γ 是折扣因子。它越接近 1,越重视后面的奖励。

状态价值函数:

Vπ(s) = Eπ[G_t | s_t = s]

动作价值函数:

Qπ(s, a) = Eπ[G_t | s_t = s, a_t = a]

优势函数:

Aπ(s, a) = Qπ(s, a) - Vπ(s)

它回答的是:在这个状态下,采取动作 a 比策略平均水平好多少。

4.3 为什么需要基线

直接用 Q(s, a) 做策略梯度,理论上可以保持无偏,但方差通常很大。奖励的绝对值一波动,梯度也会跟着剧烈变化。

减去只依赖状态的基线 V(s) 后,留下的是相对好坏:

A(s, a) = Q(s, a) - V(s)

这个操作不会改变梯度的期望,却能明显降低方差。PPO、RLOO、GRPO 和 REINFORCE++ 的一个核心区别,就是它们选择了不同的基线或归一化方式。

4.4 GAE

PPO 常用 GAE(Generalized Advantage Estimation)估计优势。先定义 TD 误差:

δ_t = r_t + γV(s_{t+1}) - V(s_t)

再把多个时间步的 TD 误差按 λ 加权:

Â_t = δ_t + (γλ)δ_{t+1} + (γλ)²δ_{t+2} + ...
  • λ 接近 0:更依赖单步 TD 误差,方差小但偏差大;
  • λ 接近 1:更接近完整回报,偏差小但方差大。

GAE 的代价是需要一个价值网络。对大模型来说,这个 Critic 往往和策略模型规模相近,显存成本很高,这也是 GRPO 想要去掉 Critic 的原因之一。

五、算法演进:一直在换基线

把这些方法放在一起看,主线大致是:

REINFORCE
    -> 使用历史或常数基线
RLOO / REMAX / REINFORCE++
    -> 使用同批次样本或组内样本构造相对优势
PPO
    -> 引入 Critic,做 token 级优势估计,并限制策略更新幅度
GRPO
    -> 去掉 Critic,用组内奖励估计优势,同时保留 KL 约束
DPO
    -> 不再在线采样,直接用偏好数据优化策略

5.1 REINFORCE

REINFORCE 是最直接的策略梯度方法:模型生成一个完整回答,拿到最终奖励,再用这个奖励更新生成过程中每个动作的概率。

它不关心中间过程,只看最后结果。对于语言模型来说,这意味着一条回答通常要生成完之后才得到反馈。

为了降低方差,可以减去一个基线:

 = R - b

最简单的 b 可以是历史平均奖励。但历史基线有一个问题:如果任务分布或生成风格发生变化,过去的平均分就不一定适合当前样本。

5.2 RLOO

RLOO(Reinforcement Learning with Leave-One-Out)让同一个 prompt 生成多个回答,用其他回答的平均奖励作为当前回答的基线。

假设同一个问题生成 4 个回答,奖励分别为:

A = 80, B = 60, C = 90, D = 70

对回答 A,留一法基线是:

b_A = (60 + 90 + 70) / 3 = 73.3
Â_A = 80 - 73.3 = 6.7

对回答 B:

b_B = (80 + 90 + 70) / 3 = 80
Â_B = 60 - 80 = -20

RLOO 的好处是基线来自当前 prompt 的其他样本,比长期历史平均更贴近当前分布;同时不需要额外训练一个 Critic。

5.3 REMAX

REMAX 只保留一组样本中奖励最高的回答,用它更新策略。它的思路很简单:既然目标是找到高奖励回答,就直接学习当前最好的那个。

问题也同样明显:

  • 其余样本被丢弃,采样成本没有被充分利用;
  • 如果奖励模型误判,最高分样本可能把策略带偏;
  • 它利用的是“第一名”,而不是整组样本的相对关系。

因此,REMAX 更像一种选优策略,而 RLOO 更接近组内比较。

5.4 PPO

PPO(Proximal Policy Optimization)解决的是策略更新过大的问题。

普通策略梯度如果一次更新太多,模型可能迅速偏离原来的策略分布,导致训练不稳定。PPO 使用旧策略和新策略的概率比:

r_t(θ) = πθ(a_t | s_t) / πold(a_t | s_t)

再使用裁剪后的目标:

L_clip = E[
  min(
    r_t(θ) Â_t,
    clip(r_t(θ), 1 - ε, 1 + ε) Â_t
  )
]

当优势为正时,模型希望提高这个动作的概率,但提高幅度不能超过 1 + ε;当优势为负时,模型希望降低概率,但降低幅度不能低于 1 - ε。

PPO 的核心不是让每次更新都正确,而是避免一次错误更新把策略推得太远。

5.5 GRPO

GRPO(Group Relative Policy Optimization)针对的是 PPO 中 Critic 成本高的问题。

对同一个 prompt,模型生成一组回答,得到奖励 r_1, r_2, ..., r_G。GRPO 用组内均值和标准差计算相对优势:

Â_i = (r_i - mean(r)) / (std(r) + ε)

这样不需要单独训练价值模型,就能知道每个回答在本组中的相对位置。

GRPO 通常还会加入参考策略的 KL 约束,并保留 PPO 式的裁剪目标,防止模型为了追求奖励而迅速偏离参考模型。

它的优势是省掉了 Critic,代价是同一个 prompt 需要生成多个回答,采样成本会随组大小 G 增长。

需要注意一个实际问题:如果一组回答全部正确或全部错误,奖励的方差接近 0,组内相对优势就没有多少信息。这类样本会消耗采样资源,却很难产生有效梯度。

5.6 REINFORCE++

REINFORCE++ 通常把奖励和 KL 正则合并成一条样本级信号,再在 batch 维度做归一化,并使用带有 clip 的策略目标进行 token 级更新。

它吸收了几种方法的思路:

  • 用 KL 项限制策略偏移;
  • 用 batch 内统计量降低奖励尺度变化;
  • 使用 PPO 的裁剪目标控制更新幅度。

它和 GRPO 的差别在于归一化范围:GRPO 更强调同一个 prompt 的组内比较,REINFORCE++ 更强调 batch 内的归一化。

5.7 DPO

DPO(Direct Preference Optimization)从一个不同的方向简化 RLHF:不在线生成,不单独训练奖励模型,直接用偏好数据优化策略。

偏好数据通常是:

{
  "prompt": "解释量子计算",
  "chosen": "量子计算利用量子比特……",
  "rejected": "量子计算就是很快的计算……"
}

在带 KL 约束的 RLHF 目标下,最优策略可以写成:

π*(y | x) ∝ πref(y | x) exp(r(x, y) / β)

把这个关系反过来,可以用策略模型和参考模型的概率比表示隐式奖励:

r(x, y) = β log [πθ(y | x) / πref(y | x)] + β log Z(x)

代入 Bradley-Terry 偏好模型,就能得到 DPO 损失。忽略与样本无关的常数后,常见形式为:

L_DPO =
- log σ(
  β [
    log πθ(yw | x) - log πref(yw | x)
    - log πθ(yl | x) + log πref(yl | x)
  ]
)

其中 yw 是 chosen,yl 是 rejected。

DPO 的梯度会重点修正模型判断错误的偏好对;如果模型已经明显把 chosen 排在 rejected 前面,梯度就会自然减小。

六、PPO 拆解

6.1 PPO 中的四个模型

PPO 训练通常涉及四类模型:

模型作用是否训练
Actor / Policy生成回答,也是主要优化对象是
Reference提供 KL 约束的参考分布,通常是 SFT 模型否
Reward Model对完整回答打分否
Critic / Value Model估计每个状态的价值,计算优势是

Reward Model 和 Critic 经常被混淆:

  • Reward Model 通常在完整回答结束后给出一个序列级分数;
  • Critic 在每个 token 位置估计“从当前状态继续生成,最后能拿到多少回报”。

Critic 的存在主要是为了提供低方差的优势估计,但它也带来了接近一个策略模型的额外显存开销。

6.2 PPO 的损失

一个常见的 PPO 总损失可以写成:

L = L_policy + c1 L_value - c2 S[πθ]

其中:

  • L_policy 是裁剪后的策略损失;
  • L_value 是价值函数损失;
  • S[πθ] 是策略熵,用于鼓励探索;
  • c1 和 c2 控制价值损失、熵正则的权重。

价值函数通常使用均方误差:

L_value = (Vφ(s_t) - V_target_t)^2

熵定义为:

S[πθ] = -Σ_a πθ(a | s) log πθ(a | s)

熵较高,表示概率分布更分散,探索性更强;熵快速下降到接近 0,通常意味着输出开始模式坍缩。

6.3 常见超参数

参数作用常见起点
学习率控制参数更新步长LLM 场景通常低于传统 RL
γ折扣因子0.99 左右
λGAE 的偏差-方差权衡0.95 左右
εPPO clip 范围0.1 ~ 0.2
K每批样本重复更新次数3 ~ 10
c1价值损失系数0.5 ~ 1.0
c2熵系数需要结合任务调节

这些数值只能作为起点。LLM 后训练对奖励尺度、序列长度、采样温度和 batch size 都很敏感,不能把表格中的范围当成固定配置。

七、GRPO 拆解

7.1 四个步骤

GRPO 的一次训练迭代可以概括为:

  1. 从数据集中采样一批 prompt;
  2. 对每个 prompt 生成 G 个回答;
  3. 对回答计算奖励,并在组内归一化;
  4. 用相对优势更新策略,同时约束策略不要偏离参考模型太远。

组内优势可以写成:

Â_i = (r_i - μ_group) / (σ_group + ε)

这里的 μ_group 和 σ_group 只由同一个 prompt 的回答计算得到。

7.2 KL 约束

如果只最大化奖励,模型可能会找到奖励模型的漏洞,而不是学会真正有用的能力。KL 约束提供了一个参考点:

KL(πθ || πref)

它的作用不是让两个策略完全相同,而是限制策略更新速度和偏离程度。

KL 太小,模型几乎不动,奖励很难提升;KL 太弱,模型可能过拟合奖励、输出同质化,甚至破坏 SFT 阶段已经学会的能力。

在工程上,β 是控制这个权衡的主要参数:

β约束强度可能的结果
接近 0很弱追求奖励,容易偏离和坍缩
中等平衡通常作为初始搜索区间
较大很强策略更保守,可能学不到新东西

7.3 数据要求

GRPO 需要同一个 prompt 对应多个回答。数据设计时要注意:

  • 回答之间应该有一定质量差异;
  • 不能让大数组全部正确或全部错误;
  • 组内评分标准要一致;
  • prompt 要覆盖不同领域和难度;
  • 组大小越大,采样成本越高。

一个简化的数据结构如下:

grpo_data = [
    {
        "prompt": "解释量子计算",
        "responses": [
            "量子计算利用量子比特……",
            "量子计算就是很快的计算……",
            "我不懂量子计算",
        ],
        "scores": [1.0, 0.3, 0.0],
    }
]

对数学、代码和 SQL 这类任务,奖励可以来自答案校验、单元测试、编译器或规则判断,这类训练通常称为 RLVR。

八、DPO 拆解

8.1 为什么需要 DPO

PPO 的问题是重:Actor、Critic、Reference、Reward 四个角色都要维护,还要不断生成新样本。

如果已经有大量“同一个 prompt 下,哪个回答更好”的离线数据,就不一定需要完整地跑在线 RL。DPO 直接在这些偏好对上训练策略。

DPO 需要的核心数据是:

dpo_data = [
    {
        "prompt": "解释量子计算",
        "chosen": "量子计算利用量子比特……",
        "rejected": "量子计算就是很快的计算……",
    }
]

训练时通常加载策略模型和冻结的参考模型。参考模型可以是 SFT 后的模型,用来约束策略不要偏离初始能力太远。

8.2 DPO 和 PPO 的区别

维度PPO / RLHFDPO
奖励模型需要不需要
在线采样需要不需要
主要数据在线生成和奖励离线 chosen / rejected 偏好对
模型角色Actor、Critic、Reference、RewardPolicy、Reference
训练稳定性超参数敏感通常更稳定
探索能力可以持续在线探索受离线数据分布限制
工程成本高低

DPO 的代价是它依赖偏好数据。如果数据覆盖不足,模型只能在已有偏好分布附近优化,无法像在线 RL 那样主动探索新的回答。

8.3 β 对 DPO 的影响

在 DPO 中,β 仍然控制策略偏离参考模型的程度:

  • β 较小,偏好损失的作用更强,策略更容易追逐 chosen;
  • β 较大,参考模型约束更强,训练更保守。

实际训练时不能只盯着训练损失。还要看 chosen / rejected 的 log probability 差异、验证集偏好准确率、输出长度和人工质量。

九、工程选型和常见问题

9.1 怎么选

场景推荐方法常见组合
指令遵循、格式对齐SFTSFT
快速做偏好对齐DPOSFT → DPO
开放式偏好、安全和有用性PPO 或其他 RLHFSFT → RM → PPO
数学、代码、SQL 等可验证任务GRPO / RLVRSFT → GRPO
算力有限、已有高质量偏好对DPOSFT → DPO

这个表不能替代评测。真实项目里,先把 SFT 和数据质量验证清楚,通常比直接上复杂 RL 更重要。

9.2 RLHF 和 RLVR

维度RLHFRLVR
奖励来源奖励模型规则、测试、编译器或答案验证器
适合任务对话、写作、安全、主观质量数学、代码、SQL、结构化输出
主要优点能处理开放式偏好奖励更客观,不需要训练 RM
主要风险reward hacking,奖励模型退化只适用于有明确验证标准的任务

RLHF 的难点是奖励模型是否真的代表目标;RLVR 的难点是验证器是否覆盖了任务真正关心的质量。

9.3 常见问题

问题典型现象排查方向
Reward hacking奖励上涨,但人工质量下降增加 KL、更新奖励模型、加入长度和格式检查
熵崩塌输出越来越同质降低学习率,调整熵系数和采样温度
长度偏置回答越来越长做长度归一化,检查奖励模型是否偏爱长答案
SFT 过强RL 阶段奖励几乎不动减少 SFT 训练轮数,保留一定生成多样性
KL 过强策略基本不变化降低 KL 权重,检查参考模型和奖励尺度
KL 过弱模式坍缩或能力退化提高 KL 约束,降低 RL 学习率
组内全对或全错GRPO 采样很多但梯度弱调整题目难度和数据配比
训练集污染评测集指标虚高严格隔离训练、验证和测试数据

9.4 一条实际的落地路线

如果从零开始做一次后训练,我会按下面的顺序推进:

  1. 先建立评测集。 没有可靠的基线,后面很难判断模型是否真的变好。
  2. 用 SFT 冷启动。 目标是让模型具备可用的格式、行为和基本能力,不是把训练集背到极致。
  3. 选择奖励来源。 有明确标准时优先使用规则或验证器;没有标准时再考虑训练奖励模型。
  4. 选择优化方法。 有高质量偏好对、资源有限时先试 DPO;需要在线探索或可验证推理时再考虑 GRPO;多目标开放式偏好且资源充足时考虑 PPO。
  5. 持续监控。 至少同时观察奖励、KL、熵、输出长度和人工评测。
  6. 把结果回流数据。 把 RL 阶段发现的好答案整理成 SFT 数据,把典型 badcase 整理成偏好对,继续迭代。

十、结语

SFT 和 RL 的区别,最终还是监督信号的区别。

SFT 有标准答案,优化的是“让模型更像示范”;RL 没有唯一答案,优化的是“让模型更偏向高奖励结果”。前者适合建立行为和能力的基础,后者适合在多个可行结果之间继续做选择。

从 REINFORCE 到 RLOO、PPO、GRPO,再到 DPO,算法变化看起来很多,但都绕不开几个问题:

  • 奖励从哪里来;
  • 基线如何构造;
  • 优势值如何估计;
  • 策略更新多大才不会失控;
  • 如何在探索新能力和保留原能力之间取平衡。

所以,“SFT 负责记忆,RL 负责泛化”可以作为一个方便记忆的总结,但它不是绝对规律。最终效果仍然取决于数据、奖励、评测和训练配置。算法只是把这些因素组织起来的一套工具。

Table of Contents