昇腾 910B NPU 大模型部署实践:vLLM 与 Transformers 方案详解
原文地址:昇腾 910B NPU 大模型部署实践:vLLM 与 Transformers 方案详解
一、概述
本文记录在华为昇腾 910B NPU 环境下部署多个开源大模型(Qwen3-4B、QED-Nano、Eva-4B-V2、GLM-OCR、Nanbeige4.1-3B)的完整技术流程。涵盖环境配置、镜像选择、框架对比(vLLM vs Transformers)及常见报错处理方案。
部署环境:
- 硬件:昇腾 910B(32GB HBM)
- 驱动:CANN 8.0 RC1
- 容器:Ascend Docker Runtime
- 网络:内部局域网
二、部署流程全景图
┌─────────────────────────────────────────────────────────────────┐
│ NPU 模型部署流程 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 1. 环境准备 │
│ ├── 确认 CANN 版本(建议 8.0 RC1+) │
│ ├── 安装 Ascend Docker Runtime │
│ └── 检查 NPU 设备可见性(npu-smi info) │
│ ↓ │
│ 2. 镜像选择 │
│ ├── Qwen3 架构 → v0.14.0rc1+ │
│ ├── 其他模型 → v0.11.0rc0+ │
│ └── 自定义镜像 → 基于 ascend/pytorch 构建 │
│ ↓ │
│ 3. 模型评估 │
│ ├── 架构是否被 vLLM 支持? │
│ │ ├── ✅ 是 → 走 vLLM 方案(高性能) │
│ │ └── ❌ 否 → 走 Transformers 方案(通用性) │
│ └── 上下文长度 vs NPU 显存估算 │
│ └── 262k 上下文可能需要限制到 8k │
│ ↓ │
│ 4. 容器配置 │
│ ├── 设备映射:-v /dev/davinciX │
│ ├── 驱动挂载:driver + fwkacllib(缺一不可) │
│ ├── 环境变量:ASCEND_RT_VISIBLE_DEVICES=0 │
│ └── 端口映射:-p 宿主机端口:容器端口 │
│ ↓ │
│ 5. 服务启动 │
│ ├── vLLM:vllm serve + 参数调优 │
│ └── Transformers:Flask + Gunicorn (gthread) │
│ ↓ │
│ 6. 验证测试 │
│ ├── 健康检查:/v1/models 或 /health │
│ ├── 功能测试:对话/推理是否正常 │
│ └── 性能测试:并发、延迟、显存占用 │
│ │
└─────────────────────────────────────────────────────────────────┘
三、技术方案选型
| 模型 | 参数 | 架构 | 部署方式 | NPU 设备 | 端口 | 耗时 |
|---|---|---|---|---|---|---|
| Qwen3-4B-Instruct | 4B | Qwen3ForCausalLM | vLLM | davinci6 | 18006 | 半天 |
| QED-Nano | 2.5B | Qwen3ForCausalLM | vLLM | davinci5 | 18005 | 2 小时 |
| Nanbeige4.1-3B | 3B | - | vLLM | davinci3 | 18003 | 1 小时 |
| Eva-4B-V2 | 4B | Qwen3ForCausalLM | Transformers | davinci6 | 18006 | 2 天 |
| GLM-OCR | 1.3B | GlmOcrForConditionalGeneration | Transformers | davinci4 | 18004 | 3 天 |
两个关键决策点:
| 决策点 | 选项 A | 选项 B |
|---|---|---|
| 部署框架 | vLLM(高性能、高并发) | Transformers(稳定、兼容性好) |
| 上下文长度 | 按模型默认(可能 OOM) | 限制 4k-8k(推荐) |
四、具体部署案例
4.1 Qwen3-4B —— 镜像版本兼容性问题
问题现象:
使用 v0.11.0rc0 镜像启动时报错:
ValueError: The model architectures ['Qwen3ForCausalLM'] are not supported
根因分析:
v0.11.0rc0 内置的 transformers 版本较低,未包含 Qwen3 架构支持。
解决方案:
升级镜像至 v0.14.0rc1 或更高版本:
# 正确的镜像版本
FROM quay.io/ascend/vllm-ascend:v0.14.0rc1
关键经验: 新架构模型需使用 vLLM-ascend 最新 RC 版本,旧版本仅支持早期模型架构。
4.2 QED-Nano —— 长上下文显存管理
问题现象:
启动 2.5B 参数模型时显存不足报错:
ValueError: No available memory for the cache blocks.
Try increasing gpu_memory_utilization or decreasing max_model_len.
技术原理:
vLLM 使用 PagedAttention 管理 KV Cache。QED-Nano 支持 262k 上下文,完整加载需几十 GB 显存,超出 910B 的 32GB 限制。
计算公式:
KV Cache = 2 × num_layers × num_heads × head_dim × seq_len × batch_size × sizeof(dtype)
解决方案:
限制最大上下文长度并提高显存利用率:
vllm serve /data/model/QED-Nano \
--port 8000 \
--dtype bfloat16 \
--max-model-len 8192 \
--gpu-memory-utilization 0.95
| 参数 | 模型支持 | 实际部署 | 原因 |
|---|---|---|---|
| max-model-len | 262k | 8k | NPU 内存限制 |
| gpu-memory-utilization | 0.9 | 0.95 | 提高内存使用效率 |
4.3 Eva-4B-V2 —— NNAL 库版本兼容性
问题现象:
启动时报错:
libatb.so: undefined symbol
根因分析:
NNAL(Neural Network Acceleration Library)版本与当前 CANN 驱动版本 ABI 不兼容。升级服务器 NNAL 需运维介入且影响其他服务。
技术决策:
| 方案 | 优点 | 缺点 | 风险 |
|---|---|---|---|
| 升级服务器 NNAL | 保持 vLLM 高性能 | 需运维介入,影响其他服务 | 高 |
| 改用 Transformers | 稳定,无额外依赖 | 并发能力较弱 | 低 |
实施方案:
Eva-4B-V2 为分类任务模型,无需高并发生成,采用 Transformers 原生加载:
from transformers import AutoModel, AutoProcessor
import torch
model = AutoModel.from_pretrained(
MODEL_PATH,
torch_dtype=torch.bfloat16,
trust_remote_code=True,
device_map="auto"
)
使用 Flask 封装 API,Gunicorn 运行:
gunicorn \
--worker-class gthread \
--workers 1 \
--threads 4 \
--bind 0.0.0.0:8000 \
--timeout 600 \
app:app
4.4 GLM-OCR —— 架构特殊性与流式输出
问题现象:
vLLM 加载报错:
ValueError: The model architectures ['GlmOcrForConditionalGeneration'] are not supported
深入排查:
即使使用通用回退路径 TransformersMultiModalForCausalLM,仍报错:
ValueError: There is no module or parameter named 'model.language_model.layers.16'
技术细节:
GLM-4 系列采用 Multi-Token Prediction (MTP) 机制,除标准 16 层 Transformer 外,包含第 17 层(layers.16)MTP 预测层。vLLM 通用回退路径仅创建标准层,无法处理 MTP 层权重。
实施方案:
采用 Transformers 原生部署,并解决流式输出技术难点:
难点 1:Gunicorn Worker 选择
| Worker 类型 | 结果 | 原因 |
|---|---|---|
| sync | ❌ 无法流式 | 阻塞式处理 |
| gevent | ❌ CANN 报错 | 与 TBE 编译器的 multiprocessing 冲突 |
| gthread | ✅ 正常工作 | 线程模式,兼容 CANN |
难点 2:模型重复生成
GLM-OCR 存在生成后进入重复循环的现象,采用三层防护机制:
# 层1: 生成层 - 降低重复概率
generation_config.repetition_penalty = 1.2
# 层2: token 层 - 连续相同 token 检测
if new_text == last_text:
repeat_count += 1
if repeat_count > 10:
break
# 层3: 段落层 - 检测文本末尾重复前文
if check_block_repeat(accumulated_text):
break
4.5 Nanbeige4.1-3B —— 标准流程部署
该模型为 3B 参数中文基础模型,架构标准、上下文长度适中,按以下流程快速部署:
- 确认模型架构被 vLLM-ascend 支持
- 检查上下文长度,预估显存需求
- 使用标准 deploy.sh 脚本,修改端口和模型路径
- vLLM 启动,半小时内部署完成
五、常见技术问题与解决方案
5.1 容器内 NPU 设备 ID 设置错误
错误配置:
# 错误做法
NPU_DEVICE_ID=$(echo ${NPU_DEVICE} | sed 's/davinci//')
# 结果:davinci6 → 6
报错信息:
set ASCEND_RT_VISIBLE_DEVICES:6 error, input data rang[0-0])
正确配置:
宿主机映射 /dev/davinci6 到容器后,容器内设备编号为 0,环境变量应设置为 0:
docker run \
-e ASCEND_RT_VISIBLE_DEVICES=0 \
-e ASCEND_DEVICE_ID=0 \
...
| 物理 NPU | 宿主机设备 | 容器内设备 ID | 环境变量值 |
|---|---|---|---|
| davinci6 | /dev/davinci6 | 0 | 0 |
| davinci5 | /dev/davinci5 | 0 | 0 |
| davinci4 | /dev/davinci4 | 0 | 0 |
5.2 驱动库挂载不完整
报错信息:
RuntimeError: Initialize:... NPU function error: aclInit, error code is 107001
[Error]: Invalid device ID.
完整挂载清单:
docker run \
-v /usr/local/Ascend/driver:/usr/local/Ascend/driver:ro \
-v /usr/local/Ascend/driver/lib64:/usr/local/Ascend/driver/lib64:ro \
-v /usr/local/Ascend/fwkacllib:/usr/local/Ascend/fwkacllib:ro \
-v /usr/local/Ascend/driver/version.info:/usr/local/Ascend/driver/version.info:ro \
-v /etc/ascend_install.info:/etc/ascend_install.info:ro \
-v /usr/local/dcmi:/usr/local/dcmi \
-e LD_LIBRARY_PATH=/usr/local/Ascend/driver/lib64:/usr/local/Ascend/fwkacllib/lib64:$LD_LIBRARY_PATH \
...
注意: fwkacllib 必须挂载,否则 NPU 初始化失败。
5.3 端口映射与网络模式冲突
错误做法:
docker run --network=host -p 18006:8000 ...
原因: --network=host 模式下 -p 参数失效。
推荐方案:
使用 bridge 模式 + -p 映射:
# 容器内保持默认 8000
vllm serve ... --port 8000
# 宿主机映射
docker run -p 18006:8000 ...
六、部署架构参考
vLLM 方案架构
┌─────────────────────────────────────────────────────────────┐
│ 宿主机 (Host) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 物理 NPU │ │ 端口映射 │ │ 模型文件 │ │
│ │ davinci6 │───▶│ 18006:8000 │◀───│ /data1/... │ │
│ └─────────────┘ └──────┬──────┘ └─────────────┘ │
│ │ │
│ ┌─────────────────────────┼─────────────────────────┐ │
│ │ Docker 容器 │ │
│ │ ┌──────────────────────┼─────────────────────┐ │ │
│ │ │ vLLM Service │ │ │
│ │ │ (port 8000, device 0) │ │ │
│ │ └──────────────────────┼─────────────────────┘ │ │
│ │ │ │ │
│ │ ┌──────────────────────┼─────────────────────┐ │ │
│ │ │ NPU Runtime (CANN) │ │ │
│ │ │ ASCEND_RT_VISIBLE_DEVICES=0 │ │ │
│ │ └──────────────────────┼─────────────────────┘ │ │
│ └─────────────────────────┼─────────────────────────┘ │
└────────────────────────────┼───────────────────────────────┘
│
┌────────▼────────┐
│ NPU davinci6 │
│ (物理设备) │
└─────────────────┘
Transformers 方案架构
Client Request → Gunicorn (gthread, 4线程) → Flask App → TextIteratorStreamer
↓
NPU (davinci4)
↓
Client ← SSE Stream ← Thread-safe Queue ← Model.generate()
七、经验总结
核心经验速查表
- 镜像版本选择:Qwen3 等新架构模型需使用 v0.14.0rc1+,旧版本无法识别
- 长上下文处理:必须限制
max-model-len,根据 NPU 内存调整,推荐 4k-8k - 容器设备 ID:无论物理 NPU 编号多少,容器内始终设为 0
- 驱动挂载:必须包含
fwkacllib,否则初始化失败 - 网络配置:使用 bridge 模式 +
-p映射,避免--network=host - 框架选择:vLLM 不支持时,Transformers 原生 + Flask 是最稳定的备选方案
- Worker 类型:Gunicorn 必须使用 gthread,gevent 与 CANN 冲突
- 重复生成处理:三层防护(repetition_penalty + token 检测 + 段落检测)
技术选型建议
- 高并发场景(对话服务):优先使用 vLLM,充分利用 PagedAttention 性能优势
- 特殊架构模型(GLM-4、自定义架构):使用 Transformers,避免兼容性问题
- 长上下文模型:根据实际 NPU 内存限制上下文长度,必要时升级硬件
八、参考文档
标签: #昇腾 #华为 #vLLM #大模型部署 #NPU #Qwen #GLM #模型推理
鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。
更多推荐



所有评论(0)