CANN-ops-transformer和ATB-昇腾NPU上算子和加速库怎么配合
本文分析了CANN生态中ops-transformer和ATB(ascend-transformer-boost)的协作关系。ops-transformer提供Ascend C编写的底层算子,ATB则负责算子编排和推理服务管理。ATB会自动调用ops-transformer的优化算子(如FlashAttention),并处理KV Cache等推理任务。两者的边界在于:ops-transformer
CANN-ops-transformer和ATB-昇腾NPU上算子和加速库怎么配合
有人问我:ops-transformer 和 ATB 到底是什么关系?我把 FlashAttention 的代码改了,ATB 的推理结果怎么也跟着变了?这两个仓库在昇腾CANN生态里是上下游关系,但它们的边界不是"底层"和"上层"那么简单。
先搞清楚各自的定位
ops-transformer:算子的提供方。 它的产出是 Ascend C 编写的算子 kernel,注册到 CANN 的 AOL 算子库里。你通过 torch_npu.npu.flash_attention 这种底层 API 可以直接调用它,但你得自己管理输入输出、内存布局、数据类型。
ATB(ascend-transformer-boost):算子的编排方。 它把 ops-transformer 的算子封装成高层 API,按 Transformer 模型的结构编排算子的执行顺序,自动处理 KV Cache 管理、请求调度、batch 合并这些推理服务必须面对的问题。
打个比方:ops-transformer 是食材供应商,ATB 是餐厅后厨。你可以自己买食材回家做(直接调算子 API),也可以去餐厅点菜(用 ATB 搭建推理服务)。食材的质量决定了菜的上限,但后厨的火候和节奏决定了出品效率。
ATB 怎么调用 ops-transformer 的算子
ATB 内部有一个算子映射表。当 ATB 解析到模型的 Attention 层时,它会:
- 检查当前 CANN 版本是否支持 FlashAttention
- 检查输入的 head_dim 是否满足对齐要求(16 的倍数)
- 如果满足,调用 ops-transformer 的 FlashAttention kernel
- 如果不满足,fallback 到标准 Attention 实现
这个映射过程对用户透明。你在 ATB 里加载一个 Llama 模型,ATB 自动把所有 Attention 层替换成 FlashAttention,把所有 MoE 层替换成 MoE 融合算子。你不需要改模型代码。
# ATB 方式:自动编排,算子替换透明
from atb import LLM
model = LLM("meta-llama/Llama-2-7b-hf", device="npu:0")
output = model.generate("Hello, world")
# 对比:直接调算子 API,需要自己管理
import torch_npu
out = torch_npu.npu.flash_attention(q, k, v) # 你自己处理 KV Cache、batch 等
数据流转
一次完整的 Transformer 推理,数据在 ops-transformer 和 ATB 之间的流转:
ATB 接收请求
→ ATB Token Embedding(ATB 自己实现)
→ ATB 调用 ops-transformer 的 RotaryEmbedding 融合算子
→ ATB 调用 ops-transformer 的 FlashAttention(自动管理 KV Cache 传入传出)
→ ATB 调用 ops-nn 的 LayerNorm
→ ATB 调用 ops-transformer 的 MergedMatMul(MoE 场景)
→ ATB 调用 ops-blas 的 MatMul(普通 FFN)
→ 循环 N 层
→ ATB 输出 Token
ATB 负责层与层之间的数据传递和内存管理,ops-transformer 只管每个算子内部的高效计算。
边界在哪里
两者最容易出现混淆的地方是"融合"的归属:
- 算子内部融合(FlashAttention 把 MatMul+Softmax+MatMul 融成一个 kernel)→ ops-transformer 的事
- 算子之间融合(FlashAttention 的输出直接送入 LayerNorm,中间不落显存)→ graph-autofusion 在 GE 编译阶段处理
- 模型级编排(KV Cache 管理、请求调度、continuous batching)→ ATB 的事
如果你发现某个算子在 ATB 里跑的性能不如直接调 API,大概率是 ATB 的编排没有触发 graph-autofusion。检查 GE 的编译日志,看有没有 autofusion 的记录。
一个实际场景
你在 ATB 里跑 Llama2-70B 的推理,发现 Attention 层比预期慢。怀疑 FlashAttention 没生效。
排查步骤:
- 看 ATB 的初始化日志,搜索
FlashAttention关键字 - 如果显示
fallback to standard attention,检查 head_dim(Llama2 是 128,满足要求) - 检查 CANN 版本——ATB 0.7 之前对 FlashAttention V2 的支持有 bug,升级到 0.8+
- 如果日志显示 FlashAttention 已启用但还是慢,看 GE 编译日志里有没有 autofusion——FlashAttention 没跟前后算子融合,每次都有额外的显存读写
什么时候该直接调算子 API
大部分场景用 ATB 就够了。但以下情况需要绕过 ATB 直接调 ops-transformer:
- 你在做算子开发,需要隔离测试单个算子的性能
- 你的模型结构不是标准 Transformer(比如混合了 CNN 和 Attention),ATB 的编排不支持
- 你需要精细控制算子的 tiling 参数,ATB 的默认值不够优
如果你在 ATB 里遇到了算子性能问题,先别急着优化算子——可能是 ATB 和 ops-transformer 之间的编排没对齐。查日志、查 CANN 版本、查 GE autofusion 记录,这三步能解决 80% 的问题。两个仓库在这里:
https://atomgit.com/cann/ops-transformer
更多推荐



所有评论(0)