附录 A · 术语与定义
全书的符号表与术语速查手册:每个记号的数学形式、中英文名、量纲与形状、首次出现的章节,外加优势函数、KL 估计器、on-policy 三个高频卡点的展开解释。
0. 这一页怎么用
这是全书唯一一页不需要按顺序读的内容。它的设计目标只有一个:当你在第 6 章看到 $\hat A_t^{\mathrm{GAE}(\gamma,\lambda)}$、在第 8 章看到 $\beta\log\frac{\pi_\theta}{\pi_{\text{ref}}}$、在第 15 章看到 $k_3$ 时,能在三十秒内查到「这个符号是什么、量纲是什么、在哪一章被定义」,然后跳回去继续读。
它做了三件正文里做不了的事。一,把符号按「概念族」而不是按章节重排——四张表分别覆盖语言模型与文本、强化学习基础、概率与信息论、RLHF 专有,正好对应你读一篇后训练论文所需的四类背景。二,给出量纲和张量形状;论文从不写「$r$ 是标量、$A_t$ 是长为 $|y|$ 的向量、$\rho_t$ 是逐 token 的比值」,而这恰恰是把公式翻成代码时唯一会出错的地方。三,把三个最容易读错的概念单独展开:优势函数(第 4 节)、KL 的三种估计器(第 6 节)、on-policy 与 off-policy(第 8 节)。
如果只记七个符号,记这七个,它们能覆盖本书 90% 的公式:
- $x$ — prompt(输入),$y$ — completion(模型生成的回复),$y_t$ — 回复的第 $t$ 个 token。
- $\pi_\theta(y\mid x)$ — 策略,就是正在训练的语言模型本身;$\theta$ 永远指它的参数。
- $\pi_{\text{ref}}$ — 参考模型,冻结不动的权重快照,通常就是 SFT 检查点。
- $r_\phi(x,y)$ — 奖励模型给整条回复打的标量分;$\phi$ 是它的参数,跑 RL 时不更新。
- $A$ — 优势,「这个样本比同批次的平均水平好多少」,策略梯度的乘子。
- $\mathcal{D}_{\text{KL}}(\pi_\theta\|\pi_{\text{ref}})$ — 策略离参考模型有多远,用来做正则。
- $\beta$ — KL 惩罚的系数(在 DPO 里含义不同,见第 10 节的陷阱表)。
整本书的目标函数都可以塞进同一个模板:$\max_\theta\ \E_{x\sim\mathcal{D},\,y\sim\pi_\theta}[r_\phi(x,y)] - \beta\,\mathcal{D}_{\text{KL}}(\pi_\theta\|\pi_{\text{ref}})$。剩下的十几章都在回答「这个式子怎么解」。
1. 语言模型速览:本书的建模对象
全书所有算法都作用在同一类对象上:一个自回归语言模型。所谓自回归(autoregressive),意思只有一句话——每一步的预测都只依赖它前面的东西。给定一串 token $x=(x_1,\dots,x_T)$,模型把整串的联合概率拆成条件概率的连乘:
$$ P_\theta(x) = \prod_{t=1}^{T} P_\theta(x_t \mid x_1,\dots,x_{t-1}). $$训练目标是让训练数据在当前模型下的似然最大,等价于最小化负对数似然(negative log-likelihood, NLL):
$$ \mathcal{L}_{\text{LM}}(\theta) = -\,\E_{x\sim\mathcal{D}}\left[\sum_{t=1}^{T}\log P_\theta(x_t\mid x_{<t})\right]. $$实现上这就是逐位置的交叉熵损失:把该位置预测出的整个词表分布,和「真实的下一个 token」这个 one-hot 标签比较。因为标签是 one-hot,词表上的求和塌缩成一项,交叉熵就退化成 $-\log P_\theta(x_t\mid x_{<t})$ 本身。「预测下一个 token」就是监督学习,标签只不过是序列里的下一个字。
从隐状态到 token:LM head、logits、softmax
现代语言模型(ChatGPT、Claude、Gemini)几乎全部是 decoder-only Transformer,核心机制是自注意力(self-attention):每个位置只能注意到自己和它之前的位置,这个「因果掩码」正是自回归性质的物理实现。Transformer 主干对每个 token 输出一个隐状态(hidden state)向量,然后:
- LM head:一个线性投影,把隐藏维度映射回词表维度(tokenizer 空间),输出 logits——词表上每个 token 一个未归一化的分数。
- softmax:把 logits 归一化成下一个 token 的概率分布,$P_\theta(x_t\mid x_{<t}) = \softmax(z^{(t)})_{x_t}$。
- 采样 / argmax:从这个分布里取出实际生成的 token。
「同一个主干、换一个 head」是本书反复出现的模式。第 5 章训奖励模型时,做法就是把 LM head 换成一个输出单个标量的线性头;PPO 的价值模型是同样的套路。换 head、换目标,主干不动——这是理解奖励模型架构最省事的一句话。
两个理由,都很实际。数值稳定性:几百个小于 1 的概率连乘会直接下溢成 0,取对数后连乘变成求和,量级从 $10^{-200}$ 变成 $-460$。可导性:求和比连乘好求导得多。所以从 SFT 的交叉熵、到 DPO 的 $\log\frac{\pi_\theta}{\pi_{\text{ref}}}$、到 PPO 的重要性采样比 $\exp(\log\pi_\theta - \log\pi_{\theta_{\text{old}}})$,代码里流动的永远是 log-prob。你在后训练代码里看到的 logsumexp、log_softmax、logsigmoid,全是同一个动机。
一条训练样本的张量解剖
后训练代码里最常见的静默 bug 都出在下标错位上。把整条路径按形状写一遍,以后看任何实现都能对上号($B$ = batch,$L$ = 序列长度,$V$ = 词表大小):
input_ids # (B, L) token ID,prompt + completion 拼在一起
-> model(input_ids).logits # (B, L, V) 每个位置一个词表打分向量
-> logits[:, :-1, :] # (B, L-1, V) 丢掉最后一位:它没有"下一个 token"可预测
-> labels = input_ids[:, 1:] # (B, L-1) 错一位:位置 t 的 logits 预测 token t+1
-> log_softmax + gather # (B, L-1) 读出每个"真实下一个 token"的 log 概率
-> (* completion_mask).sum(-1) # (B,) 每条序列一个 log pi(y|x)
那个「错一位」就是自回归本身。 而最后一步乘的 completion_mask 是后训练区别于预训练的地方:预训练每个 token 都进 loss,SFT 之后只有回复部分的 token 进 loss,prompt 只负责做条件。
因果 mask($(L,L)$ 下三角)内置在注意力里,是自回归性质本身,你不会碰它;padding mask($(B,L)$)让注意力忽略补齐用的 token,通常由 tokenizer 给;completion mask($(B,L)$)才是你天天写、也天天写错的那个。写错的后果:把 prompt 算进 loss,梯度浪费在你无法改变的输入上,模型学着「复述提问」;把 padding 算进 loss,直接在噪声上训练。最隐蔽的是忘了把 mask 也跟着错一位(mask[:, 1:])——指标看着正常,效果就是差一点点,极难查。
2. 符号表 · 语言模型与文本
这一组是「输入输出」层面的符号:文本、token、张量维度。它们在第 3 章被统一定下来,之后十四章不变。
| 记号 | 中文名 | 英文名 | 含义、形状与量纲 | 首次出现 |
|---|---|---|---|---|
| $x$ | 提示词 | prompt | 模型的输入文本。是一段 token 序列;从 prompt 数据集 $\mathcal{D}$ 里采样得到。RL 视角下它是「初始状态」 | 第 3 章 |
| $y$ | 回复 / 补全 | completion, response | 模型针对 $x$ 生成的输出文本,token 序列,长度记作 $|y|$。常写成 $y\mid x$ 强调它是条件生成的,奖励与概率也随之写成 $r(y\mid x)$、$P(y\mid x)$ | 第 3 章 |
| $y_t$ | 第 $t$ 个 token | token at step $t$ | 标量(词表索引,整数 $\in[0,|\mathcal{V}|)$)。在 RL 映射里它就是动作 $a_t$ | 第 3 章 |
| $y_{<t}$ | 前缀 | prefix | 第 $t$ 个 token 之前的所有 token。与 $x$ 拼起来构成状态 $s_t=(x,y_{<t})$ | 第 3 章 |
| $y^\star$ | 示范回复 | demonstration, reference completion | SFT 数据里给定的目标回复,人写的或强模型生成的。不是模型自己采样出来的——这一点决定了 SFT 的全部性质 | 第 4 章 |
| $\mathcal{V}$ | 词表 | vocabulary | tokenizer 的全部 token 集合,$|\mathcal{V}|\sim 10^5$(现代模型 32K–256K)。RL 视角下就是动作空间 $\mathcal{A}$ | 第 3 章 |
| $\mathcal{D}$ | 数据集 | dataset | 训练数据的分布。用下标区分用途:$\mathcal{D}_{\text{SFT}}$(指令数据)、$\mathcal{D}_{\text{pref}}$(偏好对)、$\mathcal{D}_{\text{prompt}}$(只有 prompt,用于 RL 采样) | 第 3 章 |
| $z$, $z^{(t)}$ | logits | logits | LM head 输出的未归一化打分,形状 $(V,)$(单位置)或 $(B,L,V)$(整个 batch)。无量纲,只有相对差有意义(整体加常数不改变 softmax) | 本附录第 1 节 |
| $\softmax(z)$ | softmax | softmax | $\softmax(z)_i = e^{z_i}/\sum_j e^{z_j}$,把 logits 变成词表上的概率分布,形状不变 | 本附录第 1 节 |
| $\log\pi_\theta(y\mid x)$ | 序列对数概率 | sequence log-prob | $=\sum_t\log\pi_\theta(y_t\mid x,y_{<t})$,形状 $(B,)$。典型值是几十到几百的负数,长度越长越负——这正是偏好优化里长度归一化反复出现的原因 | 第 3 章 |
| $B, L, V$ | 批大小 / 序列长度 / 词表大小 | batch, length, vocab | 整数。代码里张量维度的统一约定,全书的 shape 注释都按这三个字母写 | 第 3 章 |
| $T$(温度) | 采样温度 | temperature | $\softmax(z/T)$ 里的除数。$T\to 0$ 趋近贪心,$T>1$ 更发散。RL 训练时的采样温度会直接改变 rollout 分布,必须和算 log-prob 时用的温度一致,否则重要性采样比是错的 | 第 6 章 |
| — | 对话模板 | chat template | 把多轮消息(role + content)序列化成一串 token 的规则,含特殊 token(如 <|im_start|>)与生成起始标记。训练和推理必须用完全相同的模板,不然模型看到的分布对不上 | 第 4 章 |
| — | rollout / 生成 | rollout, generation | 用当前策略对一批 prompt 实际采样出回复的过程,也指采出来的这批数据。RL 训练里 rollout 通常占 60%–80% 的墙钟时间,因此有 vLLM/SGLang 这类推理引擎与异步 RL 系统 | 第 6 章 |
| — | completion mask | completion / loss mask | $(B,L)$ 的 0/1 张量,1 表示该位置是回复 token、要计入 loss。所有序列级量(log-prob、KL、优势)都要先乘它再求和 | 第 4 章 |
$T$ 这个字母在本书里被两个完全不同的东西占用:RL 章节里 $T$ 是时间步上限(轨迹长度 / horizon),采样章节里 $T$ 是温度。原书沿用了两个领域各自的惯例,没有统一。判断方法很简单:看它出现在 $\sum_{t=0}^{T}$ 里还是出现在 $\softmax(\cdot/T)$ 里。本页的第 3 节表里 $T$ 一律指 horizon。
3. 符号表 · 强化学习基础
强化学习的标准问题形式是马尔可夫决策过程(Markov Decision Process, MDP),一个五元组 $(\mathcal{S},\mathcal{A},P,r,\gamma)$。下表左半边是通用 RL 定义,右半边是它在语言模型里退化成什么——「退化成什么」这一列比定义本身更重要,因为 RLHF 的算法设计几乎全部由这些退化决定。
| 记号 | 中文名 | 英文名 | 含义、形状与量纲 | 在语言模型里是什么 | 首次出现 |
|---|---|---|---|---|---|
| $s_t\in\mathcal{S}$ | 状态 | state | 环境当前的完整配置 | $(x,y_{<t})$,即 prompt 加已生成前缀。状态空间随长度指数增长 | 第 3 章 |
| $a_t\in\mathcal{A}$ | 动作 | action | 智能体这一步做的决策 | 下一个 token $y_t$。动作空间 $=\mathcal{V}$,离散、$10^5$ 量级 | 第 3 章 |
| $P(s_{t+1}\mid s_t,a_t)$ | 转移动力学 | transition dynamics | 环境的性质,智能体改不了 | 确定性:把 token 拼到末尾。这条退化是 RLHF 一切简化的源头 | 第 3 章 |
| $r$, $r_t$ | 奖励 | reward | 标量,表示这一步(或这条轨迹)有多好 | 通常只在最后一个 token 处发放一次:奖励模型打分或验证器的 0/1 | 第 3 章 |
| $\gamma$ | 折扣因子 | discount factor | 标量 $\in[0,1]$,未来奖励的衰减率;$\gamma<1$ 保证无限时长求和收敛 | 通常取 $\gamma=1$(不折扣)。回复级奖励下打折会人为惩罚靠后的 token | 第 3 章 |
| $\pi$, $\pi_\theta(a\mid s)$ | 策略 / 策略模型 | policy | 从状态到动作分布的映射——注意是条件分布不是函数值,这个随机性就是探索的来源 | 语言模型本身:$\pi_\theta(y\mid x)=\prod_t\pi_\theta(y_t\mid x,y_{<t})$ | 第 3 章 |
| $\theta$ | 策略参数 | policy parameters | 被优化的那组权重。梯度永远写作 $\nabla_\theta$ | 正在训练的模型的全部权重($10^9$–$10^{12}$ 量级) | 第 3 章 |
| $\tau$ | 轨迹 | trajectory | $\tau=(s_0,a_0,r_0,\dots,s_T,a_T,r_T)$,一次完整交互 | 一次 rollout:一条 prompt + 一条完整回复 | 第 3 章 |
| $p_\pi(\tau)$ | 轨迹分布 | trajectory distribution | $\rho_0(s_0)\prod_t\pi(a_t\mid s_t)P(s_{t+1}\mid s_t,a_t)$ | 动力学项恒为 1,只剩 $\pi_\theta(y\mid x)$。序列概率因此可以精确计算,这是 KL 惩罚、重要性采样比、DPO 的共同前提 | 第 3 章 |
| $G_t$ | 回报 | return | $\sum_{k\ge 0}\gamma^k r_{t+k}$,从 $t$ 起的折扣奖励之和。标量 | $\gamma=1$ 且只有终止奖励时,$G_t = r$ 对所有 $t$ 相同 | 第 6 章 |
| $J(\theta)$, $J(\pi_\theta)$ | 期望回报(目标函数) | expected return, objective | $\E_{\tau\sim p_{\pi_\theta}}\big[\sum_t\gamma^t r_t\big]$,标量。被最大化的量 | $\E_{x\sim\mathcal{D},\,y\sim\pi_\theta(\cdot\mid x)}[r_\phi(x,y)]$ | 第 3 章 |
| $V^\pi(s)$ | 值函数 / 价值函数 | value function | $\E\big[\sum_t\gamma^t r_t\mid s_0=s\big]$。「站在 $s$,按 $\pi$ 走下去平均能拿多少分」。标量,量纲同奖励 | PPO 里由一个独立的价值模型估计(又一个 head);GRPO/RLOO 直接不要它 | 第 3 章 |
| $Q^\pi(s,a)$ | Q 函数 / 动作值函数 | Q-function, action-value | $\E\big[\sum_t\gamma^t r_t\mid s_0=s,a_0=a\big]$。「先强行做 $a$,再按 $\pi$ 走」 | 很少显式使用——动作空间是整个词表,逐动作估值不现实 | 第 3 章 |
| $A^\pi(s,a)$ | 优势函数 | advantage function | $Q^\pi(s,a)-V^\pi(s)$。相对量:正=优于平均,负=劣于平均。策略梯度的乘子 | bandit 视角下常直接取 $r-b$($b$ 是某种基线),见第 4 节 | 第 3 章 |
| $[\,\cdot\,]^{\pi}$, $d_\pi$ | 策略条件量 | policy-conditioned values | 上标 $\pi$ 不是装饰:$V,Q,A$ 全都依赖具体策略,策略一更新它们就失效。$d_\pi$ 指该策略诱导的状态分布 | 这就是 PPO 的价值模型永远在「追赶」策略的原因 | 第 3 章 |
| $\nabla_\theta J(\theta)$ | 策略梯度 | policy gradient | $\E\big[\nabla_\theta\log\pi_\theta(a\mid s)\,A(s,a)\big]$,形状同 $\theta$。不需要知道环境动力学——动力学项在取 log 后被梯度消掉 | 逐 token 的 $\nabla_\theta\log\pi_\theta(y_t\mid x,y_{<t})$ 乘上该 token 的优势 | 第 6 章 |
| $\rho_t(\theta)$ | 重要性采样比 | importance sampling ratio | $\pi_\theta(a_t\mid s_t)/\pi_{\theta_{\text{old}}}(a_t\mid s_t)$,形状 $(B,L)$,无量纲。$=1$ 表示完全 on-policy | 代码里是 exp(logp - logp_old);跑飞时会看到它远离 1 | 第 6 章 |
| $\varepsilon$ | 裁剪范围 | clip range | PPO 把 $\rho_t$ 裁到 $[1-\varepsilon,1+\varepsilon]$。典型 $0.1$–$0.2$,无量纲 | 裁剪的作用是「这个方向已经走够了就不再给梯度」 | 第 6 章 |
| $\lambda$ | GAE 混合参数 | GAE lambda | $\hat A_t^{\text{GAE}}=\sum_l(\gamma\lambda)^l\delta^V_{t+l}$ 里的几何权重,典型 $0.95$。$\lambda\to0$ 偏差大方差小,$\lambda\to1$ 反之 | 只在带价值模型的 PPO 里出现;GRPO 系没有这个超参 | 第 6 章 |
| $\delta_t^V$ | TD 残差 | TD residual | $r_t+\gamma V(s_{t+1})-V(s_t)$,标量。单步优势的最粗估计 | 终止奖励下,除最后一步外 $r_t=0$,$\delta_t$ 全靠价值模型的差分 | 第 6 章 |
| $G$ / $k$ | 组大小 | group size | GRPO / RLOO 里对同一个 prompt 采样的回复条数,典型 $4$–$64$。整数 | 组内均值当基线,$k$ 越大基线越准、算力越贵 | 第 6 章 |
RLHF 里的 MDP 被抽空了三样东西:奖励函数换成了学出来的模型、转移是确定性的(没有真正的环境)、奖励只在末尾发放且不折扣。结果是问题结构更接近 contextual bandit(上下文老虎机)而不是多步 MDP。这解释了为什么「丢掉价值模型、用一组样本的均值当基线」的 GRPO/RLOO 在语言模型上工作得很好,而同样的做法在 CartPole 上会失败——那里的多步信用分配是真问题,这里不是。
4. 展开:优势函数,以及「减基线」这件事
优势函数是全书出现频率最高、也最容易被当成黑盒的量。它的定义只有一行:
$$ A^\pi(s,a) = Q^\pi(s,a) - V^\pi(s), $$读作:「在状态 $s$ 做动作 $a$,比『按 $\pi$ 的平均水平随便做点什么』好多少」。注意它是一个相对量,量纲和奖励一样,但零点被移到了「当前策略的平均表现」上。
为什么不能直接用奖励
策略梯度的形式是 $\E[\nabla_\theta\log\pi_\theta(a\mid s)\cdot(\text{某个标量})]$。若那个标量直接取奖励 $r$,会出问题:假设某环境每步固定给 $+100$ 分,所有动作的乘子都是大正数,梯度会把所有动作的概率都往上推。但概率必须归一化,推不上去的部分互相抵消,剩下的全是噪声——信号被一个巨大的公共偏移淹没了。
减去一个只依赖状态、不依赖动作的基线(baseline)$b(s)$ 之后,乘子变成「比平均好还是比平均差」,方差大幅下降。而且这个减法是免费的——它不引入偏差:
$$ \E_{a\sim\pi_\theta(\cdot\mid s)}\big[\nabla_\theta\log\pi_\theta(a\mid s)\,b(s)\big] = b(s)\,\nabla_\theta\!\!\sum_{a}\pi_\theta(a\mid s) = b(s)\,\nabla_\theta 1 = 0. $$关键在于 $b(s)$ 与 $a$ 无关,可提到求和号外,而概率对所有动作求和恒为 1,梯度为 0。任何不依赖动作的基线都不改变梯度的期望,只改变方差。 方差最小的那个基线大致就是 $V^\pi(s)$,于是「奖励减基线」自然长成了优势函数。
四种在 RLHF 里真实使用的优势估计
| 估计方式 | 公式 | 基线是什么 | 代价 | 出处 |
|---|---|---|---|---|
| 纯 REINFORCE | $\hat A = r$ | 无 | 零额外成本,方差最大 | 第 6 章 |
| 移动平均基线 | $\hat A = r-\bar r$ | 历史奖励的滑动均值,标量 | 几乎为零;对 prompt 难度差异无能为力 | 第 6 章 |
| RLOO(留一法) | $\hat A_i = r_i - \frac{1}{k-1}\sum_{j\ne i} r_j$ | 同一 prompt 下其它 $k-1$ 条样本的均值 | 每 prompt 采 $k$ 条,无偏(留一避免了自相关) | 第 6 章 |
| GRPO(组内标准化) | $\hat A_i = \frac{r_i-\mathrm{mean}(\mathbf{r})}{\mathrm{std}(\mathbf{r})}$ | 同一 prompt 下包含自己的组均值,再除标准差 | 同上;除以 std 引入了偏差,但工程上很稳 | 第 6 章 |
| GAE(PPO 用) | $\hat A_t=\sum_l(\gamma\lambda)^l\delta^V_{t+l}$ | 学出来的价值模型 $V_\psi(s_t)$ | 多训一个和策略同规模的模型,显存翻倍 | 第 6 章 |
PPO 用一个学出来的模型去猜「这个 prompt 平均能得多少分」;GRPO 干脆直接采八条样本取实测均值。后者在语言模型上够用,正是因为第 3 节那个退化:奖励只在末尾发一次、转移确定,「每个中间状态的价值」本身就没什么信息量——同一 prompt 下所有 token 共享同一个优势值。既然如此,何必花一倍显存去学一个几乎处处相等的函数?把价值模型换成组内均值,省下的显存全部拿去加大 batch,这是 GRPO 真正的红利。
「组内标准化 = 更好的优势估计」——不一定。 除以组内标准差会让「8 条全对」和「8 条全错」的优势都变成 0(分子为零),梯度消失;这本身是对的,这类 prompt 确实没有学习信号。但它同时会放大接近全对/全错的组的梯度(分母极小),带来不稳定,所以有些实现只减均值、不除标准差。看到 $\mathrm{std}$ 出现在分母上,先问一句「组内方差很小时会发生什么」。
一个尺寸提醒
优势在代码里有两种形状:序列级 $(B,)$,每条回复一个数(GRPO/RLOO 的原生形态,用时要广播到每个 token);token 级 $(B,L)$,每个 token 一个数(GAE 的原生形态)。广播之后,一条 500 token 的回复会贡献 500 份相同的梯度,一条 50 token 的只贡献 50 份。损失怎么归一化(按 token 数、按序列数、还是按固定常数)因此会直接改变长度偏好——第 6 章第 9 节专门讲了这三种聚合方式,这是 2025 年 RL 实现里争论最多的细节之一。
5. 符号表 · 概率与信息论
这一组符号数量最少,但被引用得最频繁。KL 散度是对齐领域的中心对象:RLHF 的惩罚项是它、DPO 的推导起点是它、SFT 和 RL 的行为差异也要用它的方向来解释。
| 记号 | 中文名 | 英文名 | 含义、量纲与性质 | 首次出现 |
|---|---|---|---|---|
| $\mathcal{D}_{\text{KL}}(P\|Q)$ | KL 散度 | Kullback–Leibler divergence | $\sum_{x}P(x)\log\frac{P(x)}{Q(x)}$,标量,单位是 nat(用 $\ln$)或 bit(用 $\log_2$)。非负,且仅当 $P=Q$ 时为 0;不对称,$\mathcal{D}_{\text{KL}}(P\|Q)\ne\mathcal{D}_{\text{KL}}(Q\|P)$。注意期望是对左边那个分布取的 | 第 3 章 |
| $H(p)$ | 熵 | entropy | $-\sum_i p_i\log p_i$,标量,非负。分布的不确定性:均匀分布高、尖峰分布低。RL 训练里熵塌缩(entropy collapse)是模型停止探索的信号,常作为监控指标 | 第 6 章 |
| $H(p,q)$ | 交叉熵 | cross-entropy | $-\sum_i p_i\log q_i$。「用为 $q$ 设计的编码去编码来自 $p$ 的样本」的平均代价。语言模型的训练损失就是它 | 本附录第 1 节 |
| $\sigma(z)$ | sigmoid / 逻辑函数 | sigmoid, logistic | $1/(1+e^{-z})$,把实数压到 $(0,1)$。把分数差转成二元概率。$-\log\sigma(\cdot)$ 就是二元负对数似然 | 第 5 章 |
| $\succ$ | 偏好关系 | preference relation | $y_c\succ y_r$ 读作「$y_c$ 优于 $y_r$」。奖励模型预测的是这个关系的概率 $P(y_c\succ y_r\mid x)$ | 第 5 章 |
| $\rho$(比值) | 概率比 | probability ratio | 两个分布在同一样本上的概率之比,无量纲。KL 估计器里取 $\rho=\pi_{\text{ref}}/\pi_\theta$,PPO 里取 $\pi_\theta/\pi_{\theta_{\text{old}}}$。看到 $\rho$ 先确认分子分母是谁 | 第 6 章 |
| $k_1,k_2,k_3$ | KL 估计器 | KL estimators | 用采样近似 KL 的三种方式,见第 6 节。逐 token 标量,形状 $(B,L)$ | 第 15 章 |
| $Z(x)$ | 配分函数 | partition function | $\sum_y\pi_{\text{ref}}(y\mid x)\exp(r(x,y)/\beta)$,归一化常数。无法计算(要对所有可能的回复求和)——DPO 的全部精妙之处就在于它在相除时被消掉了 | 第 8 章 |
| $\E_{y\sim p}[\cdot]$ | 期望 | expectation | 下标写明对谁取期望、从哪个分布采样。这不是形式主义:$\E_{y\sim\pi_\theta}$ 要求现场生成(贵),$\E_{y\sim\mathcal{D}}$ 从固定数据集读(便宜) | 第 3 章 |
一个恒等式,把三个量串起来
$$ H(p,q) = H(p) + \mathcal{D}_{\text{KL}}(p\,\|\,q). $$「用错误分布 $q$ 编码来自 $p$ 的样本」的总代价 = 不可压缩的固有代价 $H(p)$ + 用错分布多付的额外代价 KL。两个推论直接解释了本书两处关键设计:
- 最小化交叉熵就是最小化到真实分布的 KL,因为 $H(p)$ 由数据决定、与参数无关。语言模型训练时标签是 one-hot,$H(p)=0$,于是交叉熵 = KL = NLL 三者完全相等。
- RLHF 里的 KL 则是被主动加上去的:不是为了拟合谁,而是为了把策略拴在参考模型附近。同一个数学对象,一个是目标,一个是约束。
重要性采样:为什么可以用旧数据算新梯度
策略梯度要求 $\E_{y\sim\pi_\theta}[\cdot]$——期望对当前策略取。但每更新一次参数就重新采样一遍太贵了,于是有了重要性采样(importance sampling)这个恒等式:
$$ \E_{y\sim p}\big[f(y)\big] = \E_{y\sim q}\left[\frac{p(y)}{q(y)}f(y)\right]. $$只要 $q$ 在 $p$ 的支撑集上处处非零,就可以用 $q$ 采的样本估计 $p$ 下的期望,代价是每个样本要乘一个修正权重 $p/q$。PPO 就是这么做的:用 $\pi_{\theta_{\text{old}}}$ 采一批 rollout,然后做好几步梯度更新,每步都用 $\rho_t=\pi_\theta/\pi_{\theta_{\text{old}}}$ 修正。
重要性采样在理论上无偏,但当 $p$ 和 $q$ 差得远时,$p/q$ 的方差可以任意大——少数几个样本拿到巨大权重,估计变得完全不可靠。这就是 PPO 必须 clip、异步 RL 必须做截断重要性采样(truncated IS)的原因。「$\rho$ 离 1 有多远」是判断一批数据还能不能用的核心指标:日志里 ratio 的均值和最大值应该是你最先看的两条曲线之一。
6. 展开:KL 的三种估计器 $k_1$、$k_2$、$k_3$
KL 的定义要对整个词表空间的所有序列求和,显然算不了。但 KL 本身是一个期望,凡是期望都可以用蒙特卡洛采样近似:
$$ \mathcal{D}_{\text{KL}}(\pi_\theta\,\|\,\pi_{\text{ref}}) = \E_{y\sim\pi_\theta}\left[\log\frac{\pi_\theta(y)}{\pi_{\text{ref}}(y)}\right] \approx \frac{1}{N}\sum_{i=1}^{N}\log\frac{\pi_\theta(y_i)}{\pi_{\text{ref}}(y_i)}. $$被求平均的东西,就是你手上已经有的每条 rollout 上的 log 概率比——不需要额外采样,这也正是 RLHF 标准写法用 $\mathcal{D}_{\text{KL}}(\pi_\theta\|\pi_{\text{ref}})$ 而不是反过来的工程原因(期望对 $\pi_\theta$ 取,而 rollout 恰好来自 $\pi_\theta$)。
令 $\rho = \pi_{\text{ref}}/\pi_\theta$(注意:参考模型在分子上),三种估计器是:
$$ k_1 = -\log\rho,\qquad k_2 = \tfrac{1}{2}(\log\rho)^2,\qquad k_3 = (\rho - 1) - \log\rho. $$| 估计器 | 是否无偏 | 是否恒 $\ge 0$ | 方差 | 典型用途 |
|---|---|---|---|---|
| $k_1 = -\log\rho$ | 无偏 | 否,单样本可为负 | 很大(可达真值的 8 倍以上) | 教科书写法;老代码库;只用于日志 |
| $k_2 = \tfrac12(\log\rho)^2$ | 有偏(两分布接近时偏差极小) | 是 | 小,比 $k_1$ 低一个数量级 | 少数实现;理论上是 KL 的二阶近似 |
| $k_3 = (\rho-1)-\log\rho$ | 无偏 | 是(逐 token 非负) | 小,与 $k_2$ 相当 | 当前开源实现的默认(配置里的 kl_estimator: kl3) |
为什么 $k_1$ 不够用
$k_1$ 按定义就是无偏的:$\E_{\pi_\theta}[-\log\rho]=\E[\log\frac{\pi_\theta}{\pi_{\text{ref}}}]=\mathcal{D}_{\text{KL}}$,一行推完。问题在于单个样本可以是负数——某个 token 上策略恰好比参考模型更不自信,$\log\rho$ 就是正的,$k_1$ 就是负的。一个数学上恒非负的量,它的估计值却在 0 附近来回穿越,意味着优化器有时会因为「离参考模型更远」而获得奖励。这在梯度上是纯噪声,训练曲线上表现为 KL 在 0 附近剧烈震荡。
无偏性。 注意 $\E_{y\sim\pi_\theta}[\rho] = \sum_y \pi_\theta(y)\frac{\pi_{\text{ref}}(y)}{\pi_\theta(y)} = \sum_y\pi_{\text{ref}}(y) = 1$。于是
$$ \E[k_3] = \underbrace{\E[\rho - 1]}_{=1-1=0} + \E[-\log\rho] = \mathcal{D}_{\text{KL}}(\pi_\theta\|\pi_{\text{ref}}). $$也就是说 $k_3$ 就是 $k_1$ 加上一个期望为零的控制变量(control variate) $\rho-1$。这是方差缩减的标准技巧:加一个不改变期望、但与被估量负相关的项,把噪声抵消掉。
非负性。 对任意 $\rho>0$ 都有 $\log\rho\le\rho-1$($\log$ 是凹函数,$y=\rho-1$ 是它在 $\rho=1$ 处的切线)。移项即得 $k_3\ge0$,等号仅在 $\rho=1$ 时成立。这是逐 token 成立的,不只是期望成立——所以你可以放心地 assert (kl >= -1e-6).all()。
# 改写自 _src/code/policy_gradients/loss.py
def approx_kl(logp, logp_ref, mask, estimator="k3"):
"""logp, logp_ref, mask: (B, L) —— 逐 token 的 log 概率与 completion mask"""
log_rho = logp_ref - logp # = log(pi_ref / pi_theta)
if estimator == "k1": # 无偏,高方差,可为负
kl = -log_rho
elif estimator == "k2": # 有偏,低方差,恒 >= 0
kl = 0.5 * log_rho.pow(2)
elif estimator == "k3": # 无偏 + 恒 >= 0(默认)
kl = log_rho.exp() - 1 - log_rho
else:
raise ValueError(estimator)
return (kl * mask).sum(-1) # (B,) —— 每条序列一个 KL
- $\rho$ 的方向反了。 $k_3$ 里参考模型在分子上:
log_rho = logp_ref - logp。写反了公式仍然能跑、数值也是正的,但估的是反向 KL,$\beta$ 的调参直觉全部失效。写完加一句 assert 检查非负性,符号反了会立刻炸。 exp会溢出。 当策略跑飞、$\log\rho$ 变成很大的正数时,$k_3$ 里的exp先给出inf,然后 loss 变nan。这其实是个有用的警报器——比训练悄悄退化好得多。- 忘了乘 mask。 把 prompt 部分的 KL 也算进去,等于在惩罚模型「对自己的输入更自信」,完全没有意义,而且 prompt 通常比回复长,这一项会主导数值。
KL 项还有第二个自由度:加在奖励里($\tilde r = r-\beta k_3$)还是加在损失里($\mathcal{L}=\mathcal{L}_{\text{PG}}+\beta k_3$)。前者要经过优势估计、白化等一系列处理,效果被稀释;后者直接、可控。第 15 章把两条路径的梯度都展开算了一遍,结论是现代实现基本都选后者。
7. 符号表 · RLHF 专有
这一组是本书真正的主场:它们在通用 RL 或 NLP 文献里都不存在,是 RLHF 为了「用人类偏好训模型」发明出来的。
| 记号 | 中文名 | 英文名 | 含义、形状与量纲 | 训练时更新? | 首次出现 |
|---|---|---|---|---|---|
| $r_\phi(x,y)$ | 奖励模型 | reward model (RM) | 输入 prompt + 完整回复,输出一个标量。$\phi$ 是它的参数(语言模型主干 + 标量头)。只有相对大小有意义——整体加常数不改变任何东西,所以「RM 打了 3.7 分」这句话本身没有信息 | 训 RM 时是;跑 RLHF 时否 | 第 5 章 |
| $\pi_{\text{ref}}$ | 参考模型 | reference model | 一份冻结的权重快照,用来正则化优化。通常就是 RL 开始前的 SFT 检查点。只做前向,用于算 log-prob。显存上是一整份模型的开销(可用 LoRA 或定期重算规避) | 否 | 第 3 章 |
| $\pi_{\theta_{\text{old}}}$ | 旧策略 / 行为策略 | old policy, behavior policy | 采出当前这批 rollout 的那个策略版本。与 $\pi_{\text{ref}}$ 完全不同:$\pi_{\text{ref}}$ 整个训练不变,$\pi_{\theta_{\text{old}}}$ 每个 rollout 批次都在更新 | 随 rollout 周期同步 | 第 6 章 |
| $\pi^\star$ | 最优策略 | optimal policy | KL 正则目标的闭式解,$\pi^\star(y\mid x)=\frac{1}{Z(x)}\pi_{\text{ref}}(y\mid x)\exp\!\big(\tfrac{1}{\beta}r(x,y)\big)$。这是 DPO 推导的核心对象 | — | 第 8 章 |
| $\beta$ | KL 系数 / DPO 温度 | KL coefficient | 两种含义:在 RL 目标里是 KL 惩罚的权重(典型 $0.01$–$0.1$,RLVR 常直接设 0);在 DPO 损失里出现在 log 比值内部,是隐式奖励的温度(典型 $0.05$–$0.1$)。无量纲 | 否(超参);有实现用自适应控制器 | 第 3 章 / 第 8 章 |
| $y_c$ / $y_w$ | 选中回复 | chosen, winning completion | 偏好对里被标注者选中的那条。token 序列。$w$ = winner,$c$ = chosen,两套记号在文献里混用 | — | 第 5 章 |
| $y_r$ / $y_l$ | 落选回复 | rejected, losing completion | 偏好对里没被选中的那条。$r$ 这个下标和奖励 $r$ 撞车,所以本书正文优先用 $y_w/y_l$ | — | 第 5 章 |
| $\hat r_\theta$ | 隐式奖励 | implicit reward | $\beta\log\frac{\pi_\theta(y\mid x)}{\pi_{\text{ref}}(y\mid x)}$,标量。DPO 的核心洞察:策略和参考模型的 log 比值本身就是一个奖励模型,不需要单独训一个 | 随策略一起变 | 第 8 章 |
| — | Bradley–Terry 模型 | Bradley–Terry | $P(y_w\succ y_l\mid x)=\sigma\big(r(x,y_w)-r(x,y_l)\big)$。把「谁更好」这个二元标注转成可微损失的桥梁,1952 年的统计模型 | — | 第 5 章 |
| $N$ | 候选数 | number of samples | 拒绝采样 / Best-of-N 里每个 prompt 采的候选条数,典型 $8$–$64$(Llama 2 用到 10–100)。整数。$N$ 越大隐含的 KL 代价越大(约 $\log N-\frac{N-1}{N}$) | — | 第 9 章 |
| — | 验证器 | verifier | 一段程序(不是模型)判断答案对错,输出 0/1。RLVR 的奖励来源。不可被「说服」,但可被钻空子(格式作弊、改测试) | — | 第 7 章 |
| $\psi$ | 价值模型参数 | value model parameters | PPO 里那个额外模型的权重。它拟合 $V^\pi$,损失是 MSE 到实测回报 | 是(与策略交替更新) | 第 6 章 |
三类模型,一张对照表
跑一次完整的 PPO 式 RLHF,显存里同时住着四份模型权重。这是理解 RLHF 工程成本最直接的一张表:
| 模型 | 记号 | 作用 | 需要梯度? | GRPO/RLOO 下是否还需要 |
|---|---|---|---|---|
| 策略 | $\pi_\theta$ | 被训练的模型,生成 rollout | 是 | 需要 |
| 参考模型 | $\pi_{\text{ref}}$ | 算 KL 惩罚的锚点 | 否,只前向 | 需要(除非 $\beta=0$,RLVR 常见) |
| 奖励模型 | $r_\phi$ | 给回复打分 | 否,只前向 | RLVR 下换成验证器,不需要 |
| 价值模型 | $V_\psi$ | 估计基线,供 GAE 使用 | 是 | 不需要——这是 GRPO 最大的省 |
把这张表和「后训练算力重心持续向 RL 迁移」的趋势放在一起看,就明白为什么 2024–2025 年算法演化的主线是做减法:DPO 砍掉了奖励模型和采样(只剩策略 + 参考模型);GRPO 砍掉了价值模型;RLVR 把奖励模型换成一段几十行的验证脚本,$\beta$ 常直接设 0 又砍掉了参考模型。剩下的算力全部喂给更大的 batch 和更长的训练。这不是理论上更优雅,是工程上更划算——而在一个「谁能多跑几倍 rollout 谁就赢」的阶段,划算就是优雅。
8. 展开:on-policy 与 off-policy 的两套用法
这对词是全书最容易被误读的术语,原因很简单:RL 圈和偏好微调圈在用同一个词说不同的事,而且两边都不觉得自己需要说明。
严格 RL 意义
在 RL 文献里,on-policy 意味着数据恰好由当前这一版智能体产生。参数一更新,之前采的数据就不再是 on-policy 的了。按这个标准:REINFORCE 采一批、走一步梯度、丢掉数据——严格 on-policy;PPO 采一批走 $1$–$4$ 步梯度,第一步之后就不是了,所以它需要重要性采样比 $\rho_t$ 修正、需要 clip 限制修正幅度,常被叫做 near-on-policy;用几周前某个检查点采的数据训现在的模型——彻底 off-policy。
偏好微调意义
在偏好微调(尤其是「DPO 到底比 PPO 差在哪」这场辩论)里,on-policy 被放宽成:数据是不是由「这一版模型」生成的——比如做偏好微调之前的那个指令微调检查点。此语境下 off-policy 指的是由别的语言模型生成的数据,比如你从 HuggingFace 下载的、用 GPT-4 和 Llama-2 生成的偏好数据集。
| 场景 | 严格 RL 判定 | 偏好微调圈的判定 | 实际影响 |
|---|---|---|---|
| REINFORCE,一批一步 | on-policy | on-policy | 方差大但无偏,理论最干净 |
| PPO,一批四步 | near-on-policy | on-policy | 必须做 IS 修正 + clip |
| 异步 RL,rollout 落后几步 | off-policy | on-policy | 需要截断 IS;落后越多越危险 |
| 用当前 SFT 模型现采的偏好对做 DPO | off-policy(参数已更新) | on-policy | 效果显著好于下载的数据集 |
| 用公开偏好数据集做 DPO | off-policy | off-policy | 分布不匹配,收益上限低 |
为什么这个区分值钱
因为它是「在线 RL vs 直接对齐算法」这场争论的真正焦点。表面上的问题是「PPO/GRPO 比 DPO 好吗」,但把两者的差异拆开会发现:DPO 用固定数据集,样本一次采好、之后策略怎么变都不再重采;在线 RL 每一轮都从当前策略重新采样,因此能持续获得「我现在最可能犯的错」的反馈。
真正的分水岭是数据是不是 on-policy,不是损失函数长什么样。 把 DPO 放进一个「每轮重新用当前策略采样、重新标注、再训一轮」的迭代循环里(iterative DPO / online DPO),它和在线 RL 的差距会大幅缩小。反过来,把 PPO 喂上固定的旧数据,它也会退化。第 8 章第 9 节完整讨论了这一点,第 11 章则从数据采集的角度说明为什么 on-policy 偏好数据是最硬的一条约束。
想象你在学下棋。off-policy 数据是别人(水平和你不同的人)下过的棋局:里面有很多你根本不会走到的局面,也缺了你现在最常犯的那些错。on-policy 数据是你自己刚下的那几盘:每一步都是你真实会遇到的局面,每一个错误都是你当前实际存在的弱点。同样一份反馈预算,花在后者上信息密度高得多。
这也解释了一个乍看反直觉的现象:on-policy 数据的质量可以比 off-policy 数据低,效果反而更好。因为训练的目标不是「见识最好的答案」,而是「修正当前分布里的偏差」。第 12 章讲 on-policy 蒸馏时用的是同一个道理——让学生自己生成、教师来评分,比让学生死记教师的输出更有效,因为前者消除了曝光偏差(exposure bias)。
与之相关的一组词
| 术语 | 英文 | 含义 |
|---|---|---|
| 在线 / 离线 | online / offline | 训练过程中是否还在产生新数据。DPO 离线,PPO 在线。与 on/off-policy 高度相关但不等价 |
| 迭代式 | iterative | 「离线训一轮 → 用新模型重新采样 → 再训一轮」的折中。iterative DPO、拒绝采样循环都属此类 |
| 异步 / 策略陈旧度 | asynchronous / staleness | 生成与训练在不同设备并行,rollout 天然落后训练若干步。用吞吐换 on-policy 程度,陈旧度通常控制在 1–4 步内,见 第 6 章 |
9. 术语速查:不带数学符号的那一半
后训练领域一半的沟通成本花在术语上,而且很多词是被重载过的——同一个词在不同论文里指不同的东西。下面按主题分组。
训练阶段
| 中文 | 英文(缩写) | 含义 | 章节 |
|---|---|---|---|
| 预训练 | pretraining | 在海量原始网页/代码上做 next-token 交叉熵。每个 token 都进 loss | 第 3 章 |
| 中训练 / 退火 | mid-training | 预训练最末尾、指令数据之前的高质量数据阶段。现代后训练配方基本都从中训练检查点起步,但这个阶段很少被公开讨论 | 第 3 章 |
| 指令微调 / 监督微调 | instruction tuning (IFT) / supervised fine-tuning (SFT) | 仍是交叉熵,但数据变成「指令–回复」对,且加 completion mask:只有回复进 loss。模型从「续写机」变成「助手」 | 第 4 章 |
| 偏好微调 | preference fine-tuning (PreFT) | RLHF 的现代泛称,涵盖 PPO 系、DPO 系、拒绝采样。信号是回复级的对比 | 第 3 章 |
| 可验证奖励强化学习 | RLVR | 把奖励模型换成一段能判对错的程序(数学答案比对、单元测试)。信号是 0/1,不可被言语说服 | 第 7 章 |
| 直接对齐算法 | direct alignment algorithms (DAA) | 跳过奖励模型、直接在偏好对上优化策略的一族方法,DPO 是代表 | 第 8 章 |
数据与合成
| 中文 | 英文(缩写) | 含义 | 章节 |
|---|---|---|---|
| 合成数据 | synthetic data | 任何由 AI 系统产出的训练数据——从开放式生成到「让模型改写一段已有内容」都算 | 第 12 章 |
| 蒸馏(宽泛义) | distillation | 用更强模型的输出训练一个模型。是造小而强模型的主力手段。是否允许通常写在开源许可证或 API 服务条款里 | 第 12 章 |
| 知识蒸馏(严格义) | knowledge distillation (KD) | ML 文献里的原义:学生不是学教师选中的那个 token,而是学教师在整个词表上的logits / 对数概率分布。损失写成 $\mathcal{L}_{\text{KD}}=-\E_x\big[\sum_t P_\phi(x_t\mid x_{<t})\log P_\theta(x_t\mid x_{<t})\big]$。Gemma 2/3 是现代代表 | 第 12 章 |
| 上下文学习 | in-context learning (ICL) | 不改权重,靠放进上下文窗口的信息改变行为。最简单的形式就是在 prompt 前加几个同类例子 | 第 12 章 |
| 思维链 | chain-of-thought (CoT) | 让模型把问题拆成分步推理再作答。最初的触发方式就是那句 "Let's think step-by-step" | 第 7 章 |
| AI 反馈 | RLAIF | 用另一个语言模型代替人类产生偏好标签。成本低几个数量级,代价是继承了那个模型的偏置 | 第 12 章 |
| 宪法式 AI | Constitutional AI (CAI) | 用一组写好的原则(「宪法」)指导模型自我批评与改写,产出对齐数据 | 第 12 章 |
奖励与评估
| 中文 | 英文(缩写) | 含义 | 章节 |
|---|---|---|---|
| 结果奖励模型 | outcome reward model (ORM) | 预测「这条推理最终会不会得出正确答案」,可逐 token 输出 | 第 5 章 |
| 过程奖励模型 | process reward model (PRM) | 在推理步骤的边界上打分,而不是只看最终答案。标注昂贵,实际收益低于直觉预期 | 第 5 章 |
| 生成式奖励模型 | generative RM / LLM-as-a-judge | 让一个语言模型用自然语言评判两条回复谁更好。灵活、可解释,但有位置偏置、长度偏置 | 第 5 章 |
| Best-of-N 采样 | best-of-N (BoN) | 采 $N$ 条、用 RM 挑最好的一条返回。推理时方法,不改权重。是拒绝采样的「不做微调」版本 | 第 9 章 |
| 拒绝采样 | rejection sampling (RS) | 采 $N$ 条、用 RM 挑出高分的,再拿去做 SFT。最简单可用的策略改进算法,工业界离不开它 | 第 9 章 |
| 过优化 / 奖励攻击 | over-optimization / reward hacking | 代理奖励一路涨、真实质量却在跌。Goodhart 定律的具体形态。不因奖励「精确」而消失——验证器也可以被钻空子 | 第 14 章 |
行为与产品
| 中文 | 英文(缩写) | 含义 | 章节 |
|---|---|---|---|
| 工具调用 / 函数调用 | tool use / function calling | 模型在生成中途输出结构化调用、拿到外部结果再继续。工具返回的 token 不应计入 loss——它们不是模型生成的 | 第 13 章 |
| 模型上下文协议 | Model Context Protocol (MCP) | 把工具/数据源统一暴露给模型的开放协议,解决「每家一套工具定义」的碎片化问题 | 第 13 章 |
| 肤浅对齐假说 / 激发理论 | Superficial Alignment Hypothesis / elicitation | 「后训练只教格式和风格,知识全在预训练里」。部分正确但被过度引用——后训练确实主要在激发已有能力,但激发得好不好差距巨大(同一基座不同后训练的评测差距可超过 7 分) | 第 1 章 |
| 模型性格 | model character / persona | 模型稳定表现出的语气、价值取向与拒绝边界。是可以被后训练有意设计的产品属性,不是副作用 | 第 17 章 |
10. 记号陷阱与跨文献对照
本书的符号是统一过的,但你读的论文不会。下面这张表用来做翻译:左边是本书的写法,右边是你在原始论文里可能遇到的写法。
| 本书 | 文献里的其它写法 | 说明 |
|---|---|---|
| $r_\phi$(奖励模型) | $r_\theta$、$r_\psi$、$R$ | 原书第 3 章有几处沿用 RL 惯例写 $r_\theta$。本书统一:$\theta$ 只给策略,$\phi$ 给奖励模型,$\psi$ 给价值模型 |
| $y_w,y_l$ | $y_c,y_r$、$y^+,y^-$、$y_{\text{chosen}},y_{\text{rejected}}$ | DPO 原论文用 $y_w,y_l$;数据集字段一般叫 chosen/rejected。$y_r$ 的下标和奖励 $r$ 撞车,写代码时建议一律用 chosen/rejected |
| $\pi_{\text{ref}}$ | $\pi_{\text{SFT}}$、$\pi_0$、$\pi_{\text{base}}$ | 指同一个东西。用 $\pi_{\text{SFT}}$ 时是在强调「参考模型就是 SFT 检查点」这个默认选择 |
| $\pi_{\theta_{\text{old}}}$ | $\pi_{\text{behav}}$、$\mu$ | 不要和 $\pi_{\text{ref}}$ 搞混:一个每批更新,一个整个训练不动 |
| $\mathcal{D}_{\text{KL}}$ | $\KL$、$D_{\text{KL}}$、$\mathbb{D}$ | 同一个量。真正要确认的是括号里谁在左边 |
| $G$(组大小) | $k$、$n$、$N$ | GRPO 论文用 $G$,RLOO 论文用 $k$,拒绝采样文献用 $N$ |
| $A_t$ | $\hat A_t$、$\Psi_t$ | 戴帽子强调它是估计值而非真值。GAE 论文用 $\Psi_t$ 泛指「策略梯度里的那个乘子」 |
- 两个 $\beta$ 不是一回事。 RLHF 目标里的 $\beta$ 是加在 KL 项前面的惩罚权重,$\beta$ 越大越保守;DPO 损失里的 $\beta$ 出现在 log 概率比的内部,扮演隐式奖励的温度。数值区间和调参直觉都不同。看到 $\beta$ 先确认上下文。
- 期望的下标必须读清楚。 $\E_{y\sim\pi_\theta}[\cdot]$、$\E_{y\sim\pi_{\text{ref}}}[\cdot]$、$\E_{y\sim\mathcal{D}}[\cdot]$ 是三件完全不同的事:第一个要求现场生成(on-policy,贵);第二个是 off-policy,需要重要性采样修正;第三个从固定数据集读取(便宜,DPO 走的就是这条)。「期望对谁取」几乎就是「这个算法贵不贵」的同义词。
- KL 的方向有意义。 $\mathcal{D}_{\text{KL}}(\pi_\theta\|\pi_{\text{ref}})$ 与 $\mathcal{D}_{\text{KL}}(\pi_{\text{ref}}\|\pi_\theta)$ 行为不同。RLHF 标准写法是前者,因为它的期望对 $\pi_\theta$ 取——正好能用你手上已有的 rollout 估计,不需要额外采样。这不是理论选择,是工程选择。(更深一层:RL 优化的形状偏向 mode-seeking,SFT 偏向 mass-covering,这解释了为什么 RL 比 SFT「忘得少」,见 第 15 章。)
- $A$ 这个字母被用了两次。 MDP 五元组里 $\mathcal{A}$ 是动作空间(花体),$A(s,a)$ 是优势函数(正体)。本书用花体/正体区分,但很多论文不区分,只能靠位置判断。
把公式翻译成代码时的三个检查点
一、这个量是序列级 $(B,)$ 还是 token 级 $(B,L)$? 奖励是序列级,log-prob 是 token 级,优势两者都可能——不匹配处的广播就是长度偏置的来源。二、要不要乘 completion mask? 凡是在 token 维度上求和的量(log-prob、KL、熵、逐 token 损失)一律要;忘了不会报错,只会让 prompt 部分主导数值。三、这份前向要不要梯度? $\pi_{\text{ref}}$、$r_\phi$、$\pi_{\theta_{\text{old}}}$ 都要包在 torch.no_grad() 里,否则显存莫名翻倍;$\pi_{\theta_{\text{old}}}$ 尤其容易忘——它在重要性采样比的分母上,必须 detach()。
「策略、参考模型、旧策略」三份 log-prob 一起用时,三者必须用完全相同的位移和 mask 计算,否则比值会错位一格。这类错误的表现是「KL 一开始就不为零」——训练刚开始时策略和参考模型是同一份权重,KL 必须精确等于 0。把「step 0 的 KL 是否为 0」写成一句断言,能挡掉一大半这类问题。
本章小结
这一页不需要被「读完」,但下面这张一页速查值得单独收藏。
整本书的一个式子
$$ \max_\theta \; \E_{x\sim\mathcal{D},\; y\sim\pi_\theta(\cdot\mid x)}\big[r_\phi(x,y)\big] \; - \; \beta\,\mathcal{D}_{\text{KL}}\big(\pi_\theta(\cdot\mid x)\,\|\,\pi_{\text{ref}}(\cdot\mid x)\big) $$读法:「在 prompt 数据集上,从当前模型采样回复,让某个标量评分尽可能高,同时不要离起点太远。」 PPO、GRPO、DPO、拒绝采样都是这个式子的不同求解方式。
符号速查卡
| 组 | 核心符号 | 一句话 |
|---|---|---|
| 语言模型 | $x$, $y$, $y_t$, $y_{<t}$, $\mathcal{V}$, $B/L/V$ | 输入、输出、token、前缀、词表、张量三维。$s_t=(x,y_{<t})$,$a_t=y_t$ |
| 强化学习 | $\pi_\theta$, $\tau$, $J(\theta)$, $V$, $Q$, $A$, $\gamma$ | 策略即语言模型;轨迹即一次 rollout;$\gamma=1$;优势是策略梯度的乘子 |
| 概率 | $\mathcal{D}_{\text{KL}}$, $H$, $\sigma$, $\rho$, $k_3$ | KL 是对齐的中心对象;sigmoid 把分数差转成偏好概率;$\rho$ 是重要性采样比 |
| RLHF | $r_\phi$, $\pi_{\text{ref}}$, $\beta$, $y_w/y_l$, $\succ$ | 学出来的奖励、冻结的锚点、正则强度、偏好对 |
要点清单
- 语言模型的一切都是 log-prob。 自回归分解 → 交叉熵 = KL = NLL;数值稳定性与可导性决定了代码里流动的永远是对数概率。
- MDP 映射的三处退化决定了算法设计: 转移确定 → 序列概率可精确计算(KL、IS 比、DPO 的共同前提);奖励只在末尾 → 值函数信息量低(GRPO 可以丢掉价值模型);$\gamma=1$ → 打折等于人为惩罚靠后的 token。
- 优势 = 奖励减基线,减去任何与动作无关的基线都不引入偏差、只降方差。RLOO/GRPO 把基线从「学出来的价值模型」换成了「同一 prompt 下其它样本的均值」。
- KL 一律用 $k_3=(\rho-1)-\log\rho$ 估计($\rho=\pi_{\text{ref}}/\pi_\theta$):既无偏又逐 token 非负,方差比 $k_1$ 低一个数量级,是几乎没有代价的免费午餐。
- on-policy 有两套定义,RL 圈严格、偏好微调圈宽泛。真正的分水岭是数据是不是由当前模型产生的,而不是损失函数长什么样。
- 写代码时永远问三句:序列级还是 token 级?要不要乘 completion mask?这份前向要不要梯度?外加一句断言——step 0 的 KL 必须精确为 0。
延伸阅读
补基础
- Sutton & Barto, Reinforcement Learning: An Introduction (2018) — RL 的标准教材。读第 3 章(MDP)和第 13 章(策略梯度)就足以支撑本书全部内容,其余可跳。
- Sebastian Raschka, Build a Large Language Model (From Scratch) — 如果第 1 节的张量解剖读起来吃力,从这本补。
- UC Berkeley CS285: Deep Reinforcement Learning — 想把策略梯度那套推导彻底搞明白时看,比教科书更贴近现代实现。
本页几个符号的原始出处
- John Schulman, Approximating KL Divergence (2016) — $k_1/k_2/k_3$ 的唯一权威出处。所有 RLHF 代码库都在用它,但几乎没有论文解释为什么,只有这篇博客讲清楚了。
- Attention Is All You Need (2017) — Transformer 与自注意力;第 1 节的 LM head / logits 那套结构来自这里。
- Hinton et al., Distilling the Knowledge in a Neural Network (2015) — 「知识蒸馏」严格定义的源头,解释了它和口语里的「蒸馏」不是一回事。
- GAE (2015) — $\lambda$、$\delta_t^V$ 与「策略梯度乘子」这套记号的出处。
符号落地成代码
- InstructGPT (2022) — $\pi_{\text{ref}}$、$r_\phi$、$\beta$ 这套记号在语言模型上的第一次完整亮相。
- DPO (2023) — 隐式奖励与配分函数 $Z(x)$ 消去的那段推导;完整过程在 第 8 章。
- GRPO / DeepSeekMath (2024) — 组内标准化优势的原始定义,即第 4 节表里的那一行。
- RLOO (2024) — 留一法基线,以及「RLHF 其实不需要 PPO 那么复杂」这个论点。
相邻的两个附录
- 附录 B · 不只是「文风」 — 反驳「后训练只改风格」,与第 9 节的「肤浅对齐假说」直接相关。
- 第 15 章 · 正则化 — 第 6 节的 KL 估计器在那里有完整的数值实验、梯度推导和 $\beta$ 选型讨论。KL 相关的问题优先去那里查。