RLHF(Reinforcement Learning from Human Feedback)全过程的详细梳理(PPO近端策略优化)
下面是 RLHF(Reinforcement Learning from Human Feedback)的PPO全过程的详细梳理,按两大阶段划分,并列出每个模块的输入与输出。
第一阶段:Reward 模型训练
-
基准模型(Pretrained LM)
-
输入:公开预训练语言模型权重(如 LLaMA、Meta-Llama-3.1-8B-Instruct)
-
输出:加载好的 Transformer 模型实例
-
-
人类偏好数据集(Human Preference Dataset)
-
格式:若干条
{ question, chosen_answer, rejected_answer } -
输入:从 JSON 文件(
preference.json)读取,每条包含用户对比偏好
-
-
数据预处理
-
输入:
question+chosen_answer,question+rejected_answer -
输出:分别的 Tokenizer 编码:
-
input_ids_chosen,attention_mask_chosen -
input_ids_rejected,attention_mask_rejected
-
-
-
Reward 模型微调(Sequence Classification)
-
输入:
-
4-bit 量化的
AutoModelForSequenceClassification(初始化权重同基准模型) -
LoRA 配置(
LoraConfig) -
上一步的编码数据集
-
-
输出:经人类偏好监督微调后的 Reward 模型权重,保存在
./reward_model
-
第二阶段:PPO 强化学习
-
训练模型初始化(Policy + Value Head)
-
输入:
-
同一基准模型权重
-
Reward 模型(
reward_adapter="./reward_model") -
LoRA + 4-bit 量化 配置
-
-
输出:
AutoModelForCausalLMWithValueHead实例,含有策略头和价值头
-
-
Query 数据集(Queries Dataset)
-
输入:JSON 文件
queries.json,每条{ query } -
输出:
datasets.Dataset,在 PPO 中逐批取出用于生成
-
-
生成(Generation / Sampling)
-
输入:
-
当前策略模型(Policy LM)
-
批量的
queryTensor -
采样参数(
do_sample=True,top_p=1.0,max_new_tokens=32等)
-
-
输出:对应的
responseTensor
-
-
Reward 计算
-
输入:
-
连接后的
input_ids = [query; response] -
Reward 模型(Sequence Classifier)
-
-
输出:每条样本的 Reward Score(标量,越高越符合人类偏好)
-
-
Baseline(状态价值估计)
-
输入:同样的
input_ids,进入训练模型内部的 Value Head -
输出:Baseline Value(状态价值估计,用于去除方差)
-
-
Advantage 计算
-
输入:
-
Reward Score (R)
-
Baseline Value (V)
-
-
输出:
Advantage = R − V
-
-
PPO 更新
-
输入:
-
原始 Policy LM logits
-
Advantage
-
KL 惩罚系数(
kl_penalty="full") -
PPO 超参(
ppo_epochs,batch_size,mini_batch_size)
-
-
输出:
-
更新后的策略网络参数
-
更新后的价值头参数
-
-
-
迭代
-
流程:回到「生成」步骤,直到遍历完所有批次或达到训练轮次
ppo_epochs
-
-
保存最终模型
-
输入:经过若干轮 PPO 更新后的训练模型
-
输出:保存到
./rl_model,即可用于下游生成任务
-
附录(一些问题):
-
Baseline(状态价值估计)的作用
在策略梯度法(包括 PPO)里,我们要最大化期望回报直接对 RR 做梯度更新会有很高的方差,因为不同轨迹(query→response)给到的 RR 可以相差很大。引入基线(baseline)——也就是对当前策略下该状态(已生成的 tokens 序列)“应该”获得的期望价值 V(s)V(s) 的一个估计——可以把梯度改写为:
这里的 (R−V(s)) 就是优势函数(Advantage),它衡量了“实得回报”比“预估回报”高了多少:
-
如果 R 远高于 V(s),说明这次动作(生成的回答)特别好,梯度就会放大;
-
如果 R远低于 V(s),说明这次回答不及预期,梯度会反向,抑制这类生成;
同时,因为你减去了一个关于状态 s 的常数项(V(s)),理论上不改变梯度的期望(保持无偏),但大幅降低了方差,使训练更稳定、更快收敛。
-
-
训练模型(Policy)和状态价值模型(Value Head)是否共用 LoRA 矩阵?
-
是的,Policy(策略头)和 Value(状态价值头)共用同一套底层 Transformer 参数,也包括同一组 LoRA adapter 权重。
-
它们的唯一区别在于:
-
策略头(Policy Head)负责预测下一个 token 的分布;
-
价值头(Value Head)负责输出当前序列的价值估计 V(s)。
-
-
更新过程:
-
在每次 PPO 步骤中,你会同时根据 Advantage 对策略头做梯度更新(提高好回复的概率,降低差回复的概率),也会对价值头做回归目标更新(让V(s) 更准确地逼近实际回报 R)。
-
由于它们共享底层 Transformer + LoRA 参数,PPO 更新实际上是联合优化:同一套参数同时被两种信号驱动,一部分来自策略梯度,另一部分来自价值回归。
-
因此,你可以把整个训练模型看成一个“骨干+两对头”的网络:
[Transformer + LoRA adapters] / \ Policy Head Value Head在 PPO 中,每一步都对这三部分(骨干、Policy Head、Value Head)进行更新,只是梯度来源不同。
-
3. 但是两个头返回的梯度不同的话,该怎么去反向传播更新骨干lora参数呢,这不就是存在两套梯度吗
在 PyTorch(以及大多数深度学习框架)里,共享参数接受来自所有损失项的梯度贡献,然后在一次 optimizer.step() 中把这些梯度“打包”更新。具体来说,在 PPO 里通常会定义一个总损失,比如

-
策略损失
来自 Policy Head(基于优势函数的剪切比率损失);
-
价值损失
来自 Value Head(一般是
的均方误差);
-
熵正则 H\mathcal{H} 也是在策略输出上计算,以鼓励多样性。
框架做的就是:
-
前向:给一批样本同时算出策略 logits(Policy Head)和价值估计V(s)(Value Head);
-
各自算损失:策略损失
、价值损失
、(可选)熵损失
;
-
合成总损失:

-
反向传播:
loss_total.backward()——这一步会对共享的 Transformer+LoRA、Policy Head 和 Value Head 都累计梯度; -
参数更新:
optimizer.step()——所有梯度一起作用,更新共享参数和各自头的参数。
这样,你就不会“有两套互斥的梯度”困扰:所有分支的梯度自动相加,在一次反向传播/一次优化步骤里共同决定参数往哪个方向走。你可以通过调节 和
来平衡策略改进和价值估计的影响力。
4. 给出”状态价值估计“的公式,并用通俗易懂的话语进行解释


5. 为什么状态价值函数计算是从后往前,而不是从前往后

6. 策略头与价值头的梯度函数


7. 那π θ 是怎么来的

8. 解释一下”取序列最后一个位置的隐藏向量 ℎ 𝑡 ∈ 𝑅 𝑑“,为什么是取最后一个位置的,隐藏向量指的是什么?


9. 这一步是怎么做的”把 ℎ 𝑡 (或者对所有位置的 ℎ 𝑖 再做一次处理)用来估计当前生成序列的总体价值 𝑉 ( 𝑠 𝑡 ) 。“



9. 策略头和价值头都是相同层数的全连接网络构成的吗


更多推荐
所有评论(0)