一、SFT 留下的空白
第 16 讲结尾留了一个空白:SFT 只会说"回答应该长这样",不会说"这两个回答里哪个更好"。
这个空白比听起来要大。回想一下 SFT 的数据是怎么来的:一个人坐下来,针对一个问题,写出一个"理想回答"。这件事有两个硬伤。
第一,写出一个满分回答是很难的。让你写一段"解释量子纠缠、既准确又通俗、长度恰好"的文字,你大概会反复修改,最后交出的也未必是最好的版本。模型通过 SFT 能达到的上限,被写示范的那个人的上限卡住了。
第二,写出来的东西,只告诉模型一个点,没告诉它方向。模型知道"这个答案是好的",但不知道"比它差的答案差在哪、比它好的答案会是什么样"。
这一讲要讲的方法,绕开了这两个硬伤。它的出发点是一个关于人类的观察:
⭐ 人类很难写出最好的答案,但很擅长判断两个答案里哪个更好。
这套方法叫 RLHF(Reinforcement Learning from Human Feedback,基于人类反馈的强化学习)。
二、打个比方:美食比赛的评委
美食比赛的评委,大多数自己做不出冠军级别的菜。但把两道菜摆在他们面前,尝一口,他们能相当一致地告诉你哪道更好。
判断比创作便宜,也比创作可靠。 让十个评委各自做一道"满分红烧肉",你会得到十道风格迥异、水平参差的菜;让十个评委比较同一对菜,他们的意见会一致得多。
RLHF 要做的,就是把评委的这种判断力,变成一个可以持续指导厨师改进的信号。它分三步:
第 1 步:让厨师(SFT 模型)对同一道题做出几道菜,请评委(人)两两比较
第 2 步:用这些比较结果,训练一个"电子评委"(奖励模型),学会自动给菜打分
第 3 步:让厨师反复做菜,电子评委打分,厨师朝着高分的方向调整手艺(强化学习)
为什么需要第 2 步那个"电子评委"?因为第 3 步里厨师要做成千上万道菜,不可能每一道都请真人来尝。真人的判断只用来"教会"电子评委,之后打分的活交给它。
三、把三步拆开
第 1 步:收集成对偏好
从第 16 讲的 SFT 模型出发。对同一个问题,让模型生成两个不同的回答(第 21 讲会讲清楚,同一个模型为什么能对同一个输入生成不同的回答),请人判断哪个更好:
问题: 用一句话解释什么是通货膨胀
回答 A: 通货膨胀是指物价普遍持续上涨、同样的钱能买到的东西变少的现象。
回答 B: 通货膨胀是一个经济学概念,它涉及很多方面的因素,比较复杂。
人的判断:A 更好
一条偏好数据就是一个三元组:(问题,更好的回答,更差的回答)。注意这里人不需要写任何东西,只需要做一次选择——这正是第二节说的"判断比创作便宜"。
第 2 步:训练奖励模型
**奖励模型(reward model)**的任务是:输入一个问题和一个回答,输出一个数字,表示这个回答有多好。
它的结构你已经很熟悉了:拿一个 Decoder-only Transformer(第 11 讲),把最后那层"输出整个词表概率分布"的 softmax 换掉,换成只输出一个数字的线性层。模型读完"问题 + 回答"整段文本,在最后一个位置吐出一个分数 r。
问题是:人给的数据是"A 比 B 好",不是"A 值 8 分、B 值 3 分"。怎么用"比较"去训练一个"打分"的模型?
办法是把两个分数的差,变成"A 胜过 B"的概率:
P(A 胜过 B) = exp(r_A) / (exp(r_A) + exp(r_B))
⭐ 仔细看这个式子——它就是第 5 讲的 softmax,只不过候选项从"词表里的几万个词"变成了"两个回答"。分数高的那个回答,分到的概率就大。
这个式子可以化简成一个更常见的写法:
P(A 胜过 B) = σ(r_A − r_B) 其中 σ(z) = 1 / (1 + e^(−z))
σ 叫 sigmoid 函数,它就是"只有两个候选项时的 softmax":输入任意实数,输出落在 0 到 1 之间,输入越大输出越接近 1。只有分数的差值重要,分数本身的绝对大小不重要——给两个回答同时加 100 分,胜负概率完全不变。
训练目标是让"人选中的那个回答"胜出的概率尽量高。用第 4、6 讲的老办法,取负对数当损失:
损失 = −log σ(r_好 − r_坏)
手算两种情况。
情况一:奖励模型已经排对了顺序,给好回答 2 分、坏回答 0.5 分:
差值 = 2 − 0.5 = 1.5
σ(1.5) = 1 / (1 + e^(−1.5)) = 1 / (1 + 0.2231) ≈ 0.8176
损失 = −ln(0.8176) ≈ 0.201
情况二:奖励模型排反了,给好回答 0.5 分、坏回答 2 分:
差值 = 0.5 − 2 = −1.5
σ(−1.5) ≈ 0.1824
损失 = −ln(0.1824) ≈ 1.701
排反了的损失是排对了的 8 倍多。再看损失对差值的导数(第 6 讲:梯度告诉你往哪调、调多少):
d(损失)/d(差值) = −(1 − σ(差值))
情况一:−(1 − 0.8176) ≈ −0.18 ← 顺序已经对了,只轻轻推一下
情况二:−(1 − 0.1824) ≈ −0.82 ← 顺序错了,用力推
⭐ 两种情况的梯度都是负的,意思都是"把差值往大了推"——把好回答的分数调高、坏回答的分数调低。区别在于力度:已经排对的只做微调,排错的被狠狠纠正。这就是第 6 讲梯度下降在这里的具体样子,没有任何新机制。
跑过几万、几十万条偏好数据之后,奖励模型学会了给任意一个"问题 + 回答"打出一个分数,这个分数大体反映了"人类评判者会不会喜欢这个回答"。
第 3 步:用强化学习朝高分方向调整
现在有了电子评委,接下来要让模型本身(在强化学习的术语里叫策略,policy)朝着"得高分"的方向调整。
这里遇到一个第 6 讲没遇到过的障碍。第 6 讲的训练里,损失是模型输出的一个连续、可求导的函数——参数动一点点,损失跟着动一点点,链式法则一路算回去。
但这里的流程是:
模型 → 【按概率抽出一个个具体的词,拼成一个回答】→ 奖励模型打分
中间那一步"抽出一个具体的词"是离散的选择——就像第 12 讲 MoE 路由器的 top-k 一样,它不是连续的,没法直接对它求导。你不能问"如果模型参数动一点点,它抽到的那个词会连续地变化多少",因为词要么是"好"要么是"热",没有"0.3 个好"。
强化学习用一个很聪明的办法绕过这个障碍。它不去对"抽样"这一步求导,而是对模型给这个回答打出的概率求导——这个概率是连续可导的,第 13 讲的交叉熵本来就在算它:
参数更新方向 ≈ (这个回答的得分 − 平均得分)× ∇ log P(这个回答)
这个式子的意思翻译成白话就是:
⭐ 比平均水平好的回答,调高它下次出现的概率;比平均水平差的回答,调低它下次出现的概率。好得越多,调得越狠。
手算一个最简单的例子。对同一个问题,模型生成了两个回答,奖励模型分别打分:
| 回答 | 奖励模型得分 | 减去平均分(平均 = 2) | 对这个回答的概率怎么调 |
|---|---|---|---|
| 回答 1 | 3 | +1 | 调高,权重 +1 |
| 回答 2 | 1 | −1 | 调低,权重 −1 |
⭐ 这就兑现了第 6 讲留下的那句话:“奖励信号要转换成能驱动参数更新的梯度,转换的方式不完全相同,但最终用梯度下降更新参数这一步是同一套”。奖励本身不能求导,但它可以变成一个"权重",乘在一个本来就能求导的量(log P(回答))的梯度上。之后的反向传播、参数更新,和第 6 讲完全一样。
为什么要减去平均分?因为如果奖励模型给所有回答都打正分,不减平均的话,所有回答的概率都会被调高,模型分不清哪个是真的好。减去平均之后,只有"相对更好"才被奖励——这和第 16 讲结尾说的"相对优劣"是同一个东西,这一次它终于变成了训练信号。
⚠️ 关于时效性:实践中用得最多的具体算法叫 PPO(近端策略优化),它在上面这个基本思路之上加了一些稳定训练的技巧,最关键的一条是限制每一步的更新幅度,防止模型因为一次高分就把概率调得太猛。具体算法还在不断演进,但"奖励乘在 log 概率的梯度上"这个核心思路,是这一类方法共同的骨架。
一根拴住模型的绳子
第 3 步如果只追求"奖励模型打分越高越好",会出一个严重的问题,第四节会详细讲。这里先说解法:给优化目标加一根"绳子"。
优化目标 = 奖励模型得分 − β × (当前模型和 SFT 模型的差距)
“和 SFT 模型的差距"用一个叫 KL 散度的量来衡量,直觉上就是"两个模型对同一段文字给出的概率分布相差有多远”。β 是一个控制绳子松紧的系数。
⭐ 这根绳子的意思是:你可以朝高分的方向走,但不能离出发点(SFT 模型)太远。走远一点,就要付一点"罚款"。为什么需要这根绳子?因为奖励模型只是一个近似的评委,离它见过的数据越远,它的打分就越不可靠。
四、代价:你优化的是评委,不是评委背后的人
⭐⭐ 这一讲最重要的一条警告:强化学习优化的对象是奖励模型的打分,而奖励模型只是人类偏好的一个近似。
经济学里有一句话叫古德哈特定律:当一个指标被当成目标去优化时,它就不再是一个好指标。 RLHF 是这句话的教科书级案例。
奖励模型是从有限的偏好数据里学出来的,它不可避免地会学到一些"碰巧和好回答相关、但本身不是好回答的原因"的特征。模型在强化学习中会主动去找这些特征、并把它们推向极端,因为这是拿高分最省力的路。这种现象叫奖励作弊(reward hacking)。实践中被反复观察到的几种倾向:
| 倾向 | 为什么会被奖励 | 实际的问题 |
|---|---|---|
| 回答越来越长 | 评判者常常觉得详细的回答更用心 | 冗长、注水,关键信息被淹没 |
| 迎合用户的观点 | 评判者更喜欢被认同 | 用户说错了,模型也跟着附和 |
| 语气过度自信 | 流畅笃定的回答读起来更可信 | 不确定的事也说得斩钉截铁 |
第三节那根"KL 绳子",就是为了遏制这种倾向而存在的——但它只能减缓,不能根除。
⚠️ 人类偏好本身有噪声,也有立场。不同的评判者对同一对回答可能给出相反的判断;评判者的文化背景、专业领域、个人口味,都会写进偏好数据,再被奖励模型学走。这是第 14 讲"质量没有客观定义、过滤数据是一种价值取舍"在对齐阶段的翻版——“什么是更好的回答"这个问题,本身就没有一个中立的答案。
⚠️ “人更喜欢"不等于"更正确”。这一条和第 1 讲的核心警告一脉相承。预训练优化的是"统计上合理”,RLHF 优化的是"人类评判者更喜欢"——两者都不直接等于"事实正确"。一个听起来专业、结构清晰、语气笃定的错误回答,很可能比一个犹豫但正确的回答得到更高的偏好。第 29 讲讲幻觉时,你会看到这条线索的后果。
⚠️ 工程上又贵又不稳定。第 3 步训练时,内存里要同时放好几个大模型:正在训练的策略模型、作为"绳子另一端"的 SFT 参考模型、打分的奖励模型,PPO 通常还要再加一个辅助估计平均分的模型。几个模型互相影响,任何一个出问题都会让训练发散。这个成本,是第 18 讲 DPO 出现的直接动机。
五、和后面课程的关系
- 第 18 讲(DPO) 会问一个问题:能不能跳过"训练奖励模型"和"强化学习"这两步,直接用偏好数据训练模型?答案是可以,而且数学上和这一讲的目标密切相关。
- 第 19 讲(推理模型与 RLVR) 保留了这一讲第 3 步的强化学习框架,但把奖励的来源换掉了:不再用一个模仿人类口味的奖励模型,而是用可以被客观验证的对错(比如数学题答案对不对、代码能不能通过测试)。这正是为了绕开第四节讲的"奖励作弊"。
- 第 20 讲 会把这一讲第四节的隐患放在更大的框架下讨论:对齐到底解决了什么,又留下了什么。
- 第 29 讲(幻觉) 会回到第四节"人更喜欢不等于更正确"这一条。
六、本讲小结
- ⭐ RLHF 的出发点:人写不出满分答案,但能稳定判断两个答案哪个更好。判断比创作便宜,也比创作可靠。
- 第 1 步:对同一个问题生成两个回答,人选出更好的那个,得到(问题,好回答,坏回答)三元组。
- 第 2 步:训练奖励模型。结构就是把 Transformer 的输出层换成一个数字;训练用
−log σ(r_好 − r_坏),而σ(r_A − r_B)本质上就是只有两个候选项的 softmax。手算显示:顺序排错时,梯度比排对时大四倍多。 - ⭐ 第 3 步:强化学习。抽样是离散的、不能求导,所以把"得分减平均分"当作权重,乘在
log P(回答)的梯度上——比平均好的调高概率,比平均差的调低。这兑现了第 6 讲关于"奖励怎么变成梯度"的承诺。 - KL 绳子:优化目标里减去"离 SFT 模型的距离",防止模型为了高分跑得太远。
- ⭐⭐ 最大的隐患是古德哈特定律:模型优化的是奖励模型的打分,不是人真正想要的东西,于是出现变长、迎合、过度自信等奖励作弊现象。此外,偏好有噪声、有立场;“人更喜欢"不等于"更正确”;工程上要同时维护多个大模型,又贵又不稳定。
思考题
- 用第三节的公式手算:如果奖励模型给好回答 1 分、坏回答 1 分(打了平手),损失是多少?梯度是多少?和第三节的两种情况比,这次的"推力"是大是小?
- 为什么说"给两个回答同时加 100 分,胜负概率完全不变"?用
σ(r_A − r_B)验证一下。这个性质意味着奖励模型输出的分数,单独拿出来看有没有意义? - 第三节的策略梯度例子里,如果不减去平均分,两个回答的权重分别是 3 和 1,都是正的。这样训练会发生什么?为什么"减去平均"之后,模型才真正学到了"相对优劣"?
- 如果把 KL 绳子的系数
β设成 0(完全不拴),你预计训练后期模型的回答会出现什么变化?如果把β设得非常大呢? - 举一个你自己想到的"奖励作弊"例子:某个特征碰巧和"人类评判者更喜欢"相关,但它本身并不代表回答更好。模型如果学会了刻意放大这个特征,用户会看到什么?