skills/ascendc-operator-precision-debug/SKILL.md
AscendC 算子精度问题调试与根因定位。当算子精度测试失败(allclose 不通过、结果偏差、输出全零/NaN 等)时使用。流程:误差分布分析 → 代码易错点审查 → 实验隔离 → printf/DumpTensor 插桩 → 修复验证。关键词:精度调试、精度问题、结果不一致、误差定位、allclose 失败、输出偏差、NaN、全零、precision debug。
npx skillsauth add Ascend/agent-skills ascendc-operator-precision-debugInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
按「由浅入深」五阶段定位根因:先看数据分布,再查代码易错点,然后实验隔离,最后插桩定位。
Phase 1: 误差分析 → Phase 2: 代码审查 → Phase 3: 实验隔离 → Phase 4: 插桩定位 → Phase 5: 修复验证
原则:先看数据,再看代码。 先搞清楚「错在哪、错多少、错成什么样」。
收集失败用例的 shape、dtype、MaxAbsErr/MeanAbsErr/CosineSim,然后基于 scripts/debug_precision_template.py 创建 csrc/ops/<op_name>/test/debug_<op_name>_precision.py(替换占位符后运行),自动分析:
| 现象 | 最可能原因 | 下一步 | |------|-----------|--------| | FP16 失败,FP32 通过 | 未升精度到 FP32 计算 | Phase 2 查 Cast | | 输出全零 | CopyOut 未执行 / GM 偏移错 | Phase 2 查 CopyOut | | 输出含 NaN/Inf | 除零 / log 负数 / 溢出 | Phase 2 查 Compute | | 全部偏差,CosineSim≈1 | 系统性精度损失 | Phase 2 查升精度 | | 周期性/条纹状错误 | tile 边界 / 搬运偏移 | Phase 3 实验 | | 仅尾部元素错 | 尾 tile 长度 / 对齐 | Phase 2 查尾 tile | | 多次运行结果不同 | 异步同步不足 | Phase 3 实验 B | | 小 shape 过、大 shape 挂 | 多核/tiling 边界 | Phase 3 实验 A | | 固定输入过、随机挂 | 地址/stride/偏移错 | Phase 3 实验 C |
MANDATORY:读取 op_host/<op_name>.cpp、op_kernel/<op_name>.cpp、design.md(若存在),按以下清单由浅入深排查。
Cast 到 FP32 计算再 Cast 回?这是最高频精度 bug。xGm[progress * tileLength] 是元素偏移,不要多乘 sizeof(T)。tileLength,计算/搬运用 curTileLength(尾 tile 可能更小)。DataCopyExtParams 的 copyLen 是字节数 = curTileLength * sizeof(T)。alignedTailLen 计算及使用是否正确。tileLength)在 host 和 kernel 中含义是否一致。Adds(backup, src, 0.0f, len) 备份。检查点:输出审查报告——疑似问题列表(按可能性排序)。若已锁定根因,跳到 Phase 5;否则进入 Phase 3。
Phase 2 无法直接锁定根因时,通过控制变量实验缩小范围。每次只改一个变量。
在 op_host 临时硬编码 blockDim = 1,重编译测试。可配合缩小 shape。
| 结果 | 结论 | |------|------| | 单核过、多核挂 | 核间问题:GM 区间重叠 / tiling 映射 / 核间同步 | | 单核也挂 | 非多核问题 → 实验 B |
将 kernel Process 中所有同步临时替换为 AscendC::PipeBarrier<PIPE_ALL>()(CopyIn / Compute / CopyOut 之间各加一个)。
| 结果 | 结论 | |------|------| | 全屏障后过 | 核内同步不足 → 逐步恢复细粒度同步定位 | | 仍失败 | 非同步问题 → 实验 C |
PIPE_ALL仅用于实验隔离,绝不可作为最终方案。
分别用全 1、等差序列(torch.arange)、随机输入测试。
| 结果 | 结论 | |------|------| | 全 1 过、等差/随机挂 | 地址/偏移/stride 错误(常数输入掩盖了偏移问题) | | 全都挂 | 计算逻辑或全局 tiling 错误 | | 全都过 | 特定数值范围触发精度问题 → 查边界值/极值 |
shape=(32,) → (tileLength,) → (tileLength*2,) → 原始 shape,定位恰好开始失败的分界点,反推 tile/核边界。
首错线性下标 → 第几个 tile → 哪个核 → 该核 GM 起始偏移 → 搬运预期字节数
周期 = tileLength → 搬运/偏移问题;周期 = 向量宽度 → 计算流程问题;与核边界对齐 → 多核/offset 问题。
问题范围已收敛到某阶段/某 tile 后,用 AscendC::printf 和 AscendC::DumpTensor 精确定位。
if (AscendC::GetBlockIdx() == 0) 减少输出量。DeQue / PipeBarrier 之后才能读 LocalTensor,否则读到未完成搬运的脏数据。AscendC::printf("v=%.6f\n", static_cast<float>(tensor.GetValue(idx)));,直接打 half 会乱码。| 场景 | 工具 |
|------|------|
| 标量、分支判断、单个下标 | AscendC::printf |
| 连续一段 tensor 快速扫 | AscendC::DumpTensor(tensor, desc, dumpSize) |
| 全量逐元素对比 | 不在 kernel 内做 — Host 读 GM + Python 脚本 |
在 Compute 函数内 DeQue 之后,逐步骤插桩,与 Python 侧用相同输入手算的中间结果逐步对比。第一个出现偏差的步骤即为根因所在。
// 示意:0 核、第 0 个 tile
if (AscendC::GetBlockIdx() == 0 && progress == 0) {
AscendC::printf("[step1] tmp[0]=%.6f\n", static_cast<float>(tmp.GetValue(0)));
}
| 根因 | 修复 | |------|------| | FP16 未升精度 | 添加 Cast(fp16→fp32) + 计算 + Cast(fp32→fp16) | | GM 偏移错 | 修正偏移公式(元素 vs 字节) | | 尾 tile 长度错 | 计算/搬运用 curTileLength,偏移用 tileLength | | tiling 参数错 | 修正 host 端 tiling 计算 | | 同步缺失 | 添加正确的 EnQue/DeQue 或 PipeBarrier | | ReduceSum 覆盖源 | 先 Adds 备份再 ReduceSum | | 搬运长度错 | 修正 DataCopyExtParams 的 copyLen |
#ifdef DEBUG_PRECISION 包裹调试完成后 MUST 在对话中展示:问题摘要、根因分析、修复内容、验证结果、≥2 条关键经验。NEVER 仅回复「已修复」。
定位到疑似根因后,加载对应案例了解完整排查过程:
| 误差现象 | 案例文件 | 何时加载 |
|----------|---------|---------|
| FP16 挂 FP32 过,全部偏差 | examples/fp16-no-upcast.md | 怀疑升精度缺失 |
| 首错在 tile 边界,周期 = tileLength | examples/gm-offset-error.md | 怀疑 GM 偏移错误 |
| 仅尾部少量元素错 | examples/tail-tile-misalign.md | 怀疑尾 tile 处理 |
| block_dim=1 过,多核挂 | examples/multicore-tiling-overlap.md | 怀疑核间 tiling |
| 多次运行结果不同 | examples/async-sync-missing.md | 怀疑同步缺失 |
不要一次性加载所有案例。 仅在误差特征匹配时加载对应案例。
GetBlockIdx() == 0 仅 0 核打印PIPE_ALL 作为最终修复 — 仅用于实验隔离testing
Kubernetes 集群健康检查与安全修复 — 诊断问题,用户确认后执行修复
tools
昇腾NPU CANN Toolkit+Kernels+NNAL安装部署技能。支持从官网下载run包安装和从Docker镜像提取两种方式,覆盖驱动检查、包下载、安装、环境变量配置与验证全流程。当用户需要安装CANN全套组件或指定版本CANN到自定义路径时调用。
development
编译 ATB (Ascend Transformer Boost) 测试框架。当用户需要编译 ATB 测试框架、 运行 CSV 测试、或构建 atb_test_framework 时调用。支持全量编译(含第三方依赖克隆与源替换) 和增量编译两种模式。需在 Docker 容器内配合 CANN 环境执行。
databases
ATB OPS→ACLNN 迁移标准化工作流主模板。整合前置学习、设计文档生成、CSV用例设计、 实际迁移、编译验证、测试验证全流程,提供明确的阶段 Gates 和用户确认机制。