前言

买了一台 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

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐