适合人群:想从全局视角理解 CANN 架构的开发者
核心仓库:https://atomgit.com/cann
阅读时长:6 分钟


目录


一、为什么需要五层架构?

拿到昇腾 NPU 的第一反应往往是:我写的 PyTorch 代码,是怎么跑到这块芯片上的?

答案藏在 CANN 的五层架构里。

先打个比方:你点外卖。用户(框架)→ 下单系统(AscendCL)→ 厨房调度(编译层)→ 出餐窗口(执行层)→ 灶台(硬件)。每一层各司其职,上层不用管下层怎么做,下层也不用管上层点什么。

这种分层的好处是解耦——框架升级不影响硬件调度,算子优化不影响上层接口。你的 PyTorch 代码今天能跑在 Ascend 910 上,明天换了新一代 NPU,代码也不用改。

如果只有三层会怎样?框架直接跟硬件打交道,每次换芯片就要重写一遍适配代码。昇腾 CANN 用五层架构把这个过程标准化了。


二、第1层:昇腾计算语言层 AscendCL

AscendCL 是 CANN 对外暴露的统一编程接口,相当于你跟昇腾 NPU 对话的"翻译官"。

不管你用的是 PyTorch、MindSpore 还是 TensorFlow,最终都会经过这一层。它提供的能力包括:

  • 模型加载与执行:加载 .om 离线模型,执行推理
  • 内存管理:在 NPU 上分配/释放显存
  • 流(Stream)管理:控制计算任务的并发执行
  • 事件(Event)同步:多流之间的同步机制
# AscendCL 的核心 API 使用示例(Python绑定)
import acl

# 1. 初始化 AscendCL
acl.init() # 初始化ACL运行环境

# 2. 指定计算设备
device_id = 0
acl.rt.set_device(device_id) # 设置当前使用的NPU设备

# 3. 创建计算上下文和流
context = acl.rt.create_context(device_id)
stream = acl.rt.create_stream() # 创建执行流

# 4. 加载离线模型 (.om文件)
model_path = "resnet50.om"
model_id = acl.mdl.load_from_file(model_path)

# 5. 准备输入数据并执行推理
input_dataset = acl.mdl.create_dataset()
output_dataset = acl.mdl.create_dataset()
ret = acl.mdl.execute(model_id, input_dataset, output_dataset)

# 6. 释放资源
acl.mdl.unload(model_id)
acl.rt.destroy_stream(stream)
acl.rt.destroy_context(context)
acl.rt.reset_device(device_id)
acl.finalize()

大多数开发者不会直接调用 AscendCL API——框架适配层(torch.npu 等)已经帮你封装好了。但理解 AscendCL 的存在,能帮你搞清楚"代码到底是怎么到 NPU 上的"。


三、第2层:昇腾计算服务层

这一层是 CANN 的"武器库",包含两大核心组件:

AOL 算子库

AOL(Ascend Operator Library)提供了大量预优化好的算子实现,覆盖 AI 计算的各个场景:

算子库 仓库 定位
ops-nn https://atomgit.com/cann/ops-nn NN 网络基础算子(Conv/BN/Pooling)
ops-transformer https://atomgit.com/cann/ops-transformer Transformer 进阶算子(FlashAttention/MoE)
ops-adv https://atomgit.com/cann/ops-adv 图像处理/科学计算算子
ascend-transformer-boost https://atomgit.com/cann/ascend-transformer-boost Transformer 全流程加速库

AOE 调优引擎

AOE(Ascend Optimization Engine)负责根据你的模型结构和硬件配置,自动寻找最优的算子参数组合。比如:

  • Conv2d 的 tile 大小用什么值最快
  • MatMul 用哪种切分策略最省显存
  • 多卡通信用什么拓扑最省带宽
# AOE 自动调优示例
# Step 1: 导出 ONNX 模型
python export_model.py --model resnet50 --output resnet50.onnx

# Step 2: 使用 AOE 调优(遗传算法 + 强化学习)
atc --model=resnet50.onnx \
 --framework=5 \
 --output=resnet50_optimized \
 --soc_version=Ascend910 \
 --auto_tune_mode="GA,RL"

# Step 3: 使用调优后的模型推理
# 调优后的 .om 文件已包含最优配置,直接部署即可
# 调优结果缓存在 ~/.ascend/aoe/ 目录,同结构模型可复用

AOE 的调优过程可能需要几小时,但只需跑一次,后续同结构的模型都能复用调优结果。


四、第3层:昇腾计算编译层

这是 CANN 架构里最"硬核"的一层,包含两个核心组件:

Graph Engine(GE)

GE 负责接收框架发来的计算图,执行以下优化:

  1. 算子融合:把相邻的小算子合成一个大算子。比如 Conv + BN + ReLU → FusedConvBNReLU,减少 kernel 启动开销和显存读写
  2. 常量折叠:编译期就能算出来的值直接算好,不等到运行时
  3. 死代码消除:删掉不会被执行到的算子
  4. 内存规划:复用中间 tensor 的显存,降低峰值

ATC 编译器

ATC(Ascend Tensor Compiler)把优化后的计算图编译成昇腾 NPU 可执行的 .om 文件:

# ATC 编译命令详解
atc --model=llama.onnx \ # 输入:ONNX模型
 --framework=5 \ # 框架类型:5=ONNX
 --output=llama_ascend \ # 输出:.om文件名
 --soc_version=Ascend910 \ # 目标芯片
 --input_shape="input:1,2048" \ # 输入shape(静态shape)
 --insert_op_conf=aipp.cfg \ # AIPP预处理配置(可选)
 --op_precision_mode=allow_fp32_to_fp16 # 精度策略

编译出的 .om 文件是一个自包含的离线模型,包含了算子指令、内存布局、调度顺序等所有信息,可以直接部署到昇腾 NPU 上运行。


五、第4层:昇腾计算执行层

编译好的 .om 文件到了这一层才真正开始跑。执行层包含:

Runtime

Runtime 是昇腾 NPU 的运行时环境,负责:

  • 任务调度:把编译好的指令下发到 NPU
  • 流管理:多流并发执行,最大化硬件利用率
  • 显存管理:运行时的显存分配与回收
  • 同步机制:Event/Stream 级别的同步

HCCL

HCCL(Huawei Collective Communication Library)是昇腾的多卡通信库,对标 NVIDIA 的 NCCL。支持:

  • AllReduce / AllGather / Broadcast 等集合通信原语
  • 多机多卡分布式训练
  • 自动拓扑感知,选择最优通信路径

六、第5层:昇腾计算基础层

最底层,直接跟硬件打交道:

  • 驱动(Driver):管理 NPU 设备的内核模块
  • 固件(Firmware):运行在 NPU 芯片上的微代码
  • 硬件管理:时钟频率、温度监控、功耗控制

这层对开发者基本透明,你唯一需要关心的是 npu-smi 工具——查看 NPU 状态、显存占用、温度等。

# npu-smi 常用命令
npu-smi list # 查看所有NPU设备
npu-smi info -t board # 查看指定卡的详细信息
npu-smi info -t usages # 查看显存和计算单元利用率

# 典型输出:
# NPU | Chip | Device | HBM-Used | AICore-Util
# 0 | 910 | 0000:01 | 12345/32768 | 85%
# 1 | 910 | 0000:02 | 8192/32768 | 42%

七、实战:追踪一个请求的完整路径

把前面六节串起来,看一个完整的请求路径:

PyTorch: model(x) → torch.npu 转发
 ↓
AscendCL: acl.mdl.execute() → 下发到编译层
 ↓
Graph Engine: 算子融合 + 内存规划 → 生成优化图
 ↓
ATC: 编译成 .om → 包含 NPU 指令
 ↓
Runtime: stream 调度 → 多流并发执行
 ↓
NPU: 达芬奇架构执行矩阵运算 → 结果写回 HBM

整个链路中,编译层的优化是性能差异最大的环节。同样一个 ResNet50,没优化可能只跑到 500fps,经过 ATC 编译 + GE 算子融合后可以跑到 2000fps 以上。

这就是为什么理解 CANN 架构很重要——不是让你手动优化每一层,而是帮你定位性能瓶颈在哪一层,然后对症下药。


八、去哪找资源

资源 链接 说明
CANN 官方仓库 https://atomgit.com/cann 全部仓库索引
Graph Engine https://atomgit.com/cann/ge 图执行引擎
ATC 编译器 https://atomgit.com/cann/atc 模型编译工具
入门教程 https://atomgit.com/cann/cann-learning-hub 从浅到深
示例代码 https://atomgit.com/cann/cann-samples 官方 Sample

建议先从 cann-learning-hub 的 “架构入门” 教程开始,把五层架构跑一遍。然后按需深入:做算子开发看 ops-* 仓库,做模型部署看 ATC 文档,做分布式训练看 HCCL。

遇到问题,atomgit 上的 issues 区和昇腾社区论坛都很活跃。


如果这篇文章帮你理清了 CANN 的架构脉络,点个赞👍,留个言💬,下期拆解 ATC 编译器的优化策略!

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐