对应 Maps to:CMU 11-868 / 11-968 Large Language Model Systems(Spring 2026,Lei Li),Lecture 25 · Wed 4/15 · Efficient Reinforcement Learning System for LLMs(该讲未公开 slides);HW7(RLHF:奖励模型、类 VERL 的 RLHF 训练、评估)。 阅读材料:Mei et al. (2024) ReaLHF: Optimized RLHF Training for Large Language Models through Parameter Reallocation(后续版本题为 ReaL);Ouyang et al. (2022) Training language models to follow instructions with human feedback(InstructGPT);Schulman et al. (2017) Proximal Policy Optimization Algorithms;Sheng et al. (2025) HybridFlow: A Flexible and Efficient RLHF Framework(veRL);Shao et al. (2024) DeepSeekMath(GRPO);DeepSeek-AI (2025) DeepSeek-R1。 依据说明:原课这一讲没有公开 slides,本讲以阅读材料为主线,并对照 HW7 的作业说明(奖励模型的排序损失、类 VERL 的 PPO 训练器、训练前后奖励分布的比较、“胡言乱语拿高奖励”的提示)。ReaLHF 的数据流、基线、参数重新分配、执行计划、代价估计与 MCMC 搜索、实验数字取自 ReaLHF 论文第一版;GRPO 与 R1 的做法取自 DeepSeekMath、DeepSeek-R1 论文。本讲义的”已知真实偏好”的设置、在城市语言模型上的奖励模型 / PPO / GRPO 实验、奖励被钻空子的测量、ReaLHF 的玩具代价模型与搜索,都是本讲义自己设计的,不代表课堂上讲了什么;玩具代价模型的数字只说明取舍,不代表真实系统。 配套代码 Code:
code/lecture25/(5 个脚本 +rlhf.py、plans.py;复用第 19 讲的模型;1–60 秒) 预计阅读时间:3 小时(含运行代码)
0. 本讲导航 · How to read this lecture
0.1 学习目标 Learning goals
学完这一讲,你应该能够:
- 说出 RLHF 的三个阶段,画出一次 PPO 迭代的数据流:四个模型、六次调用、三种负载、它们的依赖。
- 推导奖励模型的排序损失(Bradley–Terry),理解”人类标注有噪声”对准确率的影响,以及奖励模型的盲区从哪来。
- 写出 PPO 在 RLHF 里的形式(带 KL 惩罚的逐 token 奖励、GAE、截断的代理损失),并用实验解释 KL 惩罚为什么必不可少。
- 说清楚 GRPO 怎样去掉价值模型,可验证的奖励为什么不会被钻空子。
- 解释 RLHF 系统的难点(生成与训练的负载截然不同、四个模型的显存、调用之间的依赖),比较对称、非对称的安排,说出 ReaLHF 的参数重新分配、执行计划和搜索。
0.2 先修与本讲范围 Prerequisites & scope
| 默认你已经会 Assumed | 本讲只给直觉,后面再展开 Previewed only |
|---|---|
| 数据 / 张量 / 流水线并行、ZeRO(第 14–18 讲) | 过程奖励模型、蒙特卡洛树搜索等推理时的强化学习 |
| 推理服务、KV 缓存、分页(第 22、24 讲) | 异步 RL(生成与训练流水线化、“离策略”修正) |
| 策略梯度的基本概念(REINFORCE、基线、优势) | DPO 等不用强化学习的偏好优化 |
| LoRA(第 23 讲) |
0.3 本讲地图 Map
§1 为什么要 RLHF:SFT → 奖励模型 → 强化学习
§2 RLHF 是一种什么样的负载:四个模型、六次调用、两种计算 ← 代码 01
§3 奖励模型:成对偏好、Bradley–Terry 排序损失、盲区 ← 代码 02
§4 PPO:带 KL 惩罚的奖励、GAE、截断的目标;奖励被钻空子 ← 代码 03
§5 GRPO 与 DeepSeek-R1:不要价值模型、可验证的奖励 ← 代码 04
§6 系统:对称与非对称的安排、ReaLHF 的参数重新分配与执行计划搜索、HybridFlow ← 代码 05
§7 小结 §8 常见误区 §9 练习 §10 延伸阅读 §11 下一讲预告
0.4 本讲的实验设置
为了能看清”奖励模型被钻空子”,rlhf.py 让”人类偏好”成为一个已知的函数:
- 一个句子如果属于城市语言(合语法),真实分数 = 好词个数 − 坏词个数(好词:sunny、beaches、music、parks、views、wine、food、coffee;坏词:rainy、snowy、windy、cloudy、humid、rain、snow、wind);
- 不属于城市语言的(胡言乱语、没说完),一律 −3。
提示是 [, 句子的第一个词],策略模型续写一句话(最多 16 个 token)。奖励模型只能通过成对比较学这个函数,就像真实的 RLHF 一样;但因为我们知道真实分数,可以随时检查”奖励模型的分数涨了,真实分数涨了没有”。
1. 为什么要 RLHF · Why RLHF
预训练让模型学会”接着写”,但”接着写”不等于”按人的意图回答”。InstructGPT 的流程有三个阶段:
- 有监督微调(SFT):在人写的示范回答上微调;
- 奖励模型(RM):让人对同一个提示的几个回答排序,训练一个模型给回答打分;
- 强化学习(RL):用 PPO 让策略模型生成奖励更高的回答,同时用 KL 惩罚拉住它,不让它离 SFT 模型太远。
HW7 走的就是后两步:先在 hh-rlhf 的人类偏好数据上训练奖励模型(Problem 1),再用一个类 VERL 的框架做 PPO(Problem 2),最后比较训练前后的奖励分布(Problem 3)。这一讲先把算法在一个小模型上从头跑一遍(§3–§5),再讨论系统怎样把它跑快(§6)。
2. RLHF 是一种什么样的负载 · The RLHF workload
2.1 四个模型、六次调用
一次 PPO 迭代要用到四个模型:策略(actor,要训练)、价值(critic,要训练)、参考(ref,冻结的初始策略,用来算 KL)、奖励(reward,冻结)。ReaLHF 把一次迭代写成六次”模型调用”组成的数据流(01 号脚本第 1 部分):
actor_gen(生成)──┬── ref_inf(推理)────┬── actor_train(训练)
├── reward_inf(推理)──┤
└── critic_inf(推理)──┴── critic_train(训练)
下一次迭代的 actor_gen 依赖这一次的 actor_train;critic_inf 依赖 critic_train
依赖是严格的;但三次推理彼此无关,两次训练彼此无关——这是”同时跑”的机会。
2.2 显存与两种计算
把四个模型都放在 GPU 上(要训练的按混合精度 Adam 16 字节 / 参数,只推理的 2 字节 / 参数):每个 7B 时约 252 GB,每个 70B 时约 2.5 TB(第 2 部分)——必须分布到很多块 GPU 上。
更麻烦的是负载截然不同(第 3 部分):
| 计算 | 算术强度(FLOPs / 字节) |
|---|---|
| 解码一步,批 8 / 64 / 512(7B) | 6.8 / 26.2 / 40.8 |
| 训练一个 65,536 token 的微批 | 约 24,576 |
A100 的平衡点约 156。生成要逐 token 解码几百上千步,是访存受限的(第 22、24 讲),它喜欢”每张卡读得少”、怕张量并行每层每个 token 的 all-reduce 延迟;训练是计算受限的,显存吃紧,要靠张量 / 流水线并行把模型切开。一种并行策略不可能同时适合两者。 所有调用都用”节点内张量并行 8、节点间流水线并行 2”时(第 4 部分的玩具代价模型,16 张 A100,512 个提示、提示 128 + 生成 896 个 token),一次迭代 67.3 秒:生成 20%、三次推理各 10%、两次训练各 25%——六次调用依次执行,能并行的也没有并行。
3. 奖励模型 · Reward modeling
3.1 Bradley–Terry 与排序损失
人类不擅长给回答打绝对分数,但擅长比较。设每个回答有一个潜在的分数 r,Bradley–Terry 模型假设
奖励模型 r_θ(一个语言模型的骨干 + 一个标量头,取最后一个 token 的输出)最大化标注的似然,就是 HW7 Problem 1 的排序损失:
两个性质:它只学相对分数(所有分数加一个常数,损失不变),PPO 也只关心差别;损失从 ln 2 ≈ 0.693(随机猜)开始下降。
3.2 有噪声的标注
02 号脚本第 1 部分用初始策略为每个提示采样两个回答,按 Bradley–Terry 用真实分数模拟标注:2000 对里 51.1% 是平局(两个回答真实分数相同,标注是抛硬币),分数不同的对里标注选中真实更好那个的比例只有 78.7%。真实的人类标注就是这样嘈杂。
训练(第 2 部分,学习率 3e-4、300 步):排序损失 0.677 → 0.601;验证集上与标注一致 57.2%。这看起来不高,但即使知道真实分数,能期望的一致率也只有约 64.6%(一半的对是抛硬币);只看真实分数不同的对,奖励模型选中真实更好那个的比例是 90.0%。(HW7 在真实的 hh-rlhf 数据上要求 60% 以上的验证准确率。)
3.3 盲区
初始策略几乎总是说出合语法的句子(99.1%),所以奖励模型的训练数据里几乎没有胡言乱语。第 3 部分把 200 个合语法的句子打乱词序:真实分数一律变成 −3,奖励模型给它们的平均分却几乎不变(−0.02 vs 原句 +0.04),44% 的句子打乱后分数反而更高。它学到的是”好词多就好”,从来没人教过它”不合语法就差”。奖励模型只在训练数据的分布上可靠;强化学习会把策略推到分布之外,去寻找这样的盲区。
4. PPO · Proximal policy optimization
4.1 RLHF 里的 PPO
把生成一个回答看成一个回合:状态是”提示 + 已生成的 token”,动作是下一个 token。InstructGPT 的奖励是
实现时把 KL 分到每个 token:r_t = −β·(log π(y_t | s_t) − log π_ref(y_t | s_t)),奖励模型的分数加在最后一个 token 上。然后:
- 价值模型给每个 token 一个基线 V(s_t);用广义优势估计(GAE)算优势:δ_t = r_t + γV(s_{t+1}) − V(s_t),A_t = δ_t + γλA_{t+1}(这里 γ = 1、λ = 0.95)。
- 策略用截断的代理目标更新若干轮:
截断让一批数据可以被重复用几轮,又不至于让策略一步走太远。 3. 价值模型回归到回报 A_t + V(s_t)。
这正是 §2 的六次调用:生成、参考 / 奖励 / 价值三次推理、策略与价值两次训练(rlhf.ppo_iteration;还多一次”用当前策略重新算对数概率”,ReaLHF 把它并在生成里)。
4.2 KL 惩罚:一根安全绳
03 号脚本(每轮 64 个提示,60 轮):
| 奖励模型分数 | 真实分数 | 合语法 | KL | |
|---|---|---|---|---|
| 训练前 | +0.22 | +0.16 | 98% | 0 |
| PPO,β = 0.1,第 59 轮 | +0.95 | +0.94 | 98% | 1.68 |
| PPO,β = 0,第 59 轮 | +1.28 | −1.56 | 36% | 18.3 |
β = 0.1 时奖励模型的分数和真实分数一起上涨——这就是 HW7 期望看到的”奖励明显提高、训练前后的奖励分布明显不同”。去掉 KL 惩罚(β = 0),奖励模型的分数涨得更高,真实分数却崩了:策略学会了说”boston who read on weekends nice food .”、“pittsburgh engineers from austin who read on weekends love the coffee .”这样的句子——每个片段都来自真实的句子、带着好词,整体却不合语法,正好落在奖励模型的盲区里。这就是奖励被钻空子(reward hacking),也是 HW7 提醒的”胡言乱语拿高奖励”。
KL 惩罚把策略拴在参考模型附近:参考模型说不出的话,每个 token 都要付很大的 KL 代价。即便有 KL,RL 也会把概率集中到少数高分的回答上:64 个回答里不同的句子从训练前的 51 个降到 36 个(β = 0 时 20 个)——模式坍缩,多样性下降。
4.3 每次调用花多少时间
03 号脚本第 3 部分(⏱,本机 CPU,β = 0.1 的 60 轮):两次训练约占 79%,生成只占约 9%。这与真实的 RLHF 不同:我们的回答平均不到 10 个 token、模型很小、CPU 上解码也是计算受限的;真实场景里回答有几百上千个 token,在 GPU 上逐个解码访存受限,生成的占比要大得多,而且四个模型都有几十 GB。
5. GRPO 与 DeepSeek-R1 · Dropping the critic
5.1 GRPO:组内比一比
价值模型通常和策略一样大,而且要训练(16 字节 / 参数)。DeepSeekMath 提出的 GRPO(Group Relative Policy Optimization)干脆不要它:对同一个提示采样一组 G 个回答,用组内奖励的均值和标准差把奖励标准化成优势,回答里每个 token 用同一个优势:
“同一个提示的几个回答之间比一比”代替了价值模型的基线。KL 不再加进奖励,而是作为损失里的一项,用 k3 估计 π_ref/π − log(π_ref/π) − 1(总是 ≥ 0)。
04 号脚本(GRPO 每轮 16 个提示 × 4 个回答 = 64 个回答,与 PPO 相同):
| 做法 | 第 40 轮真实分数 | 第 59 轮:奖励 / 真实 / 合语法 | 模型数 | ⏱ 60 轮 |
|---|---|---|---|---|
| PPO,奖励模型,β = 0.1 | +1.00 | +0.95 / +0.94 / 98% | 4 | 16.1 秒 |
| GRPO,奖励模型,β = 0.1 | +0.94 | +1.16 / +0.66 / 92% | 3 | 9.2 秒 |
| GRPO,规则奖励,β = 0.1 | +0.95 | +0.97 / +0.97 / 100% | 2 | 8.8 秒 |
| GRPO,奖励模型,β = 0 | −0.06 | +1.09 / −0.39 / 66% | 3 | 9.3 秒 |
GRPO 和 PPO 一样能把真实分数提上去,省掉了价值模型的推理和训练;用奖励模型时同样会被钻空子(β = 0.1 到第 59 轮已开始出现苗头,β = 0 时彻底被钻)。代价是每个提示要生成一组回答(DeepSeekMath 每题采样 64 个)——生成的负担更重了。
5.2 可验证的奖励
第三行用”规则”直接算奖励(就是 true_score 本身):没有可以钻的空子,奖励就是我们真正想要的东西。DeepSeek-R1-Zero 正是这样做的:数学题看最终答案对不对、代码看能不能通过测试,再加上”把推理过程放在规定的标签里”这类格式奖励;论文明确说不用神经网络奖励模型,因为它在大规模 RL 中会被钻空子。代价是只适用于结果能自动验证的任务;聊天、写作这类开放任务仍然需要奖励模型和 KL 惩罚。
6. 系统:怎样把 RLHF 跑快 · RLHF systems
6.1 现有的两种安排
ReaLHF 论文把当时的系统分成两类:
- 对称(DeepSpeed-Chat):每个模型都放在全部 GPU 上,用 ZeRO-3 数据并行;生成时由 Hybrid Engine 临时换成张量并行。问题:对于不需要那么多卡的模型过度并行,同步和通信开销大;切换是临时的、不支持更灵活的张量 / 流水线并行。
- 非对称(OpenRLHF):GPU 分成互不相交的几组,每个模型各占一组,另有一组专门用 vLLM 做生成;每次迭代后把策略的参数同步给生成引擎。问题:调用之间的依赖让很多组 GPU 在等。
05 号脚本的玩具代价模型(16 张 A100、四个 7B 模型):非对称的安排只有 34% 的时间 GPU 在忙,一次迭代 109.6 秒;对称、启发式(所有调用都用全部 GPU,节点内张量并行、节点间流水线并行)100% 忙碌,但每次调用被迫用同一种切法:61.8 / 67.3 秒。
6.2 ReaLHF:每次调用各选各的
ReaLHF 的回答是参数重新分配(parameter reallocation):在运行时把一个模型的参数在不同的设备网格之间搬来搬去,于是每次调用都可以有自己的网格 D_i 和三维并行策略 S_i = (dp, tp, pp)。一个执行计划就是给六次调用各指定 (D_i, S_i),外加必要的参数搬运(把数据流图扩展成带”搬运节点”的图)。几个要点:
- 搬运:设备之间先重新映射流水线的各段,再给每个目标 GPU 找通信代价最低的源,并行广播;也可以在主机和设备之间卸载。论文里参数搬运平均只占 2.2% 的 GPU 时间。
- 代价估计:先对每层做性能剖析(一个模型不到 4 分钟),没测过的大小插值;再用就绪队列模拟整个时间线(考虑网格重叠),同时估计峰值显存。评估一个候选计划只要几百微秒;27 次试验里估计误差不超过 28%。
- 搜索:执行计划的空间巨大,用 Metropolis–Hastings 的 MCMC:目标分布 ∝ exp(−β·cost),每步随机改一个调用的网格和策略;放不下的计划乘以很大的惩罚;从贪心得到的计划出发,记下见过的最好的。
05 号脚本按同样的思路(玩具代价模型)搜索了 20,000 步(约 0.7 秒):
| 安排(16 卡,四个 7B) | 每次迭代(模型估算) |
|---|---|
| 对称(ZeRO-3) | 61.8 秒 |
| 非对称 | 109.6 秒 |
| 启发式 | 67.3 秒 |
| 搜索出来的执行计划 | 41.5 秒(比启发式快 1.62 倍) |
搜索出来的计划里,生成用全部 16 张卡(dp 2、tp 8),三次推理各用不同的切法,策略训练和价值训练被放到两个节点上同时执行(时间线里两行重叠),参数重新分配只占每次迭代的 0.3%。换成 ReaLHF 论文的例子(7B 策略 / 参考 + 34B 价值 / 奖励,32 张卡):启发式 124.2 秒、搜索 74.1 秒(1.68 倍),非对称的 34B 价值模型只分到 4 张卡、放不下。
要诚实地说这个玩具模型的局限:它让生成选择了张量并行 8,而 ReaLHF 论文的例子里生成用的是 (dp, tp, pp) = (8, 1, 2)——真实的解码里张量并行还有小矩阵乘效率低、内核启动、all-reduce 延迟等开销,玩具模型没有计入;它也让对称方案比启发式还快,而论文实测相反。结论依赖代价模型——这正是 ReaLHF 要先做性能剖析、再搜索的原因。
6.3 ReaLHF 的实测
论文在 16 个节点、128 张 A100 上用 LLaMA-2(7B 到 70B,最多 4 × 70B)实验:
- 比 DeepSpeed-Chat、OpenRLHF 快 2.0–10.6 倍;比启发式平均快约 26%(个别情况更多)。
- 70B 策略 + 70B 价值模型的训练时间(估计 4 × 400 次迭代):DeepSpeed-Chat 141.5 小时、OpenRLHF 152.8 小时、启发式 21.2 小时、ReaLHF 17.0 小时。
- 7B 策略 + 34B 价值的例子(生成 896 个 token):策略生成用 (8, 1, 2)——多用数据并行、不用张量并行;策略训练用 (2, 1, 8)——主要是流水线并行;价值模型的训练和推理放在另外两个节点上,与相邻迭代的策略生成重叠;比启发式快 42%。
(论文的后续版本改名为 ReaL,在 H100 上报告相对基线最多 3.58 倍。)
6.4 HybridFlow / veRL
HW7 要实现一个”类 VERL”的框架。veRL 是 HybridFlow 论文的开源实现,它的设计思路与 ReaLHF 相近、侧重编程模型:
- 混合的编程模型:用”单控制器”写模型之间的数据流(一个 Python 程序依次调用”生成""推理""训练”,像写普通的 RL 算法一样),每个模型内部的分布式计算用”多控制器”执行(每张卡一个进程,SPMD)。改 RL 算法时只改单控制器的那几行。
- 3D-HybridEngine:策略模型在训练和生成之间切换并行布局时,零冗余地重新切分参数(训练用的张量 / 流水线切法与生成用的不同)——这就是 ReaLHF 的参数重新分配在同一组 GPU 上的特例。
- 自动的设备映射:搜索每个模型放在哪些 GPU 上。论文报告相对已有系统 1.53–20.57 倍的吞吐提升。
R1 之后,GRPO 一类算法让”每个提示生成一组很长的回答”成为常态,生成成了瓶颈。新的系统(veRL、OpenRLHF、ReaL 等)普遍把 vLLM / SGLang 这样的推理引擎接进来做生成(第 22、24 讲的技术全都用得上),并在生成和训练之间快速重新切分参数;更进一步的工作把生成和训练流水线化(异步 RL),代价是策略的数据稍微”过时”,需要算法上的修正。
7. 小结 · Summary
- RLHF = 奖励模型 + 强化学习 + KL 惩罚。 奖励模型用 Bradley–Terry 排序损失从成对偏好里学相对分数;PPO 用带 KL 惩罚的逐 token 奖励、价值模型的基线、GAE 和截断的目标优化策略。
- 奖励模型只在训练数据的分布上可靠。 没有 KL 惩罚,策略会钻它的盲区(真实分数 +0.16 → −1.56,奖励模型的分数却一路上涨);有了 KL,也要警惕模式坍缩。
- GRPO 去掉价值模型,用组内标准化的奖励当优势;可验证的奖励(R1-Zero)没有可钻的空子,但只适用于能自动判对错的任务。
- RLHF 是一种混合负载:四个模型、六次调用,生成访存受限、训练计算受限,依赖严格。一种并行策略用到底必然有调用吃亏;固定分组又让 GPU 等待。
- ReaLHF:每次调用各选网格和 (dp, tp, pp),运行时重新分配参数(开销约 2.2%),用性能剖析的代价模型 + MCMC 搜索执行计划;比已有系统快 2.0–10.6 倍。HybridFlow / veRL 用单控制器 + 多控制器的编程模型和 3D-HybridEngine 达到类似的目的。
8. 常见误区 · Common pitfalls
- “奖励模型的分数越高,模型越好。” 奖励模型只是人类偏好的近似;它的分数涨了,真实质量可能在下降(03 号脚本)。必须同时看 KL、看样本、做独立的评估。
- “KL 惩罚只是为了稳定训练。” 它更重要的作用是把策略留在奖励模型可靠的区域里,防止被钻空子。
- “奖励模型的准确率只有 57%,说明它没用。” 标注本身有噪声(一半是平局);与真实偏好的一致性(90%)才是关键。
- “GRPO 比 PPO 便宜,所以总是更好。” 它省掉了价值模型,却要为每个提示生成一组回答;用神经网络奖励模型时同样会被钻空子。
- “RLHF 的瓶颈就是训练。” 真实规模下,长回答的生成(访存受限)常常占很大比重;而且调用之间的依赖和并行策略的错配会让 GPU 大量空转。
- “把每个模型放在自己的一组 GPU 上就能并行。” 依赖让它们大部分时间在等(玩具模型里只有 34% 的时间在忙)。
- “参数重新分配太贵,不值得。” ReaLHF 测到它平均只占 2.2% 的 GPU 时间,换来每次调用都能用合适的切法。
9. 练习 · Exercises
- 写出一次 PPO 迭代的六次调用和它们的依赖。哪些可以并行?跨迭代的依赖有哪两个?
- 奖励模型的排序损失对所有分数加一个常数不变。这对 PPO 有什么影响?为什么实践中常把奖励标准化?
- 一个标注集里 50% 的对是平局(标注抛硬币),另外 50% 的对标注以 80% 的概率选对。一个完美知道真实分数的奖励模型,与标注的一致率是多少?
- 推导 GAE 在 λ = 1、γ = 1 时退化成什么?λ = 0 时呢?
- PPO 的截断代理损失里,如果优势 A > 0、比值 ρ 已经大于 1 + ε,梯度是多少?为什么要这样设计?
- 为什么 KL 惩罚能防止”胡言乱语”这种钻空子?如果参考模型本身就经常说胡言乱语呢?
- GRPO 里如果一组的 G 个回答奖励完全相同,优势是多少?这组数据对训练有贡献吗?
- 估算:70B 的策略和价值模型都要训练、参考和奖励模型只推理,用混合精度 Adam,至少要多少 GB 显存(不含激活)?
- 为什么生成喜欢更多的数据并行,而训练喜欢张量 / 流水线并行?用算术强度和显存解释。
- ReaLHF 的 MCMC 搜索为什么要以一定概率接受”更差”的计划?如果只接受更好的会怎样?
参考答案
- actor_gen → {ref_inf, reward_inf, critic_inf} → {actor_train, critic_train}。三次推理彼此可以并行,两次训练彼此可以并行。跨迭代:下一次的 actor_gen 依赖这一次的 actor_train;下一次的 critic_inf 依赖这一次的 critic_train。
- 加常数不改变比较,但改变 PPO 里奖励的绝对大小:它与 KL 惩罚 β·KL 相加,常数会改变”奖励与 KL 的相对权重”,也影响价值模型要拟合的尺度。实践中常减去均值、除以标准差(或减去参考回答的分数)让奖励的尺度稳定。
- 平局部分 50% × 50% = 25%;非平局部分 50% × 80% = 40%;合计 65%。(02 号脚本算出的上限 64.6% 就是这样来的。)
- λ = 1、γ = 1:A_t = Σ_{k ≥ t} r_k − V(s_t),即蒙特卡洛回报减基线(方差大、无偏)。λ = 0:A_t = r_t + V(s_{t+1}) − V(s_t),一步 TD 误差(方差小、依赖价值模型的准确性)。
- A > 0 且 ρ > 1 + ε 时,min 取到被截断的那一项 (1 + ε)A,它对参数的梯度为 0。也就是说:这个动作的概率已经比旧策略高出 ε 以上,就不再继续推高它——防止一批数据把策略推得太远(“近端”)。
- 胡言乱语在参考模型下概率极低,log π − log π_ref 很大,每个 token 都要付 β 倍的代价,抵消了奖励模型给的那点分数。如果参考模型本身就常说胡言乱语,KL 就拦不住——所以参考模型通常是一个好的 SFT 模型。
- 分子为 0,优势全为 0(实现里分母加了一个小数防止除以 0);这组数据对策略梯度没有贡献,只通过 KL 项起作用。所以 GRPO 喜欢”有难度但能做对一部分”的题:全对或全错的组都浪费了生成。
- 策略、价值各 70B × 16 = 1120 GB,参考、奖励各 70B × 2 = 140 GB,合计 2520 GB。
- 解码的算术强度很低(每步每个序列一个 token),瓶颈是读权重和 KV 缓存;数据并行让每个副本只处理一部分序列、不需要层内通信,张量并行虽然也减少每卡读的权重,但每层每个 token 都要 all-reduce,几百步解码里延迟累积。训练的算术强度很高、显存需求 16 字节 / 参数,必须切开模型才放得下,张量 / 流水线并行把参数和激活分到多张卡上,而大块的矩阵乘能摊薄通信。
- 代价函数有很多局部最优(例如某个调用换网格会暂时变慢,但为别的调用腾出了重叠的机会)。只接受更好的计划会卡在第一个局部最优里;以 exp(−β·Δcost) 的概率接受更差的计划,让搜索能翻过”小山坡”,β 控制翻越的意愿。
10. 延伸阅读 · Further reading
- ReaLHF / ReaL:Mei et al. (2024),代码 github.com/openpsi-project/ReaLHF。
- InstructGPT:Ouyang et al. (2022);PPO:Schulman et al. (2017);GAE:Schulman et al. (2016)。
- HybridFlow / veRL:Sheng et al. (2025),代码 github.com/volcengine/verl(HW7 的”类 VERL”框架)。
- DeepSpeed-Chat:Yao et al. (2023);OpenRLHF:Hu et al. (2024)。
- GRPO:Shao et al. (2024) DeepSeekMath;DeepSeek-R1:DeepSeek-AI (2025)。
- 奖励被钻空子:Gao et al. (2023) Scaling Laws for Reward Model Overoptimization。
- 不用强化学习的偏好优化:Rafailov et al. (2023) Direct Preference Optimization(DPO)。
11. 下一讲预告 · Next lecture
RLHF 系统的教训是:不同的计算阶段需要不同的资源和并行策略。推理服务里也有同样的问题:预填充(一次处理整个提示)是计算受限的,解码(逐 token 生成)是访存受限的,把它们放在同一块 GPU 上会互相拖累——预填充让正在解码的请求卡顿(第 22 讲 §3.4 的”混合步”),解码让预填充的 GPU 算力闲置。第 26 讲讲 DistServe 与 NVIDIA Dynamo:把预填充和解码分开部署,各自选并行策略,用 goodput(满足时延目标的吞吐)来衡量,代价是在两组 GPU 之间传输 KV 缓存。