跳转至

DeepSeek-V4.1-Flash

1 简介

Note

The "PD Separation Deployment" mentioned in this document is provided only as an example/reference design to demonstrate the basic process of deploying Prefill and Decode in separated mode. It is not recommended for use in the production environment.

For the production environment on the customer side, MindIE Motor + vLLM-Ascend is recommended.

DeepSeek-V4.1-Flash 是一个原生多模态混合专家(MoE)模型,主干参数量为 552B,上下文长度最高可达 一百万个 token。它采用 40 层因果编码器-解码器(CED)架构,包含 20 层因果编码器 层和 20 层解码器层,在 Prefill 阶段每个 token 激活 8B 参数,在 Decode 阶段激活 16B 参数。

该模型引入了压缩稀疏注意力 2(CSA2)、FP4 主 KV 缓存、SWA 有界重放、 单遍 mHC、Engram 条件记忆以及 DSpark 投机解码。这些设计将全局 KV 缓存占用 降低至每个 token 890 字节,并将持久化 KV 缓存占用降低至 DeepSeek-V4-Flash 的 约八分之一。该模型接受文本和图像输入,并支持从 1 到 100 连续可调的推理强度。

vLLM Ascend 支持在 Atlas 800 A3 和 A2 服务器上进行 W8A8 部署。本指南提供了单节点共置 A3 配置和双节点 A3 Prefill-Decode(PD)分离配置。

DeepSeek-V4.1-Flash support requires the main branch of vLLM Ascend and an upstream vLLM revision dated September 11, 2026 or later. Development builds use the verified main revision recorded in .github/vllm-main-verified.commit. Release builds use the tag recorded in .github/vllm-release-tag.commit (currently v0.31.0). These are separate supported upstream revisions.

2 支持的特性

完整支持矩阵请参阅支持的模型, 特性配置请参阅特性指南。

本指南中的 A3 配置使用 W8A8 权重和 INT8 Engram 存储。单节点共置配置使用 DP4/TP4。PD 配置在 Prefill 节点上使用 DP4/TP4,在 Decode 节点上使用 DP8/TP2、DSpark 推测解码,并在 Decode 上使用 FULL_DECODE_ONLY ACL Graph。DeepSeek-V4.1-Flash 模型目前在昇腾上仅支持模型运行器 V1,因此所有 A3 脚本都显式设置 VLLM_USE_V2_MODEL_RUNNER=0。

3 前提条件

3.1 模型权重与硬件

官方 DeepSeek-V4.1-Flash 权重可从 Hugging Face 和 ModelScope 获取。

本指南使用的昇腾 W8A8 检查点将发布为 ModelScope 上的 Eco-Tech/DeepSeek-V4.1-Flash-w8a8。它包含 DSpark 草稿参数和 INT8 Engram 表。检查点可用后,将其下载到每台服务器上的相同绝对路径,并替换每个服务命令中的检查点路径占位符。

或者,使用 ModelSlim 从官方权重 准备兼容 ModelSlim 的 W8A8 权重。

使用以下硬件配置之一:

  • A3 单节点共置:一台 Atlas 800 A3 服务器,配备 8 个 NPU,每个 NPU 128GB 内存。该服务器向容器暴露 16 个逻辑设备。
  • A3 1P1D:两台 Atlas 800 A3 服务器,设备配置相同。
  • A2 系列:四台 Atlas 800 A2 服务器。每台服务器配备 8 个 NPU,每个 NPU 64GB 内存,并向容器暴露 8 个设备。其部署配置在本次更新中保持不变。

将权重存储在共享目录中,或将其复制到每台服务器上的相同绝对路径。

3.2 验证多节点通信

部署前,请遵循 验证多节点通信。 所有服务器必须能够通过所选的网络接口进行通信,且服务端口不得被阻塞。

4 安装

4.1 Docker 镜像安装

选择目标硬件对应的标签页。A2 和 A3 使用不同的验证镜像。

一台 A3 服务器暴露 16 个逻辑设备。在每台 A3 服务器上运行此命令。

export IMAGE=quay.io/ascend/vllm-ascend:deepseek-v4.1-flash-a3
export MODEL_ROOT="/data/weights"

docker pull "$IMAGE"

docker run --rm -it \
  --name deepseek-v41 \
  --net=host \
  --ipc=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 "$MODEL_ROOT:$MODEL_ROOT" \
  "$IMAGE" bash

一台 A2 服务器暴露 8 个设备。在全部四台 A2 服务器上运行此命令。

export IMAGE=quay.io/ascend/vllm-ascend:deepseek-v4.1-flash
export MODEL_ROOT="/data/weights"

docker pull "$IMAGE"

docker run --rm -it \
  --name deepseek-v41 \
  --net=host \
  --shm-size=512g \
  --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 "$MODEL_ROOT:$MODEL_ROOT" \
  "$IMAGE" bash

如果权重存储在其他位置,请修改 MODEL_ROOT。请确保每个容器内外使用相同的 绝对路径。

4.2 源码安装

如需从源码构建,请遵循 软件环境安装指南, 并使用 main 分支以及记录在 .github/vllm-main-verified.commit 中的匹配 vLLM 版本。

5 在线服务部署

5.1 单节点共置部署

此配置在一台 Atlas 800 A3 服务器上运行 Prefill 和 Decode。它在全部 16 个逻辑设备上使用 DP4/TP4、专家并行、Engram 主机卸载、异步调度以及 FULL_DECODE_ONLY ACL Graph。

将 MODEL_PATH 设置为本地检查点路径。

#!/usr/bin/env bash

MODEL_PATH="<YOUR_MODEL_PATH>"

export VLLM_USE_V2_MODEL_RUNNER=0
export VLLM_ENGINE_READY_TIMEOUT_S=36000

export HCCL_BUFFSIZE=1024
export HCCL_OP_EXPANSION_MODE="AIV"

# Ensure the model path matches the directory recorded during download
vllm serve "$MODEL_PATH" \
    --host 0.0.0.0 \
    --port 8900 \
    --max-model-len 150000 \
    --max-num-batched-tokens 8192 \
    --served-model-name dsv41 \
    --gpu-memory-utilization 0.9 \
    --max-num-seqs 32 \
    --data-parallel-size 4 \
    --tensor-parallel-size 4 \
    --enable-expert-parallel \
    --tokenizer-mode deepseek_v41 \
    --reasoning-parser deepseek_v41 \
    --tool-call-parser deepseek_v41 \
    --enable-auto-tool-choice \
    --safetensors-load-strategy lazy \
    --model-loader-extra-config '{"enable_multithread_load":true,"num_threads":128}' \
    --quantization ascend \
    --block-size 128 \
    --compilation-config '{"cudagraph_mode":"FULL_DECODE_ONLY"}' \
    --async-scheduling \
    --engram-config '{"cpu_offload":true,"dp_shared_memory":true}' \
    --additional-config '{
        "ascend_compilation_config":{
            "enable_npugraph_ex":true,
            "enable_static_kernel":false
        },
        "enable_cpu_binding":true,
        "enable_fused_mc2":1,
        "enable_dsa_cp":true,
        "enable_flashcomm1":true,
        "enable_shared_expert_dp":true
    }'

关键参数:

  • --max-model-len 150000 限制单个请求的总输入和输出长度。--max-num-batched-tokens 8192 限制单次迭代中调度的 token 数,而 --max-num-seqs 32 限制每个 DP 引擎调度的序列数。提高任一调度器限制可以提高吞吐量,但也会增加内存使用量。
  • VLLM_ENGINE_READY_TIMEOUT_S=36000 允许引擎进程最多 36,000 秒完成初始化,包括权重加载和图准备。
  • VLLM_USE_V2_MODEL_RUNNER=0 显式选择模型运行器 V1。请将此值保持为 0,因为 DeepSeek-V4.1-Flash 目前在昇腾上不支持模型运行器 V2。
  • --engram-config '{"cpu_offload":true,"dp_shared_memory":true}' 将 Engram 表保留在主机内存中,并让本地 DP rank 共享主机内存分配。这在 A3 上是必需的,因为模型的 24 个 Engram 头无法在 16 个逻辑设备上均匀分配。它还能减少重复的主机内存副本。A3 容器示例使用 --ipc=host,以便所有四个本地 DP rank 共享主机 IPC 命名空间。
  • --compilation-config '{"cudagraph_mode":"FULL_DECODE_ONLY"}' 捕获 Decode 路径,而 Prefill 保持在捕获图之外。
  • --safetensors-load-strategy lazy 避免在加载期间急切地物化整个检查点。
  • enable_fused_mc2、enable_dsa_cp、enable_flashcomm1 和 enable_shared_expert_dp 启用此配置使用的 A3 MoE 和通信优化。enable_cpu_binding 将工作进程绑定到 CPU,而 enable_npugraph_ex 启用增强的 ACL Graph 路径。

5.2 1P1D PD 分离部署

此示例使用两台 Atlas 800 A3 服务器。Prefill 节点运行四个 DP rank,使用 TP4(DP4/TP4),Decode 节点运行八个 DP rank,使用 TP2(DP8/TP2)。两种布局都消耗各自服务器上的全部 16 个逻辑设备。Mooncake 将 KV 缓存从 Prefill 引擎传输到 Decode 引擎。

5.2.1 准备 DP 启动器

将以下脚本保存为两个节点上的 launch_online_dp.py。它将节点的可见设备分配给本地 DP rank,并为每个 rank 启动一个 vLLM 进程。

import argparse
import multiprocessing
import os
import subprocess
import sys


def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument("--dp-size", type=int, required=True)
    parser.add_argument("--tp-size", type=int, default=1)
    parser.add_argument("--dp-size-local", type=int, default=-1)
    parser.add_argument("--dp-rank-start", type=int, default=0)
    parser.add_argument("--dp-address", type=str, required=True)
    parser.add_argument("--dp-rpc-port", type=str, default="12345")
    parser.add_argument("--vllm-start-port", type=int, default=9000)
    return parser.parse_args()


args = parse_args()
dp_size = args.dp_size
tp_size = args.tp_size
dp_size_local = args.dp_size if args.dp_size_local == -1 else args.dp_size_local


def run_command(visible_devices, dp_rank, vllm_engine_port):
    command = [
        "bash",
        "./run_dp_template.sh",
        visible_devices,
        str(vllm_engine_port),
        str(dp_size),
        str(dp_rank),
        args.dp_address,
        args.dp_rpc_port,
        str(tp_size),
    ]
    subprocess.run(command, check=True)


if __name__ == "__main__":
    if not os.path.exists("./run_dp_template.sh"):
        print("Template file ./run_dp_template.sh does not exist.")
        sys.exit(1)

    processes = []
    for i in range(dp_size_local):
        dp_rank = args.dp_rank_start + i
        vllm_engine_port = args.vllm_start_port + i
        visible_devices = ",".join(
            str(device) for device in range(i * tp_size, (i + 1) * tp_size)
        )
        process = multiprocessing.Process(
            target=run_command,
            args=(visible_devices, dp_rank, vllm_engine_port),
        )
        processes.append(process)
        process.start()

    for process in processes:
        process.join()

启动器参数如下:

参数 描述
--dp-size Prefill 或 Decode 节点组内的全局 DP 大小。
--tp-size 每个 DP rank 使用的逻辑设备数量。
--dp-size-local 在当前节点上启动的 DP rank 数量。
--dp-rank-start 分配给此节点的第一个 DP rank。在此 1P1D 示例中,两个单节点组均为 0。
--dp-address 协调相应 DP 组的节点 IP 地址。在 Prefill 节点上使用 Prefill IP,在 Decode 节点上使用 Decode IP。
--dp-rpc-port DP 协调端口。它必须未被使用且在节点组内可访问。
--vllm-start-port 第一个 API 端口;启动器会为每个本地 DP rank 递增该端口。

5.2.2 启动 Prefill 节点

在 Prefill 节点上,将以下脚本保存为 run_dp_template.sh。将 LOCAL_IP、NIC_NAME 和 MODEL_PATH 设置为 Prefill 节点的服务 IP、网络接口和本地检查点路径。

#!/usr/bin/env bash

unset https_proxy
unset http_proxy
export LD_LIBRARY_PATH="${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}/usr/local/lib/"

NIC_NAME="<NETWORK_INTERFACE>"
LOCAL_IP="<PREFILL_NODE_IP>"
MODEL_PATH="<YOUR_MODEL_PATH>"

export HCCL_IF_IP="$LOCAL_IP"
export GLOO_SOCKET_IFNAME="$NIC_NAME"
export TP_SOCKET_IFNAME="$NIC_NAME"
export HCCL_SOCKET_IFNAME="$NIC_NAME"
export VLLM_USE_V2_MODEL_RUNNER=0
export VLLM_ENGINE_READY_TIMEOUT_S=36000
export HCCL_BUFFSIZE=1024
export HCCL_OP_EXPANSION_MODE="AIV"
export ASCEND_RT_VISIBLE_DEVICES=$1

# Ensure the model path matches the directory recorded during download
vllm serve "$MODEL_PATH" \
    --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 \
    --enable-expert-parallel \
    --seed 1024 \
    --served-model-name dsv41 \
    --max-model-len 1048576 \
    --max-num-batched-tokens 8192 \
    --max-num-seqs 16 \
    --speculative-config '{"num_speculative_tokens":5,"method":"dspark"}' \
    --trust-remote-code \
    --block-size 128 \
    --tokenizer-mode deepseek_v41 \
    --reasoning-parser deepseek_v41 \
    --tool-call-parser deepseek_v41 \
    --enable-auto-tool-choice \
    --model-loader-extra-config '{"enable_multithread_load":true,"num_threads":128}' \
    --safetensors-load-strategy lazy \
    --gpu-memory-utilization 0.9 \
    --quantization ascend \
    --enforce-eager \
    --enable-prefix-caching \
    --engram-config '{"cpu_offload":true,"dp_shared_memory":true}' \
    --additional-config '{
        "enable_cpu_binding":true,
        "enable_fused_mc2":1,
        "enable_dsa_cp":true,
        "enable_flashcomm1":true,
        "enable_shared_expert_dp":true
    }' \
    --kv-transfer-config '{
        "kv_connector":"MooncakeHybridConnector",
        "kv_role":"kv_producer",
        "kv_port":"30000",
        "engine_id":"0",
        "kv_connector_extra_config":{
            "prefill":{"dp_size":4,"tp_size":4},
            "decode":{"dp_size":8,"tp_size":2}
        }
    }'

启动四个 DP4/TP4 Prefill 引擎。--dp-address 使用 Prefill 节点 IP。

PREFILL_NODE_IP="<PREFILL_NODE_IP>"

python launch_online_dp.py \
    --dp-size 4 \
    --tp-size 4 \
    --dp-size-local 4 \
    --dp-rank-start 0 \
    --dp-address "$PREFILL_NODE_IP" \
    --dp-rpc-port 12321 \
    --vllm-start-port 7100

5.2.3 启动 Decode 节点

在 Decode 节点上,将以下脚本保存为 run_dp_template.sh。将 LOCAL_IP、NIC_NAME 和 MODEL_PATH 设置为 Decode 节点的服务 IP、 网络接口,以及与 Prefill 节点相同的本地权重路径。

#!/usr/bin/env bash

unset https_proxy
unset http_proxy
export LD_LIBRARY_PATH="${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}/usr/local/lib/"

NIC_NAME="<NETWORK_INTERFACE>"
LOCAL_IP="<DECODE_NODE_IP>"
MODEL_PATH="<YOUR_MODEL_PATH>"

export VLLM_USE_V2_MODEL_RUNNER=0
export VLLM_ENGINE_READY_TIMEOUT_S=36000
export HCCL_IF_IP="$LOCAL_IP"
export GLOO_SOCKET_IFNAME="$NIC_NAME"
export TP_SOCKET_IFNAME="$NIC_NAME"
export HCCL_SOCKET_IFNAME="$NIC_NAME"
export HCCL_BUFFSIZE=1800
export ASCEND_RT_VISIBLE_DEVICES=$1

# Ensure the model path matches the directory recorded during download
vllm serve "$MODEL_PATH" \
    --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 \
    --enable-expert-parallel \
    --seed 1024 \
    --served-model-name dsv41 \
    --max-model-len 1048576 \
    --max-num-batched-tokens 400 \
    --max-num-seqs 32 \
    --async-scheduling \
    --block-size 128 \
    --no-enable-prefix-caching \
    --trust-remote-code \
    --tokenizer-mode deepseek_v41 \
    --reasoning-parser deepseek_v41 \
    --tool-call-parser deepseek_v41 \
    --enable-auto-tool-choice \
    --model-loader-extra-config '{"enable_multithread_load":true,"num_threads":128}' \
    --safetensors-load-strategy lazy \
    --gpu-memory-utilization 0.95 \
    --quantization ascend \
    --speculative-config '{"num_speculative_tokens":5,"method":"dspark","enforce_eager":true}' \
    --compilation-config '{"cudagraph_mode":"FULL_DECODE_ONLY"}' \
    --kv-transfer-config '{
        "kv_connector":"MooncakeHybridConnector",
        "kv_role":"kv_consumer",
        "kv_port":"30100",
        "engine_id":"1",
        "kv_connector_extra_config":{
            "prefill":{"dp_size":4,"tp_size":4},
            "decode":{"dp_size":8,"tp_size":2}
        }
    }' \
    --engram-config '{"cpu_offload":true,"dp_shared_memory":true}' \
    --additional-config '{
        "ascend_compilation_config":{
            "enable_npugraph_ex":true,
            "enable_static_kernel":false
        },
        "enable_cpu_binding":true,
        "multistream_overlap_shared_expert":true,
        "recompute_scheduler_enable":true
    }'

启动八个 DP8/TP2 Decode 引擎。--dp-address 使用 Decode 节点 IP。

DECODE_NODE_IP="<DECODE_NODE_IP>"

python launch_online_dp.py \
    --dp-size 8 \
    --tp-size 2 \
    --dp-size-local 8 \
    --dp-rank-start 0 \
    --dp-address "$DECODE_NODE_IP" \
    --dp-rpc-port 12321 \
    --vllm-start-port 7100

5.2.4 部署 PD Proxy

在所有 Prefill 和 Decode 引擎就绪后,按照 Prefill-Decode 分离部署(DeepSeek) 中的说明部署 proxy。 为 proxy 配置 Prefill 端点 <PREFILL_NODE_IP>:7100 至 <PREFILL_NODE_IP>:7103,以及 Decode 端点 <DECODE_NODE_IP>:7100 至 <DECODE_NODE_IP>:7107。

5.2.5 关键参数说明

  • VLLM_ENGINE_READY_TIMEOUT_S=36000 为每个 Prefill 和 Decode 引擎提供最长 36,000 秒的启动时间。这包括权重加载和 Decode 图准备。
  • VLLM_USE_V2_MODEL_RUNNER=0 在 Prefill 和 Decode 上显式选择 model runner V1。 请将该值保持为 0,因为 DeepSeek-V4.1-Flash 目前在昇腾上不支持 model runner V2。
  • --data-parallel-size 和 --tensor-parallel-size 在 Prefill 上定义 DP4/TP4,在 Decode 上定义 DP8/TP2。它们的乘积在每个 A3 节点上必须为 16。
  • --data-parallel-address 和 --data-parallel-rpc-port 用于协调同一角色内的 DP rank。Prefill 和 Decode 使用各自的节点 IP;端口 12321 可以复用,因为两个角色运行在不同的主机上。
  • --vllm-start-port 7100 在 Prefill 上分配 API 端口 7100-7103, 在 Decode 上分配 7100-7107。这些端点必须能被 PD proxy 访问。
  • 两个角色都使用 --max-model-len 1048576。Prefill 使用 --max-num-batched-tokens 8192 和 --max-num-seqs 16 以提升 prompt 吞吐量,而 Decode 分别使用 400 和 32 以提升 decode 并发能力。请独立调整这些角色特定的调度器限制。
  • MooncakeHybridConnector 在两个角色之间传输 KV cache。 kv_role 在 Prefill 上必须为 kv_producer,在 Decode 上必须为 kv_consumer; kv_port 必须可访问,且不能与其他服务冲突。
  • kv_connector_extra_config 必须与两侧实际的全局布局匹配: Prefill DP4/TP4 和 Decode DP8/TP2。请确保 Prefill 和 Decode 命令中的 值保持一致。
  • 两个角色都使用 DSpark,并配置五个投机 token。Prefill 以 eager 模式运行目标 模型。Decode 对目标模型使用 FULL_DECODE_ONLY, 而 --speculative-config 中的 enforce_eager 适用于 Decode 的 draft 模型。
  • --engram-config '{"cpu_offload":true,"dp_shared_memory":true}' 将 Engram 表保留在主机内存中,并让本地 DP rank 共享主机内存 分配。在 A3 上必须使用 dp_shared_memory,因为模型的 24 个 Engram head 无法在 16 个逻辑设备之间均匀划分。两个 A3 容器都使用 --ipc=host,以便本地 DP rank 可以共享该分配。
  • --compilation-config '{"cudagraph_mode":"FULL_DECODE_ONLY"}' 捕获 Decode 路径,而 Prefill 保持在捕获图之外。
  • Prefix caching 仅在 Prefill 上启用。Decode 禁用它并启用 recompute_scheduler_enable,以便 Prefill 可以重新计算不可用的 KV cache。
  • Prefill 使用以下 --additional-config 选项:

    • enable_cpu_binding: true 为 worker 进程和运行时线程启用昇腾原生 CPU 亲和性。
    • enable_fused_mc2: 1 启用融合的 MoE 通信与计算 路径,以减少 expert dispatch、FFN 和 combine 开销。
    • enable_dsa_cp: true 为 DeepSeek Sparse Attention 启用上下文并行。此选项适用于带 indexer 的模型,并要求使用 此拓扑所用的序列并行 MoE 路径。
    • enable_flashcomm1: true 启用序列并行 MoE 和 DSA 上下文并行路径所使用的 FlashComm 通信后端。
    • enable_shared_expert_dp: true 对共享 expert 使用数据并行。 仅在启用 expert 并行且 TP 大于 一时生效;Prefill DP4/TP4 同时满足这两个条件。
  • Decode 使用以下 --additional-config 选项:

    • ascend_compilation_config.enable_npugraph_ex: true 启用 FULL_DECODE_ONLY 所使用的增强 ACL Graph 编译与执行路径。
    • ascend_compilation_config.enable_static_kernel: false 禁用静态 kernel 生成,同时保留增强的 ACL Graph 路径。
    • enable_cpu_binding: true 为 worker 进程和运行时线程启用昇腾原生 CPU 亲和性。
    • multistream_overlap_shared_expert: true 在独立流上将共享 expert 执行 与 routed expert 计算重叠,以提升 Decode MoE 吞吐量。
    • recompute_scheduler_enable: true 启用 PD Decode 重计算 调度器。当 Decode 侧 KV cache 不可用时,请求可以 被发送回 Prefill 重新计算。仅在 Decode 上启用此选项。

Prefill 和 Decode 的配置是角色特定的。在未验证最终 拓扑和性能之前,请勿将 Prefill 的 fused-MC2 和 DSA 选项复制到 Decode, 也不要将 Decode 的图、multistream 和重计算选项复制到 Prefill。

HCCL_IF_IP 与套接字接口变量必须选择与所配置节点 IP 相同的高速服务网络。HCCL_BUFFSIZE 在 Prefill 上为 1024,在 Decode 上为 1800;除非已验证其他设置,否则请保留这些角色特定的值。DP RPC、引擎、Mooncake 和代理端口必须被主机防火墙放行。

等待每个引擎完成权重加载且 Decode 完成图捕获。成功启动会包含类似以下的输出:

INFO:     Started server process
INFO:     Waiting for application startup.
INFO:     Application startup complete.

5.3 多节点混布部署

本次更新保留现有 A2 配置不变。它使用四台 Atlas 800 A2 服务器,每台服务器一个本地 DP rank,全局拓扑为 DP4/TP8/EP32。

在全部四台 A2 服务器上运行此脚本。在对应节点上将 NODE_RANK 设置为 0、1、2 或 3。将 NODE0_IP 设置为 Node 0 的 IP 地址,并为每个节点设置 LOCAL_IP、NIC_NAME 和 MODEL_PATH。

#!/usr/bin/env bash
set -euo pipefail

NODE_RANK=0
NODE0_IP="<NODE0_IP>"
LOCAL_IP="<LOCAL_IP>"
NIC_NAME="<NETWORK_INTERFACE>"
MODEL_PATH="<YOUR_MODEL_PATH>"

# Allow time for weight loading and graph capture on large models.
export VLLM_ENGINE_READY_TIMEOUT_S="${VLLM_ENGINE_READY_TIMEOUT_S:-3600}"
export HCCL_IF_IP="$LOCAL_IP"
export GLOO_SOCKET_IFNAME="$NIC_NAME"
export TP_SOCKET_IFNAME="$NIC_NAME"
export HCCL_SOCKET_IFNAME="$NIC_NAME"
export ASCEND_RT_VISIBLE_DEVICES=0,1,2,3,4,5,6,7

HEADLESS_ARGS=()
if [[ "$NODE_RANK" != "0" ]]; then
  HEADLESS_ARGS+=(--headless --data-parallel-start-rank "$NODE_RANK")
fi

vllm serve "$MODEL_PATH" \
  --host 0.0.0.0 \
  --port 8000 \
  "${HEADLESS_ARGS[@]}" \
  --data-parallel-address "$NODE0_IP" \
  --data-parallel-rpc-port 13399 \
  --data-parallel-size 4 \
  --data-parallel-size-local 1 \
  --tensor-parallel-size 8 \
  --enable-expert-parallel \
  --served-model-name deepseek-v41 \
  --max-model-len 1048576 \
  --max-num-batched-tokens 4096 \
  --max-num-seqs 32 \
  --gpu-memory-utilization 0.90 \
  --block-size 128 \
  --tokenizer-mode deepseek_v41 \
  --reasoning-parser deepseek_v41 \
  --tool-call-parser deepseek_v41 \
  --enable-auto-tool-choice \
  --trust-remote-code \
  --model-loader-extra-config '{"enable_multithread_load":true,"num_threads":128}' \
  --safetensors-load-strategy lazy \
  --quantization ascend \
  --additional-config '{"enable_cpu_binding":true,"ascend_compilation_config":{"enable_npugraph_ex":false,"enable_static_kernel":false}}' \
  --speculative-config '{"method":"dspark","num_speculative_tokens":5,"enforce_eager":true}' \
  --compilation-config '{"cudagraph_mode":"FULL_DECODE_ONLY"}'

在 Node 0 上省略 --data-parallel-start-rank。先启动 Node 0,然后依次启动 Node 1 到 Node 3。只有 Node 0 暴露 API 端点。每台服务器为全局 DP4 拓扑贡献一个 TP8 rank。

5.4 服务验证

为所选部署设置端点,然后验证健康检查端点。A3 单节点混布部署使用 <A3_IP> 和端口 8900,A3 PD 部署使用 <PROXY_IP> 和 <PROXY_PORT>,保留的 A2 部署使用 <A2_NODE0_IP> 和端口 8000。

export SERVICE_URL="http://<SERVICE_IP>:<SERVICE_PORT>"

curl -sS -o /dev/null -w 'HTTP %{http_code}\n' \
  "$SERVICE_URL/health"

预期输出:

HTTP 200

然后验证已配置的模型是否可用:

curl -sS "$SERVICE_URL/v1/models" | \
  jq '{object, models: [.data[] | {id, object}]}'

响应必须包含一个模型条目,其 id 与配置的 --served-model-name 匹配:A3 示例为 dsv41,保留的 A2 示例为 deepseek-v41。

6 功能验证

6.1 文本请求

export SERVICE_URL="http://<SERVICE_IP>:<SERVICE_PORT>"

curl -sS "$SERVICE_URL/v1/chat/completions" \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "dsv41",
    "messages": [{"role": "user", "content": "Who are you?"}],
    "temperature": 0,
    "max_completion_tokens": 256
  }' | jq -e '.choices[0].message.content | length > 0'

预期输出:

true

6.2 图像请求

将 IMAGE_URL 设置为执行 Prefill 的节点可访问的 HTTP(S) 图像 URL,并发送多模态请求:

export IMAGE_URL="<YOUR_IMAGE_URL>"
export SERVICE_URL="http://<SERVICE_IP>:<SERVICE_PORT>"

curl -sS "$SERVICE_URL/v1/chat/completions" \
  -H 'Content-Type: application/json' \
  -d "{
    \"model\": \"dsv41\",
    \"messages\": [{
      \"role\": \"user\",
      \"content\": [
        {\"type\": \"image_url\", \"image_url\": {\"url\": \"${IMAGE_URL}\"}},
        {\"type\": \"text\", \"text\": \"Describe this image.\"}
      ]
    }],
    \"temperature\": 0,
    \"max_completion_tokens\": 256
  }" | jq -e '.choices[0].message.content | length > 0'

预期输出:

true

7 精度评估

请参考 使用 AISBench 来评估已部署的服务。目前尚未针对此配置发布 vLLM Ascend 任务级精度结果。 在报告结果时,请记录 checkpoint、prompt encoder、reasoning effort、采样参数、数据集 版本以及是否启用了 DSpark。

8 性能评估

请参考 AISBench 性能评估指南 或 vLLM 基准测试指南。 目前尚未针对此配置发布生产性能基线。

9 性能调优

5.1 和 5.2 节中的值是起点,而非全局最优设置。请针对目标输入长度、图像尺寸、输出长度和并发量,协同调优 --max-num-seqs、--max-num-batched-tokens 和 --gpu-memory-utilization。在验证替代配置之前,A3 单节点部署请保持 DP4/TP4,A3 PD 部署请保持 Prefill DP4/TP4 和 Decode DP8/TP2。

10 常见问题

如何启用工具调用和推理解析?

请在服务命令中保留以下选项:

--tokenizer-mode deepseek_v41 \
--tool-call-parser deepseek_v41 \
--reasoning-parser deepseek_v41 \
--enable-auto-tool-choice

有关常见的环境、安装和参数问题,请参考 公共常见问题。

11 限制

  • 文档中描述的 A3 部署使用单台服务器混布模式或两台服务器 1P1D 模式,采用昇腾 W8A8 权重和 INT8 Engram 存储。
  • A2 配置保持不变,本次更新未重新验证。其修订后的配置将单独记录。
  • DeepSeek-V4.1-Flash 目前在昇腾上仅支持 model runner V1。请在每个 A3 服务脚本中保持 VLLM_USE_V2_MODEL_RUNNER=0。本指南不涵盖流水线并行。
  • 在 A3 PD 示例中,Prefill 以 eager 模式运行。Decode 对目标模型使用 FULL_DECODE_ONLY ACL Graph,对 DSpark 草稿模型使用 eager 执行。
  • 生产性能认证和任务级精度评估尚未完成。

12 vLLM 0.30.0 的有界重放兼容性

对于不含上游重放协议的 vLLM 0.30.0 镜像,昇腾插件回移了配置、请求负载和本地前缀命中准入逻辑。已安装的 vLLM 文件和已编译算子保持不变。该兼容路径默认禁用。可通过以下方式显式启用:

--enable-prefix-caching --swa-bounded-replay

使用 --no-swa-bounded-replay 可显式禁用重放。具有原生重放的 vLLM 构建使用上游实现。兼容性通过重放接口而非版本字符串来检测。配置和传输字段在使用前注册;仅当启用重放时才修补调度器和缓存行为。不支持的调度器源码体会显式失败。该回移仅支持本地前缀缓存;在启用 KV connector 的情况下启用重放会引发错误。现有的重放限制仍适用于使用独立调度器副本的 PCP 和昇腾模式。

SWA 缓存不参与前缀复用。在另一个缓存组中命中后,调度器会重新计算已缓存前缀的最后一个 SWA 窗口。worker 在重放期间屏蔽对共享缓存组的写入,并钳制可见的 SWA 范围。不超过窗口的命中会被完整重新计算。抢占后,重新准入会重新计算并转发重放边界。

12.1 真实权重验证

以下 A5 回归配置使用 TP1/DP4/EP4。运行前请使用现有的 CANN 环境和已编译的昇腾算子:

cd /workspace
VLLM_USE_V2_MODEL_RUNNER=1 vllm serve /home/weights/deepseek-ai--DeepSeek-V4.1-Flash \
  --tokenizer-mode deepseek_v41 --served-model-name deepseek-v41-accuracy \
  --host 127.0.0.1 --port 8011 \
  --tensor-parallel-size 1 --data-parallel-size 4 --data-parallel-size-local 4 \
  --enable-expert-parallel --quantization deepseek_v4_fp8 \
  --max-model-len 16384 --max-num-batched-tokens 2048 --max-num-seqs 1 \
  --block-size 128 --enforce-eager --enable-prefix-caching --swa-bounded-replay \
  --limit-mm-per-prompt '{"image":0}' \
  --engram-config '{"cpu_offload":true,"dp_shared_memory":false}' \
  --model-loader-extra-config '{"enable_multithread_load":true,"num_threads":16}' \
  --safetensors-load-strategy lazy --additional-config '{"enable_cpu_binding":false}'

首先从禁用重放的服务保存基线,然后将相同的请求发送到启用重放的服务:

cd /path/to/vllm-ascend
python tests/e2e/models/swa_bounded_replay_probe.py \
  --base-url http://127.0.0.1:8011 --model deepseek-v41-accuracy \
  --output /tmp/replay-disabled.json

# Restart the service with --swa-bounded-replay before running this command.
python tests/e2e/models/swa_bounded_replay_probe.py \
  --base-url http://127.0.0.1:8011 --model deepseek-v41-accuracy \
  --baseline /tmp/replay-disabled.json --output /tmp/replay-enabled.json

验证要求 HTTP 请求成功、输出与基线匹配,并且服务日志中出现实际的 SWA bounded replay is active 消息。仅启动成功或配置字段为 true 并不能证明重放已被执行。跨 chunk 回归还应使用小于 SWA 窗口的 token 预算。