Closed
[Bug-Report|缺陷反馈]: MoeTokenPermuteWithEpGrad 非法 range 长度仍返回成功 #4540
KaranocaVeAdd on  Aug 24Closed at  Sep 30
KaranocaVe
KaranocaVe
Aug 24 Create

[Bug-Report|缺陷反馈]: MoeTokenPermuteWithEpGrad 非法 range 长度仍返回成功

问题描述

aclnnMoeTokenPermuteWithEpGrad 的接口文档规定 rangeOptional 的 size 为 2,
但 MoeTokenPermuteWithEpGrad Host Tiling 在传入 3 个元素的 range 时只打印错误并
继续生成 tiling,最终返回 GRAPH_SUCCESS。这使非法属性没有在 Tiling 阶段被拒绝,且
与当前测试名 test_tiling_range_size_invalid 和接口约束不一致。

环境信息

  • 仓库/commit:cann/ops-transformer / a2ee2d92804d6d04fcc64e748628000539ab1464
  • OS/架构:Linux 5.10.0-216.0.0.115.oe2203sp4 / aarch64
  • Ascend 硬件:Ascend 910B3;本条为 Host Tiling 验证
  • Driver/Toolkit/OPP:Driver 25.5.2;CANN Toolkit/OPP 9.1.0
  • 编译器和 Python:G++ 11.4.0;Python 3.12.13;CMake 3.22.1

重现步骤

  1. 在 MoeTokenPermuteWithEpGrad Host Tiling 测试框架中构造输入:
    permuted_tokens_output_grad=[16,128]、sorted_indices=[128]、
    permuted_probs_output_grad=[128]、输出分别为 [16,128] 和 [16,8]。
  2. 设置 num_topk=8、padded_mode=false,将 range 设置为 {0,16,1}。
  3. 调用已注册的 MoeTokenPermuteWithEpGrad Tiling 回调,读取返回的 graph status。
  4. 将 range 改为合法的 {0,16},重复同一调用作为对照。

预期结果

根据 moe/moe_token_permute_with_ep_grad/docs/aclnnMoeTokenPermuteWithEpGrad.md 中
rangeOptional 的说明,长度不是 2 的属性应被拒绝,Tiling 应返回
ge::GRAPH_FAILED,不应写入成功的 tiling 数据。

实际结果

range={0,16,1} 返回 ge::GRAPH_SUCCESS,测试框架记录 tilingRet=0,并继续得到
tiling key;连续 5 次复现一致。合法 range={0,16} 对照连续 5 次返回成功。
仓库现有 test_tiling_range_size_invalid 也以 GRAPH_SUCCESS 作为预期,因此当前
测试把该非法输入错误地判为通过。

日志/最小复现

构建命令:bash build.sh --ophost_test --noexec --ops=moe_token_permute_with_ep_grad -j2,
退出码 0。运行真实 Host UT 的契约对照时,合法测试退出码 0;非法测试的预期失败断言
退出码 1,日志中的关键差异为:

Expected: ge::GRAPH_FAILED
Actual:   tilingRet = 0 (ge::GRAPH_SUCCESS)

源码位置:moe/moe_token_permute_with_ep_grad/op_host/moe_token_permute_with_ep_grad_tiling.cpp
第 175-181 行检查长度,第 369-386 行忽略 Init() 的失败状态并继续 Tiling。

影响与规避方式

影响:调用方无法在 Host Tiling 阶段识别非法 range 长度,错误可能延迟到后续编译或
设备运行阶段,且生成的 tiling 数据不具备接口契约保证。规避方式是调用前保证
range 恰好包含两个元素。当前仅使用合法的二元素 range。

建议的回归测试

建议增加合法二元素、空数组、单元素和三元素 range 的 Host Tiling 回归用例:仅二元素
输入返回 GRAPH_SUCCESS,其他长度返回 GRAPH_FAILED;同时验证失败路径不调用
后续 tiling data 写入逻辑。保留现有 18 项算子 Tiling 用例作为兼容性回归。

Validation

证据摘要

版本和环境

  • 仓库/remote:cann/ops-transformer / https://gitcode.com/cann/ops-transformer.git
  • 分支和 commit:源码副本固定在 a2ee2d92804d6d04fcc64e748628000539ab1464;该 commit 的
    version.cmake 声明 ops-transformer 版本 9.1.0
  • OS/架构:Linux 5.10.0-216.0.0.115.oe2203sp4,aarch64
  • Ascend 硬件:Ascend 910B3,设备 2;npu-smi 25.5.2,设备健康状态 OK
  • Driver:25.5.2;Toolkit/OPP:CANN 9.1.0
  • 编译器/Python/CMake:G++ 11.4.0;Python 3.12.13;CMake 3.22.1
  • 版本边界:本次使用目标源码的 Host Tiling 和 CANN 9.1.0 Host 依赖完成验证;未进行
    匹配产品包的 NPU 端到端运行,不将 Host 结果外推到其他版本。

契约和源码事实

  • moe/moe_token_permute_with_ep_grad/docs/aclnnMoeTokenPermuteWithEpGrad.md:148-156
    明确 rangeOptional 的 size 为 2。
  • moe/moe_token_permute_with_ep_grad/op_host/moe_token_permute_with_ep_grad_def.cpp:52-54
    将 range 注册为可选 ListInt 属性。
  • moe/moe_token_permute_with_ep_grad/op_host/moe_token_permute_with_ep_grad_tiling.cpp:175-181
    检查 ContinuousVector 长度并在不等于 2 时记录 “the size of range only support 2”,
    但该检查位于返回 void 的 Init() 中。
  • moe/moe_token_permute_with_ep_grad/op_host/moe_token_permute_with_ep_grad_tiling.cpp:369-386
    调用 Init() 后无状态检查,继续执行 SetCoreNum、Tiling、写入 tiling data 并返回
    context->SetTilingKey(...)。因此非法长度分支只退出 Init(),没有把错误传递给外层。
  • moe/moe_token_permute_with_ep_grad/tests/ut/op_host/test_moe_token_permute_with_ep_grad_tiling.cpp:287-308
    现有测试名为 test_tiling_range_size_invalid,但对三元素 range={0,16,1} 断言
    ge::GRAPH_SUCCESS,与文档和错误日志不一致。

复现与预期/实际差异

  • 最小输入:permuted_tokens_output_grad=[16,128]、sorted_indices=[128]、
    permuted_probs_output_grad=[128];输出按现有 UT 使用 [16,128] 和 [16,8];
    num_topk=8、padded_mode=false。
  • 合法对照:range={0,16}。
  • 非法输入:range={0,16,1}。
  • 构建命令:bash build.sh --ophost_test --noexec --ops=moe_token_permute_with_ep_grad -j2,
    退出码 0;复用已构建的 transformer_op_host_ut 运行本地契约测试,真实注册的 Host
    Tiling 回调被调用。
  • 预期:根据接口文档,长度不是 2 的 range 应返回 ge::GRAPH_FAILED,不能生成成功
    的 tiling 数据。
  • 实际:三元素 range 返回 ge::GRAPH_SUCCESS(测试框架打印 tilingRet=0),并继续
    生成 tiling key;本地契约断言退出码为 1。二元素合法对照 5 次均退出码 0。
  • 重复性:非法输入的契约测试连续运行 5 次,均为 1 个合法对照通过、1 个非法输入断言
    失败,退出码均为 1;失败位置均是实际 GRAPH_SUCCESS 与预期 GRAPH_FAILED 的差异。
  • 现有回归对照:该算子原有 18 个 Host Tiling 用例全部通过(退出码 0),其中
    test_tiling_range_size_invalid 也通过,因为它当前错误地接受非法长度。
  • 证据等级:E3。

根因和影响

Init() 对非法 range 只执行函数内的 return,PermuteWithEpGradTilingCompute()
没有接收或检查该错误状态,随后使用默认初始化参数继续生成 tiling。调用者因此无法通过
Host Tiling 返回值识别输入违反接口约束,非法图可能进入后续编译或运行阶段;影响包括错误
的 tiling 数据、延迟到更晚阶段失败,以及调用侧无法可靠定位参数错误。规避方式是只传入
长度为 2 的 range,或在调用前自行校验属性长度。

修复版验证

  • 修复:将 Init() 改为返回 ge::graphStatus,非法 range 长度返回
    ge::GRAPH_FAILED,并由 PermuteWithEpGradTilingCompute() 立即传播;同步修正原有
    test_tiling_range_size_invalid 的错误成功断言。
  • 修复版 Host UT 构建退出 0;设置 BUILD_PATH=build 后,合法/非法 range 契约、18
    项既有 Tiling 用例和 2 项 InferShape 用例共 22 项,连续 5 轮均通过并退出 0。
  • 构建日志为 logs/rebuild-host-ut-fix-real.log,运行日志为
    logs/run-existing-range-suite-fix-real-with-build-path.log。
  • 结果仍限定为固定源码的 Host Tiling/InferShape 验证,未执行匹配产品包的 NPU 端到端
    运行。

关联 PR: https://gitcode.com/cann/ops-transformer/merge_requests/10538

likedislike
KaranocaVeKaranocaVe
Aug 24 Added label: bug-report
KaranocaVeKaranocaVe
Aug 24 Associated pull request
weihao18Collaborators
Aug 24 Comments:

/assign @KaranocaVe

likedislike
CANN-robotCANN-robotCollaborators
Aug 24 Assign KaranocaVe as responsible person
KaranocaVeKaranocaVe
Sep 21 Modify description of issue
KaranocaVeKaranocaVe
Sep 22 Modify description of issue
Wwang-minboCollaborators
Sep 28 Assign chen-linxin4 as responsible person
fazhenyao123fazhenyao123Collaborators
Sep 29 Associated pull request
fazhenyao123fazhenyao123Collaborators
Sep 29 Associated pull request
Cchen-linxin4Collaborators
Sep 30 changed custom state from 进行中 to 已完成
Cchen-linxin4Collaborators
Sep 30 Close issue
KaranocaVe
KaranocaVe
Oct 2 Comments:

/close

likedislike