昇腾部署第 0 课:一张地图——一个推理请求走了哪几层
课件编号:A0(体系首课 · 地图课) 编制:观澜|日期:2026-10-04 难度:入门 时长:约 40 分钟 是否需要硬件:❌ 不需要 素材来源:昇腾官方文档实时检索(CANN 9.2.0-beta.2 / HDK 26.1.x / TorchNPU 26.1.X / MindIE 3.1.0) 本课目标:学完能画出这张图,并说出任何一个报错「大概属于哪一层、先用什么命令去确认」
第一段 · 章前定位
这是整个体系的第一课,它不教你装任何东西。
它只做一件事:给你一张地图。
为什么地图要放在第一课?因为这套东西的零件太多——驱动、固件、CANN、Toolkit、ops 包、TorchNPU、MindIE、vLLM、SGLang……如果一个个按顺序学,学到第四个就乱了。
有了地图,后面每一个零件都能挂在一个固定的位置上。 你会一直知道三件事:这东西在哪、它跟谁相连、它坏了会是什么现象。
本课的一句话:先有装配图,再拆零件。
第二段 · 学习目标
学完这一课,你应该能:
- ✅ 画出昇腾 AI 部署的 5 层结构,并说清每层负责什么
- ✅ 说出部署成功的 5 个判据,以及每个判据用哪条命令验证
- ✅ 拿到任何一个报错时,能判断它属于哪一层
- ✅ 知道每一层的典型报错长什么样(本课给了 8 条真实案例)
第三段 · 全景地图(本课的核心)
一次推理请求,从应用到芯片
你(或者你的程序)发出一次请求
│
▼
┌──────────────────────────────────────────────────────┐
│ L4 应用层 │
│ 模型文件 / 权重 / 量化后的模型 / 数据集 │
│ 是「要算的东西」——数据,不是程序 │
└──────────────────────────────────────────────────────┘
│ 模型交给谁去算
▼
┌──────────────────────────────────────────────────────┐
│ L3 服务层 │
│ 推理服务框架:MindIE / vLLM / SGLang │
│ 是「接客的」——开端口、收请求、组批、返回 │
└──────────────────────────────────────────────────────┘
│ 调用谁去执行
▼
┌──────────────────────────────────────────────────────┐
│ L2 框架层 │
│ PyTorch + TorchNPU / MindSpore / TensorFlow │
│ 是「翻译官」——把算法翻译成芯片能懂的 │
└──────────────────────────────────────────────────────┘
│ 交给谁去编译、下发
▼
┌──────────────────────────────────────────────────────┐
│ L1 基础软件层 │
│ CANN(Toolkit 包 + ops 包)+ 环境变量 │
│ 是「总调度」——算子库、编译器、运行时、通信 │
└──────────────────────────────────────────────────────┘
│ 最终谁真的在算
▼
┌──────────────────────────────────────────────────────┐
│ L0 硬件层 │
│ 昇腾卡 / 服务器 + 驱动 + 固件 │
│ 是「干活的」——真正做矩阵计算的地方 │
└──────────────────────────────────────────────────────┘
记住这一张「谁依赖谁」的图
L4 应用 ─需要─▶ L3 服务 ─需要─▶ L2 框架 ─需要─▶ L1 基础软件 ─需要─▶ L0 硬件
关键规律:下面的不对,上面的全废。
- 驱动没装好 → CANN 装不上 → 框架 import 就报错 → 服务根本起不来
- 反过来:服务起不来,八成不是服务的错,是下面某一层的问题
⭐ 这句话是本课最值钱的一句。 新手最常见的错误,是在最上面那层反复折腾,而真正的问题在最下面那层。
第四段 · 每层负责什么(以及拿掉它会发生什么)
| 层 | 它负责什么 | 拿掉它 / 没装好,你会看到什么 |
|---|---|---|
| L0 硬件层 | 真正的计算。驱动让系统认得这张卡,固件是卡自己的运行程序 | 系统里根本看不到这张卡;npu-smi 命令可能直接不存在或报错 |
| L1 基础软件层 | 算子库(ops 包)、编译器、运行时(AscendCL)、通信库(HCCL);环境变量是这一层的"开关" | 看得见卡,但程序找不到算子库、找不到动态库;报 check driver compatibility failed、Failed to load the libdcmi.so 这类错 |
| L2 框架层 | 把 PyTorch / MindSpore 的调用翻译成对芯片的操作(TorchNPU 就是干这个的) | 能跑普通 Python,但一碰 NPU 就报错;set_device 失败、EL0003 |
| L3 服务层 | 对外提供推理接口:收请求、组批、调度、返回结果 | 模型能跑通,但没法对外提供服务;端口起不来、curl 没响应 |
| L4 应用层 | 模型本身(权重、量化版本、配置文件) | 服务能起,但加载模型失败或效果不对 |
第五段 · 怎么确认每一层就位了(可复制的命令)
这是本课要你动手的部分。逐条执行,看输出对不对。
判据 ① L0 硬件层:系统认得这张卡吗
npu-smi info
- 期望:出现卡的信息——型号、温度、显存占用等
- 看不到卡 → 问题在 L0,往驱动和固件查(见第七段)
顺带记一个:
npu-smi -v
查的是 npu-smi 工具本身的版本(不是卡的版本)。
官方提示:npu-smi 不支持多线程并发使用 —— 别在脚本里并发调它。
判据 ② L1 基础软件层:CANN 装好了、环境变量配上了吗
第一步:CANN 装在哪、装了什么版本
cat /etc/ascend_install.info
(这个文件在官方报错信息里出现过:check /etc/ascend_install.info —— 它是安装信息的登记处)
第二步:配环境变量(官方原文的命令)
# root 用户安装 Toolkit 时
source /usr/local/Ascend/cann/set_env.sh
# 非 root 用户安装 Toolkit 时
source ${HOME}/Ascend/cann/set_env.sh
第三步:确认关键变量真的生效了
echo $ASCEND_HOME_PATH
echo $ASCEND_OPP_PATH
期望:两条都打印出真实路径(不是空行)。
这两个变量什么意思(官方定义):
| 变量 | 官方定义 |
|---|---|
ASCEND_HOME_PATH |
同 ASCEND_TOOLKIT_HOME,Toolkit 软件安装后文件存储路径 |
ASCEND_OPP_PATH |
算子库根目录 |
ASCEND_AICPU_PATH |
AI CPU 组件的安装路径 |
PATH / LD_LIBRARY_PATH / PYTHONPATH |
可执行文件、动态库、Python 模块的查找路径 |
⭐ 为什么这一层最容易出问题:CANN 装完后,用户进程一结束,相关环境变量就失效。 官方给的做法是手动
source,或者写进~/.bashrc变成永久变量。 "装好了但一开新终端就报错" 十有八九就是这里。
判据 ③ L2 框架层:Python 认得这张卡吗
官方快速入门里的标准写法:
import torch
import torch_npu
from torch_npu.contrib import transfer_to_npu # 开启自动迁移
print(torch.npu.is_available())
- 期望:打印
True - 报
False或直接报错 → 问题在 L1 或 L2(环境变量没生效 / 框架版本不匹配)
注意
import torch_npu这一行:它不只是导入一个库,它会给 PyTorch 装上 NPU 后端。
判据 ④ L3 服务层:服务起得来、调得通吗
这一层的框架三选一(官方提供三种推理开发路径):
| 框架 | 官方定位 |
|---|---|
| MindIE | 大语言模型服务化框架(文档版本 3.1.0),含服务化部署能力(MindIE Motor) |
| vLLM | 昇腾侧的 vLLM 推理开发路径 |
| SGLang | 昇腾侧的 SGLang 推理开发路径 |
验证思路:服务起来后,从外面调一次,确认能返回结果。
# 看端口是否在监听(示例端口,按你的配置改)
ss -lntp | grep <你的服务端口>
# 从外面调一次(按你所用框架的接口文档构造请求)
curl http://127.0.0.1:<端口>/<接口路径>
- 期望:端口在监听,curl 能返回推理结果
- 端口起不来 → 先别查服务,回去查 L1 和 L2
⚠️ 具体接口路径和启动参数,随框架和版本变化很快,本课不给固定命令。 到做 D 层(服务层)课件时,我会按官方文档逐条取回并标注版本。
判据 ⑤ 汇总:一条命令看全局
把上面几条串起来,这就是"环境体检":
# ① 卡在不在
npu-smi info
# ② CANN 版本信息在不在
cat /etc/ascend_install.info
# ③ 环境变量生效没
echo $ASCEND_HOME_PATH; echo $ASCEND_OPP_PATH
# ④ 框架认不认卡
python3 -c "import torch, torch_npu; print('NPU available:', torch.npu.is_available())"
四条全过 = 部署成功。 任何一条不过 → 顺着那条往下查,不要跳层。
第六段 · 部署成功的 5 个判据(本课的验收标准)
| # | 判据 | 验证方式 | 不过说明问题在 |
|---|---|---|---|
| ① | 系统认得卡 | npu-smi info 有输出 |
L0 |
| ② | CANN 就位 | /etc/ascend_install.info + echo $ASCEND_HOME_PATH 有值 |
L1 |
| ③ | 框架认得卡 | torch.npu.is_available() → True |
L1 或 L2 |
| ④ | 服务起得来 | 端口监听 + curl 有返回 | L3 |
| ⑤ | 能定位到层 | 给一个报错,能判断属于哪层 | 本课的核心能力 |
前四条是"能不能跑",第五条是"能不能修"。 只会前四条的人,遇到新问题只能重新搜;会第五条的人,能自己缩小范围。
第七段 · 出问题了怎么查(本课的灵魂)
排查铁律:先定位层,再找原因;不要从上层往下瞎试
按现象定位层 —— 对照表
| 你看到的现象 | 先查哪一层 | 第一步动作 |
|---|---|---|
系统里看不到卡 / npu-smi 命令不存在 |
L0 | 确认卡插好、驱动固件装了;用 npu-smi -v 看工具本身在不在 |
| 看得见卡,但装 CANN 时报兼容性错误 | L0 ↔ L1 交界 | 对照 CANN 版本与驱动版本的配套关系(官方有专门的版本对应说明) |
| 命令能跑,但报"找不到动态库 / 找不到算子" | L1 | echo $ASCEND_HOME_PATH echo $ASCEND_OPP_PATH —— 先怀疑环境变量没 source |
| 昨天能跑,今天新开终端就报错 | L1 | 几乎一定是环境变量没写进 ~/.bashrc,新进程没有继承 |
Python 里 is_available() 返回 False |
L1 或 L2 | 先补 import torch_npu;再查框架版本与 CANN 的配套 |
跑训练时 set_device 失败 |
L2 | 看报错码(如 EL0003),回官方案例库对照 |
| 模型能跑,服务起不来 | L3 | 看服务日志;但先回头确认 L1/L2 没问题 |
| 服务起了,加载模型失败 | L4 | 查模型文件路径、格式、权重要不要转换 |
⭐ 一个最省时间的判断法
报错里出现 device、device 0、set_device → 基本是 L0/L1 的问题(卡根本没被正确识别)
报错里出现 .so、libxxx.so、dynamic library → 基本是 L1 的问题(动态库路径)
报错里出现算子名、OPP、operator → 基本是 L1(算子库)
报错里出现 Python 层面的 RuntimeError + 错误码 → 查 L2
能 import 能算,只是接口不通 → 查 L3
第八段 · 常见报错清单(真实案例,官方可查)
下面每一条都能在昇腾官方故障案例库查到,带完整的原因分析和解决措施。 这是本课的"故障码表"—— 建议直接收藏。
| 报错原文(片段) | 属于哪层 | 官方案例编号 | 查看量 |
|---|---|---|---|
[ERROR]ERR_NO:0x0091;ERR_DES:username not permission for root, check /etc/ascend_install.info |
L0(装驱动时) | case_92819 |
2,653 |
check driver compatibility failed(装 CANN 时提示驱动版本不兼容) |
L0↔L1 | canncase_0022 |
— |
Failed to load the libdcmi.so dynamic library(执行 ascend-dmi 时) |
L1 | toolboxcase_0054 |
2,455 |
Acl open device 0 failed, errorCode is 507033 |
L1(AscendCL 运行时) | topic_0000001633594041 |
10,585 |
acl.rt.set_device failed ret=507033(容器内执行推理) |
L1/L2 | topic_0000001522883364 |
6,583 |
EL0003,error code 507000(PyTorch 训练 set_device() 失败) |
L2 | case_95414 |
4,689 |
msdebug failed to initialize. please install HDK with --debug before debugging. |
L0(缺调试版驱动包) | atlasopdev_0006 |
3,496 |
新容器里执行 npu-smi / hccn_tool 提示设备被占用 |
L0/L1 交界(容器与设备映射) | topic_0000002238354198 |
— |
怎么用这张表:
- 把你的报错原文去掉具体数值(比如把卡号、路径去掉),留下关键词
- 到官方故障案例库搜这个关键词
- 看到上面的编号,可以直接拼出链接:
https://www.hiascend.com/document/caselibrary/detail/<案例编号>
⭐ 记住这一点:你遇到的报错,大概率已经有官方答案了。 这些案例的查看量上千,说明踩的人很多 —— 你不是第一个,也不用自己从零想。
第九段 · 小结与下一课
三句话带走
- 昇腾部署是 5 层:硬件 → 基础软件 → 框架 → 服务 → 应用;下层不对,上层全废。
- 部署成功有 5 个判据,每条都有对应命令;第 5 条"能定位到层"比前四条更重要。
- 报错不用从头查:先看它属于哪一层,再按那一层的方法查。
本课留下的"钩子"(后面每课填一个)
| 层 | 后续课件 | 要回答的问题 |
|---|---|---|
| L0 | A 层硬件课 | 卡有哪些形态?驱动和固件到底是什么关系?为什么装驱动还会报权限错? |
| L1 | B 层基础软件课 | CANN 里 Toolkit 包和 ops 包各是什么?环境变量一共几个、各自管什么? |
| L2 | C 层框架课 | torch_npu 到底做了什么?transfer_to_npu 为什么能"自动迁移"? |
| L3 | D 层服务课 | MindIE / vLLM / SGLang 三者怎么选?服务怎么起、怎么压、怎么调? |
| — | E 层排障课 | 把第八段的表,一条一条展开讲透 |
| L4 | F 层实战课 | 模型从哪来、要不要转换、量化怎么做 |
课后自测(3 题)
- 你的程序报错说「找不到 libxxx.so」。你先查哪一层?用什么命令确认?
- 同事说"昨天还好好的,今天新开一个终端就报错了"。你第一反应应该是什么?
npu-smi info有输出,但torch.npu.is_available()返回False。说明至少哪一层是好的?问题最可能在哪?
参考答案见下一课开头。
附录 · 本课引用的官方出处
| 内容 | 官方来源 |
|---|---|
| 部署链条(驱动固件 → CANN → 环境变量) | 官方文档「安装驱动固件与CANN软件包」(TensorFlow 模型迁移 / 环境准备) |
set_env.sh 路径与环境变量清单 |
CANN 9.2.0-beta.2《安装后自动配置环境变量》 |
npu-smi 命令与限制 |
HDK 26.1.x《npu-smi 工具使用导读》《查询 npu-smi 工具版本》 |
import torch_npu / transfer_to_npu |
TorchNPU 26.1.X《快速入门》 |
| MindIE 服务化部署 | MindIE 3.1.0《服务化部署》(MindIE Motor) |
| 8 条故障案例 | 昇腾官方故障案例库(hiascend.com/document/caselibrary/) |
| 版本号 | CANN 最新 9.2.0-beta.2(推荐)/ 稳定 9.1.X;HDK 26.1.x |
⚠️ 数据说明: - 本课所有命令、路径、变量名均来自官方文档原文,未做推测性补充。 - 标注「—」的查看量为检索结果未返回该字段,不是零。 - L3 服务层的具体启动命令与接口路径未在本课给出(随框架版本变化快),将在 D 层课件中按官方文档逐条取回并标注版本。
附录 B · 本课出现的命令详解(每条都拆开讲)
看图对照:本课所有命令都对应前面"5 层"里的某一层。命令报错时,先回想它属于哪一层。
通用 Linux 命令(先认这几个,后面每一课都会用到)
cat 文件路径
- 含义:把一个文件的内容打印到屏幕上。cat 本意是 concatenate(拼接),早年用于拼接文件,现在最常用的功能是"看文件内容"。
- 拆解:cat(命令名)+ 要看的文件路径
- 用法:
cat /etc/ascend_install.info # 看这个文件里写的安装信息
- 期望:终端直接把文件内容打印出来(这里是 CANN 的安装信息)
- 不过会怎样:提示
No such file or directory→ 这个文件不存在,通常说明那层软件没装上
echo 值
- 含义:把文字或变量值打印到屏幕上。最常用来检查某个环境变量到底有没有值。
- 拆解:echo(命令名)+ 要打印的东西。$ 符号表示"取这个变量的值",不加 $ 就直接打印变量名本身。
- 用法:
echo $ASCEND_HOME_PATH # 取 ASCEND_HOME_PATH 这个变量的值
echo ASCEND_HOME_PATH # 对比:这里没加 $,会原样打印这串字
- 期望:打印出一个真实路径(如
/usr/local/Ascend/...) - 不过会怎样:打印出一行空白 → 变量没设置 → 环境变量没 source(这是最常见的坑)
source 脚本路径
- 含义:在当前这个终端窗口里执行一个脚本。
- 拆解:source(命令名)+ 脚本路径
- ⭐ 关键点:source 不会新开一个进程,所以脚本里设置的环境变量会留在你当前这个窗口。这就是"装完 CANN 为什么要 source set_env.sh"的根本原因——如果换用 bash 脚本,脚本设的变量随着进程结束就没了。
- 用法:
source /usr/local/Ascend/cann/set_env.sh # root 安装
source ${HOME}/Ascend/cann/set_env.sh # 非 root 安装
- 期望:没有任何输出(命令行没报错就是成功)
- 不过会怎样:报
No such file or directory→ 路径不对,CANN 没装在这个位置
ss -lntp(配合 grep 用)
- 含义:查看当前系统上哪些端口正在被监听。ss 是 socket statistics(套接字统计)的缩写。
- 拆解:ss(命令名)+ 四个选项字母:
- -l = listen,只看正在监听(等着别人连进来)的端口
- -n = numeric,用数字显示端口号(不做域名解析,更快更清楚)
- -t = tcp,只看 TCP 协议的
- -p = process,显示是哪个进程占用的这个端口
- 用法:
ss -lntp | grep 8000 # 只看 8000 端口
|是"管道":把ss的输出交给grep去筛。grep就是在文本里找含关键词的行。
- 期望:出现一行,显示端口在监听 + 进程号
- 不过会怎样:什么也不显示 → 服务没起来 → 回头查 L1/L2(别在 L3 死磕)
curl 网址
- 含义:发一次 HTTP 请求,把返回内容打印出来。用来从外面验证服务是否真的通。
- 用法:
curl http://127.0.0.1:8000/v1/... # 具体接口路径见你所用的框架文档
- 期望:返回推理结果(通常是一段 JSON)
- 不过会怎样:
Connection refused→ 端口没起来;有响应但报错 → 服务起来了,业务层有问题
昇腾专用命令
npu-smi info
- 含义:npu-smi 是昇腾的设备管理工具(可以理解成系统资源监视器里的"显卡那一页")。info 是它的子命令,表示"查信息"。
- 拆解:npu-smi(工具名)+ info(子命令:显示设备信息)
- 用法:
npu-smi info
- 期望:打印一张表,列出每张卡的型号、温度、显存占用、正在跑的进程
- 不过会怎样:
- 提示"命令找不到" → 驱动没装(L0)
- 能跑但表里没有卡 → 硬件/权限问题(L0)
⚠️ 官方提示:
npu-smi不支持多线程并发使用 —— 别在脚本里并发调它。
npu-smi -v
- 含义:查 npu-smi 这个工具自己的版本。
- 拆解:npu-smi(工具名)+ -v(version,版本)
- ⚠️ 注意:查的是工具的版本,不是卡的固件版本。两个概念别混。
- 期望:打印版本号
- 不过会怎样:同上——命令不存在说明驱动没装
Python 侧(验证 L2)
import torch
import torch_npu
from torch_npu.contrib import transfer_to_npu # 开启自动迁移
print(torch.npu.is_available())
import:把某个库加载进来。import torch_npu不只是"导入一个库"——它会给 PyTorch 装上 NPU 后端,这是后面torch.npu能用的前提。from ... import ...:从某个库里只取其中一部分。transfer_to_npu是官方提供的自动迁移工具。print(...):把结果打印出来。- 期望:输出
True - 不过会怎样:输出
False或直接报错 → 问题在 L1(环境变量没生效)或 L2(版本不匹配)