跳转至

DeepSeek-V4-Flash-Vision-Exp(实验性)

1 引言

DeepSeek-V4-Flash-Vision-Exp 是 DeepSeek-V4 系列中的多模态混合专家模型。它将 DeepSeek-V4 语言模型与视觉编码器和对齐器相结合,通过兼容 OpenAI 的聊天 API 接受文本、单图像和多图像请求。

vLLM Ascend 上的支持为实验性功能,可在 main 分支上使用,并匹配相应的 vLLM 0.27.x 修订版本。本指南记录了在单台 Atlas 800 A3 服务器或两台 Atlas 800 A2 服务器上的 Ascend W8A8 部署。目前仅支持同地部署:Prefill 和 Decode 在同一服务中运行。请勿对此模型使用 Prefill-Decode 分离部署。

2 支持的功能

请参阅支持的模型获取完整的支持矩阵,并参阅功能指南了解功能配置。

本指南中的 A3 配置已通过 W8A8 权重、TP4/DP4/EP16、自动前缀缓存和 FULL_DECODE_ONLY ACL Graph 验证。A2 配置在两台服务器上使用相同的全局 TP4/DP4/EP16 拓扑。本指南不涵盖 BF16 服务、DSA 上下文并行、FlashComm1 和 Prefill-Decode 分离部署。

3 前提条件

3.1 模型权重与硬件

模型 下载 硬件要求
DeepSeek-V4-Flash-Vision-Exp-w8a8-QuaRot ModelScope 一台 Atlas 800 A3 服务器(128GB × 8 NPU)或两台 Atlas 800 A2 服务器(每台 64GB × 8 NPU)
DeepSeek-V4-Flash-Vision-Exp Hugging Face 原始模型权重;本指南中的部署请使用 ModelScope W8A8 QuaRot 检查点

下面的启动命令使用来自 ModelScope 的公共 Ascend W8A8 QuaRot 检查点。该检查点包含 ModelSlim 量化描述以及 vLLM Ascend 所需的多模态 bias_vl 张量。

将检查点下载或准备到您选择的目录中,并记录绝对路径。示例中使用 <YOUR_MODEL_PATH>;请将其替换为该路径,例如 /data/weights/DeepSeek-V4-Flash-Vision-Exp-w8a8-QuaRot。

3.2 软件

为目标硬件使用已发布的镜像。每个镜像都包含匹配的 vLLM 和 vLLM Ascend 修订版本:

A3: quay.io/ascend/vllm-ascend:deepseekv4-flash-vision-exp-a3
A2: quay.io/ascend/vllm-ascend:deepseekv4-flash-vision-exp

请勿在容器内单独替换任一软件包。不支持混用其他 vLLM 和 vLLM Ascend 修订版本。

3.3 验证多节点通信(可选)

如果您想部署多节点环境,需要根据验证多节点通信环境进行验证。

4 安装

4.1 Docker 镜像安装

选择目标硬件对应的选项卡。在两台服务器上运行 A2 命令。

A3 服务器有 8 个 NPU,在容器中以 16 个逻辑设备(davinci0 到 davinci15)的形式呈现。

export IMAGE=quay.io/ascend/vllm-ascend:deepseekv4-flash-vision-exp-a3
export MODEL_ROOT="/data/weights"

docker pull "$IMAGE"

docker run --rm -it \
  --name dsv4-vision \
  --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/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 个 NPU 裸片(davinci0 到 davinci7)。

export IMAGE=quay.io/ascend/vllm-ascend:deepseekv4-flash-vision-exp
export MODEL_ROOT="/data/weights"

docker pull "$IMAGE"

docker run --rm -it \
  --name dsv4-vision \
  --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

4.2 验证与源码构建

如果检查点存储在其他位置,请更改 MODEL_ROOT。保持容器内外的模型绝对路径一致,并在两台 A2 服务器上使用相同的路径。

由于这些命令会启动交互式 shell,请在另一个主机终端中打开并验证容器正在运行:

docker ps --filter name=^/dsv4-vision$ \
  --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}'

A3 的预期输出与以下内容类似。对于 A2,镜像名称没有 -a3 后缀。状态以 Up 开头表示成功。

NAMES          IMAGE                                                                  STATUS
dsv4-vision    quay.io/ascend/vllm-ascend:deepseekv4-flash-vision-exp-a3              Up 30 seconds

进入每个容器后,验证已安装的软件包:

python -m pip show vllm vllm-ascend

两个软件包都必须存在。如需改为从源码构建,请遵循软件环境安装指南,并使用 .github/vllm-main-verified.commit 中匹配的 vLLM 修订版本构建 main 分支。为目标平台使用特定于硬件的 Dockerfile。

5 在线服务部署

5.1 单节点 A3 同地部署

已验证的拓扑使用四个数据并行引擎。每个引擎使用四个张量并行 rank,而专家并行则横跨全部 16 个 rank。

# Replace <YOUR_MODEL_PATH> with the actual path recorded in Section 3.1.
export MODEL_PATH="<YOUR_MODEL_PATH>"
export ASCEND_RT_VISIBLE_DEVICES=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
export HCCL_BUFFSIZE=1024

vllm serve "$MODEL_PATH" \
  --served-model-name dsv4-vision \
  --max-model-len 130000 \
  --max-num-batched-tokens 4096 \
  --max-num-seqs 32 \
  --gpu-memory-utilization 0.9 \
  --data-parallel-size 4 \
  --tensor-parallel-size 4 \
  --enable-expert-parallel \
  --tokenizer-mode deepseek_v4 \
  --quantization ascend \
  --model-loader-extra-config '{"enable_multithread_load":true,"num_threads":32}' \
  --block-size 32 \
  --compilation-config '{"cudagraph_mode":"FULL_DECODE_ONLY"}' \
  --port 8000

关键参数:

  • --data-parallel-size 4 和 --tensor-parallel-size 4 消耗服务器 8 个 NPU 支持的全部 16 个可见逻辑设备。--enable-expert-parallel 将 MoE 专家分布到各个 rank 上。
  • --max-model-len 130000 限制单个请求的输入和输出总长度。如果服务无法分配足够的 KV 缓存,请减小该值。
  • --max-num-seqs 32 是每个 DP 引擎调度的最大序列数。如果观察到运行时内存压力,请首先减小该值。
  • --block-size 32 是已验证的 DeepSeek-V4 前缀缓存和稀疏注意力配置所必需的。
  • FULL_DECODE_ONLY 捕获解码执行,同时将 Prefill 保持在完整解码图之外。

请等待所有四个 DP 引擎完成权重加载和图捕获。成功启动时输出类似于:

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

有关一般启动问题,请参阅公共 FAQ。

5.2 双节点 A2 同地部署

A2 部署使用两台服务器,因为每台服务器提供 8 个 NPU 裸片。每台服务器运行两个使用 TP4 的本地 DP rank,消耗全部 8 个裸片。两台服务器共同构成全局 DP4/TP4/EP16 拓扑。

启动服务前,请按照 验证多节点通信进行操作。 在两台服务器上使用相同的模型路径和DP RPC端口。将NIC_NAME设置为与LOCAL_IP关联的 接口,并确保节点1可以通过NODE0_IP访问节点0。

# Replace the placeholders with the values for Node 0.
export MODEL_PATH="<YOUR_MODEL_PATH>"
export NIC_NAME="<NODE0_NIC_NAME>"
export LOCAL_IP="<NODE0_IP>"
export DP_RPC_PORT=13389

export ASCEND_RT_VISIBLE_DEVICES=0,1,2,3,4,5,6,7
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=1024
export HCCL_INTRA_PCIE_ENABLE=1
export HCCL_INTRA_ROCE_ENABLE=0

vllm serve "$MODEL_PATH" \
  --host 0.0.0.0 \
  --port 8000 \
  --served-model-name dsv4-vision \
  --max-model-len 130000 \
  --max-num-batched-tokens 4096 \
  --max-num-seqs 32 \
  --gpu-memory-utilization 0.9 \
  --data-parallel-size 4 \
  --data-parallel-size-local 2 \
  --data-parallel-start-rank 0 \
  --data-parallel-address "$LOCAL_IP" \
  --data-parallel-rpc-port "$DP_RPC_PORT" \
  --tensor-parallel-size 4 \
  --enable-expert-parallel \
  --tokenizer-mode deepseek_v4 \
  --quantization ascend \
  --model-loader-extra-config '{"enable_multithread_load":true,"num_threads":32}' \
  --block-size 32 \
  --compilation-config '{"cudagraph_mode":"FULL_DECODE_ONLY"}'
# Replace the placeholders with the values for Node 1 and Node 0.
export MODEL_PATH="<YOUR_MODEL_PATH>"
export NIC_NAME="<NODE1_NIC_NAME>"
export LOCAL_IP="<NODE1_IP>"
export NODE0_IP="<NODE0_IP>"
export DP_RPC_PORT=13389

export ASCEND_RT_VISIBLE_DEVICES=0,1,2,3,4,5,6,7
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=1024
export HCCL_INTRA_PCIE_ENABLE=1
export HCCL_INTRA_ROCE_ENABLE=0

vllm serve "$MODEL_PATH" \
  --headless \
  --host 0.0.0.0 \
  --port 8000 \
  --served-model-name dsv4-vision \
  --max-model-len 130000 \
  --max-num-batched-tokens 4096 \
  --max-num-seqs 32 \
  --gpu-memory-utilization 0.9 \
  --data-parallel-size 4 \
  --data-parallel-size-local 2 \
  --data-parallel-start-rank 2 \
  --data-parallel-address "$NODE0_IP" \
  --data-parallel-rpc-port "$DP_RPC_PORT" \
  --tensor-parallel-size 4 \
  --enable-expert-parallel \
  --tokenizer-mode deepseek_v4 \
  --quantization ascend \
  --model-loader-extra-config '{"enable_multithread_load":true,"num_threads":32}' \
  --block-size 32 \
  --compilation-config '{"cudagraph_mode":"FULL_DECODE_ONLY"}'

先启动节点0,再启动节点1。只有节点0暴露API端点; 节点1作为无头工作节点运行。多节点DP参数的含义如下:

  • --data-parallel-size 4 是两台服务器上的全局DP大小。
  • --data-parallel-size-local 2 在每台服务器上创建两个DP rank。每个DP rank通过TP4使用四个本地die,因此每台A2服务器使用全部八个die。
  • --data-parallel-start-rank 0 将DP rank 0和1分配给节点0,而 --data-parallel-start-rank 2 将rank 2和3分配给节点1。
  • --data-parallel-address 将两台服务器指向节点0,且 --data-parallel-rpc-port 在两台服务器上必须具有相同的值。
  • --headless 防止节点1启动另一个API服务器。

等待所有四个DP引擎就绪后,再向节点0发送请求。

5.3 服务验证

对于A3,在服务节点上运行以下命令。对于A2,在节点0上运行这些命令; 远程检查时,将127.0.0.1替换为节点0的IP地址。

验证健康检查端点:

curl -sS -o /dev/null -w 'HTTP %{http_code}\n' \
  http://127.0.0.1:8000/health

预期输出:

HTTP 200

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

curl -sS http://127.0.0.1:8000/v1/models | \
  jq '{object, models: [.data[] | {id, object}]}'

预期输出:

{
  "object": "list",
  "models": [
    {
      "id": "dsv4-vision",
      "object": "model"
    }
  ]
}

HTTP 200响应以及id为dsv4-vision的模型条目表示服务已就绪。

5.4 Prefill-Decode分离

当前不支持对DeepSeek-V4-Flash-Vision-Exp进行Prefill-Decode分离。 请使用第5.1和5.2节中的共置部署之一。

6 功能验证

将IMAGE_URL设置为服务容器可访问的HTTP(S) URL, 然后发送多模态聊天补全请求。对于双节点A2部署, 如果请求是远程发送的,请将127.0.0.1替换为节点0的IP地址。

export IMAGE_URL="<YOUR_IMAGE_URL>"

curl -sS -o response.json -w '%{http_code}\n' \
  http://127.0.0.1:8000/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -d "{
    \"model\": \"dsv4-vision\",
    \"messages\": [{
      \"role\": \"user\",
      \"content\": [
        {\"type\": \"image_url\", \"image_url\": {\"url\": \"${IMAGE_URL}\"}},
        {\"type\": \"text\", \"text\": \"Describe this image.\"}
      ]
    }],
    \"temperature\": 0,
    \"max_tokens\": 256
  }"

jq -e '.choices[0].message.content | length > 0' response.json

预期输出:

200
true

生成的描述存储在response.json中的.choices[0].message.content下。 要使用本地图像文件,请将其父目录挂载到容器中,并在服务命令中添加 --allowed-local-media-path <DIRECTORY>。

7 精度评估

合并后的实现已在OCRBench V1上使用1,000个样本进行了验证。 使用W8A8检查点、并发数64、温度1.0、top-p 0.95、最大输出长度8192、 种子7,并启用高推理强度的思考模式,测试无请求错误完成,得分为826/1000 (82.6)。

要复现精度评估,请参阅 使用AISBench。结果取决于检查点、提示模板、 解码参数和数据集版本;在比较运行结果时,请记录所有这些信息。

8 性能评估

该实验性模型尚未发布生产性能基线。 请使用AISBench性能评估指南 配合第5.1节中的部署,并报告图像分辨率、输入/输出长度、请求并发数、TTFT、TPOT、ITL和吞吐量。

9 性能调优

第5.1节中的值是经过验证的起点,并非全局最优设置。 请针对目标图像尺寸和序列长度,一起调整--max-num-seqs、--max-num-batched-tokens和 --gpu-memory-utilization。在替代配置得到验证之前,请保持单节点A3 TP4/DP4/EP拓扑和--block-size 32不变。

有关通用调优方法,请参阅 性能调优指南。

10 常见问题

有关常见的环境、安装和通用参数问题,请参阅 公共FAQ;本章仅涵盖模型特定问题。

11 限制

  • 共置服务仅在单台Atlas 800 A3服务器(128GB × 8 NPU)或两台Atlas 800 A2服务器 (每台64GB × 8 NPU)上提供文档说明。
  • 文档所述配置不支持Prefill-Decode分离、DSA上下文并行和FlashComm1。
  • BF16全模型验证和生产性能认证尚未完成。
  • 使用TP4 ACL Graph时,图捕获批大小必须是四的倍数。
  • DSpark使用目标端多模态Prefill,随后进行纯文本投机Decode;草稿模型不消费图像嵌入, 也不在图像跨度内提出token。