跳到内容

数据并行部署

vLLM 支持数据并行部署,其中模型权重在独立的实例/GPU 上进行复制,以处理独立的请求批次。

这适用于密集模型和 MoE 模型。

对于 MoE 模型,特别是像 DeepSeek 这样采用 MLA(多头潜在注意力)的模型,将数据并行用于注意力层,将专家并行或张量并行(EP 或 TP)用于专家层会更有优势。

在这些情况下,数据并行等级并非完全独立。前向传播必须对齐,并且所有等级的专家层在每次前向传播期间都需要同步,即使待处理请求少于 DP 等级数量。

专家层默认会形成一个 (DP x TP) 大小的张量并行组。要启用专家并行,请包含 `--enable-expert-parallel` 命令行参数(在多节点情况下的所有节点上)。

在 vLLM 中,每个 DP 等级都被部署为一个独立的“核心引擎”进程,通过 ZMQ 套接字与前端进程通信。数据并行注意力可以与张量并行注意力结合使用,在这种情况下,每个 DP 引擎拥有数量等于配置的 TP 大小的每个 GPU 工作进程。

对于 MoE 模型,当任何等级中有任何请求正在进行时,我们必须确保在所有当前没有调度请求的等级中执行空的“虚拟”前向传播。这通过一个独立的 DP 协调器进程处理,该进程与所有等级通信,并且每 N 步执行一次集体操作,以确定所有等级何时都变为空闲并可以暂停。当 TP 与 DP 结合使用时,专家层会形成一个大小为 (DP x TP) 的 EP 或 TP 组。

在所有情况下,在 DP 等级之间进行请求负载均衡都是有益的。对于在线部署,可以通过考虑每个 DP 引擎的状态来优化这种均衡,特别是其当前已调度和等待(排队)的请求以及 KV 缓存状态。每个 DP 引擎都有一个独立的 KV 缓存,并且可以通过智能地引导提示来最大化前缀缓存的效益。

本文档侧重于在线部署(带有 API 服务器)。DP + EP 也支持离线使用(通过 LLM 类),示例请参见 examples/offline_inference/data_parallel.py

在线部署支持两种不同的模式——自包含的内部负载均衡,或外部的按等级进程部署和负载均衡。

内部负载均衡

vLLM 支持“自包含的”数据并行部署,公开单个 API 端点。

只需在 vllm serve 命令行参数中包含例如 `--data-parallel-size=4` 即可进行配置。这将需要 4 个 GPU。它可以与张量并行结合,例如 `--data-parallel-size=4 --tensor-parallel-size=2`,这将需要 8 个 GPU。

在多个节点上运行单个数据并行部署需要在每个节点上运行不同的 `vllm serve`,指定哪些 DP 等级应在该节点上运行。在这种情况下,仍然会有一个单一的 HTTP 入口点——API 服务器将只在一个节点上运行,但它不一定需要与 DP 等级共同定位。

这将在单个 8 GPU 节点上运行 DP=4, TP=2

vllm serve $MODEL --data-parallel-size 4 --tensor-parallel-size 2

这将在头节点上运行 DP=4 的 DP 等级 0 和 1,在第二个节点上运行等级 2 和 3

# Node 0  (with ip address 10.99.48.128)
vllm serve $MODEL --data-parallel-size 4 --data-parallel-size-local 2 \
                  --data-parallel-address 10.99.48.128 --data-parallel-rpc-port 13345
# Node 1
vllm serve $MODEL --headless --data-parallel-size 4 --data-parallel-size-local 2 \
                  --data-parallel-start-rank 2 \
                  --data-parallel-address 10.99.48.128 --data-parallel-rpc-port 13345

这将在第一个节点上仅运行 API 服务器,在第二个节点上运行所有引擎,以实现 DP=4

# Node 0  (with ip address 10.99.48.128)
vllm serve $MODEL --data-parallel-size 4 --data-parallel-size-local 0 \
                  --data-parallel-address 10.99.48.128 --data-parallel-rpc-port 13345
# Node 1
vllm serve $MODEL --headless --data-parallel-size 4 --data-parallel-size-local 4 \
                  --data-parallel-address 10.99.48.128 --data-parallel-rpc-port 13345

这种 DP 模式也可以通过指定 `--data-parallel-backend=ray` 与 Ray 一起使用

vllm serve $MODEL --data-parallel-size 4 --data-parallel-size-local 2 \
                  --data-parallel-backend=ray

使用 Ray 时有几个显著区别

  • 只需一个启动命令(在任何节点上)即可启动所有本地和远程 DP 等级,因此比在每个节点上启动更方便
  • 无需指定 `--data-parallel-address`,并且运行命令的节点将用作 `--data-parallel-address`
  • 无需指定 `--data-parallel-rpc-port`
  • 远程 DP 等级将根据 Ray 集群的节点资源进行分配

目前,内部 DP 负载均衡是在 API 服务器进程中完成的,并基于每个引擎中运行中和等待中的队列。未来可以通过整合 KV 缓存感知逻辑使其更加复杂。

使用此方法部署大型 DP 时,API 服务器进程可能成为瓶颈。在这种情况下,可以使用正交的 `--api-server-count` 命令行选项来横向扩展(例如 `--api-server-count=4`)。这对用户来说是透明的——仍然公开单个 HTTP 端点/端口。请注意,此 API 服务器的横向扩展是“内部的”,并且仍限于“头”节点。

DP Internal LB Diagram

外部负载均衡

特别是对于更大规模的部署,外部处理数据并行等级的编排和负载均衡可能更有意义。

在这种情况下,将每个 DP 等级视为一个独立的 vLLM 部署,拥有自己的端点,并让外部路由器在它们之间均衡 HTTP 请求会更方便,同时利用来自每个服务器的适当实时遥测数据进行路由决策。

对于非 MoE 模型来说,这已经可以轻而易举地完成,因为每个已部署的服务器都是完全独立的。为此无需使用任何数据并行命令行选项。

我们支持 MoE DP+EP 的等效拓扑,可以通过以下命令行参数进行配置。

如果 DP 等级共同定位(相同节点/IP 地址),则使用默认 RPC 端口,但必须为每个等级指定不同的 HTTP 服务器端口

# Rank 0
CUDA_VISIBLE_DEVICES=0 vllm serve $MODEL --data-parallel-size 2 --data-parallel-rank 0 \
                                         --port 8000
# Rank 1
CUDA_VISIBLE_DEVICES=1 vllm serve $MODEL --data-parallel-size 2 --data-parallel-rank 1 \
                                         --port 8001

对于多节点情况,还必须指定等级 0 的地址/端口

# Rank 0  (with ip address 10.99.48.128)
vllm serve $MODEL --data-parallel-size 2 --data-parallel-rank 0 \
                  --data-parallel-address 10.99.48.128 --data-parallel-rpc-port 13345
# Rank 1
vllm serve $MODEL --data-parallel-size 2 --data-parallel-rank 1 \
                  --data-parallel-address 10.99.48.128 --data-parallel-rpc-port 13345

在此场景中,协调器进程也与 DP 等级 0 引擎共同定位。

DP External LB Diagram

在上面的图中,每个虚线框都对应一个单独启动的 `vllm serve` 实例——例如,这些可以是独立的 Kubernetes Pod。