跳至内容

数据并行部署

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

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

对于MoE模型,尤其是像DeepSeek这样采用MLA(多头潜在注意力)的模型,对注意力层使用数据并行,而对专家层使用专家并行或张量并行(EP或TP)可能更为有利。

在这些情况下,数据并行层级并非完全独立。前向传播必须保持同步,且所有层级的专家层都需要在每次前向传播期间进行协调,即使待处理的请求数量少于数据并行层级数时也是如此。

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

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

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

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

本文档主要关注在线部署(使用API服务器)。对于离线使用(通过LLM类),也支持DP + EP,示例请参见 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 ranks。在这种情况下,仍然会有一个统一的HTTP入口点——API服务器将仅在一个节点上运行,但不一定需要与DP ranks位于同一节点。

这将在单个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模式也可以通过指定--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模型来说,这已经可以轻松实现,因为每个部署的服务器都是完全独立的。为此不需要使用任何数据并行的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

对于多节点场景,还必须指定rank 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 rank 0引擎位于同一位置。

DP External LB Diagram

在上图中,每个虚线框对应一次独立的vllm serve启动 - 例如这些可以是独立的Kubernetes pods。

优云智算