Qwen3.5-27B 与 Qwen3.6-27B¶
1 简介¶
Qwen3.5-27B 和 Qwen3.6-27B 是 Qwen3.5/Qwen3.6 系列中的稠密混合 Mamba-Transformer 语言模型,融合了架构效率、强化学习规模和全球可访问性方面的突破。它们采用相同的混合注意力设计(GDN + 全注意力),因此在 Ascend NPU 上的部署方式对两个模型一致。它们适用于在 Ascend NPU 上运行的通用文本生成任务,例如对话、内容创作和代码生成。
本文档将演示这些模型的主要验证步骤,包括支持的特性、特性配置、环境准备、单节点和多节点部署,以及精度和性能评估。
强烈建议使用 vllm-ascend 的最新候选版本(rc)或最新正式版本。作为最低版本要求,Qwen3.5-27B 首次在 vllm-ascend:v0.17.0rc1 中得到支持,Qwen3.6-27B 首次在 vllm-ascend:v0.18.0rc1 中得到支持。对 Atlas 300I DUO 和 950DT Products 的支持从 vllm-ascend:v0.23.0rc1 开始。
2 支持的特性¶
请参阅支持的特性列表获取模型支持矩阵。
有关特性配置信息,请参阅特性指南。
3 前提条件¶
3.1 模型权重¶
| 权重版本 | 硬件要求 | 下载链接 |
|---|---|---|
Qwen3.5-27B(BF16 版本) |
1 个 Atlas 800 A3(64GB × 16)节点,或 1 个 Atlas 800 A2(64GB × 8)节点,或 Atlas 300I DUO | ModelScope | Hugging Face |
Qwen3.5-27B-w8a8(量化版本) |
1 个 Atlas 800 A3(64GB × 16)节点,或 1 个 Atlas 800 A2(64GB × 8)节点,或 Atlas 300I DUO | ModelScope |
Qwen3.6-27B(BF16 版本) |
1 个 950DT Products(96GB × 8)节点,或 1 个 Atlas 800 A3(64GB × 16)节点,或 1 个 Atlas 800 A2(64GB × 8)节点,或 Atlas 300I DUO | ModelScope | Hugging Face |
Qwen3.6-27B-w8a8(量化版本) |
1 个 Atlas 800 A3(64GB × 16)节点,或 1 个 Atlas 800 A2(64GB × 8)节点 | ModelScope |
Qwen3.6-27B-w8a8-mxfp8(量化版本) |
1 个 950DT Products(96GB × 8)节点 | ModelScope |
Qwen3.6-27B-w8a8-310p(量化版本) |
1 个 Atlas 300I DUO | ModelScope |
建议将模型权重下载到多节点的共享目录,例如 /root/.cache/。
路径说明:将模型权重下载到您选择的目录并记录下来。确保后续部署命令中的模型路径与该目录一致。
3.2 验证多节点通信¶
如果要部署多节点环境,需要按照验证多节点通信环境进行多节点通信验证。
4 安装¶
4.1 Docker 镜像安装¶
请根据您的机器类型选择镜像,并在节点上启动 Docker 镜像,参考使用 Docker。
建议使用 vllm-ascend 镜像的最新候选版本(rc)或最新正式版本,以确保最佳兼容性并获取最新特性。作为最低版本要求,对于 Qwen3.5-27B 使用 vllm-ascend:v0.17.0rc1(或更高版本),对于 Qwen3.6-27B 使用 vllm-ascend:v0.18.0rc1(或更高版本)。对于 Atlas 800 A3 上的 Qwen3.6-27B,请使用匹配的 v0.18.0rc1-a3(或更高版本的 -a3)镜像。对于 Atlas 300I DUO,请使用 vllm-ascend:v0.23.0rc1-310p(或更高版本的 -310p)镜像。
在每个节点上启动 Docker 镜像。
export IMAGE=quay.io/ascend/vllm-ascend:v0.23.0-a3
docker run --rm \
--name vllm-ascend \
--shm-size=1g \
--net=host \
--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 /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=1g \
--net=host \
--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 /root/.cache:/root/.cache \
-it $IMAGE bash
在每个节点上启动 docker 镜像。
export IMAGE=quay.io/ascend/vllm-ascend:v0.23.0-310p
docker run --rm \
--name vllm-ascend \
--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/devmm_svm \
--device /dev/hisi_hdc \
-v /usr/local/dcmi:/usr/local/dcmi \
-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 /root/.cache:/root/.cache \
-p 8000:8000 \
-it $IMAGE bash
在每个节点上启动 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 \
-it $IMAGE bash
docker run 成功之后,你可以通过执行 docker ps 命令来验证正在运行的容器服务。预期结果是容器 vllm-ascend 出现在列表中且状态为 Up,这确认 docker 安装成功。
4.2 源码安装¶
如果你不想像上面那样使用 docker 镜像,你也可以全部从源码构建:
-
克隆仓库并从源码安装
vllm-ascend:完整的安装步骤请参阅 安装。
-
如果你想部署多节点环境,你需要在每个节点上设置环境。
要验证源码安装,请运行以下命令并确认显示的版本与你安装的版本一致:
预期结果:显示 vllm-ascend 的版本信息,确认安装成功。
5 在线服务部署¶
5.1 单节点在线部署¶
单节点部署在同一节点内完成 Prefill 和 Decode,适用于开发、测试以及中等规模推理场景。Qwen3.5-27B、Qwen3.5-27B-w8a8、Qwen3.6-27B 和 Qwen3.6-27B-w8a8 模型均可部署在 1 台 Atlas 800 A3(64GB × 16)或 1 台 Atlas 800 A2(64GB × 8)上。在 Atlas 300I DUO 上,至少需要 2 个设备。Qwen3.6-27B 和 Qwen3.6-27B-w8a8-mxfp8 模型均可部署在 1 台 950DT Products(96GB × 8)上。量化版本需要使用 --quantization ascend 参数启动。
Qwen3.5-27B 和 Qwen3.6-27B 共享相同的 MTP 头部设计,因此两者都可以使用 qwen3_5_mtp 投机解码方法。
以下示例适用于 Atlas 800 A3 / Atlas 800 A2。量化版本需要 --quantization ascend。
启动命令:
#!/bin/sh
# Load model from ModelScope to speed up download
export MODEL_PATH=Eco-Tech/Qwen3.5-27B-w8a8-mtp
export VLLM_USE_MODELSCOPE=True
export HCCL_BUFFSIZE=512
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
# To reduce memory fragmentation and avoid out of memory
# Size of the shared buffer (in MB) used by HCCL for NPU-to-NPU collective communication
# Model weight path; can be a ModelScope model id (e.g., Eco-Tech/Qwen3.5-27B-w8a8-mtp) or a local directory path
# Ensure the model path matches the directory recorded during download
vllm serve $MODEL_PATH \
--host 0.0.0.0 \
--port 8000 \
--data-parallel-size 1 \
--tensor-parallel-size 2 \
--seed 1024 \
--quantization ascend \
--served-model-name qwen3.5 \
--max-num-seqs 32 \
--max-model-len 133000 \
--max-num-batched-tokens 16384 \
--trust-remote-code \
--gpu-memory-utilization 0.90 \
--no-enable-prefix-caching \
--speculative-config '{"method": "qwen3_5_mtp", "num_speculative_tokens": 3, "enforce_eager": true}' \
--compilation-config '{"cudagraph_mode":"FULL_DECODE_ONLY"}' \
--additional-config '{"enable_cpu_binding":true}'
启动命令:
#!/bin/sh
# Load model from ModelScope to speed up download
export MODEL_PATH=Eco-Tech/Qwen3.6-27B-w8a8
export VLLM_USE_MODELSCOPE=True
export HCCL_BUFFSIZE=512
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
# To reduce memory fragmentation and avoid out of memory
# Size of the shared buffer (in MB) used by HCCL for NPU-to-NPU collective communication
# Model weight path; can be a ModelScope model id (e.g., Eco-Tech/Qwen3.6-27B-w8a8) or a local directory path
# Ensure the model path matches the directory recorded during download
vllm serve $MODEL_PATH \
--host 0.0.0.0 \
--port 8000 \
--data-parallel-size 1 \
--tensor-parallel-size 2 \
--seed 1024 \
--quantization ascend \
--served-model-name qwen3.6 \
--max-num-seqs 32 \
--max-model-len 262144 \
--max-num-batched-tokens 16384 \
--trust-remote-code \
--gpu-memory-utilization 0.90 \
--no-enable-prefix-caching \
--speculative-config '{"method": "qwen3_5_mtp", "num_speculative_tokens": 3, "enforce_eager": true}' \
--compilation-config '{"cudagraph_mode":"FULL_DECODE_ONLY"}' \
--additional-config '{"enable_cpu_binding":true}'
关键参数说明:
- `--data-parallel-size 1` 和 `--tensor-parallel-size 2` 是数据并行(DP)和张量并行(TP)大小的常见设置。
- `--max-model-len` 表示上下文长度,即单个请求的输入加输出的最大值。Qwen3.6-27B 模型最高支持 262144。
- `--max-num-seqs` 表示每个 DP 组允许处理的最大请求数。如果发送到服务的请求数超过该限制,超出的请求将保持等待状态,不会被调度。请注意,等待状态所花费的时间也会计入 TTFT 和 TPOT 等指标。因此,在测试性能时,通常建议 `--max-num-seqs` * `--data-parallel-size` >= 实际总并发数。
- `--max-num-batched-tokens` 表示模型在单个步骤中可处理的最大 token 数。目前,vLLM v1 调度默认启用 ChunkPrefill/SplitFuse,其含义为:
- (1) 如果请求的输入长度大于 `--max-num-batched-tokens`,将根据 `--max-num-batched-tokens` 拆分为多轮计算;
- (2) 解码请求优先调度,仅在存在可用容量时才调度 prefill 请求。
- 通常,如果将 `--max-num-batched-tokens` 设置为更大的值,整体延迟会更低,但对 HBM 内存(激活值占用)的压力会更大。
- `--gpu-memory-utilization` 表示 vLLM 将用于实际推理的 HBM 比例。其本质功能是计算可用的 kv_cache 大小。在预热阶段(在 vLLM 中称为 profile run),vLLM 会记录输入大小为 `--max-num-batched-tokens` 的推理过程中的峰值 HBM 内存使用量。随后,可用的 kv_cache 大小按以下公式计算:`--gpu-memory-utilization` * HBM 大小 - 峰值 HBM 内存使用量。因此,`--gpu-memory-utilization` 的值越大,可使用的 kv_cache 就越多。然而,由于预热阶段的 HBM 内存使用量可能与实际推理时不同(例如由于 EP 负载不均衡),将 `--gpu-memory-utilization` 设置得过高可能导致实际推理中出现 OOM(内存溢出)问题。默认值为 `0.9`。
- `--no-enable-prefix-caching` 在上面的示例中禁用了前缀缓存。对于具有长共享前缀的工作负载,可以使用 `--enable-prefix-caching --prefix-match-unit 16` 启用更细粒度的混合前缀匹配。匹配单元必须能整除每个 KV cache 组的块大小。更小的单元可以复用更多部分物理页,但代价是额外的哈希元数据、写时复制操作,以及在最终匹配边界处额外的一次 prefill 拆分。
- `--quantization ascend` 表示使用了量化。若要禁用量化,请移除此选项。
- `--speculative-config` 对 `Qwen3.5-27B` 和 `Qwen3.6-27B` 均使用 `qwen3_5_mtp`,因为它们共享相同的 MTP head 设计。
- `--compilation-config` 包含与 aclgraph 图模式相关的配置。最重要的配置是 `"cudagraph_mode"` 和 `"cudagraph_capture_sizes"`,其含义如下:
- `"cudagraph_mode"`:表示具体的图模式。目前支持 `"PIECEWISE"` 和 `"FULL_DECODE_ONLY"`。图模式主要用于降低算子调度开销。目前推荐 `"FULL_DECODE_ONLY"`。
- `"cudagraph_capture_sizes"`:表示不同级别的图模式。默认值为 `[1, 2, 4, 8, 16, 24, 32, 40,..., --max-num-seqs]`。在图模式下,不同级别图的输入是固定的,级别之间的输入会自动填充到下一级。目前推荐默认设置。仅在某些场景下,才需要单独设置该项以获得最佳性能。
目前仅支持 TP 场景。根据可用设备选择 TP=2 或 TP=4。将 MODEL_PATH 替换为 ModelScope 模型 ID 或本地目录路径。量化版本需要以 --quantization ascend 参数启动。
启动命令:
#!/bin/sh
# Load model from ModelScope to speed up download
export MODEL_PATH=Eco-Tech/Qwen3.5-27B-w8a8-mtp
export VLLM_USE_MODELSCOPE=True
# Model weight path; can be a ModelScope model id (e.g., Eco-Tech/Qwen3.5-27B-w8a8-mtp) or a local directory path
# Ensure the model path matches the directory recorded during download
vllm serve $MODEL_PATH \
--host 127.0.0.1 \
--port 8000 \
--tensor-parallel-size 4 \
--served-model-name qwen3.5 \
--max-num-seqs 128 \
--max-model-len 16384 \
--trust-remote-code \
--gpu-memory-utilization 0.90 \
--mamba-ssm-cache-dtype float16 \
--dtype float16 \
--speculative-config '{"method": "qwen3_5_mtp","num_speculative_tokens":1}' \
--compilation-config '{"cudagraph_mode": "FULL_DECODE_ONLY", "cudagraph_capture_sizes": [2,16]}' \
--additional-config '{"ascend_compilation_config": {"enable_npugraph_ex": false}}'
启动命令:
#!/bin/sh
# Load model from ModelScope to speed up download
export MODEL_PATH=Eco-Tech/Qwen3.6-27B-w8a8-310p
export VLLM_USE_MODELSCOPE=True
# Model weight path; can be a ModelScope model id (e.g., Eco-Tech/Qwen3.6-27B-w8a8) or a local directory path
# Ensure the model path matches the directory recorded during download
vllm serve $MODEL_PATH \
--host 127.0.0.1 \
--port 8000 \
--tensor-parallel-size 4 \
--served-model-name qwen3.6 \
--max-num-seqs 128 \
--max-model-len 16384 \
--trust-remote-code \
--gpu-memory-utilization 0.90 \
--mamba-ssm-cache-dtype float16 \
--dtype float16 \
--speculative-config '{"method": "qwen3_5_mtp","num_speculative_tokens":1}' \
--compilation-config '{"cudagraph_mode": "FULL_DECODE_ONLY", "cudagraph_capture_sizes": [2,16]}' \
--additional-config '{"ascend_compilation_config": {"enable_npugraph_ex": false}}'
Key Parameter Descriptions:
- `--tensor-parallel-size` 设置张量并行大小。根据可用设备选择 **TP=2** 或 **TP=4**。
- `--max-model-len` 表示上下文长度,即单次请求的输入加输出的最大值。请根据实际工作负载和可用内存进行配置;Qwen3.6-27B 模型最大支持 262144。
- `--max-num-seqs` 表示最大并发请求数。请按需配置——设置过高可能导致 OOM。
- `--gpu-memory-utilization` 表示 vLLM 将用于实际推理的 HBM 比例。请根据实际设备内存配置该值;设置过高可能导致 OOM。默认值为 `0.9`。
- `--mamba-ssm-cache-dtype` 设置 Mamba SSM 缓存的数据类型。在 Atlas 300I DUO 上,仅支持 `float16`。
- `--dtype float16` 必须在 Atlas 300I DUO 上设置。这些设备仅支持 FP16 数据类型。
- `--speculative-config` 对于 `Qwen3.5-27B` 和 `Qwen3.6-27B` 都使用 `qwen3_5_mtp`,因为它们共享相同的 MTP 头设计。在 Atlas 300I DUO 上,建议将 `num_speculative_tokens` 设置为 `1`。
- `--compilation-config` 包含与 aclgraph 图模式相关的配置。其中最重要的配置是 `"cudagraph_mode"` 和 `"cudagraph_capture_sizes"`,含义如下:
- `"cudagraph_mode"`:表示具体的图模式。目前支持 `"PIECEWISE"` 和 `"FULL_DECODE_ONLY"`。图模式主要用于降低算子分发开销。目前推荐使用 `"FULL_DECODE_ONLY"`。
- `"cudagraph_capture_sizes"`:表示不同级别的图模式。启用张量并行(TP)时,硬件 event-id 约束最多允许两个捕获大小(例如 `[1, 8]`)。启用 MTP 时,每个捕获大小按 `n * (num_speculative_tokens + 1)` 计算,其中 `n` 是未启用 MTP 时的捕获大小。例如,当 `num_speculative_tokens` 为 `1` 时,非 MTP 大小 `[1,2,4,8]` 变为 `[2,4,8,16]`。
- `--additional-config` 在 Atlas 300I DUO 上需要设置,其中包含 `"ascend_compilation_config": {"enable_npugraph_ex": false}`,因为该平台不支持 `enable_npugraph_ex`。
以下示例适用于 950DT 产品。量化版本需要 --quantization ascend。
启动命令:
#!/bin/sh
# Load model from ModelScope to speed up download
export MODEL_PATH=Eco-Tech/Qwen3.6-27B-w8a8-mxfp8
export VLLM_USE_MODELSCOPE=True
export HCCL_BUFFSIZE=512
export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True
# To reduce memory fragmentation and avoid out of memory
# Size of the shared buffer (in MB) used by HCCL for NPU-to-NPU collective communication
# Model weight path; can be a ModelScope model id (e.g., Eco-Tech/Qwen3.6-27B-w8a8-mxfp8) or a local directory path
# Ensure the model path matches the directory recorded during download
vllm serve $MODEL_PATH \
--host 0.0.0.0 \
--port 8000 \
--data-parallel-size 1 \
--tensor-parallel-size 1 \
--seed 1024 \
--quantization ascend \
--served-model-name qwen3.6 \
--max-num-seqs 32 \
--max-model-len 262144 \
--max-num-batched-tokens 16384 \
--trust-remote-code \
--gpu-memory-utilization 0.90 \
--no-enable-prefix-caching \
--speculative-config '{"method": "qwen3_5_mtp", "num_speculative_tokens": 3, "enforce_eager": true}' \
--compilation-config '{"cudagraph_mode":"FULL_DECODE_ONLY"}' \
--additional-config '{"enable_cpu_binding":true}'
关键参数说明:
--data-parallel-size 1和--tensor-parallel-size 1分别是数据并行(DP)和张量并行(TP)大小的常用设置。--max-model-len表示上下文长度,即单次请求的输入加输出的最大值。Qwen3.6-27B 模型最大支持 262144。--max-num-seqs表示每个 DP 组允许处理的最大请求数。如果发送到服务的请求数超过此限制,超出的请求将保持等待状态,不会被调度。请注意,等待状态花费的时间也会计入 TTFT 和 TPOT 等指标。因此,在测试性能时,通常建议--max-num-seqs*--data-parallel-size>= 实际总并发数。--max-num-batched-tokens表示模型单步可处理的最大 token 数。目前,vLLM v1 调度默认启用 ChunkPrefill/SplitFuse,这意味着:- (1) 如果请求的输入长度大于
--max-num-batched-tokens,则按--max-num-batched-tokens将输入分成多轮计算; - (2) 优先调度 Decode 请求,仅当有剩余容量时才调度 Prefill 请求。
- 通常,
--max-num-batched-tokens设置得越大,整体时延越低,但对 HBM 内存(激活值占用)的压力也越大。
- (1) 如果请求的输入长度大于
--gpu-memory-utilization表示 vLLM 将用于实际推理的 HBM 比例。其核心作用是计算可用的 kv_cache 大小。在预热阶段(vLLM 中称为 profile run),vLLM 会记录在输入大小为--max-num-batched-tokens的推理过程中的 HBM 峰值内存占用。可用 kv_cache 大小计算如下:--gpu-memory-utilization* HBM 大小 - HBM 峰值内存占用。因此,--gpu-memory-utilization的值越大,可用的 kv_cache 越多。但由于预热阶段的 HBM 内存占用可能与实际推理时不同(例如,由于 EP 负载不均衡),设置过高可能会导致实际推理时出现 OOM(内存不足)问题。默认值为0.9。--no-enable-prefix-caching表示禁用前缀缓存。Qwen3.6-27B 当前的混合 kv cache 实现可能会导致启用前缀缓存时实际的block_size非常大(例如 2048),这意味着任何短于block_size的前缀都不会被缓存。如果工作负载中有大量较短且重复的前缀,请考虑保持禁用前缀缓存。相关问题请参阅常见问题。--quantization ascend表示使用量化。要禁用量化,请移除该选项。--speculative-config对Qwen3.6-27B使用qwen3_5_mtp,因为它与Qwen3.5-27B共享相同的 MTP 头设计。--compilation-config包含与 aclgraph 图模式相关的配置。其中最重要的配置是"cudagraph_mode"和"cudagraph_capture_sizes",含义如下:"cudagraph_mode":表示具体的图模式。目前支持"PIECEWISE"和"FULL_DECODE_ONLY"。图模式主要用于降低算子分发开销。目前推荐使用"FULL_DECODE_ONLY"。"cudagraph_capture_sizes":表示不同级别的图模式。默认值为[1, 2, 4, 8, 16, 24, 32, 40,..., --max-num-seqs]。在图模式下,不同级别图的输入是固定的,级别之间的输入会自动填充到下一级别。目前推荐使用默认设置。仅在部分场景下需要单独设置以获得最佳性能。
常见问题提示:如果遇到问题,请参阅 公共 FAQ 进行故障排除。
服务验证:
如果服务启动成功,将显示以下启动日志:
(APIServer pid=<pid>) INFO: Started server process [<pid>]
(APIServer pid=<pid>) INFO: Waiting for application startup.
(APIServer pid=<pid>) INFO: Application startup complete.
有关功能测试(例如,带预期响应的 completions 和 chat.completions curl 示例),请参阅第 6 节。
5.2 多节点 PD 分离部署¶
Note
多节点 PD 分离部署在 Atlas 300I DUO 上不受支持。
对于高并发生产场景,可以使用多节点 PD(Prefill-Decode)分离来扩展服务。推荐使用 Mooncake 进行部署:Mooncake 多节点 PD 分离指南。
在标准的单节点部署模式下,Prefill(提示处理)和 Decode(令牌生成)任务运行在同一组 NPU 上。这可能导致两个问题:
- Prefill 抢占中断 Decode:Prefill 是一项计算密集型任务,一次性处理整个输入上下文,而 Decode 逐个生成令牌。当新的用户请求到达时,其 Prefill 阶段会抢占并中断正在进行的 Decode 任务,导致抖动和更高的每输出令牌时间(TPOT)延迟。
- 资源分配不灵活:Prefill 和 Decode 具有根本不同的计算特征——Prefill 受计算限制且对内存带宽要求高,而 Decode 受内存带宽限制。将它们运行在同一硬件上会迫使二者妥协,无法使任何一方达到最优。
PD(Prefill-Decode)分离通过在专用的节点组上分别运行 Prefill 和 Decode 来解决这些问题,每个节点组独立配置:
- Prefill 节点专注于高吞吐量的提示处理,针对计算和通信进行了优化(例如,启用序列并行以实现 Allreduce 加速)。
- Decode 节点专注于低延迟的令牌生成,针对内存带宽进行了优化(例如,启用 full-decode aclgraph)。
对于 Qwen3.5-27B-w8a8 和 Qwen3.6-27B-w8a8,典型的 1P1D 配置需要 2 个 Atlas 800 A3(64GB × 16)节点(1 个 Prefill 节点 + 1 个 Decode 节点),每个节点上 TP=2 和 DP=8,这充分利用了 Atlas A3 的全部 16 个 NPU。下面的示例使用 Qwen3.5-27B-w8a8;对于 Qwen3.6-27B-w8a8,请将模型路径替换为 Eco-Tech/Qwen3.6-27B-w8a8,并将 --served-model-name 调整为 qwen3.6(如有需要,--max-model-len 可调整为 262144)。
为什么是 TP=2 + DP=8(DP 优先策略)?
Qwen3.5-27B-w8a8(以及Qwen3.6-27B-w8a8)模型仅约 30 GB,可以轻松放入单个 NPU(每个 NPU 有 64 GB HBM)。TP > 1 主要用于无法放入单个 NPU 的模型。 对于 27 B 的模型,TP=2足以在 NPU 之间平衡算子分发开销,同时 最大化 DP 可让 Atlas A3 的全部 16 个 NPU 忙于处理独立的请求批次,从而充分利用硬件。这种 DP 优先的并行策略 是小型稠密模型(例如 Qwen3.5-27B、Qwen3.6-27B、Llama-3-8B)的标准做法,并已通过 Qwen3.5-27B B200 基准测试 验证,其中从 TP=8 切换到 DP=8 后,单节点吞吐量从 9.5k 提升到 95k tokens/s。注意:由于
Qwen3.5-27B和Qwen3.6-27B适合在单个节点上运行,多节点 PD 分离仅推荐用于高并发生产部署。有关 Mooncake 部署的具体信息,请参阅 Mooncake 多节点 PD 分离指南。
要运行 vllm-ascend Prefill-Decode 分离服务,您需要:
- 在每个节点上部署
launch_online_dp.py脚本和run_dp_template.sh脚本; -
在 prefill 主节点上部署
load_balance_proxy_server_example.py脚本以转发请求。 -
launch_online_dp.py用于启动外部 dp vllm 服务器。 launch_online_dp.py参数说明:
参数 类型 是否必填 默认值 描述 --dp-sizeint 是 - 数据并行大小(所有节点上 DP rank 的总数)。 --tp-sizeint 否 1 每个 DP rank 内的张量并行大小。 --dp-size-localint 否 (与 --dp-size相同)当前节点上的 DP rank 数量。如果未设置,默认值为 --dp-size。--dp-rank-startint 否 0 此节点上数据并行 rank 的起始 rank 偏移量。 --dp-addressstr 是 - 数据并行主节点(节点 0)的 IP 地址。 --dp-rpc-portstr 否 12345 用于数据并行主节点通信的 RPC 端口。 --vllm-start-portint 否 9000 此节点上每个 vLLM 引擎实例的起始端口。每个 DP rank 的引擎端口 = vllm_start_port+ 本地 rank 索引。 -
Prefill 节点 0 的
run_dp_template.sh脚本。您可以在仓库的 examples 目录中获取该模板:run_dp_template.sh。# nic_name is the network interface name corresponding to local_ip of the current node nic_name="xxx" local_ip="192.xx.xx.1" export HCCL_BUFFSIZE=1024 export HCCL_IF_IP=$local_ip export HCCL_OP_EXPANSION_MODE="AIV" export HCCL_SOCKET_IFNAME=$nic_name export ASCEND_RT_VISIBLE_DEVICES=$1 export LD_LIBRARY_PATH=/usr/local/Ascend/ascend-toolkit/latest/python/site-packages/mooncake:$LD_LIBRARY_PATH export GLOO_SOCKET_IFNAME=$nic_name export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True # [Optional] jemalloc # jemalloc is for better performance, if `libjemalloc.so` is installed on your machine, you can turn it on. # export LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libjemalloc.so.2:$LD_PRELOAD # Ensure the model path matches the directory recorded during download vllm serve Eco-Tech/Qwen3.5-27B-w8a8-mtp \ --host 0.0.0.0 \ --port $2 \ --data-parallel-size $3 \ --data-parallel-rank $4 \ --data-parallel-address $5 \ --data-parallel-rpc-port $6 \ --tensor-parallel-size $7 \ --seed 1024 \ --quantization ascend \ --served-model-name qwen3.5 \ --trust-remote-code \ --max-num-seqs 4 \ --max-model-len 32768 \ --max-num-batched-tokens 16384 \ --no-enable-prefix-caching \ --gpu-memory-utilization 0.95 \ --enforce-eager \ --speculative-config '{"method": "qwen3_5_mtp", "num_speculative_tokens": 3, "enforce_eager": true}' \ --additional-config '{"enable_cpu_binding":true}' \ --kv-transfer-config \ '{"kv_connector": "MooncakeConnectorV1", "kv_role": "kv_producer", "kv_port": "30000", "engine_id": "0", "kv_connector_extra_config": { "prefill": { "dp_size": 8, "tp_size": 2 }, "decode": { "dp_size": 8, "tp_size": 2 } } }' -
解码节点 0 的
run_dp_template.sh脚本。您可以在仓库的 examples 目录中获取该模板:run_dp_template.sh。# nic_name is the network interface name corresponding to local_ip of the current node nic_name="xxx" local_ip="192.xx.xx.2" export HCCL_BUFFSIZE=1024 export HCCL_IF_IP=$local_ip export HCCL_OP_EXPANSION_MODE="AIV" export HCCL_SOCKET_IFNAME=$nic_name export ASCEND_RT_VISIBLE_DEVICES=$1 export LD_LIBRARY_PATH=/usr/local/Ascend/ascend-toolkit/latest/python/site-packages/mooncake:$LD_LIBRARY_PATH export GLOO_SOCKET_IFNAME=$nic_name export PYTORCH_NPU_ALLOC_CONF=expandable_segments:True # [Optional] jemalloc # jemalloc is for better performance, if `libjemalloc.so` is installed on your machine, you can turn it on. # export LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libjemalloc.so.2:$LD_PRELOAD # Ensure the model path matches the directory recorded during download vllm serve Eco-Tech/Qwen3.5-27B-w8a8-mtp \ --host 0.0.0.0 \ --port $2 \ --data-parallel-size $3 \ --data-parallel-rank $4 \ --data-parallel-address $5 \ --data-parallel-rpc-port $6 \ --tensor-parallel-size $7 \ --seed 1024 \ --quantization ascend \ --served-model-name qwen3.5 \ --trust-remote-code \ --max-num-seqs 16 \ --max-model-len 32768 \ --max-num-batched-tokens 2048 \ --no-enable-prefix-caching \ --gpu-memory-utilization 0.91 \ --compilation-config '{"cudagraph_mode":"FULL_DECODE_ONLY"}' \ --additional-config '{"recompute_scheduler_enable":true,"enable_cpu_binding":true}' \ --speculative-config '{"method": "qwen3_5_mtp", "num_speculative_tokens": 3, "enforce_eager": true}' \ --kv-transfer-config \ '{"kv_connector": "MooncakeConnectorV1", "kv_role": "kv_consumer", "kv_port": "30200", "engine_id": "1", "kv_connector_extra_config": { "prefill": { "dp_size": 8, "tp_size": 2 }, "decode": { "dp_size": 8, "tp_size": 2 } } }'
关键参数说明:
recompute_scheduler_enable: true:启用重计算调度器。当解码节点的 KV Cache 不足时,请求将被发送到预填充节点以重新计算 KV Cache。在 PD 分离场景中,仅在解码节点上启用此配置。-
--compilation-config '{"cudagraph_mode":"FULL_DECODE_ONLY"}'(在解码节点上):启用完整解码 aclgraph 模式,可显著降低解码侧的调度延迟。 -
为每个节点运行服务器:
# p0 (Prefill node 0) python launch_online_dp.py --dp-size 8 --tp-size 2 --dp-size-local 8 --dp-rank-start 0 --dp-address 192.xx.xx.1 --dp-rpc-port 12321 --vllm-start-port 7100 # d0 (Decode node 0) python launch_online_dp.py --dp-size 8 --tp-size 2 --dp-size-local 8 --dp-rank-start 0 --dp-address 192.xx.xx.2 --dp-rpc-port 12321 --vllm-start-port 7100 -
在预填充主节点上运行代理服务器。
您可以在仓库的 examples 目录中获取代理程序:load_balance_proxy_server_example.py。
注意:由于每个节点有 8 个 DP rank(使用
--vllm-start-port 7100+ 本地 rank 索引,占用端口 7100-7107),您需要在代理命令中为每个节点列出全部 8 个端口:python load_balance_proxy_server_example.py \ --port 8000 \ --host 192.xx.xx.1 \ --prefiller-hosts \ 192.xx.xx.1 \ 192.xx.xx.1 \ 192.xx.xx.1 \ 192.xx.xx.1 \ 192.xx.xx.1 \ 192.xx.xx.1 \ 192.xx.xx.1 \ 192.xx.xx.1 \ --prefiller-ports \ 7100 7101 7102 7103 7104 7105 7106 7107 \ --decoder-hosts \ 192.xx.xx.2 \ 192.xx.xx.2 \ 192.xx.xx.2 \ 192.xx.xx.2 \ 192.xx.xx.2 \ 192.xx.xx.2 \ 192.xx.xx.2 \ 192.xx.xx.2 \ --decoder-ports \ 7100 7101 7102 7103 7104 7105 7106 7107
部署验证:
在 PD 分离服务完全启动后,通过预填充主节点上的代理端口发送请求,以验证 Prefill 和 Decode 节点是否协同正常工作:
curl http://<proxy_node0_ip>:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3.5",
"messages": [
{"role": "user", "content": "The future of AI is"}
],
"max_tokens": 1024,
"temperature": 1.0,
"top_p": 0.95
}'
注意:对于
Qwen3.6-27B-w8a8,将上述model字段更改为"qwen3.6",并将 Prefill/Decode 节点的--served-model-name更改为qwen3.6。
预期结果:代理返回 HTTP 200 OK。JSON 响应包含带有生成文本的 choices 字段,确认 Prefill 节点已成功处理提示词,Decode 节点已生成响应。
常见问题提示:如果在 PD 分离部署中遇到问题,请参阅 公共常见问题 进行排查。
6 功能验证¶
服务启动后,可以通过发送提示词来调用模型。支持两个 API 接口:completions 和 chat.completions。请使用您配置的 --served-model-name(Qwen3.5-27B 使用 qwen3.5,Qwen3.6-27B 使用 qwen3.6)。
Completions API:
curl http://localhost:8000/v1/completions \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3.5",
"prompt": "The future of AI is",
"max_tokens": 50,
"temperature": 0
}'
注意:对于
Qwen3.6-27B,请在请求体中设置"model": "qwen3.6"。
Chat Completions API:
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3.5",
"messages": [
{"role": "user", "content": "The future of AI is"}
],
"max_completion_tokens": 1024,
"temperature": 0.7,
"top_p": 0.95
}'
注意:对于
Qwen3.6-27B,请在请求体中设置"model": "qwen3.6"。
预期结果:服务返回 HTTP 200 OK。JSON 响应包含带有生成文本的 choices 字段。completions API 的示例输出(为简洁起见,内容已截断):
{
"id": "cmpl-xxxxxxxxxxxxx",
"object": "text_completion",
"created": 1780971952,
"model": "qwen3.5",
"choices": [
{
"index": 0,
"text": "The future of AI is a rapidly evolving landscape with breakthroughs in natural language understanding, multimodal reasoning, and autonomous agents. As models grow more capable and efficient...",
"logprobs": null,
"finish_reason": "length"
}
],
"usage": {
"prompt_tokens": 4,
"total_tokens": 54,
"completion_tokens": 50
}
}
7 精度评估¶
以下是两种精度评估方法。
7.1 使用 AISBench¶
-
详情请参见 使用 AISBench。
-
执行后,您可以获取结果。以下是
Qwen3.5-27B-w8a8在vllm-ascend:v0.17.0rc1中的结果,仅供参考。Qwen3.6-27B-w8a8的精度结果可以以相同方式获取,此处不再列出。
精度评估配置文件:
# Example configuration: benchmarks/ais_bench/benchmark/configs/models/vllm_api/vllm_api_general_chat.py
from ais_bench.benchmark.models import VLLMCustomAPIChat
from ais_bench.benchmark.utils.model_postprocessors import extract_non_reasoning_content
models = [
dict(
attr="service",
type=VLLMCustomAPIChat,
abbr="vllm-api-general-chat",
path="your_model_path",
model="qwen3.5",
request_rate=0,
retry=2,
host_ip="127.0.0.1",
host_port=8000,
max_out_len=32768,
batch_size=32,
trust_remote_code=False,
generation_kwargs=dict(
temperature=1.0,
top_p=0.95,
top_k=20,
min_p=0.0,
presence_penalty=1.5,
repetition_penalty=1.0,
ignore_eos=False,
),
pred_postprocessor=dict(type=extract_non_reasoning_content)
)
]
对于
Qwen3.6-27B-w8a8,请将model更改为qwen3.6,并将path更改为对应的模型权重路径。
| 数据集 | 版本 | 指标 | 模式 | vllm-api-general-chat |
|---|---|---|---|---|
| gsm8k | - | accuracy | gen | 96.74 |
7.2 使用 Language Model Evaluation Harness¶
以 gsm8k 数据集作为示例测试数据集,在在线模式下运行 Qwen3.5-27B-w8a8 的精度评估。
- 关于
lm_eval的安装,请参见 使用 lm_eval。 - 运行
lm_eval执行精度评估。
# For Qwen3.5-27B-w8a8
export VLLM_USE_MODELSCOPE=True
vllm serve Eco-Tech/Qwen3.5-27B-w8a8-mtp \
--served-model-name qwen3.5 \
--trust-remote-code \
--quantization ascend \
--tensor-parallel-size 2 \
--max-model-len 133000 \
--max-num-seqs 32 \
--gpu-memory-utilization 0.90 \
--no-enable-prefix-caching
# Run lm_eval in another terminal
lm_eval \
--model local-completions \
--model_args model=qwen3.5,base_url=http://127.0.0.1:8000/v1/completions,tokenized_requests=False,trust_remote_code=True \
--tasks gsm8k \
--output_path ./
8 性能评估¶
8.1 使用 AISBench¶
详情请参见 使用 AISBench 进行性能评估。
8.2 使用 vLLM Benchmark¶
以运行 Qwen3.5-27B-w8a8 或 Qwen3.6-27B-w8a8 的性能评估为例。
更多详情请参见 vllm benchmark。
vllm bench 有三个子命令:
latency:基准测试单个请求批次的延迟。serve:基准测试在线服务吞吐量。throughput:基准测试离线推理吞吐量。
以 serve 为例,按如下方式运行代码。
export VLLM_USE_MODELSCOPE=True
# For Qwen3.5-27B-w8a8:
vllm bench serve --model Eco-Tech/Qwen3.5-27B-w8a8-mtp --dataset-name random --random-input 200 --num-prompts 200 --request-rate 1 --save-result --result-dir ./
# For Qwen3.6-27B-w8a8:
vllm bench serve --model Eco-Tech/Qwen3.6-27B-w8a8 --dataset-name random --random-input 200 --num-prompts 200 --request-rate 1 --save-result --result-dir ./
大约几分钟后,您可以获取性能评估结果。
9 性能调优¶
9.1 推荐配置¶
注意:以下配置已在特定测试环境中验证,仅供参考。最优配置取决于最大输入/输出长度、前缀缓存命中率、精度要求以及部署机器比例等因素。建议根据实际条件参考 第 9.2 节 进行调优。
并行策略:
Qwen3.5-27B-w8a8和Qwen3.6-27B-w8a8仅 ~30 GB,可以轻松放入单个 NPU(每个 NPU 64 GB HBM)。遵循 DP 优先 原则,在大多数场景中,TP=2 是推荐默认值,其余 NPU 应分配给 DP,用于并行处理请求批次。TP=8 仅推荐用于超长上下文(256k+)场景,此时它会将 KV 缓存分片到 8 个 NPU 上,以最大化每个 rank 可用的上下文窗口。对于Qwen3.6-27B-w8a8,在相同的 TP/DP 布局下,您还可以将--max-model-len提高到 262144。Atlas 300I DUO:目前仅支持 TP 场景。根据可用设备选择 TP=2 或 TP=4。使用 TP=4 时,
--max-model-len可支持 128k 和 256k 长序列场景;请根据需要配置--max-num-seqs——设置过高可能导致 OOM。950DT 产品:
Qwen3.6-27B-w8a8-mxfp8模型权重可以轻松放入单个 NPU(每个 NPU 96 GB HBM)。遵循 DP 优先 原则,在大多数场景中,TP=1 是推荐默认值,其余 NPU 应分配给 DP,用于并行处理请求批次。对于Qwen3.6-27B-w8a8-mxfp8,在相同的 TP=1 + DP=8 布局下,--max-model-len最高可支持 262144。
表 1:场景概览¶
| 场景 | 部署模式 | *总 NPU 数量 | 权重版本 | 关键考量 |
|---|---|---|---|---|
| 高吞吐 (128k 上下文) |
单节点(A2) | 8(A2) | Qwen3.5-27B-w8a8 / Qwen3.6-27B-w8a8 | TP=2 + DP=4 充分利用全部 8 个 NPU 处理并行请求批次 |
| 高吞吐 (128k 上下文) |
单节点(A3) | 16(A3) | Qwen3.5-27B-w8a8 / Qwen3.6-27B-w8a8 | TP=2 + DP=8 充分利用全部 16 个 NPU 处理并行请求批次 |
| 低延迟 (128k 上下文) |
单节点(A3) | 16(A3) | Qwen3.5-27B-w8a8 / Qwen3.6-27B-w8a8 | TP=2 + DP=8 降低小交互式批次的逐层 Allreduce 开销 |
| 长上下文 (256k+ 上下文) |
单节点(A3) | 16(A3) | Qwen3.5-27B-w8a8 / Qwen3.6-27B-w8a8 | TP=8 + DP=2 将 KV 缓存分片到 8 个 NPU 上,以最大化可用上下文窗口 |
| 高吞吐 (128k 上下文) |
单节点(950DT Products) | 8(950DT Products) | Qwen3.6-27B-w8a8-mxfp8 | TP=1 + DP=8 充分利用全部 8 个 NPU 处理并行请求批次 |
| 长上下文 (256k+ 上下文) |
单节点(950DT Products) | 8(950DT Products) | Qwen3.6-27B-w8a8-mxfp8 | TP=1 + DP=8 在保持全部 8 个 NPU 忙碌的同时最大化可用上下文窗口 |
*Total NPUs表示所有节点使用的 NPU 总数。1 个 Atlas 800 A3 节点 = 16 个 NPU,1 个 Atlas 800 A2 节点 = 8 个 NPU,1 个 950DT Products 节点 = 8 个 NPU。
表 2:详细节点配置¶
| 场景 | 配置 | NPU 数量 | TP | DP | 最大序列数 | 最大批处理 Token 数 | 最大模型长度 | MTP 推测数量 | 异步调度 |
|---|---|---|---|---|---|---|---|---|---|
| 高吞吐(128k) | 单节点(A2) | 8 | 2 | 4 | 32 | 16384 | 133000 | 3 | 开启 |
| 高吞吐(128k) | 单节点(A3) | 16 | 2 | 8 | 32 | 16384 | 133000 | 3 | 开启 |
| 低延迟(128k) | 单节点(A3) | 16 | 2 | 8 | 4 | 4096 | 133000 | 3 | 开启 |
| 长上下文(256k+) | 单节点(A3) | 16 | 8 | 2 | 8 | 8192 | 262144 | 3 | 开启 |
| 高吞吐(128k) | 单节点(950DT Products) | 8 | 1 | 8 | 32 | 16384 | 133000 | 3 | 开启 |
| 长上下文(256k+) | 单节点(950DT Products) | 8 | 1 | 8 | 32 | 16384 | 262144 | 3 | 开启 |
完整的启动命令和参数说明,请参阅 第 5 章 中的部署示例。
9.2 调优指南¶
9.2.1 通用调优参考¶
请参阅 公开性能调优文档 了解调优方法。 请参阅 功能矩阵 了解详细功能说明。
10 常见问题¶
对于常见的环境、安装和通用参数问题,请参阅 公开常见问题。
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 vl/vllm-ascend