引言
随着大模型和高性能计算的快速发展,针对专用加速器的编译与优化变得越来越重要。AscendNPU IR作为华为昇腾(Ascend)处理器的软件栈核心组成,用于桥接高层算子定义与底层硬件执行。它不仅承载算子逻辑的表达,也提供优化和调度的接口,是实现高效 NPU 推理的关键。
本文档旨在为开发者提供一份简明、实用的 AscendNPU IR 语法速查指南。通过对核心概念、基本语法、算子调用方式以及常用优化技巧的梳理,帮助开发者快速理解 IR 结构与使用方法,为算子开发、性能调优和调试排障提供参考。
AscendNPU IR git地址:https://gitcode.com/Ascend/AscendNPU-IR

第一章:AscendNPU IR 核心概念速查
在正式讲解 AscendNPU IR 核心语法和结构之前,我先带大家快速梳理一下整体框架,就像打开一张地图,先了解每个路标和主要路线,为后续深入解析和高效开发打下基础。
进入AscendNPU IR git仓库后找到README文档,在文档中我们可以找到和AscendNPU IR相关的核心基础知识的概念,接下来我给大家整理一些表格,方便大家进行查看和理解。

基础定位相关
|--------------|----------------------------------------------|-----------------------------------------------------------|
| 概念 | 核心解析 | 语法 / 应用要点 |
| AscendNPU IR | 针对昇腾硬件设计的 MLIR 方言,是连接上层框架与底层硬件的中间表达层 | 核心作用是将硬件指令抽象为高阶 OP,完成向 LLVM / 机器码的翻译,适配 Ascend 910B 等昇腾芯片 |
| 高阶 OP | 对昇腾硬件的计算、搬运、同步等操作的抽象封装 | 分为计算、搬运、内存三大类,开发者无需关注硬件细节,仅需通过 OP 组合实现算子逻辑 |
| 方言对接 | AscendNPU IR 作为 MLIR 的特定方言,可与 Linalg 等通用方言适配 | 是对接 Triton 等第三方框架的关键,实现 "一次编写,多芯运行" 的跨架构兼容 |
算子与计算相关
|------------|-------------------------------------|-------------------------------------------------------------------------------------------------------|
| 概念 | 核心解析 | 语法 / 应用要点 |
| 算子 IR 注册 | 将自定义算子的输入输出类型、属性等信息录入昇腾算子库,供计算图引擎调度 | 注册后 GE 可自动推导算子类型并分配内存,是自定义算子集成到昇腾平台的必要步骤 |
| compute_op | 计算类核心语法,用于封装硬件计算指令 | 语法示例:%result = ascendnpu.compute_op(%input1, %input2) { ascendnpu.instruction("VectorAdd") },指定具体计算指令 |
| Block | 编程层面对 AI Core 计算单元的逻辑抽象 | BlockDim 表示逻辑核数量,BlockID 标识具体逻辑核,每个 Block 映射到一个 AI Core 计算单元 |
存储与内存相关
|--------------|------------------------|-----------------------------------------------------------------------------------------------|
| 概念 | 核心解析 | 语法 / 应用要点 |
| memory_op | 内存操作类语法,负责内存同步、数据搬运等操作 | 语法示例:%output = ascendnpu.memory_op(%result) { ascendnpu.instruction("MemorySync") },保障数据读写一致性 |
| GlobalTensor | 对应全局内存(GM)的数据容器 | 用于存储大规模待处理数据,是设备主存中的数据载体,需通过搬运操作传入计算单元 |
| LocalTensor | 对应片上高速存储(如 UB)的数据容器 | UB 为 AI Core 独享高速存储,LocalTensor 可提升计算时的数据访问速度,降低访存延迟 |
| Tiling | 对大规模 Tensor 的分块技术 | 通过TilingData记录分块参数,适配 AI Core 的计算粒度,充分利用 Cube 单元等硬件资源 |
- 编译与优化相关
|-----------|-----------------------------------|-------------------------------------|
| 概念 | 核心解析 | 语法 / 应用要点 |
| 流水并行 | 毕昇编译器通过多处理单元流水线优化,提升算子性能 | AscendNPU IR 自动实现片上内存管理与流水并行,掩盖访存延迟 |
| 细粒度 OP 控制 | 分层开放的底层接口,支持同步指令插入、片上内存地址控制等精细化操作 | 适合深度性能调优,例如通过控制乒乓流水提升数据处理效率 |
第二章:基本语法速查
AscendNPU IR 作为基于 MLIR 构建的昇腾硬件专属中间表示,是连接上层框架(如 Triton)与底层昇腾 NPU 硬件的关键桥梁。其核心价值在于通过高阶操作抽象(OP)掩盖硬件指令细节,同时支持细粒度性能调优,以下从核心语法与结构解析两大维度展开详细说明。

AscendNPU IR 语法以 MLIR 方言(Dialect)为基础,通过计算、内存、同步三类核心 OP 实现昇腾硬件能力的完备表达,语法设计兼顾开发易用性与硬件控制灵活性,关键语法规则与示例如下:
在社区官网我们可以找到对应的AscendNPU IR参考资料,接下来的话就带大家一起来熟悉下AscendNPU IR的基础语法吧。

2.1 基础语法规范
-
方言标识 :所有 AscendNPU IR 专属操作均以
ascendnpu.为前缀,明确与 MLIR 通用方言(如 Linalg、MemRef)的区分,示例:ascendnpu.compute_op、ascendnpu.memory_op。 -
函数定义 :采用 MLIR 标准函数语法
func.func,输入输出需指定张量类型(含形状与数据类型),需匹配昇腾硬件支持的 dtype(如f32、f16、int8),示例:// 向量加法函数定义:输入为两个1024维f32张量,输出为1024维f32张量
func.func @vector_add(%input1: tensor<1024xf32>, %input2: tensor<1024xf32>) -> tensor<1024xf32> {
// 核心操作逻辑
%result = ascendnpu.compute_op(%input1, %input2) { ascendnpu.instruction("VectorAdd") } : (tensor<1024xf32>, tensor<1024xf32>) -> tensor<1024xf32>
%output = ascendnpu.memory_op(%result) { ascendnpu.instruction("MemorySync") } : (tensor<1024xf32>) -> tensor<1024xf32>
return %output : tensor<1024xf32>
} -
属性配置 :通过大括号
{}为 OP 附加硬件指令、参数等属性,属性键需以ascendnpu.开头,常用属性包括ascendnpu.instruction(指定硬件指令)、ascendnpu.addr(片上内存地址,细粒度控制时使用)。
2.2 三大核心 OP 语法
AscendNPU IR 将昇腾硬件操作抽象为计算、内存、同步三类 OP,覆盖从数据处理到硬件执行的全流程,是语法体系的核心:
(1)计算类 OP:ascendnpu.compute_op
-
作用:封装昇腾 NPU 的计算指令(如向量运算、矩阵乘、激活函数),自动映射到底层 AI Core 的 Cube 单元(矩阵计算)或 Vector 核(向量计算)。
-
语法格式:
%结果张量 = ascendnpu.compute_op(输入张量1, 输入张量2, ...) {
ascendnpu.instruction("硬件指令名"), // 必选,指定具体计算指令
[可选属性:如精度控制、计算单元选择]
} : (输入张量类型列表) -> 输出张量类型 -
常用硬件指令:
-
VectorAdd/VectorMul:向量加减/乘,对应 Vector 核操作;CubeMatMul:矩阵乘法,强制调用 AI Core 的 Cube 单元(16x16 计算粒度);ActivationReLU:ReLU 激活函数,支持与前序计算指令融合。
-
示例:矩阵乘法(调用 Cube 单元)
// 256x256 矩阵乘,输入为f16类型(适配Cube单元最优精度)
%matmul_res = ascendnpu.compute_op(%mat_a, %mat_b) {
ascendnpu.instruction("CubeMatMul"),
ascendnpu.precision("f16") // 可选:指定计算精度
} : (tensor<256x256xf16>, tensor<256x256xf16>) -> tensor<256x256xf16>
(2)内存类 OP:ascendnpu.memory_op
-
作用:管理昇腾 NPU 的内存层级(全局内存 GM、片上内存 UB、寄存器),实现数据搬运、同步、地址控制,是优化访存延迟的关键。
-
语法格式:
%处理后张量 = ascendnpu.memory_op(输入张量) {
ascendnpu.instruction("内存指令名"), // 必选,指定内存操作类型
[可选属性:如目标内存类型、地址偏移]
} : (输入张量类型) -> 输出张量类型 -
常用硬件指令:
-
MemorySync:内存同步,确保计算单元读取到最新数据(如 GM 到 UB 的数据搬运完成后触发);GM2UB/UB2GM:全局内存与片上 UB 之间的数据搬运;Reg2UB:寄存器数据写入 UB(细粒度控制时使用)。
-
示例:全局内存到片上 UB 的数据搬运
// 将GM中的输入张量搬运到UB,指定UB地址偏移为0x100
%ub_tensor = ascendnpu.memory_op(%gm_input) {
ascendnpu.instruction("GM2UB"),
ascendnpu.addr("0x100"), // 可选:指定UB目标地址
ascendnpu.mem_type("UB") // 明确目标内存类型
} : (tensor<1024xf16>) -> tensor<1024xf16>
(3)同步类 OP:ascendnpu.sync_op
-
作用:控制 AI Core 计算单元、内存模块之间的执行顺序,避免数据竞争,常用于流水线优化(如"计算-搬运"并行)。
-
语法格式:
ascendnpu.sync_op() {
ascendnpu.instruction("同步指令名"), // 如"Barrier"(核间同步)、"PipeSync"(流水同步)
[可选属性:如同步范围、等待时间]
} : () -> () // 无输入输出,仅控制执行时序 -
示例:多 AI Core 核间同步
// 等待所有AI Core完成当前计算后再执行后续操作
ascendnpu.sync_op() {
ascendnpu.instruction("Barrier"),
ascendnpu.sync_scope("all_cores") // 同步范围:所有AI Core
} : () -> ()
2.3 细粒度控制语法(进阶)
针对高性能调优场景,AscendNPU IR 提供片上内存地址、流水同步点等细粒度控制语法,需结合昇腾硬件架构细节使用:
-
片上内存地址指定 :通过
ascendnpu.addr属性直接控制 UB 内存地址,避免 Bank 冲突,示例:%ub_tensor = ascendnpu.memory_op(%gm_input) {
ascendnpu.instruction("GM2UB"),
ascendnpu.addr("0x200"), // UB地址偏移为0x200(需为16字节对齐,适配UB存储粒度)
ascendnpu.mem_type("UB")
} : (tensor<1024xf16>) -> tensor<1024xf16> -
乒乓流水优化 :通过
ascendnpu.pipe_stage属性指定流水线阶段,实现"数据搬运"与"计算"并行,示例:// 第1阶段:搬运数据到UB(PipeStage=1)
%ub_data1 = ascendnpu.memory_op(%gm_data1) {
ascendnpu.instruction("GM2UB"),
ascendnpu.pipe_stage("1")
} : (tensor<512xf16>) -> tensor<512xf16>// 第2阶段:计算(与第1阶段并行,PipeStage=2)
%compute1 = ascendnpu.compute_op(%ub_data1) {
ascendnpu.instruction("VectorAdd"),
ascendnpu.pipe_stage("2")
} : (tensor<512xf16>) -> tensor<512xf16>
第三章 AscendNPU IR 结构解析
AscendNPU IR 采用分层架构设计 ,自下而上实现"硬件指令抽象→中间表示转换→上层框架对接"的全链路能力,同时通过"计算-内存-同步"的操作组合,构建算子的完整执行流程,核心结构可从整体架构分层 与算子执行流程两方面解析。
3.1 整体架构分层:从硬件到框架的三级抽象
AscendNPU IR 作为 MLIR 的昇腾专属方言,处于"上层框架-Triton IR-MLIR通用方言-AscendNPU IR-昇腾机器码"编译链路的核心位置,整体架构分为硬件表达层、中间优化层、框架对接层三级,每层各司其职且灵活联动:
|-------|------------------------------------------------------|------------------------------------------------------------------------|
| 架构层级 | 核心作用 | 关键组件/操作 |
| 硬件表达层 | 抽象昇腾硬件原生能力,将 AI Core 指令、内存层级、同步机制封装为高阶 OP | 计算 OP(CubeMatMul/VectorAdd)、内存 OP(GM2UB/UB2GM)、同步 OP(Barrier/PipeSync) |
| 中间优化层 | 基于 MLIR 通用优化能力,实现硬件无关优化(循环展开、算子融合)与昇腾亲和优化(UB 复用、流水线) | MLIR Linalg 方言转换、毕昇编译器"多处理单元流水并行"优化、UB 内存自动分配 |
| 框架对接层 | 提供统一接口对接上层框架(如 Triton、PyTorch),降低生态适配成本 | Triton IR → MLIR Linalg → AscendNPU IR 转换逻辑、Tensor 级 OP 快速适配接口 |
- 核心流转逻辑:以上层 Triton 框架为例,其算子开发流程的结构流转如下:
-
- 开发者用 Python 编写 Triton 算子代码(如矩阵乘);
- Triton 前端将 Python 代码解析为 Triton IR(语言级优化,如循环展开);
- 中端将 Triton IR 转换为 MLIR Linalg 方言(硬件无关优化,如内存布局调整);
- 后端将 Linalg 方言转换为 AscendNPU IR(绑定昇腾硬件能力,如映射 Cube 单元);
- 毕昇编译器将 AscendNPU IR 翻译为 昇腾 NPU 机器码(最终在 AI Core 上执行)。
3.2 算子执行流程结构:"数据搬运-计算-同步"三步闭环
基于 AscendNPU IR 开发的算子,其执行流程需遵循昇腾硬件"存储-计算分离"的架构特性,核心结构为**"数据搬运→计算→同步"三步闭环**,确保数据高效流转与计算资源充分利用,以矩阵乘算子为例解析流程结构:
步骤 1:数据搬运(内存 OP 主导)
-
目标:将全局内存(GM)中存储的大规模矩阵数据,分块搬运到片上 UB(Unified Buffer),降低计算时的访存延迟(UB 带宽远高于 GM)。
-
核心操作 :调用
ascendnpu.memory_op执行GM2UB指令,结合 Tiling 分块策略(如将 2048x2048 矩阵切分为 256x256 子块),确保 UB 不溢出(昇腾 910B UB 容量通常为 32KB/核)。 -
结构示例:
// 将GM中的2048x2048矩阵切分为256x256子块,搬运到UB
%gm_mat_a: tensor<2048x2048xf16>, %gm_mat_b: tensor<2048x2048xf16>
%tiled_a = ascendnpu.memory_op(%gm_mat_a) {
ascendnpu.instruction("GM2UB"),
ascendnpu.tiling("256x256"), // Tiling分块参数
ascendnpu.mem_type("UB")
} : (tensor<2048x2048xf16>) -> tensor<256x256xf16>
%tiled_b = ascendnpu.memory_op(%gm_mat_b) {
ascendnpu.instruction("GM2UB"),
ascendnpu.tiling("256x256"),
ascendnpu.mem_type("UB")
} : (tensor<2048x2048xf16>) -> tensor<256x256xf16>
步骤 2:计算(计算 OP 主导)
-
目标:在 AI Core 上执行矩阵乘计算,调用 Cube 单元实现 16x16 粒度的高效计算,同时通过流水线优化掩盖后续数据搬运的延迟。
-
核心操作 :调用
ascendnpu.compute_op执行CubeMatMul指令,自动匹配 Cube 单元的计算粒度(子块大小需为 16 的倍数,如 256=16×16),确保算力利用率最大化。 -
结构示例:
// 调用Cube单元执行256x256子块矩阵乘,计算精度为f16
%tiled_result = ascendnpu.compute_op(%tiled_a, %tiled_b) {
ascendnpu.instruction("CubeMatMul"),
ascendnpu.precision("f16"),
ascendnpu.compute_unit("Cube") // 强制使用Cube单元
} : (tensor<256x256xf16>, tensor<256x256xf16>) -> tensor<256x256xf16>
步骤 3:同步与结果回写(同步 OP + 内存 OP 主导)
-
目标:等待计算完成后,将 UB 中的子块计算结果回写到 GM,同时通过同步指令确保多子块计算的顺序一致性(避免数据覆盖)。
-
核心操作 :先调用
ascendnpu.sync_op执行Barrier同步,再调用ascendnpu.memory_op执行UB2GM指令回写结果。 -
结构示例:
// 同步:等待当前子块计算完成
ascendnpu.sync_op() { ascendnpu.instruction("Barrier") } : () -> ()// 结果回写:将UB中的子块结果写入GM
%gm_result_tile = ascendnpu.memory_op(%tiled_result) {
ascendnpu.instruction("UB2GM"),
ascendnpu.tiling_offset("0,0") // 指定GM中的目标偏移位置
} : (tensor<256x256xf16>) -> tensor<256x256xf16>
3.3 关键结构特性:分层开放与硬件亲和
AscendNPU IR 结构设计的两大核心特性,决定了其"易用性"与"性能上限"的平衡:
- 分层开放:自下而上提供"细粒度硬件控制→核资源抽象→Tensor 级 OP"三级接口,开发者可按需选择:
-
- 快速适配:使用 Tensor 级 OP(如
CubeMatMul),无需关注硬件细节; - 深度调优:使用细粒度接口(如 UB 地址控制、流水同步),优化极端场景性能。
- 快速适配:使用 Tensor 级 OP(如
- 硬件亲和:结构设计与昇腾达芬奇架构深度绑定,如:
-
- 分块策略匹配 UB 容量(避免溢出);
- 计算 OP 自动映射 Cube/Vector 核(释放硬件算力);
- 流水线同步匹配 AI Core 多周期执行特性(掩盖访存延迟)。
第四章 结语
本指南聚焦 AscendNPU IR 的核心语法与结构逻辑,以速查形式梳理了其关键知识点,为开发者搭建起快速上手的实用框架。作为昇腾硬件与上层 AI 框架之间的 "通用翻译器",AscendNPU IR 凭借计算、内存、同步三类高阶 OP 的抽象封装,既屏蔽了底层硬件细节,降低了 Triton 等框架的适配门槛,又通过分层开放的细粒度接口,保留了极致性能调优的空间,实现了开发效率与硬件潜力的平衡。