跳到内容

数据并行部署

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

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

对于 MoE 模型,特别是像 DeepSeek 这样采用 MLA(多头潜在注意力)的模型,可以考虑为注意力层使用数据并行,为专家层使用专家并行或张量并行(EP 或 TP)。

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

默认情况下,专家层形成一个大小为 DP × TP 的张量并行组。要使用专家并行,请包含 --enable-expert-parallel CLI 参数(在多节点情况下,所有节点都需要)。有关注意力层和专家层在启用 EP 后行为差异的详细信息,请参阅 专家并行部署

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

对于 MoE 模型,当任何等级中有请求正在处理时,我们必须确保在当前没有安排任何请求的等级中执行空的“虚拟”前向传播。这通过一个独立的 DP 协调器进程(与所有等级通信)和一个每 N 步执行的集体操作来处理,以确定所有等级何时空闲并可以暂停。当 TP 与 DP 一起使用时,专家层形成一个大小为 DP × TP 的组(默认使用张量并行,如果设置了 --enable-expert-parallel 则使用专家并行)。

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

本文档侧重于在线部署(通过 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。在调整 DP 部署大小时,请记住 --max-num-seqs 是按 DP 等级应用的。

在多节点上运行单个数据并行部署需要在每个节点上运行不同的 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

这将运行 DP=4,其中第一个节点上只有 API 服务器,所有引擎都在第二个节点上

# 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 模式也可以与 Ray 一起使用,方法是指定 --data-parallel-backend=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 组需要多个节点时,*例如*,如果单个模型副本需要在至少两个节点上运行,请确保设置 VLLM_RAY_DP_PACK_STRATEGY="span",在这种情况下,--data-parallel-size-local 将被忽略并自动确定。
  • 远程 DP 等级将根据 Ray 集群的节点资源进行分配。

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

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

DP Internal LB Diagram

混合负载均衡

混合负载均衡介于内部和外部方法之间。每个节点运行自己的 API 服务器,这些服务器仅将请求排队到位于该节点上的数据并行引擎。上游负载均衡器(例如,入口控制器或流量路由器)将用户请求分发到这些每节点端点。

使用 --data-parallel-hybrid-lb 启用此模式,同时仍然使用全局数据并行大小启动每个节点。与内部负载均衡的主要区别在于:

  • 您必须提供 --data-parallel-size-local--data-parallel-start-rank,以便每个节点知道它拥有的等级。
  • --headless 不兼容,因为每个节点都公开一个 API 端点。
  • 根据本地等级的数量,每个节点按比例缩放 --api-server-count

在此配置中,每个节点将调度决策保留在本地,这减少了跨节点流量,并避免了在较大 DP 大小时出现单节点瓶颈。

外部负载均衡

特别是在大规模部署中,由外部系统来处理数据并行rank的编排和负载均衡可能更为合理。

在这种情况下,将每个 DP 等级视为单独的 vLLM 部署,并具有自己的端点,然后由外部路由器在它们之间平衡 HTTP 请求,利用来自每个服务器的适当实时遥测数据来做出路由决策,这样更方便。

对于非 MoE 模型,这已经可以轻松实现,因为每个部署的服务器都是完全独立的。对此不需要使用数据并行 CLI 选项。

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

如果 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,例如。