用 AI Skill 写九齿算子:NineToothed Operator Skill 实战指南

写 GPU 算子一定要手搓 Triton kernel 吗?有了 NineToothed Operator Skill,你只需要提供一段 CPU 参考实现,剩下的交给 AI。

写 GPU 算子,到底痛在哪?

做过算子开发的同学,大概都经历过这样一套"折磨流程":

  1. 先写 CPU 版本——用 NumPy 或 PyTorch 快速验证算法对不对;
  2. 再翻译成 Triton kernel——处理指针运算、mask、数据类型转换等底层细节;
  3. 反复调精度——fp16 和 fp32 的差异、累加溢出、各种边界 case;
  4. 手动调参——'BLOCK_SIZE'、'num_warps'、'num_stages'……一个个试。

整个过程不仅耗时,而且极其容易出错。尤其是从 CPU 实现到 Triton kernel 的翻译环节,充斥着大量重复的模板代码,写多了真的会怀疑人生。

后来有了 NineToothed 框架,用 Python 风格的语法替代了原始 Triton,自动处理指针运算和 mask,已经省了不少事。但你仍然需要理解 arrangement(分块策略)和 application(计算逻辑)的设计,掌握 'tile()'、'expand()'、'squeeze()' 等元操作。

门槛降低了,但还没低到"人人都能写"的程度。

NineToothed Operator Skill 的目标更强:让 AI 完成从 CPU 实现到 NineToothed 算子的全流程——代码生成、自动调优、精度验证、性能优化,一条龙服务。

NineToothed Operator Skill
是什么?

简单说,它是一个为 Claude Code(或兼容 AI 编程助手)设计的 Skill,定义在项目的 '.claude/skills/ninetoothed-operator/SKILL.md' 中。

它教会 AI 做四件事:

  • 分析用户提供的 CPU 参考实现
  • 判断算子类型(element-wise、reduction、matmul、attention……)
  • 生成符合 NineToothed 规范的 GPU 算子代码
  • 执行完整的"自动调优 → 精度验证 → 性能优化"闭环

你给 CPU 代码,AI 还你 GPU 算子。

核心工作流:严格的六阶段闭环

Skill 定义了一个不允许跳过任何阶段的六阶段工作流:

为什么"CPU 实现是唯一的精度基准"?

这是 Skill 设计中一个非常关键的决策:

  1. 消除歧义:自然语言描述可能有多种理解,但代码不会说谎
  2. 可复现:每次精度验证都对比同一份 CPU 代码的输出
  3. 完整性:CPU 实现通常已覆盖边界情况(None 值、空 tensor 等)

什么时候会停止迭代?

迭代不会无限循环,以下情况触发终止:

  1. 连续 3 次精度验证不通过 → 报告精度问题
  2. 连续 3 次性能改进幅度 < 5% → 接受当前最优
  3. 达到最大迭代次数(默认 10 次)→ 输出当前结果

两个核心概念:
Arrangement & Application

在看实战之前,有两个 NineToothed 的核心概念必须理解:

Arrangement(分块策略)——数据怎么切

Arrangement 决定 GPU 线程网格如何映射到 tensor 的各个维度。

'''Python
def arrangement(input, output, BLOCK_SIZE=block_size()):
return input.tile((BLOCK_SIZE,)), output.tile((BLOCK_SIZE,))
'''
翻译成人话:把 'input' 和 'output' 都切成 'BLOCK_SIZE' 大小的块,每个 GPU 线程块处理一块。

不同算子的 Arrangement 复杂度差异巨大:

算子类型 复杂度 典型模式
Element-wise 所有 tensor 同样切法
Reduction 需指定规约维度
Matmul tile + expand + squeeze 组合
Attention 很高 多级层次结构 + online softmax

Application(计算逻辑)——每块数据怎么算

'''python
def application(input, output):
output = input + 1
'''
接收切好的 tensor 块,执行实际计算,就这么简单。

常用原语速查表

操作 语法 用途
分块 'x.tile((BLOCK_SIZE,))' 将 tensor 切成固定大小的块
扩展 'x.expand((-1, N))' 广播单维度(-1 表示保持原样)
压缩 'x.dtype.squeeze(0)' 移除广播引入的退化维度
规约 'ntl.sum(x) / ntl.max(x)' 求和 / 最大值
条件 'ntl.where(cond, a, b)' 条件选择
类型转换 'ntl.cast(x, ntl.float32)' 精度转换

精度验证:AI 怎么保证结果正确?

这是整个工作流中最关键的环节。Skill 定义了详细的验证策略:

按数据类型的容差标准:

数据类型 rtol atol 标准说明
float32 1e-5 1e-5 标准精度
float16 1e-3 1e-3 低精度
bfloat16 1e-2 1e-2 更低精度
int32/int64 0 0 必须精确匹配

按算子类型的容差标准

不同算子因为计算特性不同,允许的误差范围也不同。比如 element-wise 算子(add、relu)误差极小,而 softmax 和 attention 因为涉及指数运算,误差会更大。

四项必检

  1. 'torch.allclose' 在设定容差下通过
  2. 无 NaN 值
  3. 无 Inf 值
  4. 整数运算精确匹配

性能优化:六策略逐项评估

Auto-tune 已经处理了底层参数(BLOCK_SIZE、num_warps、num_stages)的搜索。在此基础上,性能优化子 Agent 会严格按顺序评估以下六项高层策略:

优先级 策略 说明
1 内存访问模式优化 确保合并访问(coalesced access),减少 bank conflict
2 算子融合 合并相邻操作,减少 kernel launch 和内存搬运
3 循环展开 小循环手动展开,减少循环开销
4 减少同步开销 移除不必要的同步点
5 精度策略调整 在精度允许的前提下使用更低精度
6 计算重组 调整计算顺序,提升指令级并行度

每项策略都必须显式标注"已评估"或"不适用(附原因)",不允许跳过。

Skill 的设计哲学

精度优先——先正确,再快速

整个工作流中,精度验证在性能优化之前。精度不通过?不会进行任何性能优化。

自我迭代——不到山穷水尽不停手

性能优化不是一次性的。只有连续 3 次改进幅度低于 5% 时才停止。这意味着 AI 会不断尝试不同策略,直到性能提升空间被耗尽。

NineToothed Operator Skill 目前仍在持续迭代中。文中所描述的工作流、验证策略和优化机制,代表当前的设计思路和已实践验证的部分,并非最终形态。
欢迎反馈,帮助我们打磨得更好

实战演示:AI 生成一个 Clamp 算子

光说不练假把式,来看一个完整的实战案例。根据提供的 cpu 算法,实现对应的九齿算子:
'''Python
def clamp(x, min_val=None, max_val=None):
"""标准的 clamp 算子"""
y = x.copy()
if min_val is not None:
y = np.maximum(y, min_val)
if max_val is not None:
y = np.minimum(y, max_val)
return y
'''

Step 1️⃣:触发 Skill,创建任务清单

根据触发机制自动加载 ninetoothed-operator skill,主 Agent 立即创建包含 6 个阶段的任务清单:分析 CPU 实现→生成初始算子→自动调优→精度验证→性能优化→输出报告。有条不紊地逐步推进。

Step 2️⃣:分析 CPU 实现

主 Agent 提取关键信息:

  • 算子类型:Element-wise(逐元素)
  • 输入:1 个张量 + 2 个可选标量参数('min_val'、'max_val')
  • 输出:形状与输入相同

Step 3️⃣:探索代码库 + 生成初始代码

子 Agent 探索 NineToothed 代码库,查找已有的逐元素算子作为参考,了解标量参数的声明方式'(Tensor(0))'以及 'ntl.maximum'、'ntl.minimum' 等 API 的使用模式。

生成的 NineToothed 核心逻辑仅需 三行:先用 'ntl.minimum '截断上界,再用 'ntl.maximum' 截断下界。

'min_val' 和 'max_val' 以 'Tensor(0)' 声明为标量,未提供时默认为 'inf/-inf',对应的截断操作不产生实际效果。同时生成覆盖各种边界条件的测试用例。

Step 4️⃣:精度验证

以 CPU 实现为基准,对比 GPU 输出。测试覆盖:

  • float32 / float16 两种数据类型
  • 不同输入规模
  • 五种场景:"同时限定上下界"、"仅限下界"、"仅限上界"、"无限定"、"多维输入"

全部测试通过,精度验证合格。

Step 5️⃣:性能优化

按六项策略优先级依次评估。对于 'clamp' 这种简单的逐元素算子,Auto-tune 已达最优,6 项策略均无额外提升空间。

Step 6️⃣:输出报告

主 Agent 输出完整报告:最终代码位置、精度验证结果(28/28 通过)、自动调优结果、以及性能优化策略评估记录,整个算子生成流程结束。

写在最后

NineToothed Operator Skill 本质上在做一件事:把"写 GPU 算子"这件事的门槛,从"懂 Triton + 懂调优 + 懂精度"降到了"写一段能跑的 CPU 代码"。

你不需要理解 tile/expand/squeeze 怎么组合,不需要手动调 BLOCK_SIZE,甚至不需要知道什么是 bank conflict——AI 帮你全包了。

NineToothed(九齿) 开源仓库:https://github.com/InfiniTensor/ninetoothed
2026春季启元人工智能大赛同步开放「九齿 · skill」创新挑战赛道,欢迎报名参与: https://www.infinitensor.com/, 或点击 【阅读原文】 直达报名网站