已关闭
[bug] STFT算子批跑精度偶现失败:MTE3与Cube matmul流水线竞态导致输出帧为0 #2868
east_yang创建于  13 天前关闭于  13 天前
east_yang成员
13 天前 创建

问题描述

STFT 算子在 atk 批跑精度测试中偶现失败:单跑成功、批跑失败,失败用例不固定(如 case 169 有时成功有时失败)。对比 NPU 与 CPU 输出发现,失败时 NPU 输出在部分行的尾部帧输出 0,其余位置数值完全正确。

复现命令(Ascend950PR 环境):

atk node --backend npu --devices 1 node --backend cpu --name acc task -c ./error_case_stft.json --task accuracy -p ./exec_stft.py -mt 5 --save_data input --save_data output

失败示例(case 281,nfft=7/hop=1/win=4/onesided=false,输出 shape [7,7]):

  • NPU 在 (1,4)(1,5)(1,6)(3,4)(3,5)(3,6)(4,6)(6,5)(6,6) 等位置输出 0
  • CPU 对应位置有正常值(如 -760.1+839.2j)

根因分析

STFT AICore kernel 内存在 MTE3(UB→GM 异步拷贝,Vector 流水线)与 Cube matmul(读 GM,Cube 流水线)之间的流水线竞态

  1. StftPlanMul::Process():plan×window 结果通过 MTE3 写入 plan workspace 后没有等待写完成,主算子 Cube matmul 立即读取
  2. STFTGeneralized::Process()SplitWindows 通过 MTE3 写 splitWindow workspace 后同样无同步,StftMatmul 立即读取
  3. STFTGeneralizedComplex::Process():complex 输入路径存在相同问题

首次调用时 workspace 为新分配内存(内容为 0),matmul 抢先读到未写入的数据 → 输出 0;后续调用 workspace 残留上次正确的数据,竞态被掩盖 → 呈现“偶现”特性。这也是单跑(新进程首次调用易触发)与批跑表现差异的原因。

修复方案

在三处 MTE3 写 workspace 之后、Cube matmul 读取之前插入 HardEvent::MTE3_S 跨流水线事件同步:

event_t eventIdMTE3ToS = static_cast<event_t>(GetTPipePtr()->FetchEventID(HardEvent::MTE3_S));
SetFlag<HardEvent::MTE3_S>(eventIdMTE3ToS);
WaitFlag<HardEvent::MTE3_S>(eventIdMTE3ToS);

涉及文件:

  • math/stft/op_kernel/stft_plan_mul.h
  • math/stft/op_kernel/stft_generalized.h
  • math/stft/op_kernel/stft_generalized_complex.h

同时清理 stft_tiling_base 中冗余代码:删除从未使用的 l1Size/l0ASize/l0BSize/l0CSize(其中 l0A/B/C 获取时误用了 CoreMemType::UB)及重复的 l1SizePlatform 赋值。

验证结果

Ascend950PR 环境验证:

  • 修复前:atk 批跑 5 用例通过率约 60%,失败用例轮换出现
  • 修复后:10 轮 × 5 用例 = 50/50 全部 PASS;25 次逐次调用(每次不同输入)全部与 CPU 参考一致(max_diff < 1e-4),零值消失
likedislike
Eeast_yang成员
13 天前 关联了pull request:fix(stft): 修复STFT算子MTE3与Cube matmul流水线竞态导致的精度偶现失败
陈思
陈思成员
13 天前 评论:

/assign @east_yang

likedislike
CANN-robotCANN-robot成员
13 天前 将 east_yang 设为负责人
CANN-robotCANN-robot成员
13 天前 关闭了 issue
CANN-robotCANN-robot成员
13 天前 添加了label:resolved
Eeast_yang成员
8 天前 关联了pull request:fix(stft): 修复Cube matmul FIX写GM与Gather MTE2读GM流水线竞态导致的精度偶现失败