已合并
feat(trainer): support Qwen3-MoE attention activation swap #1177
feat(trainer): support Qwen3-MoE attention activation swap #1177
已合并
songjiaqi创建于 8月15日
songjiaqi
songjiaqi成员
8月15日

What type of PR is this?

/kind feature


What does this PR do / why do we need it:
本 PR 为 Hugging Face Qwen3-MoE 模型新增注意力激活换出(attention activation swap)能力,通过在训练期间将较大的注意力激活张量换出设备,降低设备显存占用。

主要变更如下:

  • 新增训练器配置项 activation_swap,支持 noneattention,默认值为 none,不会改变现有训练行为。
  • 使用 swap_wrapper 包装每一层 Qwen3MoeAttention 模块,并通过 SwapManager 配置逐层预取。
  • 仅换出需要梯度、存储空间独立且大小达到阈值的注意力激活张量;小张量和共享底层存储的视图仍保留在设备上。
  • 将该能力接入训练器和模型构建流程,并确保在分片、torch.compile 和 FSDP 包装之前完成配置校验及模块包装。
  • 对暂不支持的组合进行显式校验,包括 torch.compile、激活重计算和流水线并行。
  • 校验模型类型与模块层级,当前仅支持 Hugging Face Qwen3MoeForCausalLM
  • 新增配置解析、参数传递、张量筛选策略、互斥特性校验、注意力模块包装及逐层预取调度相关单元测试。

Which issue(s) this PR fixes:

Fixes #https://gitcode.com/mindspore/hyper-parallel/issues/323


Test Plan and Test result:What scenarios were tested, and what were the verification results(function, performance, reliability, etc.)

本 PR 新增或更新了以下单元测试:

  • tests/hyper_models/trainer/test_attention_swap.py
    • 验证仅符合条件的大型注意力激活张量会被换出。
    • 验证开启 torch.compile、激活重计算或流水线并行时能够正确拒绝不兼容配置。
    • 验证 Qwen3-MoE 的 48 个注意力模块均被正确包装,归一化层和 MLP 模块保持不变。
    • 验证正确建立 47 个相邻层预取关系,且模型的 state_dict 键保持不变。
  • tests/hyper_models/trainer/test_data_build.py
    • 验证 activation_swap 能够从 TrainerConfig 正确传递至模型构建流程。
  • tests/ut/config/test_resolver.py
    • 验证 activation_swap 的默认值及合法配置值能够正确解析。
    • 验证不支持的配置值会被拒绝。

本地执行命令:

python -m pytest tests/hyper_models/trainer/test_attention_swap.py tests/hyper_models/trainer/test_data_build.py tests/ut/config/test_resolver.py -q

当前本地环境未安装可选依赖 transformers,测试在收集阶段中止,尚未获得本地执行通过结果,最终执行结果以 CI 为准。


Self-checklist:(请自检,在[ ]内打上√,我们将检视你的完成情况,否则会导致pr无法合入)

likedislike
Pull Request已成功合入, 合并人@MindSpore-Bot
(感谢 songjiaqi 的贡献)
songjiaqisongjiaqi成员
8月15日 创建了 pull request,commit c46df27c
atomgit-bot
atomgit-bot
8月15日 评论:

变更摘要

本 PR 引入面向 Hugging Face Qwen3-MoE 模型的注意力激活交换(attention activation swap)能力:新增 activation_swap 配置项(取值 none / attention,默认 none),并新增 hyper_models/components/distributed/attention_swap.py 模块,利用 swap_wrapperSwapManagerCheckpointPolicyQwen3MoeAttention 进行包装和逐层 prefetch 调度,将注意力前向中的大张量激活换出以降低显存占用。同时将该能力接入模型构建链路(auto_model.pyinfrastructure.pybase.py),并在应用 sharding、torch.compile、FSDP 之前完成包装,且校验其与编译、激活重计算、流水线并行等特性的互斥关系。

主要改动

  • 新增配置项 activation_swap:在 TrainerConfig 中新增 activation_swap: Literal["none", "attention"] = "none" 字段,并在 examples/training_demo/train.yaml 中增加 activation_swap: none # attention, none 配置项。
  • 新增 attention_swap.py 模块:实现 qwen3_attention_swap_policy(按张量是否可导、维度、存储是否独立、大小是否超过 _MIN_SWAP_TENSOR_BYTES 决定 MUST_SWAP / MUST_SAVE)、validate_attention_swap(校验非法模式及与 torch.compile、activation checkpointing、pp_size != 1 的互斥)以及 apply_qwen3_moe_attention_swap(校验模型层级结构、用 swap_wrapper 替换各层 self_attn 并通过 SwapManager.set_forward_prefetch_layer 建立层间 prefetch)。
  • 模型构建链路接入auto_model.pyfrom_pretrainedfrom_config 及核心构建函数均新增 activation_swap 参数并透传;apply_model_infrastructure 新增参数并在 Step 9-2 于 sharding、compile、FSDP 之前执行校验与 attention swap 包装。
  • 训练器透传配置base.py 在构建模型时将 self.config.activation_swap 传入,测试辅助函数 _model_target 及对应断言同步增加 activation_swap 字段。
  • 新增测试覆盖:新增 tests/hyper_models/trainer/test_attention_swap.py,覆盖 policy 过滤、互斥特性校验、仅包装 attention 且调度 47 层 prefetch 等场景;test_resolver.py 增加 activation_swap 默认值、合法值及非法值解析测试。
likedislike
不准确?
atomgit-bot
atomgit-bot
8月15日 评论:

代码审查

我已逐一审查全部 9 个变更文件。下面是审查结论汇总。

审查结论(按文件)

  1. examples/training_demo/train.yaml — 无问题。activation_swap: none 为顶层键,缩进正确,与 TrainerConfig.activation_swap 字段对应;none 会被 PyYAML 解析为字符串而非 null,能通过 resolver 的 Literal 校验。
  2. hyper_models/_transformers/auto_model.py — 发现问题:_build_model 删除了 distributed_setup=distributed_setup 透传(P1)。
  3. hyper_models/_transformers/infrastructure.py — 发现问题:attention swap 被放在 sharding 之后,违反其自身注释的"sharding 前安装"前置条件(P2)。
  4. hyper_models/components/distributed/attention_swap.py — 发现问题:未使用的 get_platform/PlatformType 导入与模块级 get_platform() 副作用(P3)。
  5. hyper_models/trainer/base.py — 无问题。activation_swap=self.config.activation_swap 透传正确,且 Target.build 会按签名过滤未知参数,不会破坏自定义 model target。
  6. hyper_models/trainer/config.py — 无问题。activation_swap: Literal["none", "attention"] = "none" 与 resolver 的 Literal 处理及错误信息格式一致。
  7. tests/hyper_models/trainer/test_attention_swap.py — 无问题。policy 边界用例(1MiB 阈值、view/共享存储、requires_grad)与 48 层→47 次 prefetch 断言均正确。
  8. tests/hyper_models/trainer/test_data_build.py — 无问题。_model_target 新增 activation_swap 形参,_build_model 恒会传入,断言一致。
  9. tests/ut/config/test_resolver.py — 无问题。默认值/合法值/非法值三测与 resolver 行为匹配。

发现数量统计

  • P0:0
  • P1:1
  • P2:1
  • P3:1

整体风险判断

中高风险。核心风险是 P1 回归:distributed_setup 不再透传给 apply_model_infrastructure,导致 plan_overrides 中的 replace_module 模块替换被静默跳过,属于无报错的生产功能回归,建议合入前必须修复。P2 的 attention swap 安装顺序问题在启用 TP/CP/EP 分片时会触发精确类型校验失败,也应在合入前澄清设计(前移安装或扩展 validate 拒绝矩阵)。P3 为死代码/import 期副作用,属于可选清理。

类型 数量
🔴 阻塞 1
🟡 建议 1

⛔ 需要修改

likedislike
不准确?
MindSpore-BotMindSpore-Bot成员
8月15日 添加了label:mindspore-cla/yes
songjiaqisongjiaqi成员
8月15日 修改了pull request 的描述
此处折叠了44条消息 查看更多
司小南(机器人)司小南(机器人)成员
8月18日 添加了label:ci-pipeline-running
司小南(机器人)
司小南(机器人)成员
8月18日 评论:
Project Name Build_Stage Build Result Details
Hyper-parallel_Atomgit_Gate - SUCCESS 7192
likedislike
司小南(机器人)司小南(机器人)成员
8月18日 删除了label:ci-pipeline-running
司小南(机器人)司小南(机器人)成员
8月18日 添加了label:ci-pipeline-passed
MindSpore-BotMindSpore-Bot成员
8月18日 合入了pull request,合并节点 SHA:bc6aa2fed59c21bbf7970f0bbf2f3e1773fecd18