首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >07-PPO 在 LLM 后训练里真正训练了什么

07-PPO 在 LLM 后训练里真正训练了什么

作者头像
anzhsoft
发布2026-07-01 21:09:13
发布2026-07-01 21:09:13
670
举报

上一组最后一篇按 fit()走完了一轮 PPO/GRPO step。进入第二组,我们换一个视角:同一轮 step 里有 actor、rollout、reference policy、reward、critic,哪些真的在训练,哪些只是提供信号,哪些只是服务于生成?

本文的核心判断是:PPO 在 LLM 后训练里真正优化的是 actor policy;critic 如果启用,会作为辅助 value baseline 参与训练;reference policy 和 reward 不是在这轮 PPO 里被更新的主策略,而是分别提供偏离基准和偏好信号。把这些角色混成“几个模型一起训练”,会直接误解 PPO 的工程边界。

下面这张图先给出角色地图。看图时重点看箭头方向:谁产出样本,谁产出分数,谁产出基线,谁被反向更新。

PPO 后训练里的四个角色

这张图故意把 rollout engine 也画出来,因为很多误解来自这里:rollout 负责用策略生成 response,但它不是 loss 里的训练对象。训练后的 actor 权重还要同步回 rollout 侧,下一轮生成才会体现新策略。

1. 四个角色的职责不同

actor 是主策略。RayPPOTrainer._update_actor()会把已经补齐字段的 batch 转成 TensorDict,写入 mini-batch size、PPO epochs、shuffle、compute_loss=True等训练控制信息,然后调用 actor_rollout_wg.update_actor()verl/trainer/ppo/ray_trainer.py:1205-1245)。worker 侧 update_actor()再调用 actor 的 train_mini_batch()verl/workers/engine_workers.py:646-651)。

critic 是辅助 value model。只有 self.use_critic为真时,trainer 才会创建 critic worker、设置 value_loss,并在 step 中计算 values、更新 critic(verl/trainer/ppo/ray_trainer.py:714-738verl/trainer/ppo/ray_trainer.py:785-794verl/trainer/ppo/ray_trainer.py:1130-1142verl/trainer/ppo/ray_trainer.py:1247-1272)。它训练的是 value baseline,不是部署时回答用户的策略。

reference policy 是偏离基准。trainer 会用 need_reference_policy(config)决定是否需要 ref,并在需要时计算 ref_log_probverl/trainer/ppo/ray_trainer.py:290-295verl/trainer/ppo/ray_trainer.py:1144-1166)。如果 LoRA 场景下 ref_in_actor为真,reference policy 可能通过 actor worker 的无 LoRA adapter 路径计算,而不是独立 worker(verl/trainer/ppo/ray_trainer.py:303-307verl/trainer/ppo/ray_trainer.py:1151-1157)。这不改变它的职责:提供基准 logprob。

reward 是偏好信号来源。_compute_reward_colocate()只是调用 reward_loop_manager.compute_rm_score(batch)verl/trainer/ppo/ray_trainer.py:504-510)。它可以是 reward model、规则函数或环境反馈的统一入口;在这篇讨论的 PPO 主循环里,它的产物是 rm_scorestoken_level_scores或额外 reward 信息,而不是 actor 参数更新。

2. Actor loss 的输入合同是什么

actor 真正被训练,发生在 worker 侧的 ppo_loss()和 policy loss 函数里。ppo_loss()先从 model output 里拿当前 actor 的 log_probs,再从 data 中选择 response_maskold_log_probsadvantages,如果存在还会选择 rollout_is_weightsref_log_probverl/workers/utils/losses.py:57-91)。这说明 actor loss 的输入不是一个 reward 标量,而是一组已经在 fit()中准备好的证据。

下面这张图把 actor loss 合约展开。它补的是上一篇时间线没有展开的内部接口:old_log_probs是更新前锚点,当前 log_prob来自 actor forward,advantages决定强化方向,response_mask决定只训练 response tokens。

Actor policy loss 的输入合同

源码里默认的 vanilla policy loss 会计算 ratio = exp(log_prob - old_log_prob),再用 unclipped loss 和 clipped loss 取更保守的一项,最后按 response_mask聚合成 pg_lossverl/trainer/ppo/core_algos.py:1279-1370)。因此 PPO 的“稳定更新”在工程上体现为两个事实:必须重算或保留 old logprob,必须只在 response token 上聚合。

如果 actor 配置开启 use_kl_lossppo_loss()还会读取 ref_log_prob,计算 KL penalty,并把 kl_loss * kl_loss_coef加进 policy loss(verl/workers/utils/losses.py:131-144)。这条路径会直接改变 actor 的反向传播目标。

3. Critic 训练的是 baseline,不是另一个策略

critic 的训练合约更窄。value_loss()从 model output 里拿当前预测的 values,从 data 里选择旧 valuesreturnsresponse_mask,然后调用 compute_value_loss()得到 value loss 和相关指标(verl/workers/utils/losses.py:147-186)。也就是说,critic 不是在学习“怎样回答”,而是在学习 actor 已采样轨迹上的 value baseline。

PPO/GAE 为什么需要这个 baseline?compute_advantage()的 GAE 分支会把 token_level_rewardsvaluesresponse_mask传进 compute_gae_advantage_return(),后者反向递推 advantage,并把 returns = advantages + values作为 critic 训练目标(verl/trainer/ppo/ray_trainer.py:166-182verl/trainer/ppo/core_algos.py:216-263)。actor 消费 advantage,critic 消费 returns,两者在同一批 DataProto 上分工。

GRPO 的对比能更清楚地说明 critic 的角色。下面这张图把两种 baseline 放在一起:PPO/GAE 是可学习 value baseline,GRPO 是同一 prompt 多条 response 的组内相对 baseline。

Critic baseline 与 GRPO group baseline 的选择

在 GRPO 分支里,compute_advantage()compute_grpo_outcome_advantage()时传的是 token_level_rewardsresponse_maskuid,不传 valuesverl/trainer/ppo/ray_trainer.py:183-195)。compute_grpo_outcome_advantage()会把每条 response 的 reward 求和,再按 uid 计算组内均值和标准差,最后把相对分数广播到 response mask 上(verl/trainer/ppo/core_algos.py:268-331)。这也是下一篇《GRPO 为什么能省掉 critic》的入口。

4. Reference policy 有两个 KL 位置

reference policy 的职责容易被误解,因为它可能出现在两个位置。

第一个位置是 in-reward KL。fit()在 advantage 前会检查 algorithm.use_kl_in_reward;如果开启,会调用 apply_kl_penalty(),用 old_log_probsref_log_prob计算 KL,并从 token_level_scores中扣掉 beta * KL,得到 token_level_rewardsverl/trainer/ppo/ray_trainer.py:1496-1512verl/trainer/ppo/ray_trainer.py:75-114)。这时 KL 改写的是 advantage 看到的 reward。

第二个位置是 actor KL loss。前面提到,ppo_loss()config.use_kl_loss为真时,会把 KL loss 直接加进 actor policy loss(verl/workers/utils/losses.py:131-144)。这时 reward 不一定被改写,KL 作为 actor 更新目标的一部分出现。

下面这张图把两个位置分开。它和上一张 actor loss 图互补:上一张解释 loss 合约,这张解释 ref policy 的信号到底在哪一层进入训练。

Reference policy 的两个 KL 位置

配置校验里也能看到这两个位置的关系:如果同时开启 in-reward KL 和 actor KL loss,validate_config()会打印 notice(verl/utils/config.py:169-170)。这不是说一定错误,而是提醒读代码和写系统分析时必须先说清楚:KL 是放进 reward,还是放进 actor loss,还是两者都开。

小结:PPO 训练的是策略,其他角色定义训练问题

这一篇可以压缩成一句话:

代码语言:javascript
复制
reward 定义偏好信号,reference 定义偏离边界,
critic 定义 baseline,actor 才是被 PPO policy loss 更新的主策略。

这句话也把第二组的路线打开了。下一篇写 GRPO 时,重点不再是重复 actor/ref/reward/critic 的角色,而是解释为什么把 baseline 从 critic value 换成 group-relative reward 后,系统可以省掉 critic 路径,同时会引入 rollout.n、同 prompt 多样本、reward 方差和长度偏置等新问题。

本文源码索引

  • verl/trainer/ppo/ray_trainer.py:290-312:trainer 如何判断 reference policy、critic、in-reward KL 是否启用。
  • verl/trainer/ppo/ray_trainer.py:714-807init_workers()如何创建 actor、critic、ref worker。
  • verl/trainer/ppo/ray_trainer.py:504-510:reward loop 如何提供 reward 分数。
  • verl/trainer/ppo/ray_trainer.py:1130-1166:critic value 和 reference logprob 的计算路径。
  • verl/trainer/ppo/ray_trainer.py:1205-1272:actor update 与 critic update 的 trainer 入口。
  • verl/trainer/ppo/ray_trainer.py:1496-1512:advantage 前 token-level reward 与 in-reward KL 的位置。
  • verl/workers/utils/losses.py:57-144ppo_loss()的输入字段、policy loss 和 actor KL loss。
  • verl/workers/utils/losses.py:147-186value_loss()如何训练 critic baseline。
  • verl/trainer/ppo/core_algos.py:216-331:GAE 与 GRPO 两种 advantage/baseline 路径。
  • verl/trainer/ppo/core_algos.py:1279-1370:vanilla PPO clipped objective 的实现。
  • verl/workers/engine_workers.py:646-651:actor worker 如何进入 train_mini_batch()
  • verl/utils/config.py:169-170:同时开启 in-reward KL 与 actor KL loss 的配置提示。
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-06-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 训推工坊 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 四个角色的职责不同
  • 2. Actor loss 的输入合同是什么
  • 3. Critic 训练的是 baseline,不是另一个策略
  • 4. Reference policy 有两个 KL 位置
  • 小结:PPO 训练的是策略,其他角色定义训练问题
  • 本文源码索引
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档