Closed
[Bug|算子缺陷][迭代加固]: aclnnMoeFinalizeRoutingV3 non_contig 压测发现 是bug #575
Alice_zhouAdd on  1 day agoClosed at  9 hours ago
Alice_zhouCollaborators
1 day ago Create

一、问题描述(必填)

  • 接口名:aclnnMoeFinalizeRoutingV3;测试场景:non_contig;压测日期:2026-11-13;执行卡号:0
  • 压测结果:总条数 10000 / 实际成功 1519 / 实际失败 8481
  • bug 判定:是bug(经 执行日志+plog+资料 三方交叉分析,详见判定依据)
  • 是否存在 aicore_error:是:kernel_name=MoeFinalizeRoutingV2_c5e02307a9415acd08d67488d4a5602d_30010等,判定串the error is aivec error命中
  • 失败原因摘要:是bug:8197条aclrtSynchronizeStream失败(507035 vector core exception)+284条GWS跳过;非连续输入(SLICE/TRANSPOSE/ASSTRIDED/STORAGE_PADDED全场景)触发kernel MoeFinalizeRoutingV2 VEC地址越界(aicore_error);md标注全部输入支持非连续,构造合规(步长有界,out已按md列x连续化),连续基线97.6%无异常

二、问题复现步骤(必填)

  1. 下载测试框架:https://gitcode.com/Alice_zhou/Vector_fuzz_cpp_testing/tree/main/turing_sec/aclnnAPI_fuzz/
  2. 环境准备(清除原有内容,将附件 cpp 放入对应目录下):
    rm -rf aclnnAPI_fuzz/src/op/*
    # 将附件 aclnnMoeFinalizeRoutingV3_non_contig.cpp 放入 aclnnAPI_fuzz/src/op/ 下
    
    (本场景 cpp 目录:aclnnAPI_fuzz/src/op/)
  3. 编译:
    cd aclnnAPI_fuzz/ ; make
    
  4. 执行:
    cd out ; ./aclnnAPI_fuzz aclnnMoeFinalizeRoutingV3_non_contig_fuzz 10000
    

三、附件与证据(必填)

💡 存在的问题(选填)
该问题由 fuzz 自动化压测平台发现(每日自动统计当天判定为 bug 的记录并提单);如需更多上下文(完整打屏日志/plog/覆盖度报告),请下载上方附件压缩件。

🔍 代码bug点定位(2026-11-13,结合 ops-* git 仓源码复核)

测试框架复核(F1~F7,aicore 前置门禁):通过

  • F1 索引有界:expandedRowIdx hostData 恒为有界小值(< N*K)✓
  • F3 shape 关系:N/K/H/E/C 连贯体系,步长在 storage 界内(SLICE view[32,1,64]/strides[128,64,1]/storage[64,1,64] 最大偏移 4031<4096)✓
  • F4 kernel_name=MoeFinalizeRoutingV2* 归属本 API ✓
  • F5 基线:连续(normal)场景 97.6% 无 aicore,失败集中在非连续注入之后 ✓

代码排查(ops-transformer/moe/moe_finalize_routing_v2)

  1. aclnn 层(op_host/op_api/aclnn_moe_finalize_routing_v3.cpp:81-127):GWS 对全部 11 个输入调用 l0op::Contiguous() 连续化——设计上非连续输入应被物化为稠密张量
  2. tiling 层(op_host/moe_finalize_routing_v2_tiling_arch35.cpp):无非连续布局驱动的 tiling_key 分支(non_contig support=unknown,静态分析)
  3. kernel 层(op_kernel/):崩溃点为 VEC 访问 UB 越界(errcode 341,pc start 0x120041073eb8)

定位分析

  • 合法非连续输入(md「非连续Tensor」列全√)在 Contiguous() 连续化链路之后仍触发 kernel VEC UB 越界,82% 非连续用例崩溃(SLICE/TRANSPOSE/ASSTRIDED/STORAGE_PADDED 全场景)
  • 两种可能路径:① Contiguous() 对特定 stride 布局误判为"已连续"直接透传(如仅 storage offset 的视图),kernel 按稠密假设搬运越界;② Contiguous 物化路径本身的偏移计算缺陷
  • 确切 kernel 行需 core 现场(pc 0x120041073eb8)比对 kernel 符号表;已排查范围:aclnn 层连续化链、tiling 无非连续分支、kernel 入口模板

同根因关联:本 issue(non_contig 场景)与 #576(multithread 场景,同 kernel_name=MoeFinalizeRoutingV2)为同一缺陷的两处场景复现,任一修复后另一处复测闭环。


✅ 定性修正(2026-11-14,开发复核采纳 + 框架修复复测定谳)

结论修正:不是bug(测试框架 F1 索引有界性缺陷),本 issue 关闭。

开发复核(@guoqiuhao)确认的根因——测试框架缺陷而非算子缺陷:

  1. 框架 CreateAclTensorByScene(utils.h:290-304)按 storageShape 分配内存后仅将 hostData 连续拷贝到存储前部,未按 stride/offset 写入逻辑元素、未初始化剩余存储
  2. 实测附件佐证:case_4 expandedRowIdx viewShape=[128]/stride=[2]/storageShape=[256],hostData 大小=view 元素数(128),仅覆盖物理 0~127;视图读取 0、2、…、254,其中逻辑元素 64~127(物理 128~254)为未初始化存储——垃圾索引值进入 kernel 后形成与日志相符的 VEC UB 越界
  3. 原 F1~F7 复核遗漏点:仅核对了 hostData 值有界(全 1),未核对框架写入位置正确性与存储完整初始化

框架修复(已落地 turing_sec 与 turing_sec_card1 两实例 inc/utils/utils.h):

  • 按 stride/offset 将逻辑元素写入物理位置 + 全存储以 hostData[0] 初始化 + 标准连续布局快路径

修复后复测证据(Ascend 950 / CANN 9.3.0):

  • 本接口 non_contig 全量 10000 条:成功 9767 / 同步失败 0 / aicore_error 0(修复前:成功 1519、同步失败 8197 次 507035 vector core exception、全进程 aivec)
  • 1000 条快速复测:974/1000 成功、0 同步失败

同根因关联:#576(multithread 场景)与 #582(aclnnSituMxQuant multithread broadcast aicore)同为该框架缺陷所致,一并修正关闭;#582 复测(单接口目录 5000 条)4910/5000 成功、0 aivec、进程完整结束。

likedislike
AAlice_zhouCollaborators
1 day ago Modify description of issue
AAlice_zhouCollaborators
1 day ago Modify description of issue
Guoqh
1 day ago Comments:

复核结论:当前复现材料存在测试框架的非连续索引初始化缺陷,建议按测试构造问题处理,暂不认定为算子缺陷;先修正构造,再复测。

具体依据:

  1. 附件 aclnnMoeFinalizeRoutingV3_non_contig.cpp 第 296~300 行将 expandedRowIdxHostData、expertIdxOptionalHostData 的逻辑元素初始化为 1,随后调用 CreateAclTensorByScene。
  2. 按 issue 链接的公开框架实现核查,utils.h 第 290~304 行 按 storageShape 分配内存,但只将 hostData 连续拷贝到存储前部,没有按 stride/offset 写入逻辑元素,也没有初始化剩余存储。
  3. 附件执行日志中,首个同步异常为 case_4:expandedRowIdx 的 viewShape 为 [128]、stride 为 [2]、storageShape 为 [256]。框架只初始化物理位置 0~127,视图却读取 0、2、4……254,因此逻辑元素 64~127 共 64 个会读取未初始化存储。该用例的 expertIdxOptional 同样有此问题。

所以,“hostData 全为 1”和“stride 未超出 storage”不能证明实际传入的索引值合法。该用例 drop-pad 模式下 E=32、C=1,有效行索引应在 [0,32),专家索引也应在 [0,32);未初始化数据不能保证满足这些约束。非法索引进入全载入 UB 的 kernel 后,可形成与日志中 VEC UB 越界相符的访问,因此目前不能据此归因于 Contiguous()。

建议修正 CreateAclTensorByScene:按实际 stride/offset 将逻辑数据写入物理存储,并初始化所需存储;对于本次索引全为 1 的用例,也可将整个索引物理存储填为 1。之后先在独立进程中重跑 case_4,再以相同逻辑数据做连续/非连续布局对照。若修正后仍异常,再继续定位算子。

本次结论基于附件日志、CPP 和公开框架源码复核,尚未进行修正后的上卡复测。

likedislike
AAlice_zhouCollaborators
9 hours ago Modify description of issue
AAlice_zhouCollaborators
9 hours ago Close issue