AI 学习课程 / LESSON 17

第十七节:策略梯度与大语言模型对齐

DQN 先估计每个动作的价值,再选动作。策略梯度直接调整「选各动作的概率」。从一条完整轨迹的 REINFORCE 更新出发,逐步连接基线、Actor-Critic、PPO,再看偏好数据如何用于 RLHF 与 DPO。

PyTorch · REINFORCE 实验基线与优势Actor-Critic / PPORLHF / DPO离线 HTML

01 / 三种方法究竟学了什么

从 Q(s,a) 转到 π(a|s)

方法训练对象行动时本课程位置
表格 Q-learning每个状态—动作的 Q 表查表,再选最大 Q 或 ε 探索第十五节
DQN神经网络 Qθ(s,a)网络给出所有动作 Q,再选动作第十六节
策略梯度策略 πθ(a|s)网络直接给出动作概率并采样本节

仍使用同一张小网格,并保留第十六节的 10% 动作随机重抽:S 向右到 C 可立即得 +2;向下经过 A、B、D 到 G 才得 +10。策略网络输入当前状态 one-hot (6,),输出四个 logits (4,),softmax 后是右、下、上、左的概率。

状态 s
6 个数
→策略网络
4 个 logits
→softmax
四个概率和为 1
→采样动作 a
与环境互动

输入所在位置

训练后实际动作概率

训练时按这些概率采样,较小概率的动作仍可能被试到;“选最大概率动作”是另外一种确定性评估方式。概率高不代表环境一定照做,因为动作随机重抽独立存在。

02 / 不必对环境求导

给好结果的动作增加概率

设一条轨迹是 s₀,a₀,r₀,s₁,a₁,r₁,…,从时刻 t 往后的折扣回报是 Gₜ=rₜ+γrₜ₊₁+…。目标是提高从起点算的期望折扣回报。对轨迹概率使用 ∇p=p∇log p,再利用“t 时刻的动作不影响之前的奖励”,得到下面的得分函数估计:

J(θ) = Eπ[ Σₜ γᵗ rₜ ] ∇θ J(θ) = Eπ[ Σₜ γᵗ Gₜ ∇θ log πθ(aₜ|sₜ) ] 训练时最小化:L = −(1/N) Σ轨迹 Σₜ γᵗ log πθ(aₜ|sₜ) · Gₜ N = 新采样的完整轨迹数;本例 N=8,γ=0.8。

这里 γᵗ 是从起点到 t 的折扣,Gₜ 是从 t 往后的回报;两者不能随意混成一个因子。环境的转移和奖励不需要可微,梯度只穿过策略网络算出的 log π。

REINFORCE 必须先拿到整条轨迹的回报,才能为较早动作填入 Gₜ。本例最多采样 20 步,以这 20 步内的折扣奖励为目标;没有进入终点也会在第 20 步结束这一条训练轨迹。

真实训练轨迹:末尾奖励怎样传回起点

trajectory = collect(policy, environment_seed)  # 当前策略采样的一整回合
for t, (state, log_prob, G_t) in enumerate(trajectory):
    loss_terms.append(-gamma**t * log_prob * G_t)
loss = sum(loss_terms) / 8
loss.backward()
optimizer.step()

代码里一次更新汇总 8 条新轨迹;这段是未加基线的核心表达式,完整实现还包含梯度裁剪和可选基线。

03 / 数学上不改方向,采样时能改波动

从 Gₜ 减去一个与当前动作无关的基线

把 Gₜ 换成 Gₜ − b(sₜ)。因为固定状态下 Σₐ π(a|s)∇logπ(a|s)=Σₐ∇π(a|s)=0,一个不依赖当前动作的 b(s) 不改变期望策略梯度。它改变每条采样轨迹的更新大小与正负,因此可能降低方差;基线选得不合适也可能让方差变大。

Aₜ = Gₜ − b(sₜ) # 回报高于基线则是正优势 L = −(1/N) Σ轨迹 Σₜ γᵗ log π(aₜ|sₜ) · Aₜ 若 b(sₜ) ≈ Vπ(sₜ),Aₜ 就是在估计“此动作比该状态平均表现好多少”。

先看一个与网格训练分开的单次双路线例子:选 G 的概率为 p,拿 10;选 C 的概率为 1−p,拿 2。设 p=σ(z),直接微分得 dJ/dz=8p(1−p)。调节 p 和 b,观察两个采样梯度的值、它们的加权平均和方差。

两种样本的梯度

加权平均与方差

实际代码里 b(s) 是上一批以前的同状态回报移动平均。当前批次先用旧 b 计算损失,再更新 b 给下一批使用;它不是会求导的价值网络。Actor-Critic 则常用一个单独训练的价值网络作基线。

04 / 同一环境的六次实际训练

看多种子结果,不只看一条曲线

基础 REINFORCE 与加状态基线各用 3 个训练种子,各训练 1200 回合,每 8 回合更新一次。检查点用同一组 60 个环境种子、按策略概率采样评估;最终另外用 150 回合,分别按概率采样和选最大概率动作评估。随机策略用 300 回合。

三个训练种子的采样策略评估均值

只在标记的回合数评估;点之间的线仅辅助阅读。每个点基于 60 个评估回合,训练期的平均回报包含策略探索。

当前检查点

最终评估

“采样评估”保留策略本身的概率;“贪心评估”总选最大概率动作。两者都关闭训练过程中的参数更新,但环境的 10% 动作随机重抽仍存在。这里的基线是减小梯度采样波动的手段,不保证每次训练表现更好。仅凭三个种子也不能判断普遍优势。

05 / REINFORCE 的后续思路

Actor-Critic 估价值;PPO 约束更新幅度

Actor-Critic 的分工

状态 s→Actor
π(a|s)
→采样动作
状态 s→Critic
V(s)
→估优势

Actor 决定动作概率;Critic 学习状态价值,帮助估计优势。常见一步 TD 优势近似是 r+γV(s′)−V(s);它可以更早更新,但会引入价值估计误差。本节代码训练的是 REINFORCE,没有实现 Actor-Critic。

PPO 剪裁的直觉

用旧策略收集数据后,比较新旧策略对同一动作的概率比 ρ=π新(a|s)/π旧(a|s)。裁剪目标会在“朝着有利方向变化得太多”时停止继续奖励这种变化。

Lclip = min(ρA, clip(ρ, 1−ε, 1+ε) A) 本页 ε=0.2;数值玩具仅讲直觉,不运行 PPO。

PPO 的剪裁是优化目标中的限制信号,不是“新旧策略概率比绝不超过边界”的硬保证。实际训练还要考虑采样、价值估计、KL 监控等细节。

06 / 把生成看成一串动作

语言模型输出下一个 Token,也是在执行策略

给定提示词和已经生成的前缀,语言模型给出下一 Token 的概率分布。可以把“已有上下文”当状态信息,把采样的 Token 当动作;生成结束后才得到的偏好评分会影响整段生成的更新。下面只是概念序列,字块不代表真实 tokenizer 的切分。

提示词:“请用一句话说明张量。”

状态信息:提示词 + 已生成的 Token 前缀 动作:下一 Token 策略:πθ(下一 Token | 上下文) 回报:可来自整段回答的偏好评分,并可能叠加与参考模型的偏离惩罚

这里的“状态”是否充分取决于可见上下文;真实模型的上下文长度有限。一个较高的模型评分也不等于回答事实正确。

07 / 同一份偏好数据,两条训练路线

典型 RLHF 与 DPO 的位置

以下是教学中的典型流程,不是所有语言模型训练都必须按此顺序执行。先有预训练模型,再用示范回答做监督微调(SFT)。之后让人比较同一提示下的两个回答,例如偏好 A 胜过 B。

预训练模型→SFT 示范数据→同题两个回答
人选更好者

RLHF:先学奖励,再做 RL

偏好成对数据→奖励模型
估评分
→采样新回答→优化策略
例:PPO

奖励模型把偏好转为训练信号;策略模型生成回答并接受这个信号。常加参考模型约束,减少策略偏离原有模型过多。最后仍要用独立人工或任务评估检查结果。

DPO:直接用偏好对更新策略

偏好成对数据→策略与参考模型
比较相对概率
→偏好损失
直接优化

原始 DPO 方法无需单独训练显式奖励模型,也不需要在其偏好优化步骤中在线采样回答再跑 RL 循环。它依赖偏好数据和参考策略;这不表示它没有目标函数、没有参考模型,或能免除偏好数据质量问题。

要问的问题典型 RLHF(奖励模型 + PPO)原始 DPO
偏好数据用在哪?训练显式奖励模型直接构造策略偏好损失
该训练阶段需要在线采样新回答吗?策略优化时通常需要偏好优化阶段不需要
需要单独的显式奖励模型吗?需要不需要
输出的是什么?改进后的语言模型策略改进后的语言模型策略

08 / 学会质疑优化目标

高代理评分不一定是真正的好回答

假设评估器喜欢“看起来很详细”。下面的分数完全是虚构的教学数字:回答 A 简短且正确,人类质量 9;回答 B 冗长但有事实错误,人类质量 2。调整代理评分对篇幅的权重,看它什么时候错误地更偏好 B。

真实奖励模型可能误读事实、格式或提示意图;策略会倾向于利用评分器的缺陷。最终要用与训练奖励不同的证据检查正确性、帮助程度与失败案例。

09 / 实现、比较、画流程

动手练习与自测

配套代码:lesson-17-policy-gradient.py。在项目根目录运行 uv run python lessons/lesson-17-policy-gradient.py;它使用项目已有的 CPU PyTorch 和本地网格,不下载语言模型或数据。运行结果保存到 lessons/lesson-17-output/results.json。

  1. 在代码中找到 Categorical(logits=...)、log_prob、倒序计算 Gₜ 的函数和最终 loss。手算奖励 [0,0,0,10]、γ=0.8 时每个 Gₜ。
  2. 解释为什么式子里同时出现 γᵗ 和 Gₜ。把状态基线开关前后的三种子结果并排记录,别把一组实验当作通用定律。
  3. 自己画出典型 RLHF 以及 DPO 的训练流,指出奖励模型、参考模型和策略模型分别在哪。
  4. 用自己的话回答:Q-learning、DQN 与 REINFORCE 分别学什么?如果奖励模型喜欢冗长但错误的答案,你会怎样评估和修正?
验收:能解释一条延迟奖励轨迹如何更新最早动作;能说明基线为何不改变期望梯度;能区分本课实际运行的 REINFORCE 与只作概念讲解的 Actor-Critic/PPO/RLHF/DPO。本阶段不要求训练大语言模型。
1. REINFORCE 直接学习什么?
2. 若某个状态的基线只与状态有关、与当前动作无关,它在期望上会怎样影响策略梯度?
3. PPO 剪裁是否保证每次更新后的实际概率比都在边界内?
4. 原始 DPO 偏好优化阶段需要单独训练显式奖励模型吗?
下一节:构建知识问答系统。从模型训练回到完整应用:切分资料、检索相关内容,让回答能指出依据。