Prhub

#7544 [BREAKING][megatron, cfg] fix: remove unused grad_offload

原始 PR 作者 ji-huazhong 合并时间 2026-08-25 19:12 文件变更 53 提交数 1 评论 1 代码增减 +7 / -67

执行摘要

移除失效 grad_offload 配置,属 Breaking 清理

PR body 明确指出:The option was assigned to MegatronEngine._is_offload_grad but never consumed. Gradient buffer lifecycle already follows param_offload through the engine context, so removing this option does not change runtime behavior. 动机是消除误导性配置键,避免用户误以为存在独立的梯度 offload 开关,同时让 param_offload 成为唯一管理参数/梯度驻留的入口,并提前搜索确认没有其他 open PR 处理 grad_offload

值得快速阅读(约 15 分钟),重点关注两点:一是 verl/workers/config/engine.py 如何通过 dataclass + 生成配置联动维护配置契约,二是本 PR 与 #7536/#7466 形成的“清理死配置键”模式。如果有外部 Megatron 脚本或自定义配置,需要检查是否引用 grad_offload 并完成迁移。实现本身较机械,不需要深读。

讨论亮点

PR 只有 1 条 comment,是作者 @wuxibin89 请求 review;审查阶段没有 review comments,wuxibin89 直接以 APPROVED 状态合并,未留下额外意见。由于 grad_offload 已被证明是死配置项,且 PR body 已自查同类 PR,评审过程没有出现争议或未解决问题。值得注意的点是改动被明确标记为 BREAKING,并同步清理了所有仓库内引用,这降低了评审成本。

实现拆解

变更入口是 verl/workers/config/engine.pyEngineConfig dataclass,随后逐层清理引用。

  1. 配置层清理:删除 EngineConfig.grad_offload: bool = False 字段及其注释,并在 McoreEngineConfig 文档字符串中把 param_offload 的语义扩展为“offload 参数到 CPU,并在引擎非活跃时释放梯度缓冲”。
  2. 引擎层收敛:在 verl/workers/engine/megatron/transformer_impl.pyMegatronEngine.__init__ 中删除 self._is_offload_grad = self.engine_config.grad_offload,初始化只保留 _is_offload_param_is_offload_optimizer
  3. 示例与测试覆盖删除:从 53 个文件中的 shell 脚本移除 grad_offload 相关环境变量与参数覆盖,涉及 tests/special_e2e/run_ppo_trainer_megatron.shrun_v1_separate_async*.shtests/special_npu/nightly_ci_ascend/*.sh 以及 examples/ 下脚本;例如删除 COMMON_GRAD_OFFLOADACTOR_GRAD_OFFLOADCRITIC_GRAD_OFFLOAD 变量及 actor_rollout_ref.actor.megatron.grad_offload=$... 等参数。
  4. 生成配置与文档同步:重新生成 verl/trainer/config/_generated_ppo_megatron_trainer.yaml 等扁平配置,修改 verl/trainer/config/engine/megatron.yaml 删除 grad_offload 键并更新 param_offload 注释,同时更新相关文档说明。
  5. 测试验证:更新 tests/workers/config/test_engine_config_on_cpu.pyparametrize 参数列表(移除 "grad_offload")与 tests/models/test_engine.pykwargs;PR body 报告 CPU 配置测试 10 passed、shell 脚本 bash -n 通过、pre-commit 全部通过,且无需改动 CI workflow。
文件 模块 状态 重要度
verl/workers/config/engine.py 引擎配置 modified 5.34
verl/workers/engine/megatron/transformer_impl.py 引擎实现 modified 4.96
verl/trainer/config/engine/megatron.yaml 训练配置 modified 3.92
tests/special_e2e/run_ppo_trainer_megatron.sh 端到端测试 modified 4.06
tests/workers/config/test_engine_config_on_cpu.py 配置测试 modified 3.46
tests/models/test_engine.py 模型测试 modified 3.49

关键符号

EngineConfig McoreEngineConfig MegatronEngine.__init__

关键源码片段

verl/workers/config/engine.py core-logic

删除 `EngineConfig.grad_offload` 字段并更新 `McoreEngineConfig` 文档,是本次配置契约变更的源头。

@dataclass
class EngineConfig(BaseConfig):
    _mutable_fields = BaseConfig._mutable_fields | {
        "use_dynamic_bsz",
        "max_token_len_per_gpu",
        "micro_batch_size_per_gpu",
        "infer_max_token_len_per_gpu",
        "infer_micro_batch_size_per_gpu",
        "use_fused_kernels",
        "use_remove_padding",
        "forward_only",
        "param_offload",
    }
​
    # 参数 offload 开关;开启后参数驻留 CPU,引擎空闲时同步释放梯度缓冲
    param_offload: bool = False
    # 优化器状态 offload 开关
    optimizer_offload: bool = False
    # grad_offload 已整体移除:此前仅被赋值给 MegatronEngine._is_offload_grad,
    # 从未被任何逻辑消费,梯度缓冲生命周期已完全由 param_offload 管理
    # 引擎是否仅做 forward(例如 ref policy)
    forward_only: bool = False
verl/workers/engine/megatron/transformer_impl.py core-logic

移除 `MegatronEngine.__init__` 中唯一的 `_is_offload_grad` 赋值,确认该标志在引擎层面从未被消费。

def __init__(
    self,
    model_config: HFModelConfig,
    engine_config: McoreEngineConfig,
    optimizer_config: McoreOptimizerConfig,
    checkpoint_config: CheckpointConfig,
):
    super().__init__()
    self.model_config = model_config
    self.engine_config = engine_config
    self.optimizer_config = optimizer_config
    self.checkpoint_config = checkpoint_config
    assert self.engine_config.use_mbridge, "use_mbridge must be True"
    _check_dcp_unsupported_features(self.engine_config, self.model_config)
    self._init_device_mesh()
    set_random_seed(seed=self.engine_config.seed)
​
    # 参数 offload:控制参数是否驻留 CPU
    self._is_offload_param = self.engine_config.param_offload
    # 梯度缓冲的生命周期不再由独立开关控制,
    # 引擎上下文会依照 param_offload 在闲置时释放梯度缓冲
    # 优化器 offload:控制优化器状态是否驻留 CPU
    self._is_offload_optimizer = self.engine_config.optimizer_offload
    self.mode = None
verl/trainer/config/engine/megatron.yaml configuration

Megatron 引擎默认配置模板,删除 `grad_offload` 键并更新 `param_offload` 注释,是用户直接可见的配置入口。

_target_: verl.workers.config.McoreEngineConfig# 参数 offload 开关;引擎非活跃时同步释放梯度缓冲
param_offload: False# 优化器状态 offload 开关
optimizer_offload: False# tensor model parallel size
tensor_model_parallel_size: 1# expert model parallel size
expert_model_parallel_size: 1# pipeline model parallel size
pipeline_model_parallel_size: 1# sequence parallel
sequence_parallel: True# 是否使用 distributed optimizer
use_distributed_optimizer: True

评论区精华

没有提炼出高价值讨论线程

当前评论区没有形成足够清晰的争议点或结论,后续有更多讨论时会体现在这里。

风险与影响

  1. Breaking 配置契约EngineConfig 删除 grad_offload 字段后,任何仍通过 Hydra 配置、命令行覆盖或外部脚本引用该键的用户配置都会在 dataclass 实例化时报错,需要用户手动删除该键。仓库内 53 个文件已同步,但仓库外部 recipe、内部工具或用户自定义脚本可能存在遗漏引用。
  2. 配置同步面广:该改动需要与 _generated_*_megatron_trainer.yaml 等生成文件、示例脚本和文档保持同步;若后续其他 PR 重新引入类似开关,需要警惕配置与实例化检查脱节。
  3. 回归风险较低但存在:PR 声明 grad_offload 从未被消费,但主要验证集中在 CPU 配置测试与 shell 语法检查,缺少一次真实 GPU/NPU 训练 E2E 来最终确认 offload 路径无行为变化。由于没有运行时路径变更,此风险很低。
  4. 不涉及性能或安全问题,因为改动不影响运行时逻辑。

对用户而言,使用 Megatron 后端并显式设置 grad_offload 的配置将在升级后加载失败,属于需要迁移的 Breaking 变更;使用默认配置或未引用该键的用户无感知。对代码库而言,配置面收敛为 param_offload + optimizer_offload,减少误导性配置项与文档负担,降低新用户误用成本。影响范围主要在配置层与 shell 脚本,不涉及训练/推理运行时热路径,整体影响面中等但影响深度较浅。

Breaking 配置契约 跨 53 文件同步 外部引用风险 低回归风险

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论