【昇腾 Ascend 910C 部署 Qwen3-VL-32B-Instruct 实战教程】
昇腾 Ascend 910C 部署 Qwen3-VL-32B-Instruct 实战教程
本文记录在昇腾 Ascend 910C 双 NPU 环境中,使用 vLLM + vLLM-Ascend 部署 Qwen3-VL-32B-Instruct 的完整过程,包括环境检查、离线安装、常见报错及解决方法,最后通过 OpenAI 兼容接口提供公网服务。
一、硬件与系统环境
本次环境信息:
系统:Ubuntu 20.04.5 LTS
架构:aarch64
Python:3.11.4
NPU:Ascend 910C,2 张
单卡显存:约 64GB
torch:2.7.1+cpu
torch_npu:2.7.1.post4
检查 NPU:
npu-smi info
检查 Python:
python3 --version
python3 -m pip --version
uname -m
检查 NPU 是否可用:
python3 - <<'PY'
import torch
import torch_npu
print("torch:", torch.__version__)
print("torch_npu:", torch_npu.__version__)
print("NPU可用:", torch.npu.is_available())
print("NPU数量:", torch.npu.device_count())
PY
如果显示:
NPU可用: True
NPU数量: 2
说明基础驱动和 torch_npu 正常。
二、网络受限环境的处理思路
容器内部可能无法访问公网,但宿主机或外部电脑可以访问网络。这种情况下建议:
- 在外部机器下载 Git 仓库和 Python 安装包;
- 通过 CANNLab 文件上传、挂载目录或共享盘传入容器;
- 模型提前下载到
/mnt/workspace/models; - 容器内部使用本地源码安装,不依赖外网。
模型目录:
/mnt/workspace/models/Qwen3-VL-32B-Instruct
确认模型文件:
find /mnt/workspace/models/Qwen3-VL-32B-Instruct -maxdepth 2 -type f | head
三、vLLM 与 vLLM-Ascend 版本匹配
最初尝试安装:
pip3 install \
"vllm==0.11.0" \
"vllm-ascend==0.11.0"
出现依赖冲突:
vllm 0.11.0 depends on torch==2.8.0
vllm-ascend 0.11.0 depends on torch==2.7.1
原因是官方 vLLM 0.11.0 与 vLLM-Ascend 0.11.0 的默认依赖不一致,而当前环境已经固定为:
torch==2.7.1
torch_npu==2.7.1.post4
因此采用源码方式安装 vLLM,并跳过依赖解析。
四、安装 vLLM 源码
假设源码位于:
/mnt/workspace/vllm-src
安装前设置昇腾目标为空设备,避免编译 CUDA:
cd /mnt/workspace/vllm-src
VLLM_TARGET_DEVICE=empty \
python3 -m pip install -e . \
--no-build-isolation \
--no-deps
第一次可能报错:
ModuleNotFoundError: No module named 'setuptools_scm'
如果容器可以访问镜像源,可以安装:
python3 -m pip install --user setuptools_scm
如果网络不可用,则需要在外部机器下载对应 wheel,再上传到容器离线安装。
安装成功后应看到:
Successfully built vllm
Successfully installed vllm-0.11.0+empty
五、安装 vLLM-Ascend
假设源码位于:
/mnt/workspace/vllm-ascend-src
由于容器缺少部分自定义编译依赖,使用以下方式安装:
cd /mnt/workspace/vllm-ascend-src
COMPILE_CUSTOM_KERNELS=0 \
python3 -m pip install -e . \
--no-build-isolation \
--no-deps \
--config-settings editable_mode=compat
曾经遇到的错误:
static library kineto_LIBRARY-NOTFOUND not found
ninja: build stopped
原因是环境中缺少 Kineto 相关库,且没有安装 Ninja。对于当前推理部署,可以先关闭自定义 Kernel 编译:
COMPILE_CUSTOM_KERNELS=0
成功后应看到:
Successfully built vllm_ascend
Successfully installed vllm_ascend-0.11.0
六、补齐 Python 依赖
由于使用了 --no-deps,部分 Python 依赖需要手动安装。
常见缺失模块和解决方法:
python3 -m pip install --user prometheus-client
python3 -m pip install --user uvloop
python3 -m pip install --user starlette
python3 -m pip install --user yarl
python3 -m pip install --user pkg_resources
pkg_resources 通常由 setuptools 提供:
python3 -m pip install --user -U setuptools
推荐一次性安装:
python3 -m pip install --user \
modelscope \
qwen-vl-utils \
pillow \
prometheus-client \
uvloop \
starlette \
watchfiles \
xgrammar \
aiohttp \
yarl
七、解决 Transformers 版本冲突
曾遇到:
transformers requires tokenizers>=0.22.0,<=0.23.0
but found tokenizers==0.23.1
调整为:
python3 -m pip install --user --no-deps --force-reinstall \
transformers==4.57.1 \
tokenizers==0.22.2 \
huggingface-hub==0.36.0
注意,华为镜像可能没有 tokenizers==0.23.0,但有 0.22.2,因此使用 0.22.2 即可。
检查版本:
python3 - <<'PY'
import transformers
import tokenizers
import huggingface_hub
print("transformers:", transformers.__version__)
print("tokenizers:", tokenizers.__version__)
print("huggingface-hub:", huggingface_hub.__version__)
PY
八、解决 libatb.so 缺失问题
启动时曾遇到:
OSError: libatb.so: cannot open shared object file
以及:
Please check that the nnal package is installed.
Please run 'source set_env.sh' in the NNAL installation path.
最初执行:
find /usr/local/Ascend -name libatb.so -type f
没有找到文件,以为容器没有 NNAL。
后来全盘查找发现 NNAL 实际安装在:
/opt/home/developer/Ascend/nnal/atb/set_env.sh
/opt/home/developer/Ascend/nnal/atb/9.0.0/atb/cxx_abi_1/lib/libatb.so
/opt/home/developer/Ascend/nnal/atb/9.0.0/atb/cxx_abi_0/lib/libatb.so
查找命令:
find / -name libatb.so -type f 2>/dev/null
find / -path '*nnal*' -name set_env.sh 2>/dev/null
启动前必须加载 NNAL:
source /opt/home/developer/Ascend/nnal/atb/set_env.sh
source /opt/home/developer/Ascend/ascend-toolkit/set_env.sh 2>/dev/null || true
测试动态库:
python3 - <<'PY'
import ctypes
ctypes.CDLL("libatb.so")
print("libatb.so 加载成功")
PY
如果仍然找不到:
export LD_LIBRARY_PATH=/opt/home/developer/Ascend/nnal/atb/9.0.0/atb/cxx_abi_0/lib:$LD_LIBRARY_PATH
检查依赖:
ldd /opt/home/developer/Ascend/nnal/atb/9.0.0/atb/cxx_abi_0/lib/libatb.so \
| grep "not found" || echo "libatb依赖正常"
九、创建 Qwen3-VL 启动脚本
创建:
vim /mnt/workspace/start_qwen3vl.sh
内容如下:
#!/usr/bin/env bash
set -e
source /opt/home/developer/Ascend/nnal/atb/set_env.sh
source /opt/home/developer/Ascend/ascend-toolkit/set_env.sh 2>/dev/null || true
export ASCEND_RT_VISIBLE_DEVICES=0,1
export HCCL_OP_EXPANSION_MODE=AIV
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
export VLLM_ASCEND_ENABLE_NZ=0
export COMPILE_CUSTOM_KERNELS=0
export OMP_PROC_BIND=false
export OMP_NUM_THREADS=1
export TASK_QUEUE_ENABLE=1
export PATH=/home/developer/.local/bin:$PATH
cd /mnt/workspace/vllm-src
python3 -m vllm.entrypoints.openai.api_server \
--model /mnt/workspace/models/Qwen3-VL-32B-Instruct \
--host 0.0.0.0 \
--port 8000 \
--served-model-name qwen3-vl-32b \
--tensor-parallel-size 2 \
--dtype bfloat16 \
--trust-remote-code \
--max-model-len 4096 \
--max-num-seqs 1 \
--max-num-batched-tokens 2048 \
--gpu-memory-utilization 0.90 \
--no-enable-prefix-caching \
--mm-processor-cache-gb 0 \
--api-key "sujiapikey"
赋予执行权限:
chmod +x /mnt/workspace/start_qwen3vl.sh
启动:
/mnt/workspace/start_qwen3vl.sh
看到以下日志表示服务启动成功:
Application startup complete.
十、启动日志中的警告
以下警告不一定影响推理:
Model architecture Qwen3NextForCausalLM is already registered
这是模型架构重复注册提示。
Failed to import vllm_ascend_C
Sleep mode will be disabled
这是因为之前关闭了自定义 Kernel 编译:
COMPILE_CUSTOM_KERNELS=0
会导致 Sleep mode 不可用,但通常不影响基础推理。
十一、测试 OpenAI 接口
1. 查看模型列表
curl http://127.0.0.1:8000/v1/models \
-H "Authorization: Bearer sujiapikey"
2. 测试文本对话
curl http://127.0.0.1:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sujiapikey" \
-d '{
"model": "qwen3-vl-32b",
"messages": [
{
"role": "user",
"content": "你好,请用一句话介绍你自己。"
}
],
"max_tokens": 100
}'
成功时会返回:
{
"object": "chat.completion",
"model": "qwen3-vl-32b",
"choices": [
{
"message": {
"role": "assistant",
"content": "你好,我是一个多模态大语言模型。"
},
"finish_reason": "stop"
}
]
}
之前出现的:
JSON decode error
是由于命令粘贴或 JSON 格式错误,并非模型故障。
十二、查看 NPU 使用情况
另开终端:
watch -n 1 npu-smi info
推理时重点观察:
HBM-Usage
AICore(%)
Process memory
如果两张 NPU 都有显存占用,并且推理时 AICore 利用率变化,说明张量并行正常运行。
十三、通过 FRP 暴露公网接口
网络拓扑:
互联网客户端
↓
公网虚拟机 frps
↓
NPU容器 frpc
↓
127.0.0.1:8000
公网虚拟机 frps 配置
/etc/frp/frps.toml:
bindPort = 7000
auth.method = "token"
auth.token = "请修改为复杂随机字符串"
启动:
frps -c /etc/frp/frps.toml
开放端口:
ufw allow 7000/tcp
ufw allow 18000/tcp
NPU 容器 frpc 配置
/mnt/workspace/frpc.toml:
serverAddr = "公网虚拟机IP"
serverPort = 7000
auth.method = "token"
auth.token = "请使用与frps相同的随机字符串"
[[proxies]]
name = "qwen3-vl-api"
type = "tcp"
localIP = "127.0.0.1"
localPort = 8000
remotePort = 18000
启动:
frpc -c /mnt/workspace/frpc.toml
公网测试:
curl http://公网虚拟机IP:18000/v1/models \
-H "Authorization: Bearer sujiapikey"
十四、安全建议
不要直接使用:
sujiapikey
建议生成随机 Key:
openssl rand -hex 32
然后修改启动脚本:
--api-key "生成的随机字符串"
另外建议:
- FRP 使用 token 认证;
- 只开放必要端口;
- 不要暴露 FRP 的管理端口;
- 公网 API 最好通过 HTTPS;
- 对接口增加访问频率限制;
- 不要把模型服务直接裸奔在公网;
- 长时间运行建议使用 systemd、tmux 或 supervisor。
十五、问题总结
| 问题 | 原因 | 解决方法 |
|---|---|---|
| vLLM 与 vLLM-Ascend 依赖冲突 | 两者要求不同 torch 版本 | 源码安装并使用 --no-deps |
缺少 setuptools_scm | 构建依赖未安装 | 安装 setuptools_scm 或离线上传 |
kineto_LIBRARY-NOTFOUND | 缺少 Kineto 库 | 使用 COMPILE_CUSTOM_KERNELS=0 |
缺少 prometheus_client | vLLM API 服务依赖 | 手动安装 prometheus-client |
缺少 uvloop | API Server 依赖 | 安装 uvloop |
缺少 starlette | FastAPI 依赖未完整安装 | 安装 starlette |
| transformers 与 tokenizers 冲突 | 版本不匹配 | 使用 transformers 4.57.1、tokenizers 0.22.2 |
| huggingface-hub 版本冲突 | 版本过新 | 降级到 0.36.0 |
libatb.so 找不到 | 没有加载 NNAL 环境 | source NNAL 的 set_env.sh |
| Worker 初始化失败 | ATB 动态库无法加载 | 检查 LD_LIBRARY_PATH 和 ldd |
| JSON decode error | curl JSON 格式错误 | 检查引号、逗号和字段格式 |
| API 启动后退出 | 引擎 Worker 初始化失败 | 优先查看最早出现的 Worker 根因 |
十六、最终验证标准
以下条件全部满足,说明部署成功:
NPU可用: True
NPU数量: 2
vllm: 0.11.0
vllm_ascend: 0.11.0
libatb.so 加载成功
Application startup complete.
/ v1/models 可以返回模型
/ v1/chat/completions 可以正常回答
npu-smi 可以看到两张 NPU 使用情况
至此,Qwen3-VL-32B-Instruct 已经在昇腾双 NPU 环境中成功部署,并通过兼容 OpenAI 的 API 对外提供服务。
更多推荐



所有评论(0)