跳转至

ray_trainer.py — SeparateRayPPOTrainer 扩展了标准的 RayPPOTrainer

文件路径: verl/experimental/separation/ray_trainer.py

文件概述

SeparateRayPPOTrainer 扩展了标准的 RayPPOTrainer,实现了分离式 PPO 训练。核心特点是将训练步骤(fit_step)拆分为约 15 个独立的子方法,支持: - 完全异步策略(Fully Async Policy):推理和训练使用不同版本的策略 - 一步离策略(One-Step Off-Policy):使用旧策略生成的数据来更新当前策略

核心设计:模块化的 fit_step

标准 RayPPOTrainer 的 fit_step 是一个大方法,SeparateRayPPOTrainer 将其拆分:

class SeparateRayPPOTrainer(RayPPOTrainer):
    def fit_step(self):
        """一步 PPO 训练,拆分为多个子步骤"""
        self._fit_prepare_step()        # 准备阶段
        self._fit_generate()            # 生成 rollout
        self._fit_compute_reward()      # 计算奖励
        self._fit_compute_ref_log_prob() # 计算参考策略对数概率
        self._fit_compute_advantages()   # 计算优势函数
        self._fit_update_actor()        # 更新 Actor
        self._fit_update_critic()       # 更新 Critic
        self._fit_log_metrics()         # 记录指标
        self._fit_cleanup()             # 清理

模块化的好处

  1. 可重写性:子类可以只覆盖需要修改的步骤
  2. 可测试性:每个子步骤可以独立测试
  3. 灵活组合:不同训练模式可以重新组合这些步骤

完全异步策略(Fully Async Policy)

在标准 PPO 中,生成数据和训练更新是串行的。异步策略允许:

def _fit_generate(self):
    """使用旧版本策略生成数据,同时当前策略可能在训练"""
    if self.async_mode:
        # 推理使用 rollout 模型(可能是旧版本)
        # 不需要等待训练完成
        data = self.rollout_wg.generate_sequences(...)
    else:
        data = self.actor_wg.generate_sequences(...)

异步流水线

时间线:
Step N:   [生成数据 N] ──> [计算奖励] ──> [训练更新 N]
Step N+1: [生成数据 N+1] ──> [计算奖励] ──> ...
                              (与训练 N 并行)

一步离策略(One-Step Off-Policy)

使用前一步生成的数据来训练,而不是必须用当前策略生成的数据:

def _fit_update_actor(self):
    """更新 Actor,支持离策略数据"""
    if self.off_policy:
        # 使用旧数据训练(数据可能是前一步策略生成的)
        data = self.previous_step_data
    else:
        # 使用当前步骤数据训练(标准 on-policy)
        data = self.current_step_data

    self.actor_wg.update_policy(data)

GPU 资源分离

配合 DetachActorWorker,实现 GPU 时分复用:

def _fit_generate(self):
    # Actor 模型在 GPU 上做推理
    data = self.actor_wg.generate_sequences(...)
    # 保存 Actor 到 CPU
    self.actor_wg.save_model_to_cpu()

def _fit_update_critic(self):
    # Critic 模型占用 GPU 做训练
    self.critic_wg.update_value(...)

def _fit_update_actor(self):
    # 恢复 Actor 到 GPU 做训练
    self.actor_wg.restore_model_from_cpu()
    self.actor_wg.update_policy(...)

核心类/函数列表

名称 类型 说明
SeparateRayPPOTrainer 类 分离式 PPO 训练器
fit_step 方法 模块化的训练步骤
_fit_prepare_step 方法 准备阶段
_fit_generate 方法 生成 rollout 数据
_fit_compute_reward 方法 计算奖励
_fit_compute_ref_log_prob 方法 计算参考策略概率
_fit_compute_advantages 方法 计算 GAE 优势函数
_fit_update_actor 方法 更新 Actor 网络
_fit_update_critic 方法 更新 Critic 网络
_fit_log_metrics 方法 记录训练指标
_fit_cleanup 方法 清理临时数据

与其他模块的关系

  • 继承自 verl.trainer.ppo.ray_trainer.RayPPOTrainer
  • 使用 DetachActorWorker(engine_workers.py)做模型迁移
  • 与 verl.experimental.fully_async_policy 和 verl.experimental.one_step_off_policy 概念相关

小结

SeparateRayPPOTrainer 通过将训练步骤模块化,支持了更灵活的训练模式。核心价值是: 1. 异步训练提高 GPU 利用率(生成和训练可以并行) 2. GPU 时分复用降低硬件需求(同一组 GPU 服务多个模型) 3. 模块化设计方便扩展和定制