Prhub

#5967 [fully_async] fix: Add Mindspeed Patch for Async Training on Ascend NPUs

原始 PR 作者 HwCARI 合并时间 2026-04-20 13:54 文件变更 2 提交数 4 评论 5 代码增减 +167 / -1

执行摘要

修复完全异步训练在 Ascend NPU 上因 MindSpeed 补丁未应用导致的 torch_npu 错误。

根据PR body和review评论,动机是解决在Ascend NPU上进行完全异步训练时出现的torch_npu错误。问题根源是DetachActorWorker在初始化时立即调用_get_strategy_handlers(),导致megatron模块过早导入,使得MindSpeed的猴子补丁无法生效。这影响了完全异步训练路径在NPU上的正常运行。

该PR值得精读,特别是对于在Ascend NPU上使用完全异步训练的开发者。关注点包括:

  • 设计决策:将策略处理器改为属性方法以控制导入顺序,这是一种常见的延迟初始化模式,适用于依赖外部补丁的场景。
  • 代码组织:注意review中提到的补丁位置重构建议,这可能影响未来代码维护。
  • 关联风险:了解init_model中未解决的配置访问问题,避免在非Megatron策略下误用。
讨论亮点

review讨论主要集中在MindSpeed补丁的应用时机和安全性上:

  • gemini-code-assist[bot]指出潜在运行时崩溃风险:在verl/workers/engine_workers.pyinit_model方法中,直接访问self.config.actor.megatron可能在不使用Megatron策略时导致AttributeError或KeyError,建议添加防护条件。
  • HwCARI解释了问题根源DetachActorWorker.__init__()过早调用_get_strategy_handlers(),导致megatron模块在MindSpeed补丁前导入,使补丁失效。
  • wuxibin89建议重构补丁位置:提议将repatch函数移到verl/workers/engine/mindspeed/transformer_impl.py中,以更好地组织代码。
  • 结论:PR通过延迟加载策略处理器解决了导入顺序问题,但review中提到的init_model中的安全风险和补丁重构建议未在本PR中解决,可能留待后续处理。

实现拆解

  1. 修改DetachActorWorker的策略处理器加载逻辑

    • 文件:verl/experimental/separation/engine_workers.py
    • 关键符号:copy_handlerrestore_handler
    • 变更:移除__init__中直接调用_get_strategy_handlers()的代码,将copy_handlerrestore_handler改为@property装饰的属性方法,实现延迟加载。
    • 原因:避免在初始化时过早导入verl.utils.megatron_utils模块,从而确保MindSpeed补丁能在megatron模块导入前正确应用。
    • 影响:修复了完全异步训练在NPU上的兼容性问题,使save_model_to_cpurestore_model_from_cpu方法能正常调用处理器。
  2. 新增完全异步训练脚本示例

    • 文件:verl/experimental/fully_async_policy/shell/geo3k_qwen3vl_30b_megatron_6_2_npu_async.sh
    • 关键符号:无
    • 变更:新增一个shell脚本,配置了使用Megatron策略在Ascend NPU上训练Qwen3-VL-30B模型的完全异步训练参数。
    • 原因:提供修复后的使用示例,展示如何在实际场景中应用此修复。
    • 影响:帮助用户快速上手在NPU上进行完全异步训练。
  3. 其他配套调整

    • verl/experimental/separation/engine_workers.py中添加了from typing import Callable导入,以支持类型注解。
    • 无测试或配置文件的直接改动,但修复确保了现有测试和配置在NPU环境下的正确性。
文件 模块 状态 重要度
verl/experimental/separation/engine_workers.py 分离引擎 modified 6.92
verl/experimental/fully_async_policy/shell/geo3k_qwen3vl_30b_megatron_6_2_npu_async.sh 异步策略 added 4.89

关键符号

copy_handler restore_handler _get_strategy_handlers save_model_to_cpu restore_model_from_cpu

关键源码片段

verl/experimental/separation/engine_workers.py core-logic

核心修复文件,修改了 DetachActorWorker 的策略处理器加载逻辑,解决了 MindSpeed 补丁导入顺序问题。

class DetachActorWorker(ActorRolloutRefWorker):
    # ... 其他代码 ...
​
    def __init__(self, config: DictConfig, role: str):
        ActorRolloutRefWorker.__init__(self, config, role)
        self._strategy_handlers = None # 移除直接调用 _get_strategy_handlers(),避免过早导入
​
    def _get_strategy_handlers(self):
        # 延迟加载策略处理器,支持 FSDP、FSDP2 和 Megatron
        if self._strategy_handlers is not None:
            return self._strategy_handlers
        strategy = self.config.actor.strategy
        if strategy in ["fsdp", "fsdp2"]:
            from verl.utils.fsdp_utils import fsdp2_sharded_save_to_cpu, fsdp2_sharded_load_from_cpu
            self._strategy_handlers = (fsdp2_sharded_save_to_cpu, fsdp2_sharded_load_from_cpu)
        elif strategy == "megatron":
            from verl.utils.megatron_utils import copy_megatron_model_to_cpu, restore_megatron_model_from_cpu
            self._strategy_handlers = (copy_megatron_model_to_cpu, restore_megatron_model_from_cpu)
        else:
            raise NotImplementedError(f"Unsupported strategy: {strategy}")
        return self._strategy_handlers
​
    @property
    def copy_handler(self) -> Callable:
        """
        获取策略对应的复制处理器。
        通过属性延迟加载,确保在需要时才导入相关模块,避免干扰MindSpeed补丁。
        """
        return self._get_strategy_handlers()[0]
​
    @property
    def restore_handler(self) -> Callable:
        """获取策略对应的恢复处理器。"""
        return self._get_strategy_handlers()[1]
​
    @register(dispatch_mode=Dispatch.ONE_TO_ALL)
    def save_model_to_cpu(self, n):
        if not hasattr(self, "cpu_saved_models"):
            self.cpu_saved_models = {}
        self.cpu_saved_models[n] = self.copy_handler(self.actor.engine.module) # 使用属性方法调用处理器

评论区精华

MindSpeed 补丁导入顺序问题 正确性

HwCARI 指出 DetachActorWorker 初始化时过早调用 _get_strategy_handlers(),导致 megatron 模块在 MindSpeed 补丁前导入,使补丁失效。

结论:通过将 copy_handler 和 restore_handler 改为属性方法实现延迟加载,解决了导入顺序问题。 · 已解决

init_model 中配置访问安全性 正确性

gemini-code-assist[bot] 警告直接访问 self.config.actor.megatron 可能在不使用 Megatron 策略时导致运行时崩溃。

结论:未在本 PR 中解决,建议添加防护条件或后续重构。 · unresolved

补丁代码组织 设计

wuxibin89 建议将 repatch 函数移到 verl/workers/engine/mindspeed/transformer_impl.py 中以改善代码结构。

结论:未在本 PR 中实施,可能作为未来重构任务。 · unresolved

风险与影响

技术风险较低,主要涉及:

  • 回归风险:修改copy_handlerrestore_handler为属性方法,可能影响其他依赖这些属性的代码,但变更保持了接口一致性,风险可控。
  • 性能风险:延迟加载可能导致首次调用时轻微延迟,但避免了不必要的早期导入,整体影响可忽略。
  • 兼容性风险:修复针对Ascend NPU和Megatron策略,可能不适用于其他硬件或策略,但未破坏现有功能。
  • 安全风险:无直接安全影响。
  • 未解决风险:review中提到的init_model方法中的配置访问安全问题仍未处理,可能在非Megatron策略下引发崩溃。

影响范围有限但关键:

  • 对用户的影响:修复后,用户可以在Ascend NPU上正常使用完全异步训练功能,避免torch_npu错误,提升NPU训练的可用性。
  • 对系统的影响:仅影响使用Megatron策略的完全异步训练路径,对FSDP等其他策略无影响,系统其他部分保持稳定。
  • 对团队的影响:提供了NPU异步训练的示例脚本,降低了团队在NPU环境下的配置和调试成本。
  • 影响程度:中等,解决了特定硬件和训练模式下的阻塞问题,但未引入新功能或架构变更。
导入顺序敏感 配置访问未防护

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论