Prhub

#6438 [fully_async] fix: initialize _dump_executor in FullyAsyncTrainer and FullyAsyncRollouter

原始 PR 作者 nanastassacos 合并时间 2026-05-22 22:07 文件变更 2 提交数 2 评论 2 代码增减 +4 / -0

执行摘要

修复 FullyAsync 未初始化 _dump_executor 的 bug

FullyAsyncTrainer 和 FullyAsyncRollouter 由于跳过 super().init(),导致 _dump_executor 未初始化,使得 _dump_generations 在验证或训练时抛出 AttributeError。PR body 明确描述了错误堆栈和原因。

本 PR 为一次精准的 bugfix,改动小、风险低,建议快速合并。对于关注 fully_async 功能的开发者,可以留意 _init_dump_executor 和 validation_generations_logger 的后续维护,确保与基类变更保持同步。

讨论亮点

gemini-code-assist[bot] 在 review 中指出,FullyAsyncTrainer 还缺少 validation_generations_logger 的初始化,若配置了 rollout_data_dir,_fit_dump_data 会调用 _dump_generations 进而访问 validation_generations_logger,导致另一个 AttributeError。作者回复认为验证路径通过 FullyAsyncRollouter 执行,但该添加无害,接受建议。

实现拆解

  1. 在 FullyAsyncTrainer.init 中补充初始化:在设置 global_steps、epoch 之后,插入 self._init_dump_executor()self.validation_generations_logger = None。确保后续 _dump_generations 调用时 _dump_executor 已存在。
  2. 在 FullyAsyncRollouter.init 中补充初始化:在设置 use_prefix_grouper 之后、进入“fully async config”小节之前,插入 self._init_dump_executor()。这样在调用 _validate → _dump_generations 时不会缺失 executor。
  3. review 反馈处理:gemini-code-assist[bot] 指出 FullyAsyncTrainer 还缺少 validation_generations_logger 初始化,若配置了 rollout_data_dir 可能触发另一 AttributeError。作者接受建议并补充了该初始化。
文件 模块 状态 重要度
verl/experimental/fully_async_policy/fully_async_trainer.py 异步训练器 modified 4.89
verl/experimental/fully_async_policy/fully_async_rollouter.py 异步 Rollouter modified 4.72

关键源码片段

verl/experimental/fully_async_policy/fully_async_trainer.py core-logic

修复核心文件,补充了 _dump_executor 初始化和 validation_generations_logger 初始化,解决训练时 _dump_generations 的 AttributeError。

# verl/experimental/fully_async_policy/fully_async_trainer.py
# 在 __init__ 的 SeparateRayPPOTrainer 配置段中补全基类应有的初始化
def __init__(self, config, ...):
    # ... 前置代码 ...
    self.global_steps = 0
    self.epoch = 0
    # 修复 : 初始化 _dump_executor (ThreadPoolExecutor),否则 _dump_generations 会报 AttributeError
    self._init_dump_executor()
    # 修复 : 初始化 validation_generations_logger,避免 _fit_dump_data 中访问 None
    self.validation_generations_logger = None
    self.max_steps_duration = 0
    # ... 后续代码 ...
verl/experimental/fully_async_policy/fully_async_rollouter.py core-logic

修复核心文件,补充了 _dump_executor 初始化,解决验证时 _dump_generations 的 AttributeError。

# verl/experimental/fully_async_policy/fully_async_rollouter.py
# 在 __init__ 中补全 dump executor 初始化
def __init__(self, config, ...):
    # ... 前置代码 ...
    self.use_prefix_grouper = self.config.actor_rollout_ref.actor.get("use_prefix_grouper", False)
    # 修复 : 初始化 _dump_executor,否则 do_validate -> _validate -> _dump_generations 会报 AttributeError
    self._init_dump_executor()
​
    # ==================== fully async config ====================
    # ... 后续代码 ...

评论区精华

FullyAsyncTrainer 缺少 validation_generations_logger 初始化 正确性

gemini-code-assist[bot] 指出,FullyAsyncTrainer 还缺少 validation_generations_logger 的初始化,若配置了 rollout_data_dir 可能导致另一 AttributeError。建议初始化为 None。

结论:作者接受建议,在 FullyAsyncTrainer 的 __init__ 中添加了 self.validation_generations_logger = None。 · 已解决

风险与影响

风险极低。变更仅在两处添加方法调用和属性初始化,未修改任何现有逻辑。但若 _init_dump_executor 内部存在副作用(如创建线程池)且被重复调用,需确保其幂等。当前 PR 中 init 只调用一次,无此问题。

影响范围限于 experimental/fully_async_policy 模块,仅 FullyAsyncTrainer 和 FullyAsyncRollouter 两个类。修复后,使用完全异步训练的用户在执行验证或训练 rollout 日志记录时不会再遇到 AttributeError。

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论