Merged
fix: enable mask-out for DVM causal FlexAttention #47833
fix: enable mask-out for DVM causal FlexAttention #47833
Merged
SorryNaCNAdd on 25 days ago
SorryNaCN
SorryNaCNCollaborators
25 days ago

【合入来源】

Fixes https://gitcode.com/Ascend/pytorch/issues/5414

设置 TORCHINDUCTOR_NPU_BACKEND=dvm 并用 torch.compile(..., fullgraph=True) 编译 BF16 causal FlexAttention(B=8, H=128, S=2048, D=128)时,原实现禁止 DVM 使用 mask-out,进入 mask-in 后编译失败,最终报 NoValidChoicesError。本修改启用已有 mask-out 路径,并适配反向 reduction 的整数 axis,使该场景完成前向和反向。

【修改方案】

  1. _supports_flex_attention_mask_out() 返回 True,允许 DVM 使用已有 mask-out 路径。
  2. 在公共 MLIR lowering 的 sum_() 入口将整数 axis 转为列表,再执行负轴处理。这样 FlexAttention 的 sum(axis=-1) 可以正常进入 reduction,避免在遍历整数 axis 时抛出 TypeError。

本 MR 仅涉及 kernel/flex_attention.py 和 ascend_npu_ir/npu/inductor_patch/lowering.py,共新增 3 行、删除 1 行。验证范围为默认 dispatch 的 causal 场景。

【资料变更】

不涉及。

【接口变更】

不涉及。

【功能验证】

环境:Ascend950PR、CANN 9.1.0、PyTorch 2.13.0,使用已完成构建的 PTA 运行时加载本次 Python 源码。提交基于 master 7eb2fe2f7;基线对照使用已构建的 bd966924b,两者生产源码相同。

本地验证(生产代码与已验证版本一致):

  • 本地执行 (8, 128, 2048, 128) BF16 causal 前反向验证通过(1 passed in 71.38s)。输出与 q/k/v 梯度均为有限值,梯度形状均为 [8, 128, 2048, 128]。该大形状用例不包含在本 MR 中。
  • 现有 MLIR reduction 测试:13 passed, 30 deselected in 9.33s,覆盖静态/动态 FP16、FP32、BF16、cat+reduce、deterministic reduction 和 NPUGraph。
  • git diff --check 通过;测试目录与基线一致。

已知问题(以下为 9a51e5eba 的验证结果):

  • 其余三个原有 FlexAttention 用例为 1 passed, 2 failed,通过的是 test_uses_npu_triton_templates。
  • test_backend_switch_after_torch_npu_inductor_import 报 lowering helper 的 KeyError;test_composed_mask_pointwise_lowerings 的自定义 score 场景出现梯度误差(最大绝对误差约 0.2144,容差 0.03)。这两个用例在未修改基线上均报 NoValidChoicesError。本修订仅调整 axis 规范化位置,没有修复上述两个问题,不能视为全部 FlexAttention 回归通过。

未显式调用 torch.compile 的同尺寸 eager 脚本仍会因展开完整 scores 而发生 HBM OOM,不属于本次修复范围。

【CheckList】

likedislike
Pull Request has been successfully merged by ascend-robot.
(Thank you for SorryNaCN's contribution.)
SorryNaCNSorryNaCNCollaborators
25 days ago Created pull request, commit c503b6bc
atomgit-bot
atomgit-bot
25 days ago Comments:

变更摘要

本 PR 针对设置 TORCHINDUCTOR_NPU_BACKEND=dvm 后编译 BF16 causal FlexAttention(B=8, H=128, S=2048, D=128)因原 mask-in 路径的 UB 分配/同步问题报 NoValidChoicesError 的问题,改为让 DVM 使用现有 mask-out 路径,从而支持该形状的前向与反向计算。修改仅涉及 DVM 注册入口、DVM wrapper 与 DVM 测试,Triton 后端代码及共享 FlexAttention kernel/template 保持不变。

主要改动

  • 新增 DVM FlexAttention 注册入口: 新增 torch_npu/_inductor/dvm/flex_attention.py 的 register_flex_attention(),在 flex_attention(options_index=6, graph_index=3)与 flex_attention_backward(options_index=11, graph_index=7)两个 lowerings 上包裹 _wrap_lowering,从而在 DVM lowering 期间启用 mask-out。
  • 启用 mask-out 并绑定 lowering helper: _wrap_lowering 通过 patch.object(flex, "_supports_flex_attention_mask_out", lambda: True) 强制走 mask-out,并结合 _is_score_mod_identity_graph 判断是否保留自定义 score 的 mask-in 路径,同时把 lowerings、empty、empty_strided、to_dtype 替换为 inductor_lowering 的版本。
  • 补充同步与 buffer reuse 编译配置: 针对 flex_attention_template 与 flex_attention_backward_template 复制模板并覆写 NPUTemplateCompileOption,新增 sync_solver、disable_tightly_coupled_buffer_reuse 两个编译选项。
  • 规范化 DVM reduction 的整数 axis: 对 torch.ops.aten.sum 的 lowering 包裹 sum_,当 axis 为 int 时转换为 [axis] 再调用原实现。
  • DVM wrapper 复用 runtime helper 生成机制: NpuDvmWrapperCodeGen 新增 runtime_helper_definitions 初始化、write_async_compile_wait 中追加 _RuntimeHelperDefinitionsLine,并提供 write_runtime_helper_once 转调 NPUPythonWrapperCodeGen。
  • 切换 DVM 后端的注册调用与回归用例更新: _load_dvm_backend() 改为调用 register_flex_attention();测试将大尺寸用例形状调整为 (1, 2, 256, 128) 并收紧断言阈值,新增 test_large_causal_attention_backward 覆盖 (8, 128, 2048, 128) causal 前反向,并在后端切换回归中改用环境变量启用 DVM。

主要改动

  • DVM FlexAttention 注册入口: 新增 torch_npu/_inductor/dvm/flex_attention.py 的 register_flex_attention(),包裹 flex_attention 与 flex_attention_backward 的 lowerings。
  • mask-out 与 helper 绑定: _wrap_lowering 通过 patch _supports_flex_attention_mask_out 返回 True 启用 mask-out,并按 _is_score_mod_identity_graph 判断保留自定义 score 的 mask-in 路径,同时覆写 lowerings/empty/empty_strided/to_dtype。
  • 模板编译选项调整: 为 flex_attention_template 与 flex_attention_backward_template 复制并设置 NPUTemplateCompileOption 的 sync_solver 与 disable_tightly_coupled_buffer_reuse。
  • aten.sum axis 规范化: 对 torch.ops.aten.sum 包裹 sum_,将 int 类型的 axis 统一为列表形式。
  • wrapper 与入口调用更新: NpuDvmWrapperCodeGen 新增 runtime helper 相关方法与 _RuntimeHelperDefinitionsLine 输出,_load_dvm_backend() 改为调用 register_flex_attention();测试新增 test_large_causal_attention_backward 并调整后端切换用例。
likedislike
Incorrect?
atomgit-bot
atomgit-bot
25 days ago Comments:

代码审查

✅ 未发现问题

likedislike
Incorrect?
ascend-robotascend-robotCollaborators
25 days ago Added label: ascend-cla/yes
ascend-robotascend-robotCollaborators
25 days ago Added label: needs-issue
185 messages are collapsed here。 See more
zichun_ye
zichun_yeCollaborators
23 days ago Comments:

/approve

likedislike
zichun_ye
zichun_yeCollaborators
23 days ago Comments:

/check-pr

likedislike
ascend-robotascend-robotCollaborators
23 days ago Added label: lgtm
ascend-robotascend-robotCollaborators
23 days ago Merged pull request
AtlasAccount
AtlasAccountCollaborators
23 days ago Comments:
流水线 pytorch_gitcode_PR_multiVersion-onetrack#400 [ commitID:b3bdb3fe ] 已完成
likedislike