你去超市买过那种混合装坚果吗?一袋里面核桃、腰果、巴旦木都有,打开直接吃,不用自己搭配。ops-nn 在昇腾CANN生态里就是这个角色——把神经网络最常用的算子打包好了,打开就能用。昇腾NPU跑大模型、跑视觉模型,底层都绕不开它。

定位:算子层的标准件

ops-nn 是 CANN AOL 算子库里的神经网络类基础算子仓库。它不追求极致融合——那是 ops-transformer 的事——它追求的是覆盖广、接口稳、性能靠谱。

在 CANN 五层架构里,ops-nn 跟 ops-transformer 一样位于第二层昇腾计算服务层,属于 AOL 算子库。ops-nn 在下,ops-transformer 在上:

ops-math/ops-blas  →  ops-nn  →  ops-transformer  →  ATB
   基础数学           神经网络      大模型融合          加速库

ops-nn 的算子会被 ops-transformer 的融合算子作为组件调用,也会被 ATB 直接调用(非融合路径)。

算子清单

类别 代表算子 说明
卷积 Conv2D, Conv3D, DepthwiseConv2D CNN 的核心,Tiling 对性能影响最大
全连接 MatMul + Bias + Activation 融合 单独的 MatMul 在 ops-blas,这里带激活的版本
归一化 LayerNorm, BatchNorm, GroupNorm, RMSNorm 大模型用 LayerNorm/RMSNorm,CV 用 BatchNorm
激活函数 ReLU, GELU, SiLU, Swish, Sigmoid 单独的激活函数性能差异不大,融合价值在跟前后算子合体
池化 MaxPool, AvgPool, AdaptiveAvgPool CV 模型用得多
损失函数 CrossEntropy, NLLLoss, BCELoss 训练场景
采样 Interpolate, Upsample 图像生成模型

这些算子单独看都不复杂。但在昇腾NPU上把每个都跑出理论性能,需要针对达芬奇架构做适配。ops-nn 的价值就是帮你把这些适配工作做了。

融合算子:ops-nn 的隐藏能力

ops-nn 不只是简单算子的集合,它也有融合算子。最典型的是 MatMul + Bias + Activation 三合一:

import torch_npu

# 标准写法:3个kernel
x = torch.nn.functional.linear(x, w, b)      # MatMul + Bias
x = torch.nn.functional.silu(x)               # Activation
# 总共2个kernel(Linear内部已融合Bias)

# ops-nn 融合写法:1个kernel
x = torch_npu.npu.linear_activation(x, w, b, activation="silu")
# MatMul + Bias + SiLU 一次完成

昇腾NPU上这个融合的收益不只是少一次 kernel launch。更关键的是中间结果不写回 HBM——Linear 的输出在 Cube 单元算完后,直接在片上缓存传给 Vector 单元做 SiLU,零显存开销。

在大模型的 FFN 层,这个融合每层能省约 0.1 GB 的 HBM 读写。32 层就是 3.2 GB,看起来不多,但在 decode 阶段 NPU 利用率只有 30-40% 的场景下,每次 HBM 读取都是延迟来源。

跟 ops-transformer 的边界

容易混淆的地方:

  • LayerNorm:ops-nn 实现,ops-transformer 不会重新实现。FlashAttention 不包含 LayerNorm。
  • SiLU 激活:ops-nn 有独立实现,但在 ops-transformer 的 MergedMatMul 里可能被融合掉。
  • QKV Linear:ops-nn 的 linear_activation 可以做,但 ops-transformer 的 MergedMatMul + RotaryEmbedding 融合效果更好。

简单规则:如果你的模型是标准 Transformer 架构,优先用 ops-transformer 的融合算子;如果是自定义模型结构,用 ops-nn 的基础算子自己拼。

和 PyTorch 原生算子的关系

CANN 的 torch_npu 会自动把 PyTorch 的标准 API 映射到 ops-nn:

# 这两行等价
x = torch.nn.functional.layer_norm(x, [4096])
x = torch_npu.npu.layer_norm(x, [4096])  # 底层走 ops-nn 的 kernel

不需要手动调 ops-nn API。PyTorch 代码在昇腾NPU上跑的时候,torch_npu 自动把算子分发到 CANN 的实现。


ops-nn 是你不太需要主动关心的仓库——它在底层默默干活,通过 torch_npu 和 ATB 间接服务你。但当你的自定义模型在昇腾NPU上性能不达标时,查一下算子是不是走到了 ops-nn 的融合路径,往往能找到突破口。仓库在这里:

https://atomgit.com/cann/ops-nn

Logo

鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。

更多推荐