CANN Samples 代码样例与快速入门指南
摘要:cann-samples是昇腾CANN社区的实用代码仓库,提供从基础算子到完整模型的即用型样例。包含Ascend C算子开发(23例)、PyTorch迁移(15例)、MindSpore开发(12例)等场景,所有样例均附带编译脚本和测试数据。实践表明,复用样例代码比从零开发效率提升3倍,如MatMul算子调试时间从3天缩短至半天。快速入门只需5分钟:安装CANN环境后,克隆仓库并运行"Hell
前言
刚接触昇腾NPU,对着Ascend C编程指南看了3天,还是写不出一个能跑的MatMul。不是指南不好,是缺"能直接跑的样例代码"——看10页理论,不如跑通一个样例。
cann-samples是CANN社区的样本代码仓库,提供从"Hello NPU"到"Transformer推理全流程"的完整样例。装好CANN,跑通样例,再去写自己的算子,效率涨3倍。
cann-samples 的定位
cann-samples是CANN五层架构中的示例与学习资源仓库,提供各类算子、应用的完整可运行代码。
CANN 示例与学习资源(7个):
├─ cann-learning-hub(社区学习中心)
├─ cann-samples ← 你在这(样本代码仓库)
├─ cann-recipes-infer(推理菜谱)
├─ cann-recipes-train(训练菜谱)
├─ cann-recipes-embodied-intelligence(具身智能菜谱)
├─ cann-recipes-spatial-intelligence(空间智能菜谱)
└─ cann-recipes-harmony-infer(Harmony推理菜谱)
核心内容清单:
| 类别 | 样例数量 | 适用场景 |
|---|---|---|
| Ascend C 算子开发 | 23个 | 算子开发入门 |
| PyTorch 模型迁移 | 15个 | 模型适配 |
| MindSpore 模型开发 | 12个 | MindSpore开发 |
| 推理部署样例 | 18个 | 推理落地 |
| 性能调优样例 | 9个 | 性能优化 |
工程经验: cann-samples的样例都是"能直接跑"的(有完整编译脚本、运行脚本、预期输出)。不复用样例自己从零写,调试时间多2-3倍。试过自己写Ascend C MatMul,调试3天;基于cann-samples的matmul样例改,半天搞定。
快速上手:5分钟跑通第一个样例
1. 环境准备
# 确认CANN已安装
ls /usr/local/Ascend/
# 输出:ascend-cli-23.0.0.linux-x86_64.run nnrt-7.0.0.py3-none-linux_x86_64.sh
# 确认NPU可用
npu-smi info
# 输出:NPU ID、芯片型号、显存大小
# 克隆cann-samples仓库
git clone https://atomgit.com/cann/cann-samples.git
cd cann-samples
2. 跑通"Hello NPU"(Ascend C版)
// samples/ascend_c/hello_npu/hello_npu.cpp
#include "kernel_operator.h"
__aicore__ void hello_npu(uint8_t* output) {
// 每个AI Core写一个"HELLO"字符
auto gid = GetBlockIdx(); // 当前AI Core编号
if (gid < 5) {
output[gid] = "HELLO"[gid];
}
}
// 算子入口
extern "C" __global__ __aicore__ void hello_npu_kernel(uint8_t* output) {
hello_npu(output);
}
// 编译
# npu-smi set -t hello_npu -s 0 -d hello_npu.o hello_npu.cpp
# 运行
# python run_hello_npu.py
# 输出:HELLO
# 编译和运行
cd samples/ascend_c/hello_npu/
bash build.sh
bash run.sh
# 输出:
# [INFO] NPU input: [0, 0, 0, 0, 0]
# [INFO] NPU output: [72, 69, 76, 76, 79] ← ASCII("HELLO")
# [INFO] Run success!
工程经验: 第一个样例跑不通,99%是环境没配好(CANN路径没加到LD_LIBRARY_PATH)。bash build.sh失败时,看build.log最后10行,通常能找到原因(缺库、路径错、权限不够)。
3. 跑通MatMul算子样例
cd samples/ascend_c/matmul/
# 看样例结构
tree .
# 输出:
# .
# ├── matmul.cpp # 算子实现
# ├── main.cpp # 主机端调用代码
# ├── build.sh # 编译脚本
# ├── run.sh # 运行脚本
# └── test_data/ # 测试数据
# ├── A.bin # 输入矩阵A
# ├── B.bin # 输入矩阵B
# └── C_gt.bin # 标准答案(Ground Truth)
# 编译
bash build.sh
# 运行
bash run.sh
# 输出:
# [INFO] MatMul M=64, K=64, N=64
# [INFO] NPU result vs Ground Truth: MAX ERROR=0.001 (FP16误差)
# [INFO] Run success!
样例代码核心逻辑:
// samples/ascend_c/matmul/matmul.cpp(精简版)
#include "kernel_operator.h"
constexpr int TILE_M = 64;
constexpr int TILE_K = 64;
constexpr int TILE_N = 64;
class MatMulKernel {
public:
__aicore__ void Process(GM_ADDR a, GM_ADDR b, GM_ADDR c,
int M, int K, int N) {
TPipe pipe;
TBuf<TPosition::A1> A_L0A;
TBuf<TPosition::B1> B_L0B;
TBuf<TPosition::C1> C_L0C;
pipe.AllocBuf(A_L0A, TILE_M * TILE_K * sizeof(half));
pipe.AllocBuf(B_L0B, TILE_K * TILE_N * sizeof(half));
pipe.AllocBuf(C_L0C, TILE_M * TILE_N * sizeof(half));
for (int m = 0; m < M; m += TILE_M) {
for (int n = 0; n < N; n += TILE_N) {
// 初始化C_tile为0
DataCopy(C_L0C, 0, TILE_M * TILE_N * sizeof(half));
for (int k = 0; k < K; k += TILE_K) {
// 从HBM读A_tile到L0A
DataCopy(A_L0A, a + m * K + k, TILE_M * TILE_K * sizeof(half));
// 从HBM读B_tile到L0B
DataCopy(B_L0B, b + k * N + n, TILE_K * TILE_N * sizeof(half));
// Cube算A_tile × B_tile,累加到C_tile
MatMul(C_L0C, A_L0A, B_L0B, TILE_M, TILE_K, TILE_N,
{ .accumulate = true });
}
// 把C_tile写回HBM
DataCopy(c + m * N + n, C_L0C, TILE_M * TILE_N * sizeof(half));
}
}
}
};
工程经验: cann-samples的MatMul样例是"标准实现"(无预取、无流水线),性能只有ops-math的60%。但它结构简单,适合学习Ascend C编程模型。要性能,看cann-recipes-infer的优化版。
PyTorch 模型迁移样例
cann-samples提供15个PyTorch模型迁移样例,覆盖CV、NLP、推荐系统。
样例1:ResNet50 迁移到昇腾
# samples/pytorch/resnet50/train.py(精简版)
import torch
import torch_npu # 导入NPU后端
# 1. 模型放到NPU
model = resnet50(pretrained=True).npu()
# 2. 数据放到NPU
inputs = inputs.npu()
labels = labels.npu()
# 3. 优化器用NPU版本
optimizer = torch.optim.AdamW(model.parameters(), lr=1e-4)
# 4. 训练(跟GPU代码一模一样)
for epoch in range(10):
for batch in dataloader:
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
cd samples/pytorch/resnet50/
bash run_train.sh
# 输出:
# [INFO] Epoch 1/10, Loss: 1.234
# [INFO] Epoch 2/10, Loss: 0.987
# ...
# [INFO] Train success! Throughput: 1234 images/s
工程经验: PyTorch模型迁移到昇腾,90%的情况只要.npu()就够了。剩下10%是算子不支持(报错ACL_ERROR_NONE: Op Xxx not supported),要解决。
样例2:LLaMA2-7B 推理部署
# samples/pytorch/llama2-7b/infer.py(精简版)
import torch
import torch_npu
from transformers import LLaMAForCausalLM, LLaMATokenizer
# 1. 加载模型(自动映射到NPU)
model = LLaMAForCausalLM.from_pretrained("llama2-7b").npu()
# 2. 编译模型(开GE图编译)
model = torch.compile(model, backend="npu")
# 3. 推理
inputs = tokenizer("Hello, ", return_tensors="pt").input_ids.npu()
outputs = model.generate(inputs, max_new_tokens=50)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
cd samples/pytorch/llama2-7b/
bash run_infer.sh
# 输出:
# [INFO] Load model: llama2-7b, params: 6.7B
# [INFO] Compile model: GE graph compile time: 12.3s
# [INFO] Generate: "Hello, how are you doing today? I hope..."
# [INFO] Throughput: 34 tokens/s
性能调优样例
cann-samples提供9个性能调优样例,教你怎么用msprof分析性能瓶颈。
样例:MatMul 性能调优
cd samples/profiling/matmul/
# 1. 跑msprof做性能分析
msprof --output=./prof --aic-metrics=memory_bandwidth_utilization \
python run_matmul.py
# 2. 导出报告
msprof --export=on --output=./prof
# 3. 打开报告(prof/summary/report.html)
# 看"算子耗时分布":MatMul占85% → 计算瓶颈
# 看"HBM带宽利用率":35% → 访存瓶颈
# 4. 优化(开Tiling、开预取)
# 修改matmul.cpp,加Tiling、加预取
bash rebuild.sh
# 5. 再跑msprof
msprof --output=./prof2 --aic-metrics=memory_bandwidth_utilization \
python run_matmul.py
# 6. 对比报告
# HBM带宽利用率:35% → 82%(+134%)
# 吞吐:34 tokens/s → 89 tokens/s(+162%)
工程经验: 性能调优的正确流程:先profile找瓶颈 → 针对性优化 → 再profile验证。不复用profile盲目优化,可能优化半天瓶颈不在这。
踩坑实录
坑1:样例编译失败(CANN路径找不到)
bash build.sh报错fatal error: kernel_operator.h: No such file or directory。
原因:CANN没装,或者ASCEND_HOME环境变量没设。
解决:
# 设ASCEND_HOME
export ASCEND_HOME=/usr/local/Ascend/
export LD_LIBRARY_PATH=$ASCEND_HOME/lib64:$LD_LIBRARY_PATH
export PATH=$ASCEND_HOME/bin:$PATH
# 再编译
bash build.sh
坑2:样例运行失败(NPU驱动没装)
bash run.sh报错ACL_ERROR_NONE: Initialize failed, reason: driver not installed。
原因:NPU驱动没装,或者驱动版本跟CANN版本不匹配。
解决:
# 查驱动版本
npu-smi info | grep "Driver Version"
# 查CANN要求的驱动版本
cat $ASCEND_HOME/version.info
# 版本不匹配,重装驱动
sudo bash ASCEND/ascend-driver_23.0.0_linux-x86_64.run --full
坑3:PyTorch样例跑不通(torch_npu没装)
import torch_npu报错ModuleNotFoundError: No module named 'torch_npu'。
原因:torch_npu没装。
解决:
# 装torch_npu(匹配PyTorch版本)
pip install torch_npu==2.1.0 # PyTorch 2.1.0对应torch_npu 2.1.0
# 验证
python -c "import torch_npu; print(torch_npu.__version__)"
坑4:样例输出跟文档不一致(CANN版本不同)
样例输出文档写"Throughput: 1234 images/s",实际跑出来"Throughput: 987 images/s"。
原因:CANN版本不同,性能有差异(新版通常更优)。
解决:看样例目录下的README.md,确认CANN版本要求。装对应版本的CANN。
https://atomgit.com/cann/cann-samples
https://atomgit.com/cann/cann-learning-hub
https://atomgit.com/cann/cann-recipes-infer
更多推荐




所有评论(0)