Qwen3-VL-30B-A3B-Instruct¶
1 简介¶
Qwen3-VL-30B-A3B-Instruct 是 Qwen3-VL 系列中的稀疏 MoE 视觉语言模型,总参数量约 30B,每个 token 激活参数量约 3B。它适用于 Ascend 硬件上的图像理解、视频理解、多模态对话以及长上下文在线服务。
本文档介绍该模型的主要验证步骤,包括支持的功能、前提条件、安装、图像和视频在线部署、离线推理、功能验证、精度与性能评估、性能调优以及常见问题。
Qwen3-VL-30B-A3B-Instruct 教程是为 vllm-ascend v0.13.0 验证周期引入的。使用该模型时请使用 v0.13.0 或更高版本。以下示例使用文档构建系统配置的版本占位符。
2 支持的功能¶
请参阅支持的功能列表以获取模型支持的功能矩阵。
请参阅功能指南以获取功能的配置。
3 前提条件¶
3.1 模型权重¶
| 权重版本 | 硬件要求 | 下载链接 |
|---|---|---|
Qwen3-VL-30B-A3B-Instruct(BF16 版本) |
1 个 Atlas 800 A3(64GB x 16)节点或 1 个 Atlas 800 A2(64GB x 8)节点 | ModelScope |
Qwen3-VL-30B-A3B-Instruct-w8a8-mxfp8(量化版本) |
1 个 950DT 产品(96GB x 8)节点 | ModelScope |
建议将模型权重下载到跨多个节点的共享目录中。
路径说明:将模型权重下载到您选择的目录并记录该目录。确保后续部署命令中的模型路径与该目录一致。
4 安装¶
4.1 Docker 镜像安装¶
根据您的机器类型选择镜像,并在您的节点上启动 docker 镜像,请参阅使用 docker。
在每个节点上启动 docker 镜像。
export IMAGE=quay.io/ascend/vllm-ascend:v0.23.0-a5
export NAME=vllm-ascend
docker run --rm \
--name $NAME \
--net=host \
--shm-size=1g \
--device /dev/davinci0 \
--device /dev/davinci1 \
--device /dev/davinci2 \
--device /dev/davinci3 \
--device /dev/davinci4 \
--device /dev/davinci5 \
--device /dev/davinci6 \
--device /dev/davinci7 \
--device /dev/davinci_manager \
--device /dev/hisi_hdc \
--device /dev/ummu \
--device /dev/uburma \
-v /usr/local/Ascend/driver:/usr/local/Ascend/driver \
-v /etc/ascend_install.info:/etc/ascend_install.info \
-v /etc/hccl_rootinfo.json:/etc/hccl_rootinfo.json \
-v /etc/hixlep/:/etc/hixlep/ \
-v /root/.cache:/root/.cache \
-v /usr/local/sbin:/usr/local/sbin \
-v /usr/local/dcmi:/usr/local/dcmi \
-v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \
-v /usr/local/sbin/npu-smi:/usr/local/sbin/npu-smi \
-v /usr/lib64:/usr/lib64 \
-itd $IMAGE bash
在每个节点上启动 docker 镜像。
export IMAGE=quay.io/ascend/vllm-ascend:v0.23.0-a3
docker run --rm \
--name vllm-ascend \
--shm-size=512g \
--net=host \
--privileged=true \
--device /dev/davinci0 \
--device /dev/davinci1 \
--device /dev/davinci2 \
--device /dev/davinci3 \
--device /dev/davinci4 \
--device /dev/davinci5 \
--device /dev/davinci6 \
--device /dev/davinci7 \
--device /dev/davinci8 \
--device /dev/davinci9 \
--device /dev/davinci10 \
--device /dev/davinci11 \
--device /dev/davinci12 \
--device /dev/davinci13 \
--device /dev/davinci14 \
--device /dev/davinci15 \
--device /dev/davinci_manager \
--device /dev/devmm_svm \
--device /dev/hisi_hdc \
-v /usr/local/dcmi:/usr/local/dcmi \
-v /usr/local/Ascend/driver/tools/hccn_tool:/usr/local/Ascend/driver/tools/hccn_tool \
-v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \
-v /usr/local/Ascend/driver/lib64/:/usr/local/Ascend/driver/lib64/ \
-v /usr/local/Ascend/driver/version.info:/usr/local/Ascend/driver/version.info \
-v /etc/ascend_install.info:/etc/ascend_install.info \
-v /etc/hccn.conf:/etc/hccn.conf \
-v /root/.cache:/root/.cache \
-it $IMAGE bash
在每个节点上启动 docker 镜像。
export IMAGE=quay.io/ascend/vllm-ascend:v0.23.0
docker run --rm \
--name vllm-ascend \
--shm-size=512g \
--net=host \
--privileged=true \
--device /dev/davinci0 \
--device /dev/davinci1 \
--device /dev/davinci2 \
--device /dev/davinci3 \
--device /dev/davinci4 \
--device /dev/davinci5 \
--device /dev/davinci6 \
--device /dev/davinci7 \
--device /dev/davinci_manager \
--device /dev/devmm_svm \
--device /dev/hisi_hdc \
-v /usr/local/dcmi:/usr/local/dcmi \
-v /usr/local/Ascend/driver/tools/hccn_tool:/usr/local/Ascend/driver/tools/hccn_tool \
-v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \
-v /usr/local/Ascend/driver/lib64/:/usr/local/Ascend/driver/lib64/ \
-v /usr/local/Ascend/driver/version.info:/usr/local/Ascend/driver/version.info \
-v /etc/ascend_install.info:/etc/ascend_install.info \
-v /etc/hccn.conf:/etc/hccn.conf \
-v /root/.cache:/root/.cache \
-it $IMAGE bash
启动容器后,运行以下命令以验证安装:
预期结果:容器以 Up 状态列出。您还可以在容器内验证 vllm-ascend 版本:
预期结果:显示版本信息,且与拉取的镜像版本一致。
4.2 源代码安装¶
如果您不想使用 Docker 镜像,可以从源代码构建。请先从源代码安装 vLLM:
- 克隆并安装 vLLM:
- 克隆并安装 vLLM-Ascend 仓库:
安装验证:
预期结果:显示两个包的版本信息,确认安装成功。
Note
如果部署多节点环境,请在每个节点上配置环境。
有关更多详细信息,请参阅安装指南。
5 在线服务部署¶
5.1 单节点在线部署¶
单节点部署在同一节点上同时运行 Prefill 和 Decode。以下示例适用于仅图像的在线服务。
运行以下脚本,在 1 台 950DT 产品(96G x 8)上执行在线推理。量化版本(Qwen3-VL-30B-A3B-Instruct-w8a8-mxfp8)可以部署在单个 950DT 产品节点上。W8A8 版本需要 --quantization ascend。
#!/bin/sh
# Load model from ModelScope to speed up download.
export VLLM_USE_MODELSCOPE=True
export HCCL_BUFFSIZE=400
export HCCL_OP_EXPANSION_MODE="AIV"
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
# Reduce memory fragmentation and avoid out-of-memory errors.
# Ensure the model path matches the directory recorded during download
vllm serve Eco-Tech/Qwen3-VL-30B-A3B-Instruct-w8a8-mxfp8 \
--host 0.0.0.0 \
--port 8000 \
--distributed-executor-backend mp \
--data-parallel-size 1 \
--tensor-parallel-size 8 \
--enable-expert-parallel \
--seed 1024 \
--quantization ascend \
--served-model-name qwen3-vl-30b \
--max-num-seqs 32 \
--max-model-len 32768 \
--max-num-batched-tokens 8192 \
--trust-remote-code \
--no-enable-prefix-caching \
--mm-processor-cache-gb 0 \
--limit-mm-per-prompt.image 1 \
--limit-mm-per-prompt.video 0 \
--gpu-memory-utilization 0.9 \
--compilation-config '{"cudagraph_mode":"FULL_DECODE_ONLY"}'
运行以下脚本,在 1 台 Atlas 800 A3(64G x 16)节点上启动仅图像服务。
#!/bin/sh
# Load model from ModelScope to speed up download.
export VLLM_USE_MODELSCOPE=True
export HCCL_BUFFSIZE=1024
export HCCL_OP_EXPANSION_MODE="AIV"
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
# Reduce memory fragmentation and avoid out-of-memory errors.
# Ensure the model path matches the directory recorded during download
vllm serve Qwen/Qwen3-VL-30B-A3B-Instruct --additional-config '{"enable_fused_mc2":1}' \
--host 0.0.0.0 \
--port 8000 \
--served-model-name qwen3-vl-30b \
--data-parallel-size 1 \
--tensor-parallel-size 2 \
--enable-expert-parallel \
--seed 1024 \
--max-num-seqs 32 \
--max-model-len 32768 \
--max-num-batched-tokens 16384 \
--gpu-memory-utilization 0.9 \
--no-enable-prefix-caching \
--mm-processor-cache-gb 0 \
--limit-mm-per-prompt.image 1 \
--limit-mm-per-prompt.video 0 \
--compilation-config '{"cudagraph_mode":"FULL_DECODE_ONLY","cudagraph_capture_sizes":[1,2,4,8,16,24,32]}' \
--additional-config '{"enable_fused_mc2": 1}'
上述 A3 系列脚本在 1 台 Atlas 800 A2(64G x 8)节点上配合 --tensor-parallel-size 2 也可以使用。
关键参数说明:
--tensor-parallel-size 2将模型映射到两个 NPU。仅在验证硬件上的内存、通信和吞吐量后,再增加 TP。--enable-expert-parallel为 MoE 层启用专家并行。请勿在同一 MoE 层中混合使用 MoE 张量并行和专家并行。--max-model-len是单个请求的最大输入加输出长度。默认情况下,模型可以支持长上下文,但128000是许多图像/视频工作负载的实用验证值。--max-num-seqs是每个 DP 组调度的最大活动请求数。视频请求会消耗更多内存,因此视频示例使用较小的值。--max-num-batched-tokens是一个调度器步骤中处理的最大 token 数。较大的值可以提高 prefill 效率,但会消耗更多激活内存。--gpu-memory-utilization控制 vLLM 可用于计算 KV 缓存容量的 HBM 大小。仅在确认服务稳定后再增加该值。--limit-mm-per-prompt.video 0禁用视频输入,并为仅图像服务节省内存。--allowed-local-media-path /media允许请求使用本地文件,例如file:///media/test.mp4。--compilation-config '{"cudagraph_mode":"FULL_DECODE_ONLY"}'启用完整解码 ACLGraph 重放,以减少调度开销。
常见问题提示:如果您遇到问题,请参阅公共常见问题解答进行故障排除。
服务验证:
curl http://<server_ip>:<port>/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3-vl-30b",
"messages": [
{
"role": "user",
"content": "Who are you?"
}
],
"max_tokens": 256,
"temperature": 0
}'
预期结果:
服务返回 HTTP 200 OK,且 JSON 响应中包含 choices 字段。
6 功能验证¶
服务器启动后,发送请求以验证基本的多模态功能。
curl http://<server_ip>:<port>/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3-vl-30b",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": [
{"type": "image_url", "image_url": {"url": "https://modelscope.oss-cn-beijing.aliyuncs.com/resource/qwen.png"}},
{"type": "text", "text": "What is the text in the illustration?"}
]}
],
"max_completion_tokens": 100,
"temperature": 0
}'
预期结果:HTTP 状态为 200,JSON 响应中包含带有生成文本的 choices 字段,例如类似于 TONGYI Qwen 的文本。
7 精度评估¶
使用 AISBench¶
-
有关详细信息,请参阅使用 AISBench。
-
执行后,您即可获取结果。
| 数据集 | 版本 | 指标 | 模式 | 结果 |
|---|---|---|---|---|
| mmmu_val | - | acc,none | gen | 0.58 |
8 性能评估¶
8.1 使用 AISBench¶
有关详细信息,请参阅使用 AISBench 进行性能评估。对于图像或视频性能测试,请使用带有真实多模态负载的数据集,而不是仅包含随机文本的提示。
8.2 使用 vLLM Benchmark¶
以 Qwen3-VL-30B-A3B-Instruct 为例执行性能评估。更多详情请参阅 vLLM 基准测试。
vllm bench 有三个子命令:
latency:基准测试单批请求的延迟。serve:基准测试在线服务的吞吐量。throughput:基准测试离线推理的吞吐量。
以 serve 为例:
export VLLM_USE_MODELSCOPE=True
vllm bench serve \
--model Qwen/Qwen3-VL-30B-A3B-Instruct \
--served-model-name qwen3-vl-30b \
--dataset-name random \
--random-input 200 \
--num-prompts 200 \
--request-rate 1 \
--save-result \
--result-dir ./
数分钟后,您即可获取性能评估结果。该随机基准测试对于服务流水线验证很有用;如需测试图像/视频 Token 性能,请使用 AISBench 或自定义多模态数据集。
9 性能调优¶
9.1 推荐配置¶
注意:以下配置已在特定测试环境中验证,仅供参考。最佳配置取决于硬件类型、图像分辨率、视频长度、最大输入/输出长度、请求并发数、前缀缓存命中率以及 prefill/decode 比例。请根据实际工作负载调整第 9.2 节中的参数。
表 1:场景概览¶
| 场景 | 部署模式 | *NPU 总数 | 权重版本 | 关键注意事项 |
|---|---|---|---|---|
| 仅图像服务 | 单节点在线服务 | 2 个或更多 NPU | BF16 | 禁用视频,调整上下文长度,并为视觉 token 保留足够的 KV 缓存。 |
| 视频服务 | 单节点在线服务 | 2 个或更多 NPU | BF16 | 使用本地媒体路径,降低并发数;如果发生 OOM,可缩短视频长度或减少帧采样。 |
| 功能图验证 | 单节点 PP | 2 个 NPU | BF16 | 使用较短的上下文和显式的捕获大小来验证完整 decode ACLGraph 行为。 |
*NPU 总数表示所有节点上使用的 NPU 总数。1 个节点 = 1 台 Atlas 800 A3 服务器(64GB × 16 NPU)。
表 2:详细节点配置¶
| 场景 | 节点角色 | NPU 数 | TP | PP | 最大序列数 | 最大模型长度 | 最大批量 Token 数 | 前缀缓存 | 主要优化 |
|---|---|---|---|---|---|---|---|---|---|
| 仅图像服务 | 单节点 | 2 个或更多 | 2 | 1 | 16 | 128000 | 4096 | 取决于工作负载 | FullGraph、EP、禁用视频 |
| 视频服务 | 单节点 | 2 个或更多 | 2 | 1 | 8 | 128000 | 4096 | 取决于工作负载 | FullGraph、EP、本地媒体路径 |
| 图验证 | 单节点 | 2 | 1 | 2 | 按测试调整 | 4096 | 1024 | 关闭 | FullGraph 捕获大小 |
完整的启动命令和参数说明,请参阅第 5 章中的部署示例。
9.2 调优指南¶
9.2.1 通用调优参考¶
调优方法请参阅公共性能调优文档。
详细功能说明请参阅功能矩阵。
9.2.2 推荐的调优顺序¶
- 从仅图像服务开始。只有在图像路径稳定后再添加视频。
- 使用
--max-model-len选择最大上下文长度。多模态请求会同时消耗文本 token 和视觉 token 的 KV 缓存,因此如果发生 OOM,请降低图像分辨率、缩短视频长度、降低请求并发数或上下文长度。 - 调整多模态限制。使用
--limit-mm-per-prompt.image和--limit-mm-per-prompt.video来匹配您的请求形态。 - 调整
--max-num-batched-tokens。较大的值通常会提高 prefill 吞吐量,但会增加激活内存。视频密集型工作负载通常需要保守的值。 - 根据服务并发数调整
--max-num-seqs。视频请求比图像请求更消耗内存,因此请从较小的值开始。 - 调整
--gpu-memory-utilization。增大该值可提供更多 KV 缓存,但要为运行时内存波动和媒体预处理预留余量。 - 调整 ACLGraph 捕获。decode 建议使用
FULL_DECODE_ONLY。如果您手动设置cudagraph_capture_sizes,请包含常见的 decode 批处理大小。
9.3 模型特定优化¶
| 优化 | 启用 | 收益 | 备注 |
|---|---|---|---|
| 多模态 Prompt 限制 | --limit-mm-per-prompt.image, --limit-mm-per-prompt.video |
避免为未使用的媒体类型预留内存。 | 对于仅图像服务,禁用视频。 |
| 本地媒体访问 | --allowed-local-media-path /media |
避免在服务期间缓慢的网络视频下载。 | 在请求中使用 file:///media/...。 |
| 完整解码 ACLGraph | --compilation-config '{"cudagraph_mode":"FULL_DECODE_ONLY"}' |
减少算子调度开销并稳定解码性能。 | 推荐用于解码密集型服务。 |
| 专家并行 | --enable-expert-parallel |
提升 MoE 服务吞吐量。 | 不要在同一个 MoE 层中混合 MoE 张量并行和专家并行。 |
| 前缀缓存 | --enable-prefix-caching |
改善重复前缀工作负载。 | 随机 Prompt 或唯一媒体可能无法受益。 |
| 流水线并行验证 | --pipeline-parallel-size 2 |
提供另一种双卡验证布局。 | 功能测试时使用更短的上下文和更低的批处理 Token。 |
10 常见问题¶
对于常见环境、安装和通用参数问题,请参阅 公共常见问题。本节仅涵盖 Qwen3-VL-30B-A3B-Instruct 的模型特定问题。
Q1:服务启动时为什么报告 OOM?¶
现象: 服务在 profile run 期间失败,或在接受请求之前退出。
原因: 长上下文、高图像分辨率、视频输入、较大的 --max-num-seqs、较大的 --max-num-batched-tokens 或较高的 --gpu-memory-utilization 可能导致 HBM 余量不足。
解决方案: 从仅图像服务开始,设置 --limit-mm-per-prompt.video 0,降低 --max-model-len,降低 --max-num-seqs,降低 --max-num-batched-tokens,或降低 --gpu-memory-utilization。保持 PYTORCH_NPU_ALLOC_CONF=expandable_segments:True。
Q2:为什么在仅图像命令中禁用了视频?¶
现象: 即使请求仅包含图像,服务也会预留比预期更多的内存。
原因: 允许视频输入可能会为长视觉嵌入和预处理路径预留内存。
解决方案: 对于仅图像服务,使用 --limit-mm-per-prompt.video 0。仅在工作负载需要时启用视频。
Q3:为什么使用本地文件路径的视频请求会失败?¶
现象: 请求报告文件不被允许或找不到。
原因: 服务器只能访问已挂载到容器中并由 --allowed-local-media-path 允许的本地媒体路径。
解决方案: 将主机媒体目录挂载到 /media,使用 --allowed-local-media-path /media 启动服务器,并使用类似 file:///media/test.mp4 的请求 URL。
Q4:为什么启用前缀缓存后性能没有提升?¶
现象: 已启用前缀缓存,但吞吐量或延迟没有改善。
原因: 只有当请求共享可复用前缀时,前缀缓存才有帮助。唯一图像、唯一视频或随机 Prompt 可能会增加内存压力,而没有明显收益。
解决方案: 对于重复前缀工作负载,启用前缀缓存。对于随机基准测试或内存受限的视频工作负载,请与禁用前缀缓存的情况进行比较。
Q5:为什么多模态准确率评估无法插入图像 Token?¶
现象: 评估失败,因为在 Prompt 中找不到图像占位符。
原因: Qwen3-VL 多模态任务依赖模型 chat template 在多模态处理之前插入图像占位符 Token。
解决方案: 在评估配置中启用 chat template 应用。对于基于 lm_eval 的多模态任务,将 apply_chat_template 设置为 true。
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 vl/vllm-ascend