前言

买了一台 Atlas 服务器,想把 PyTorch 模型跑在昇腾 NPU 上。第一步装什么、环境怎么配、第一个 demo 怎么跑起来,asc-devkit 给你一套完整的工具链。这篇文章手把手从零开始,完整走一遍环境配置到 ResNet50 推理的全流程。

环境准备:驱动和 CANN 版本对应

硬件与软件版本检查

昇腾 NPU 的运行环境有一套严格的版本对应关系:

硬件层:Atlas 训练服务器(Ascend 910)× 8
驱动层:驱动版本 23.0.rc3
CANN层:CANN 8.0.RC3
框架层:PyTorch 2.1.0 + torch_npu
工具层:asc-devkit

版本错配是最常见的报错原因。升级之前先去社区查兼容性矩阵。

# 1. 检查 NPU 状态
npu-smi info

# 预期输出:
# +-----------------------------------------------------------------------------+
# | NPU  0  Card  Type: Ascend 910P8        |  0  Used  32GB  |  Product: Atlas |
# | NPU  1  Card  Type: Ascend 910P8        |  0  Free  32GB  |  Product: Atlas |
# +-----------------------------------------------------------------------------+

# 2. 检查驱动版本
cat /usr/local/Ascend/driver/version.info

# 3. 检查 CANN 版本
python -c "import acl; print(acl.__version__)"
# 或
python -c "import torch; print(torch.__version__); import torch_npu; print(torch_npu.__version__)"

驱动安装(如果还没装)

驱动安装需要 root 权限,按以下顺序:

# 1. 下载驱动包(从昇腾官网下载对应版本)
# 注意:驱动版本必须跟 CANN 版本匹配
wget https://www.hiascend.com/document/detail/Ascend/Resources/drivepack/ATlas800-9000/...

# 2. 安装驱动
sudo bash Ascend-driver-{version}-linux.run --full

# 3. 验证安装
ls /usr/local/Ascend/driver/
# 应该看到 driver/ 目录和 version.info

# 4. 检查版本
cat /usr/local/Ascend/driver/version.info
# 输出示例:Driver Version=23.0.rc3 Build Date=2024-03-15

驱动和 CANN 版本对应规则

CANN 版本 驱动版本要求 备注
CANN 8.0.RC3 驱动 23.0.rc3 当前最新
CANN 7.1 驱动 22.0.x 长期支持版
CANN 6.4 驱动 21.0.x 旧版本兼容

版本错配会导致 ACL 初始化失败(error code 101)。

CANN 安装

CANN 是昇腾的异构计算架构,包含了算子库、编译器、Runtime 等组件。

# 1. 下载 CANN 包(社区版或商业版)
# 社区版下载地址:https://www.hiascend.com/document/detail/Ascend/Resources/cann/
wget https://www.hiascend.com/document/detail/Ascend/Resources/cann/...

# 2. 安装 CANN(社区版不需要 root)
pip install Ascend-cann-community-8.0.RC3-linux.x86_64.run

# 3. 设置环境变量
source /usr/local/Ascend/ascend-toolkit/set_env.sh

# 4. 验证 CANN 安装
python -c "import acl; print(acl.__version__)"
# 或用命令行
atc --version
# 预期输出:Ascend CANN 8.0.RC3

# 5. 永久写入环境变量(推荐)
echo 'source /usr/local/Ascend/ascend-toolkit/set_env.sh' >> ~/.bashrc

CANN 组件说明

组件 功能 重要目录
ACL(Ascend Computing Language) 统一 API 层 /usr/local/Ascend/ascend-toolkit
HCCL 集合通信库 分布式训练用
GE(Graph Engine) 图编译器 模型转换用
Runtime 运行时 推理执行用
算子库 各类算子实现 ops-* 仓库

asc-devkit 安装

pip 安装(推荐)

# 安装最新稳定版
pip install ascend-mindx-sdk -i https://repo.huaweicloud.com/repository/pypi/simple/

# 或者从源码安装(体验最新功能)
git clone https://atomgit.com/cann/asc-devkit
cd asc-devkit
pip install -e .

# 验证安装
python -c "import asc_devkit; print('asc-devkit 版本:', asc_devkit.__version__)"

# 如果 import 报错,检查安装路径
pip show ascend-mindx-sdk

conda 环境隔离(强烈建议)

每个项目用独立的 conda 环境,避免依赖冲突和版本污染:

# 创建昇腾专用环境
conda create -n ascend-env python=3.10 -y
conda activate ascend-env

# 安装 PyTorch NPU 版(注意版本对应关系)
pip install torch==2.1.0
pip install torch-npu==5.1.rc3 -i https://repo.huaweicloud.com/repository/pypi/simple/

# 验证 PyTorch 识别 NPU
python -c "import torch; print('PyTorch 版本:', torch.__version__)"
python -c "import torch_npu; print('NPU 版本:', torch_npu.__version__)"

# 确认 NPU 可用
python -c "import torch; print('CUDA' if torch.cuda.is_available() else 'CPU')"
# 输出应为:NPU(表示昇腾 NPU 被识别)

模型转换:.onnx → .om

步骤1:从 PyTorch 导出 ONNX

asc-devkit 支持多种模型格式。这里以 PyTorch ResNet50 为例,先导出 ONNX:

# 1_pytorch_to_onnx.py
import torch
import torchvision.models as models

# 加载预训练模型
model = models.resnet50(weights=models.ResNet50_Weights.DEFAULT)
model.eval()

# 准备输入(标准 ImageNet 预处理尺寸)
dummy_input = torch.randn(1, 3, 224, 224)

# 导出 ONNX
torch.onnx.export(
    model,
    dummy_input,
    "resnet50.onnx",
    input_names=["input"],
    output_names=["output"],
    opset_version=13,        # 推荐 13 或以上
    dynamic_axes={           # 动态 batch size,方便推理时调整
        "input": {0: "batch_size"},
        "output": {0: "batch_size"}
    }
)

print("ONNX 导出成功:resnet50.onnx")

步骤2:ONNX 转 OM(Acore 模型格式)

# 2_onnx_to_om.py
import cann

# 模型转换配置
config = cann.ModelConvertConfig(
    input_format="NCHW",
    input_shape="input:1,3,224,224",
    output_path="resnet50.om",
    soc_version="Ascend910P8",
    precision_mode="force_fp16",   # 混合精度,FP16 推理
    op_debug_level="0"
)

# 执行转换
model = cann.ModelConverter()
model.convert("resnet50.onnx", config)

print("OM 转换成功:resnet50.om")

步骤3:ATC 命令行转换(备选)

如果 Python API 有问题,可以用 ATC 命令行:

# 设置环境变量
source /usr/local/Ascend/ascend-toolkit/set_env.sh

# 执行转换
atc \
    --model=resnet50.onnx \
    --framework=5 \
    --output=resnet50 \
    --input_shape="input:1,3,224,224" \
    --soc_version=Ascend910P8 \
    --precision_mode=force_fp16 \
    --op_debug_level=0

# 参数说明:
# --framework=5  表示 ONNX 格式
# --soc_version  芯片型号
# --precision_mode  精度模式(force_fp16/auto/force_fp32)

推理部署:ACL 接口调用

基本推理流程

# 3_inference.py
import cann
import numpy as np
from PIL import Image

# 1. 加载 OM 模型
model = cann.model.load_model("resnet50.om")

# 2. 图片预处理(ImageNet 标准)
def preprocess(image_path):
    img = Image.open(image_path).convert("RGB")
    img = img.resize((224, 224))
    img_array = np.array(img).astype(np.float32) / 255.0

    # 标准化(ImageNet 统计值)
    mean = np.array([0.485, 0.456, 0.406])
    std = np.array([0.229, 0.224, 0.225])
    img_array = (img_array - mean) / std

    # HWC → CHW
    img_array = img_array.transpose(2, 0, 1)

    # 加 batch 维度
    return img_array[np.newaxis, :, :, :]

# 3. 执行推理
image = preprocess("test_image.jpg")
outputs = model.execute(image)

# 4. 后处理(取最大概率类别)
pred_class = int(np.argmax(outputs[0]))
print(f"预测类别:{pred_class}")

批量推理

# 4_batch_inference.py
import cann
import numpy as np
import glob

# 加载模型
model = cann.model.load_model("resnet50.om")

# 批量处理文件夹中的图片
image_paths = glob.glob("test_images/*.jpg")
batch_size = 8

for i in range(0, len(image_paths), batch_size):
    batch_paths = image_paths[i:i+batch_size]

    # 批量读取和预处理
    batch_images = []
    for path in batch_paths:
        img = preprocess(path)
        batch_images.append(img)

    # 拼接 batch
    batch_tensor = np.concatenate(batch_images, axis=0)

    # 推理
    outputs = model.execute(batch_tensor)

    # 批量后处理
    for j, out in enumerate(outputs):
        pred = int(np.argmax(out))
        print(f"图片 {batch_paths[j]}: 类别 {pred}")

性能验证

# 5_performance_test.py
import cann
import numpy as np
import time

model = cann.model.load_model("resnet50.om")

# Warmup(第一次有 JIT 编译)
_ = model.execute(np.random.randn(1, 3, 224, 224).astype(np.float32))

# 测试 100 次推理
iterations = 100
times = []

for _ in range(iterations):
    dummy = np.random.randn(1, 3, 224, 224).astype(np.float32)

    start = time.time()
    _ = model.execute(dummy)
    elapsed = (time.time() - start) * 1000  # ms

    times.append(elapsed)

# 统计
times.sort()
print(f"Avg: {np.mean(times):.2f} ms")
print(f"P50: {times[iterations//2]:.2f} ms")
print(f"P95: {times[int(iterations*0.95)]:.2f} ms")
print(f"P99: {times[int(iterations*0.99)]:.2f} ms")

# 吞吐
print(f"Throughput: {1000/np.mean(times):.2f} FPS")

常见错误码和解决方式

错误1:驱动版本不匹配

Error: aclInit failed with error code 101

这是最常见的错误。解决方式:

# 检查驱动和 CANN 版本对应关系
# CANN 8.0 配 驱动 23.0.rc3
# 降级或升级 CANN/驱动到匹配版本

# 临时方案:设置忽略版本检查(不推荐生产环境)
export ASCEND_SKIP_VERSION_CHECK=1

错误2:模型转换 Shape 不匹配

Error: Invalid input shape, expected [1,3,224,224]

检查输入数据的实际 shape:

import numpy as np
print(f"实际 shape: {input_tensor.shape}")
print(f"预期 shape: (1, 3, 224, 224)")

错误3:OM 加载失败

Error: Model file not found or format error

检查 OM 文件是否损坏:

# 检查文件是否存在
ls -lh resnet50.om

# 用 ATC 重新转换,开启详细日志
atc ... --log_level=3

错误4:NPU 显存不足

Error: Out of memory in device 0

清理显存或减小 batch size:

# 查看显存使用
import cann
info = cann.rt.get_mem_info()
print(f"Used: {info.used / 1024**3:.2f} GB")

# 减小 batch size
model.set_option("batch_size", 4)

踩坑记录:Atlas 服务器特殊注意事项

Atlas 服务器的环境配置跟普通开发机有些不同:

问题 原因 解决方式
镜像版本选择错误 Atlas A2/A3 服务器镜像不同 社区下载页按机器型号选对应包
环境变量不生效 多用户同时操作互相覆盖 每个项目用独立 conda 环境
推理第一次很慢 JIT 编译 Warmup 10 次再正式测性能
batch size 大了 OOM 默认 batch_size 配置 逐步加 batch,观察显存峰值
# Atlas 服务器专用检查
# 1. 确认机器型号(决定驱动版本)
cat /proc/device-tree/model

# 2. 确认 NUMA 亲和性(多卡时性能关键)
numactl --hardware

# 3. 设置 NPU 可见性(8 卡时)
export ASCEND_VISIBLE_DEVICES=0,1,2,3,4,5,6,7

完整脚本汇总

# 完整流程脚本:run_resnet.sh
#!/bin/bash
set -e

# 环境激活
source /usr/local/Ascend/ascend-toolkit/set_env.sh

# 1. 推理(已有 OM 文件时)
python 3_inference.py

# 2. 批量推理性能测试
python 5_performance_test.py

# 3. 如果需要重新转换模型
python 1_pytorch_to_onnx.py
python 2_onnx_to_om.py

echo "完成!"

总结

asc-devkit 工具链的核心流程:

  1. 查版本:驱动/CANN/PyTorch 版本对应正确
  2. 装工具:asc-devkit + torch_npu
  3. 转模型:ONNX → OM(ATC 或 Python API)
  4. 跑推理:ACL 接口调用
  5. 测性能:batch size + 吞吐验证

遇到问题先去社区 FAQ 查,90% 的问题在 FAQ 里有答案。

仓库地址:https://atomgit.com/cann/asc-devkit

Logo

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

更多推荐