Ascend C / Operator performance
一天,两个算子,
先证明正确,
再追性能。
以昇腾AI创新大赛-算子挑战赛第二届年度冠军赛【基础性能命题】为背景, 用 Model Agent 的 Skills 与工作流能力,复盘 tensorEqual 和 GeluV2 的工程化解题路径。
Why this case
The engineering problem
这不是“让 Agent 写两个 Kernel”,而是管理一条有证据的优化链。
赛题把正确性放在性能之前:不同数据类型、取值范围与 Shape 都可能进入验收; 浮点精度有明确容差,整数要求无误差。只有精度通过,AI Core 的 Profiling 耗时才有排名意义。
同时,Tiling 必须具备泛化能力,不能针对已公布样例硬编码。最适合 Agent 的部分, 正是把这些约束变成检查点、生成可重复的测试、保存每轮基线,并在失败后沿证据回退。
Model Agent
Repository capability map
把仓库功能翻译成一张算子开发工作台。
指定版本把 301 个主 Skill 分成 11 类,并提供动态工作流、检查点、重试、并行步骤与 MCP 工具接入。 对这个案例最有价值的不是 Skill 数量,而是已经形成了 Ascend C 端到端编排链。
动态工作流
把两个算子拆成可并行分支,把环境、编译、精度和性能设为串行门禁,并在检查点恢复。
Ascend C 技能链
从需求、Tiling、op_host / op_kernel 生成,到框架注册、编译与系统测试形成连续产物。
精度与 Profiling
用固定用例对照基线,先诊断误差分布,再检查搬运、对齐、多核和 API 使用。
经验沉淀
把有效优化、失败原因和环境差异写回经验层,供下一轮计划和相似算子复用。
Task brief
Prompt as a contract
先把赛题改写成一份不会偷换目标的任务说明。
下面这段不是“万能提示词”,而是一份启动合同。正式执行时,要把官方题目包、接口文档和基线脚本一起放进上下文。
目标:
为 tensorEqual 与 GeluV2 生成可提交的 Ascend C 实现,并在精度通过后优化 AI Core 执行时间。
事实源优先级:
1. 大赛官方题目包与算子接口文档
2. CANN 社区版 8.5.0 文档与当前硬件实测
3. 仓库内 Ascend C Skills
硬约束:
- 不猜测 dtype、Shape、广播、容差或计算公式;先从题目包提取
- Tiling 必须覆盖未公开 Shape,不得为榜单样例硬编码
- 每次性能修改后,使用同一组完整精度用例回归
- FP16 / BF16 涉及复杂数学时,先升精度到 FP32;除非题目明确允许,不改变数学近似
- 只用官方 Profiling 口径判断最终性能
输出:
- 环境报告与需求清单
- 两个算子的 design.md、op_host、op_kernel 与 ST 用例
- 每轮精度结果、Profiling 基线、修改原因和回退点
- 按官方脚本生成的提交 zip;不得混入无关文件
暂停并请求人工确认:
- 题目定义存在歧义
- 精度与性能目标冲突
- 需要更改数学公式、近似模式或支持范围
- 三轮优化后仍无稳定收益Workflow
A vertical execution log
一条主线、两个并行分支、四道硬门禁。
- 0008:30
Gate / 事实冻结
导入赛题包,先列出“已知、未知、禁止假设”。
核对接口、输出语义、支持 dtype、Shape 约束、参考实现、基线脚本和提交目录。未确认的信息不进入代码。
产物 requirements.md · acceptance-matrix.md - 0109:00
Gate / 环境确认
确认 NPU、CANN 8.5.0、工具链和设备占用。
运行环境检查,保存 npu-smi、CANN 路径、编译器与自定义算子安装状态。环境不对,后续性能数字全部作废。
产物 env-report.txt - 0209:30
Parallel / 双算子设计
分别完成算法、Tiling、Buffer 与尾块策略。
两个分支共享验收矩阵,但各自维护设计文档。Agent 可以并行检索资料和生成候选方案,人负责批准语义与硬件取舍。
产物 tensor_equal/design.md · gelu_v2/design.md - 0311:00
Gate / 编译与精度
生成 Host、Kernel 和测试,先拿到完整绿色基线。
先通过小 Shape、尾块、多核和极值用例,再扩展到官方支持矩阵。失败时按误差分布 → 搬运对齐 → Tiling → API 陷阱定位。
产物 op_host · op_kernel · precision-report.md - 0414:00
Loop / 性能闭环
固定用例,保存基线,每次只验证一个优化假设。
围绕 Tiling、搬运、API、内存和流水逐项排查。每轮都记录“改了什么、为什么、精度是否保持、AI Core 时间是否下降”。
产物 profiler/round_001… · optimization-log.md - 0519:00
Gate / 提交封装
冻结最后一次有效代码,再按官方脚本打包。
源码必须与最后一次有效性能一致。只保留 op_host、op_kernel 与 custom_*.run,并使用主办方提供的脚本生成 zip。
产物 submission.zip · final-evidence.md
Two operators
Different bottlenecks
两个算子不能套同一份“优化秘方”。
以下是进入实测前的优化假设,不是已经证明的结论。真正的路径必须由题目定义和 Profiling 数据选择。
tensor
Equal
比较与聚合路径
先确认
- 两输入的 Shape、dtype 与广播规则
- 浮点是否为严格相等或带容差比较
- 输出是标量、张量,还是题目定义的其他形态
Profiling 假设
- 多核切分与最终聚合的同步成本
- 尾块、32B 对齐和 GM ↔ UB 搬运
- 小 Shape 下启动开销是否高于计算本身
不为已知 Shape 写特例;所有分支必须能由通用 Tiling 参数解释。
Gelu
V2
逐元素复杂数学路径
先确认
- 官方公式、approximate 模式与输入范围
- 支持 dtype 及对应精度阈值
- 是否允许等价近似,还是必须保持指定计算路径
Profiling 假设
- 复杂数学链路中的 Cast 与中间 Tensor 复用
- 双缓冲、搬运计算重叠和 Vector API 组合
- 大 Shape 的核间均衡与小 Shape 的固定开销
FP16 / BF16 复杂计算先升到 FP32;任何公式替换都必须先经人工确认。
Public evidence
Leaderboard snapshot
公开结果只做参照,不冒充本案例的实测。
官方榜单显示,两个单项的头部性能由不同队伍获得;最终金奖队伍 Cishoon 在两个单项均排名第二。 这恰好说明总分赛制需要平衡两条优化线,而不是只押注一个算子。
| 算子 | 公开第 1 名 | AI Core 耗时 | Cishoon | AI Core 耗时 |
|---|---|---|---|---|
| TensorEqual | 经常帮助跷家人 | 9,387.166 μs | #2 | 13,169.541 μs |
| GeluV2 | Tangefly | 1,889.272 μs | #2 | 2,028.137 μs |
榜单算子名使用 “TensorEqual”;本文在叙述中沿用用户给出的 “tensorEqual”。数据读取于 2026-07-26。
Evidence
Definition of done
没有这七类证据,就不能说“做完了”。
- 01环境快照NPU / CANN / 编译器 / 设备状态待实测
- 02需求矩阵dtype / Shape / 范围 / 容差 / 公式待导入题目包
- 03设计文档算法 / Tiling / Buffer / 尾块待生成
- 04源码产物op_host / op_kernel / 注册与编译待实现
- 05精度报告完整支持矩阵与失败归因待上板
- 06性能报告同用例基线、每轮改动与 AI Core 耗时待上板
- 07提交归档源码与 custom_*.run 一致的官方 zip待封版
Human in the loop
Responsibility stays human
Agent 可以加速执行,但不能替你承担赛题判断。
交给 Agent
- 整理题目约束并生成覆盖矩阵
- 生成设计草案、代码骨架和测试
- 批量运行检查、解析误差与 Profiling
- 保存基线、比较迭代、整理交付文档
必须由人确认
- 算子语义与数学公式是否解释正确
- 近似计算是否在赛题允许范围内
- 性能收益是否来自公平、可泛化的实现
- 最终代码、运行包与提交材料是否一致
最好的 Agent 产物不是“一份看起来很快的 Kernel”,而是一条别人能够复查、重跑并解释的证据链。