RRLforge
完整主线 路线7 / 27 · L1 认料退出路线
原理预计 25 分钟

RL 的最小心智模型:试、评、改

不讲马尔可夫决策过程。先用「模型自己生成一批答案,好的多学一点,坏的少学一点」把整件事说完。

学完这节你能做到

  • 用一句话讲清 RL 与监督学习的根本区别:标签是自己采样出来的
  • 把 state / action / reward / policy 对应到 LLM 里的具体东西
  • 说出「为什么不能直接对 reward 做梯度下降」

监督学习:抄答案。强化学习:自己写,别人打分

这是唯一需要记住的区别。

监督学习给你 (问题, 标准答案)。你的模型输出和标准答案对比,差多少就往那个方向改多少。标签是给定的

强化学习只给你问题和一个打分函数。模型自己生成答案,打分函数给个分数,然后你根据分数调整「以后更/更不倾向于这样答」。标签是自己采样出来的

监督学习:  问题 → 模型 → 输出 ←比对→ 标准答案 → 梯度
强化学习:  问题 → 模型 → 输出 → 打分器 → 分数 → 梯度
                     ↑                            │
                     └────── 好的多学,坏的少学 ──────┘

这个差别带来三个后果,后面每一节课基本都在处理其中之一:

  1. 。每次更新前都要先生成一批答案,而生成很慢。
  2. 不稳。采样有随机性,同一批数据可能这次全对下次全错。
  3. 会作弊。模型优化的是打分函数,不是你心里想的那个目标。
i那为什么还要用 RL

因为很多任务没有标准答案可抄

「把这段代码写得更好」——好在哪?没有唯一答案,但你能判断哪个更好。 「多想几步再回答」——推理过程没有标准写法,但你能验证最终答案对不对。

监督学习只能教模型模仿已有的答案。RL 能让模型探索出训练数据里没有的解法——DeepSeek-R1 那种「等一下,我重新想想」的行为,没有人在 SFT 数据里教过它。

术语对照表

RL 的术语来自机器人和游戏,套到 LLM 上要翻译一下。这张表建议记住:

RL 术语在 LLM 里是什么备注
policy 策略就是你的模型看到「策略模型」就想「那个要训的模型」
state 状态当前已有的 token 序列(prompt + 已生成部分)每生成一个 token 状态就变了
action 动作下一个 token动作空间 = 整个词表,15 万个选择
trajectory 轨迹一条完整的回答也叫 rollout、episode、completion
reward 回报这条回答的得分LLM 里通常只在结尾给一次
return 累积回报从某步到结尾的总分单轮任务里就等于 reward
value 价值「从这个状态出发预期能拿多少分」PPO 要学它,GRPO 不学
advantage 优势「这条比平均好多少」真正乘到梯度上的东西
×最容易绕晕的一点:动作是 token,不是整条回答

数学上,每生成一个 token 就是一次动作,一条 100 token 的回答是 100 步决策。

但 reward 通常只在最后给一次(答案对不对)。中间 99 步都没有直接反馈——这叫稀疏奖励

实践上的处理很直接:把整条回答的优势值平摊到每个 token 上。所以代码里你会看到优势是按序列算的,然后广播到 token 维度。第一次看会觉得别扭,记住「按序列打分、按 token 求梯度」就行。

一个玩具例子:教模型只输出数字

假设我们要让模型回答算术题时只输出数字,不要废话。

监督学习的做法:准备 1000 条 ("3+4=?", "7"),微调。问题:你得先有这 1000 条数据。

RL 的做法:写一个打分函数。

def reward(response: str) -> float:
    return 1.0 if response.strip().isdigit() else 0.0

然后:

  1. 问模型 "3+4=?",让它生成 8 条不同回答(temperature > 0,所以每条不一样)
  2. 打分:"7" → 1.0;"7" → 1.0;"答案是 7" → 0.0;"让我算一下:3+4=7" → 0.0 …
  3. 得分高的那几条,提高它们出现的概率;得分低的,降低

跑几十轮之后,模型学会了只输出数字。你一条训练数据都没有标注。

!现在来看这个 reward 会怎么被钻空子

isdigit() 只检查「是不是数字」,不检查「对不对」。

模型很快会发现:随便输出一个数字就能拿 1.0 分。于是它学会输出 "0",永远拿满分,而算术能力毫无长进。

这就是 reward hacking,而且是最典型的一种:你写的 reward 有一条不用真的解决问题就能拿分的捷径。修法很简单——把答案对不对也算进去。但真实任务里的捷径往往没这么显眼。

后面「reward 从哪来」那一节会系统讲怎么设计和自查。

为什么不能直接对 reward 做梯度下降

一个自然的想法是:reward 是个数,我对它求梯度不就行了?

不行,因为 reward 函数对模型参数不可导

参数 θ → 模型 → 采样出 token → 拼成文本 → 打分函数 → reward
                    ↑
              这一步是采样(离散、随机)
              梯度传不过去

isdigit() 对参数的导数是什么?没有意义。中间「采样一个 token」这一步彻底切断了梯度链。

RL 的核心技巧就是绕过这个断点:不对 reward 求梯度,而是对「采样到这条回答的概率」求梯度,用 reward 当权重。

朴素梯度  ≈  Σ  reward × ∇log P(这条回答)
             回答

log P(这条回答) 是模型算出来的,可导。reward 只是一个标量系数。

直觉上:

  • reward 高 → 系数为正 → 提高这条回答的概率
  • reward 低 → 系数为负 → 降低这条回答的概率

这就是策略梯度,「先采样,再按分数加权地提高/降低概率」。L1 后面那节会把它一步步推出来。

三个必然出现的麻烦

写在这里,好让你知道后面每节课在解决什么:

麻烦症状哪一节解决
方差大同一批数据梯度方向乱跳,训练不稳基线与优势(策略梯度、PPO→GRPO)
会作弊分数涨了但能力没涨reward 设计、L4 失效模式
会跑飞为了刷分把说人话的能力训丢了KL 惩罚与 clip(PPO→GRPO)
检查点单选

强化学习和监督学习最本质的区别是什么?

检查点单选

为什么不能直接对 reward 求梯度?

检查点单选

在 LLM 的 RL 里,一次「动作」对应什么?

这节课的落点

  • RL 的标签是自己采样出来的,这一条派生出「贵、不稳、会作弊」三个后果
  • 术语翻译:policy = 模型,action = token,trajectory = 一条回答,advantage = 比平均好多少
  • 动作是 token,reward 在序列结尾给;实践上把序列优势平摊到每个 token
  • reward 不可导,所以改为对 log P(回答) 求梯度、用 reward 当权重
  • 玩具例子里的 isdigit() 就是一个现成的 reward hacking 案例

延伸资料