Prhub

#6674 [trainer, megatron] fix: fix MindSpeed repatch config bug

原始 PR 作者 chengminhua 合并时间 2026-06-10 16:57 文件变更 1 提交数 1 评论 3 代码增减 +9 / -2

执行摘要

修复 MindSpeed 重复 patch 注册问题

Fix NPU Megatron actor initialization when using MindSpeed batch-invariant training ( batch_invariant_mode + use_flash_attn_npu_batch_invariant ), e.g. true-on-policy / train-inference consistency recipes. Two issues:

1) attention_backend type mismatch causes 'Batch invariant mode only supports FlashAttention' even when flash is configured;
2) Duplicate MindSpeed patch registration causes RuntimeError: the patch of forward exist !.

本 PR 属于针对特定硬件(NPU)和配置(批次不变训练)的修复,改动量小但关键。建议相关工程师精读,尤其是 mapping_string_to_attn_backend 的类型转换模式值得在其他类似场景复用。review 中关于 .get() 安全性的建议虽未采纳,但在不同运行环境下可能成为问题,需关注。

讨论亮点

reviewer gemini-code-assist[bot] 指出 engine_config.get("override_transformer_config", {}) 中 .get() 方法在 engine_config 为原生 dataclass 而非 OmegaConf DictConfig 时会抛出 AttributeError,建议改为属性访问 engine_config.override_transformer_config or {} 以确保兼容性。但作者未采纳此建议,最终合并的代码仍保留了 .get() 调用。此外,wucong25 询问 mapping_string_to_attn_backend 的作用,作者 chengminhua 解释为类型转换 helper,将 Hydra 传入的字符串 attention 后端转为 Megatron 枚举,以规避 MindSpeed 复用 Megatron 代码时的参数校验问题。

实现拆解

  1. 类型转换前置:在 _mindspeed_repatch 中新增导入 verl.utils.megatron_utils.mapping_string_to_attn_backend,用其对 override_transformer_config 中的 attention_backend 字段进行类型转换,将 Hydra/YAML 传入的字符串 flash 转为 Megatron 枚举 AttnBackend.flash,确保 MindSpeed 内部的类型校验通过。
  2. 避免重复 patch:当 repatch_config 中 use_flash_attn_npu_batch_invariant 为 True 时,显式将 use_flash_attn 设为 False,防止批次不变注意力机制与融合注意力机制同时注册 DotProductAttention.forward 导致重复 patch 错误。仅在 use_flash_attn_npu_batch_invariant 为 False 或缺失时,才执行原有的 .setdefault("use_flash_attn", True)。
  3. 其他逻辑不变:保留原有对 context_parallel_size 的处理逻辑。
  4. 测试配套:本次变更未附带新增的单元测试或集成测试,仅对原有函数逻辑进行了修复。由于该修复涉及 NPU 硬件场景,可能依赖 NPU CI 验证。
文件 模块 状态 重要度
verl/workers/engine/mindspeed/transformer_impl.py 引擎 modified 6.89

关键符号

_mindspeed_repatch

关键源码片段

verl/workers/engine/mindspeed/transformer_impl.py bugfix

修复 MindSpeed repatch 配置 bug 的唯一修改文件,核心逻辑变更。

# verl/workers/engine/mindspeed/transformer_impl.py
​
def _mindspeed_repatch(engine_config):
    if repatch is not None:
        # 内部导入以避免循环依赖
        from verl.utils.megatron_utils import mapping_string_to_attn_backend
​
        # 1. 将 override_transformer_config 中的 attention_backend 从字符串(如 "flash")
        # 转换为 Megatron 枚举 AttnBackend.flash,避免 MindSpeed 校验时类型不匹配
        repatch_config = mapping_string_to_attn_backend(
            dict(engine_config.get("override_transformer_config", {}))
        )
​
        # 2. 若启用了 NPU 批次不变闪存注意力,则禁用融合注意力(use_flash_attn),
        # 因为两者都会注册 DotProductAttention.forward,导致 "patch of forward exist" 错误
        if repatch_config.get("use_flash_attn_npu_batch_invariant"):
            repatch_config["use_flash_attn"] = False
        else:
            repatch_config.setdefault("use_flash_attn", True)
​
        if engine_config.context_parallel_size > 1:
            repatch_config["context_parallel_size"] = engine_config.context_parallel_size
​
        repatch(repatch_config)

评论区精华

engine_config.get() 兼容性 正确性

gemini-code-assist[bot] 指出 `engine_config.get()` 在原生 dataclass 上会抛出 AttributeError,建议改为属性访问。

结论:作者未采纳建议,最终代码仍使用 `.get()`。 · 已解决

mapping_string_to_attn_backend 的作用 question

wucong25 询问新引入的转换函数的作用。

结论:chengminhua 解释为将 Hydra 字符串转为 Megatron 枚举,以规避 MindSpeed 参数校验。 · 已解决

风险与影响

  1. 兼容性风险:engine_config.get() 在原生 dataclass 上可能抛出 AttributeError,但实际运行时 engine_config 通常为 OmegaConf DictConfig,风险较低。
  2. 回归风险:修改了 _mindspeed_repatch 的默认行为,若 use_flash_attn_npu_batch_invariant 在某些配置中意外被错误推断为 True,可能导致闪存注意力被禁用。
  3. 缺失测试:本次变更未添加单元测试,仅依赖 NPU CI 验证,回归覆盖不足。

影响范围限定于使用 MindSpeed 引擎在 NPU 上训练且启用批次不变模式的用户。修复后,用户可使用 use_flash_attn_npu_batch_invariant=True 配置正常启动训练,不再报错。对不使用 NPU 或 MindSpeed 的用户无影响。

新增函数调用路径 缺少测试覆盖 兼容性潜在问题

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论