工作台课程

CS336 · 从零构建语言模型

Lecture 16 · 对齐 II:RLVR

Lecture 16 · 对齐 II:RLVR

CS336: Language Modeling from Scratch · Stanford · Spring 2025
📅 May 22 · 💻 不可执行讲义(PDF) · 讲者 Tatsunori Hashimoto


承上启下

上一讲(Lecture 15 · 对齐 I:SFT 与 RLHF
- SFT 教模型模仿指令数据,RLHF/DPO 用偏好数据优化模型行为。
- 但 reward model 是偏好数据的拟合器,容易被 overoptimization;偏好数据本身又充满风格与标注偏差。

本讲(RLVR)
- 换到可验证奖励(verifiable rewards):数学、代码、形式化任务——只要能自动判对错,就能绕开人类偏好噪声这一整层问题。
- 重点:PPO → GRPO 的算法简化,以及 DeepSeek-R1、Kimi K1.5、Qwen3 三个完整的 reasoning RL recipe。
- 下一讲 Lecture 17 · 对齐 III:RL 实战 会在一个玩具任务上把这些算法的机械细节逐行拆开。

摘要

RLHF 优化的是有噪声的人类偏好,RLVR 优化的是可验证正确性。在数学/代码等窄域里,只要能自动打 reward,就能用 RL 把模型推到超过 SFT 的区域;但 GRPO 等算法有长度偏置与难度偏置,RL 训练系统的工程复杂度也远超预训练。


1. 从 RLHF 到 RLVR

RLHF 的结构性问题在上一讲已经展开:reward model 不是真实目标而是代理,偏好数据带着长度与风格偏差,优化久了 proxy reward 上升而真实质量下降;无论 PPO 还是 DPO,上限都被偏好数据的质量卡死。

RLVR(Reinforcement Learning from Verifiable Rewards,可验证奖励强化学习)的思路是:在奖励可以程序化判定的任务上,把 reward model 整个换成 verifier

  • 数学题:最终答案与标准答案匹配则$R=1$,否则$R=0$;
  • 代码题:程序通过全部单元测试则得分;
  • 格式:输出符合规定结构(如把推理放进 <think> 标签)给 format reward;
  • game / environment:任务成功与否由环境直接给出。

形式化地,最常见的 RLVR reward 就是一个指示函数:

$$R(x, y) = \mathbb{1}\!\left[\operatorname{answer}(y) = a^*(x)\right]$$

其中$x$是题目,$y$是模型的完整回答(含思维链),$\operatorname{answer}(y)$是从回答中抽取的最终答案,$a^*(x)$是标准答案。$R$不可微、且对整条回答只有一个标量(outcome reward),所以只能用 RL 而不能用监督学习直接优化。

graph LR
    P["prompt"] --> M["model rollout"]
    M --> A["answer / code / proof"]
    A --> V["verifier"]
    V --> R["reward 0/1 or shaped"]
    R --> RL["policy update"]

核心条件一句话:

If you can measure it, you can optimize it.

提示

RLHF 的一切坑都源于「奖励信号是学出来的、会被钻空子」。RLVR 把奖励换成不可欺骗的程序判定,Goodhart 问题在「答案对不对」这个维度上消失了——模型没法「说服」单元测试。代价是适用面收窄:只有存在可靠 verifier 的窄域(数学、代码、逻辑)能这么做;写作、对话、开放问答仍然只能依赖偏好类信号。另外「可验证」也有边界:答案抽取脚本判错、测试用例覆盖不全时,reward hacking 会换个形式回来(比如硬编码测试样例的输出)。

注意

RLVR 并不是「不需要 KL、随便优化」的自由天堂。奖励信号干净只是说 verifier 不会被欺骗,但策略仍可能塌缩(只会做一种题)、遗忘通用能力、或利用 verifier 的实现漏洞。实践中 R1 等 recipe 仍然保留(或阶段性使用)KL 正则与后续通用对齐阶段。


2. PPO 回顾

PPO(Proximal Policy Optimization)是策略梯度(policy gradient,见 CS221 Lecture 9 · 函数逼近与策略梯度(未找到对应页面))的稳定化版本,也是 InstructGPT 与早期 RLVR 的默认算法。

语言模型的 RL 形式化:

  • state$s$:prompt + 已生成的 token 前缀;
  • action$a$:下一个 token;
  • trajectory:一条完整回答;
  • reward:整条回答结束后 verifier 给出的分数(outcome reward);
  • policy$\pi_\theta$:语言模型本身。

PPO 的核心量是新旧策略的概率比(probability ratio):

$$r_t(\theta) = \frac{\pi_\theta(a_t \mid s_t)}{\pi_{\theta_{\mathrm{old}}}(a_t \mid s_t)}$$

其中$\pi_{\theta_{\mathrm{old}}}$是采样这批数据时的旧策略(冻结不更新)。这个比值来自重要性采样:数据是旧策略生成的,但要用来估计新策略的梯度。PPO 的 clipped objective 对每个 token 取:

$$\mathcal{L}^{\mathrm{CLIP}}(\theta) = \mathbb{E}_t\!\left[\min\!\left(r_t(\theta)\,\hat{A}_t,\ \operatorname{clip}\!\left(r_t(\theta),\, 1-\epsilon,\, 1+\epsilon\right)\hat{A}_t\right)\right]$$

其中$\hat{A}_t$是优势(advantage)估计——「这个动作比平均预期好多少」,$\epsilon$(典型值 0.2)限定单步更新中概率比的可信区间。$\min$与 clip 组合的效果:当更新方向会让$r_t$超出$[1-\epsilon, 1+\epsilon]$时梯度被截断,防止一步把策略改得太远,导致重要性采样失效、训练崩溃。

在 RLHF/RLVR 中还常把 KL 惩罚并入奖励,防止偏离参考模型:

$$R^{\mathrm{total}} = R - \beta\,\mathbb{D}_{\mathrm{KL}}\!\left[\pi_\theta \,\|\, \pi_{\mathrm{ref}}\right]$$

PPO 用在语言模型上的痛点,每一条都有明确的因果来源:

  • 需要 value model(critic):$\hat{A}_t$的标准估法(如 GAE)需要一个逐 token 预测期望回报的价值网络,它通常与 policy 同规模——显存和训练成本直接翻倍;
  • outcome reward 下 critic 很难学:奖励只在序列末尾出现一次,价值网络要把这一个标量的功劳摊派到几千个 token 上,信号极稀疏;
  • 实现复杂:policy、old policy、reference model、value model、reward/verifier 五个组件要协调;
  • rollout 慢:训练循环内嵌着自回归生成这个推理 workload(参见 Lecture 10 · 推理);
  • 超参多:$\epsilon$、$\beta$、value loss 权重、GAE 参数、采样温度都要调。

3. GRPO:去掉 critic 的 PPO 简化

GRPO(Group Relative Policy Optimization,组相对策略优化)来自 DeepSeekMath(2024),核心思想一句话:不训练 value model,用「同一道题的多条回答互相比较」来当 baseline

对每个 prompt$x$,从旧策略采样$G$条回答并打分:

$$y_1, \dots, y_G \sim \pi_{\theta_{\mathrm{old}}}(\cdot \mid x), \qquad R_i = \operatorname{verifier}(x, y_i)$$

组内标准化得到优势(同一条回答内的所有 token 共享这一个优势值):

$$\hat{A}_i = \frac{R_i - \operatorname{mean}\left(\{R_j\}_{j=1}^{G}\right)}{\operatorname{std}\left(\{R_j\}_{j=1}^{G}\right)}$$

再套用 PPO 式的概率比 + clip 更新(DeepSeekMath 原版目标还包含对每条回答按长度$1/|y_i|$平均、以及显式的 KL 正则项)。

3.1 为什么 GRPO 天然适合语言模型?

在经典 RL(机器人、游戏)里,你无法「把环境重置到同一状态再试 G 次」,所以需要 value function 来估计「这个状态平均能拿多少分」。而语言模型恰好可以:

  • 同一个 prompt 采样多条 CoT / 多个程序几乎零边际成本(batch 生成);
  • verifier 自动判分,无需人工;
  • 「同一道题的其他回答」就是「这个 state 的平均水平」的无偏样本——组内均值$\operatorname{mean}(R)$正是$V(s)$的蒙特卡洛估计。

于是 value model 的两大成本(显存翻倍、稀疏信号下难训练)被一次多采样替代。这也呼应了上一讲 Bradley-Terry 的观察:reward 只有相对比较才有意义,绝对值无意义——GRPO 把这个原则直接实现成了算法。

提示

GRPO 像考试的「曲线给分」(grading on a curve):你的更新信号不是绝对分数,而是「比同题的其他 G-1 份答卷好多少」。这自动解决了「题目难度不同导致 reward 不可比」的问题——难题的 2 分可能比简单题的 9 分更值得奖励。这正是 Lecture 17 · 对齐 III:RL 实战 里 baseline 例子的算法化。

3.2 GRPO 的问题

讲义与后续工作(尤其 Dr. GRPO, 2025)指出了几处系统性偏差:

  • 除以 std 引入难度偏差(difficulty bias):太容易或太难的题目组内 reward 几乎相同,$\operatorname{std}$很小,除以它会把微小的 reward 差放大成巨大的 advantage——等于给「接近全对/全错的题」不成比例的梯度权重,且放大的是噪声;
  • 按长度归一化引入长度偏置(length bias):DeepSeekMath 目标里的$1/|y_i|$意味着一条错误的长回答,每个 token 分摊到的惩罚更小——模型学到「答错时把话说长一点更划算」,这是 R1 类模型回答越训越长的一个被低估的机械原因;
  • 零方差组浪费计算:某道题$G$条全对或全错时,所有$\hat A_i = 0$,这批 rollout 完全不产生梯度(后续 DAPO 等工作用动态采样过滤这类 prompt);
  • reward 稀疏时依旧难学:GRPO 只是省了 critic,没有解决「模型一次也做不对就没有任何学习信号」的冷启动问题——这正是各家 recipe 都需要 SFT 初始化或难度课程的原因。

Dr. GRPO 的修正很直接:去掉$1/|y_i|$长度归一化和$\operatorname{std}$归一化,只保留组内减均值(centering),在无偏性上更干净。


4. DeepSeek-R1:RLVR 的标志性案例

4.1 R1-Zero:纯 RL 能走多远?

DeepSeek-R1-Zero 是一个刻意极简的实验:从 base model(DeepSeek-V3-Base)直接做 GRPO,不做任何 SFT 初始化。奖励只有两条规则:

  • 正确性 reward:最终答案(数学)或测试结果(代码)判定;
  • 格式 reward:推理过程必须包在 <think>...</think> 标签里。

观察到的现象:训练过程中回答长度自发增长,出现反思、验证、换思路等行为,以及著名的「aha moment」(模型在推理中途写出「等等,我重新想想」式的自我纠正)。这说明长链推理行为可以纯靠 RL 激励涌现,不必先靠人类示范教会。

注意

不要把训练曲线上的现象过度神话。回答长度增长有多重来源:一部分确实是「更长的推理带来更高正确率」的正向选择,但另一部分可能只是 3.2 节所述目标函数的长度偏置(错误回答按 token 摊薄惩罚)。Dr. GRPO 论文专门论证:修掉偏置后,长度增长明显放缓而准确率不受损。「aha moment」也在 base model 的采样中就能偶尔观察到——RL 是放大了已有行为,不是无中生有。

R1-Zero 的遗留问题:推理轨迹可读性差、多语言混杂——这正是完整版 R1 要修的。

4.2 R1:完整的四阶段 pipeline

DeepSeek-R1 在 R1-Zero 的经验上构建了完整 recipe:

  1. 冷启动 SFT:用少量(数千条)精选的长 CoT 数据微调 base model,解决可读性与冷启动;
  2. Reasoning RL:GRPO 优化数学/代码等可验证任务(加语言一致性 reward 抑制混语);
  3. 拒绝采样 + 通用 SFT:用 RL 模型生成大量回答、筛出高质量样本,混合通用指令数据再做 SFT;
  4. 全场景 RLHF/RL:恢复聊天、安全等通用行为(回到 Lecture 15 · 对齐 I:SFT 与 RLHF 的偏好优化)。
flowchart LR
    BASE["Base model"] --> SFT["Cold-start long CoT SFT"]
    SFT --> RL["Reasoning RL / GRPO"]
    RL --> RS["Rejection sampling + General SFT"]
    RS --> POST["General RLHF"]
    RL --> DISTILL["Distill to smaller models"]

4.3 蒸馏:推理能力的廉价传播

R1 生成约 80 万条推理 traces,直接 SFT 到 Qwen/Llama 系列小模型上(不做 RL)。关键实验结论:

  • 蒸馏后的小模型推理能力大幅提升,优于对同规模小模型直接做 RL——小模型自己探索不出高质量推理模式,但模仿大模型的轨迹很有效;
  • 成本远低于跑完整 RL pipeline;
  • 但蒸馏本质是把 RL 搜索到的解的分布做模仿学习(回到 SFT 的范式),小模型未必获得继续自我改进的能力。

提示

RL 的角色可以理解为「昂贵的搜索」:在大模型的能力空间里找到长推理这个高回报区域。一旦找到,「结果」可以用便宜的监督学习复制传播。这就是为什么 R1 发布后开源社区能在几周内量产「R1 味」的小模型——搜索只需做一次,模仿可以无限次。


5. Kimi K1.5

Kimi K1.5 与 R1 同期发布(2025 年 1 月),路线相近但在长度控制与课程学习上着墨更多。

5.1 数据与 SFT 启动

RL prompt 集的构建被当作一等公民来处理:

  • 覆盖数学/代码等可验证任务,同时保证难度分布均匀、可准确判分;
  • 过滤太容易和太难的样本:模型采样 N 次全对的题(学不到东西)与全错的题(没有信号)都被剔除——这正对应 GRPO 零方差组的问题;
  • 排除容易被 verifier 误判、或容易靠猜(如选择题)拿分的题型,防止 reward hacking;
  • 用长 CoT SFT 做 warm-up,让模型先具备规划、评估、反思、探索等推理「原语」。

5.2 RL 与长度控制

Kimi 的 RL 目标不是标准 GRPO,而是带相对熵(KL)正则的在线策略镜像下降(online policy mirror descent)变体,同样不用 value network。此外它直面「CoT 越长越准但越贵」的现实:

  • 长度惩罚(length penalty):在正确回答中奖励较短者、惩罚过长者,逐步引入以免早期压制探索;
  • 课程学习(curriculum):从易到难推进采样难度;
  • 优先采样(prioritized sampling):按成功率反比采样,把预算集中在「还没学会但有希望」的题上;
  • long2short 蒸馏:用模型合并、最短正确回答的拒绝采样、长短对 DPO 等手段,把长 CoT 模型的能力压进短 CoT 模型,控制推理成本。

6. Qwen3:思考模式融合

Qwen3(2025 年 5 月)展示了 reasoning RL 如何被整合进一个产品级后训练流水线,四个阶段:

  1. Long-CoT 冷启动 SFT
  2. Reasoning RL(GRPO 类算法优化可验证任务);
  3. Thinking Mode Fusion(思考模式融合):把 thinking / non-thinking 两种行为用 SFT 合进同一个模型,靠 /think/no_think 标签在对话中动态切换是否展开思维链;
  4. 通用 RLHF:恢复聊天、指令遵循、安全等通用能力。

还引入 thinking budget:思考超过 token 预算时截断思维链、强制开始作答,让用户在延迟与质量之间连续调节——这本质上是把「测试时计算量」(test-time compute)变成一个可控旋钮。

关键的现实权衡(Qwen3 报告的消融明确给出):

  • reasoning RL 显著提升数学/STEM/代码;
  • 但后续通用 RLHF 阶段会稍微拉低纯数学/推理指标;
  • 最终产品必须在 reasoning、聊天、安全、推理成本之间取平衡——没有免费的午餐,单项 benchmark 最强的中间 checkpoint 通常不是发布的那个。

说明

对比三个 recipe 可以看到共同骨架:长 CoT SFT 冷启动 → 可验证任务 RL → 通用对齐收尾,差异在长度控制、课程设计与模式融合等工程细节。这个骨架如今几乎是所有 reasoning 模型的标准配方。


7. RL 系统为什么难?

与预训练「数据是静态的、训练循环是纯计算」不同,RLVR 需要一个在线闭环

  1. 采样 prompt batch;
  2. 当前 policy 生成多条回答(rollout);
  3. verifier 打 reward(可能要真的执行代码、跑判分脚本);
  4. 计算 advantage;
  5. 更新 policy;
  6. 同时维护 reference model、old policy 等多个模型副本。

每一环都有自己的瓶颈:

  • rollout 是推理 workload:自回归逐 token 生成,memory-bound(见 Lecture 10 · 推理),与训练的 compute-bound 特性完全不同——同一套硬件很难同时对两者高效,实践中常用 vLLM 等推理引擎跑 rollout、训练框架跑更新,两边定期同步权重;
  • 显存压力大:policy、reference、old policy(有时还有 value model)多份权重与优化器状态同时驻留,常常需要 Lecture 7 · 并行 I:基础 中的分布式技术来摆放;
  • 生成长度方差大:一批里有的回答几十 token、有的几万 token,负载不均导致 GPU 利用率低(长尾拖慢整批);
  • verifier 调度复杂:代码执行需要沙箱与超时控制,判分服务成为训练循环里的外部依赖;
  • on-policy 数据保质期短:policy 一更新,旧 rollout 就过期;推理引擎与训练引擎的数值实现差异还会引入隐性的 off-policy 偏差。

提示

预训练是「流水线灌数据」,RL 是「自己发球自己打」:训练数据由当前模型实时生产,质量由外部系统实时评判。任何一环(生成吞吐、判分延迟、权重同步)卡住,整个闭环就停转。这就是为什么 RLVR 的工程复杂度普遍高于预训练——不是 loss 难写,而是系统难转。


总结

mindmap
  root((RLVR))
    Motivation
      reward model noise
      verifiable correctness
    PPO
      policy ratio
      clip
      value model
      KL
    GRPO
      group samples
      group baseline
      no critic
      length bias
      difficulty bias
    Case Studies
      DeepSeek R1
      Kimi K1.5
      Qwen3
    Systems
      rollout
      verifier
      reference model
      on-policy data

关键要点

  1. RLVR 适合可自动判分任务
    - 数学、代码、格式、环境成功率;verifier 不可被「说服」,Goodhart 问题在正确性维度上消失,但适用面窄。

  2. GRPO 简化了 PPO
    - 用同 prompt 的$G$条回答的组内均值当$V(s)$的蒙特卡洛估计,省掉 value model 及其全部成本。

  3. GRPO 也有偏置和超参坑
    - std 归一化带来难度偏差、长度归一化带来长度偏置(Dr. GRPO 修正)、零方差组浪费计算。

  4. R1 的成功是 pipeline 成功,不只是一个 loss
    - 冷启动 SFT、reasoning RL、拒绝采样、通用对齐、蒸馏共同构成结果;R1-Zero 证明纯 RL 可行,R1 证明工程整合才实用。

  5. RL 系统很重
    - rollout 推理与训练的负载特性冲突、多模型副本、verifier 调度、on-policy 数据过期,系统复杂度高于预训练。

下一讲预告(Lecture 17 · 对齐 III:RL 实战

本讲讲了 RLVR 的大图和案例;下一讲用一个简化的排序任务把 policy gradient / GRPO 的机械过程逐行拆开:state/action/reward 的形式化、baseline 与 advantage、raw/centered/normalized rewards 的实验对比、KL 正则的实现、以及「old policy 必须冻结」这类隐蔽 bug。


复习自测

题目

PPO 需要 value model 是为了估计「当前 state 平均能拿多少 reward」作为 baseline。语言模型可以对同一 prompt 低成本采样$G$条回答,组内 reward 均值$\operatorname{mean}(\{R_j\})$就是$V(s)$的蒙特卡洛估计——「重置环境重试多次」在 LM 设置下是免费的,在机器人等经典 RL 中做不到,这是 GRPO 适合 LM 的根本原因。

题目

第一组:均值$0.5$,(总体)标准差$0.5$,故$\hat A = [+1, -1, -1, +1]$:两条正确回答被推高,两条错误回答被压低。第二组:均值$1$,所有$R_i-\operatorname{mean}=0$,advantage 全为 0,这批 rollout 不产生任何梯度——全对(或全错)的题对训练是纯浪费,所以 Kimi 过滤难度极端的题、DAPO 做动态采样。

题目

一是长度偏置:目标中对每条回答按$1/|y_i|$归一化,错误的长回答每 token 分摊的惩罚更小,模型学会「答错时写长一点」,导致回答长度虚增。二是难度偏差:advantage 除以组内 std,接近全对/全错的题 std 极小,微小 reward 差被放大成巨大梯度权重,等于系统性地过度加权极端难度的题并放大噪声。修正:只做减均值的 centering,去掉两种归一化。

题目

蒸馏更强。RL 本质是在模型自身能力空间里搜索高回报行为:小模型自己采样很难探索出高质量长推理(冷启动信号太稀疏),RL 无从强化;而大模型已经搜索到的推理轨迹可以通过 SFT 直接模仿,绕过搜索。代价是蒸馏模型学到的是解的分布而非搜索能力本身。

题目

RLVR 消除的是「奖励模型可被说服」这一类 hacking:单元测试与答案匹配不受花言巧语影响。但 verifier 本身是程序,有实现漏洞:答案抽取脚本判错、测试用例覆盖不全(模型硬编码样例输出)、选择题可以靠猜。此外格式 reward、长度归一化等 shaped 信号仍可被钻空子。所以 Kimi 要专门剔除易误判和易猜题型,reward 设计仍是安全关键环节。


参考资料