分布式推理与服务¶
单模型副本的分布式推理策略¶
为单个模型副本选择分布式推理策略时,请参考以下准则:
- 单GPU(非分布式推理):如果模型能在单个GPU上运行,可能不需要分布式推理。直接在该GPU上进行推理。
- 单节点多GPU张量并行推理:如果模型对于单个GPU来说太大,但可以放在具有多个GPU的单个节点上,则使用张量并行。例如,在使用具有4个GPU的节点时设置
tensor_parallel_size=4。 - 使用张量并行和流水线并行进行多节点多GPU推理:如果模型对于单个节点来说太大,可以将张量并行与流水线并行结合使用。将
tensor_parallel_size设置为每个节点的GPU数量,将pipeline_parallel_size设置为节点数量。例如,当使用2个节点且每个节点有8个GPU时,设置tensor_parallel_size=8和pipeline_parallel_size=2。
增加GPU和节点数量,直到有足够的GPU内存来运行模型。将tensor_parallel_size设置为每个节点的GPU数量,将pipeline_parallel_size设置为节点数量。
在您配置足够的资源以适配模型后,运行vllm。查找类似以下的日志消息:
INFO 07-23 13:56:04 [kv_cache_utils.py:775] GPU KV cache size: 643,232 tokens
INFO 07-23 13:56:04 [kv_cache_utils.py:779] Maximum concurrency for 40,960 tokens per request: 15.70x
GPU KV缓存大小这一行显示GPU KV缓存一次可存储的令牌总数。最大并发数这一行提供了当每个请求需要指定数量令牌(上例中为40,960)时,可同时处理的请求数量估算值。每个请求的令牌数取自模型配置中的最大序列长度ModelConfig.max_model_len。如果这些数值低于您的吞吐量需求,请向集群添加更多GPU或节点。
边缘情况:GPU分配不均
如果模型适合单个节点但GPU数量不能均匀分配模型大小,请启用流水线并行,该技术沿模型层进行分割并支持不均匀分割。在此场景下,设置tensor_parallel_size=1并将pipeline_parallel_size设为GPU数量。此外,如果节点上的GPU没有NVLINK互连(例如L40S),则利用流水线并行而非张量并行,以获得更高的吞吐量和更低的通信开销。
分布式服务专家混合(MoE)模型¶
通过为专家层采用独立的并行策略来利用专家的固有并行性通常是有优势的。vLLM支持将数据并行注意力与专家或张量并行MoE层相结合的大规模部署。更多信息请参阅数据并行部署。
单节点部署¶
vLLM支持分布式张量并行和流水线并行推理与服务。该实现包含Megatron-LM的张量并行算法。
默认的分布式运行时环境是Ray用于多节点推理,原生Python的multiprocessing用于单节点推理。您可以通过在LLM类中设置distributed_executor_backend参数,或在API服务器中使用--distributed-executor-backend选项来覆盖默认设置。使用mp表示multiprocessing,或使用ray表示Ray。
对于多GPU推理,在LLM类中设置tensor_parallel_size参数为所需的GPU数量。例如,要在4个GPU上运行推理:
from vllm import LLM
llm = LLM("facebook/opt-13b", tensor_parallel_size=4)
output = llm.generate("San Francisco is a")
对于多GPU服务,启动服务器时需包含--tensor-parallel-size参数。例如,要在4个GPU上运行API服务器:
要启用流水线并行,请添加--pipeline-parallel-size参数。例如,要在8个GPU上运行API服务器并启用流水线并行和张量并行:
多节点部署¶
如果单个节点没有足够的GPU来承载模型,可以在多个节点上部署vLLM。确保每个节点提供相同的执行环境,包括模型路径和Python包。建议使用容器镜像,因为它们能方便地保持环境一致性并隐藏主机异构性。
什么是Ray?¶
Ray是一个用于扩展Python程序的分布式计算框架。多节点vLLM部署需要Ray作为运行时引擎。
vLLM 使用 Ray 来管理跨多个节点的分布式任务执行,并控制执行发生的位置。
Ray还提供面向大规模离线批量推理和在线服务的高级API,这些API可以利用vLLM作为引擎。这些API为vLLM工作负载增加了生产级的容错能力、扩展性以及分布式可观测性。
详情请参阅Ray文档。
基于容器的Ray集群设置¶
辅助脚本 examples/online_serving/run_cluster.sh会在多节点上启动容器并初始化Ray。默认情况下,该脚本以非管理员权限运行Docker,这会导致在性能分析或跟踪时无法访问GPU性能计数器。如需启用管理员权限,请在Docker命令中添加--cap-add=CAP_SYS_ADMIN参数。
选择一个节点作为主节点并运行:
bash run_cluster.sh \
vllm/vllm-openai \
<HEAD_NODE_IP> \
--head \
/path/to/the/huggingface/home/in/this/node \
-e VLLM_HOST_IP=<HEAD_NODE_IP>
在每个工作节点上运行:
bash run_cluster.sh \
vllm/vllm-openai \
<HEAD_NODE_IP> \
--worker \
/path/to/the/huggingface/home/in/this/node \
-e VLLM_HOST_IP=<WORKER_NODE_IP>
请注意,每个工作节点的VLLM_HOST_IP都是唯一的。保持运行这些命令的shell处于开启状态;关闭任何shell都会终止集群。确保所有节点都能通过它们的IP地址相互通信。
网络安全
出于安全考虑,请将VLLM_HOST_IP设置为私有网段地址。通过该网络发送的流量未经加密,且端点交换的数据格式可能被攻击者利用来执行任意代码(如果攻击者获得网络访问权限)。请确保不可信方无法访问该网络。
从任意节点进入容器并运行ray status和ray list nodes命令,以验证Ray是否能检测到预期的节点数量和GPU数量。
提示
或者,使用KubeRay设置Ray集群。更多信息请参阅KubeRay vLLM文档。
在Ray集群上运行vLLM¶
提示
如果Ray在容器内运行,请在本指南剩余部分在容器内部执行命令,而非在主机上执行。要进入容器内的shell,请连接到节点并使用docker exec -it 。
一旦Ray集群运行起来,就可以像在单节点环境中一样使用vLLM。vLLM可以访问Ray集群中的所有资源,因此只需在单个节点上执行一条vllm命令即可。
通常的做法是将张量并行大小设置为每个节点中的GPU数量,将流水线并行大小设置为节点数量。例如,如果您有2个节点共16个GPU(每个节点8个GPU),则将张量并行大小设置为8,流水线并行大小设置为2:
vllm serve /path/to/the/model/in/the/container \
--tensor-parallel-size 8 \
--pipeline-parallel-size 2
或者,您可以将tensor_parallel_size设置为集群中的GPU总数:
分布式部署故障排除¶
为了使张量并行发挥最佳性能,需确保节点间的通信高效,例如使用InfiniBand等高速网卡。要配置集群使用InfiniBand,请在run_cluster.sh脚本中追加类似--privileged -e NCCL_IB_HCA=mlx5的参数。如需了解所需标志的详细信息,请联系系统管理员。验证InfiniBand是否正常工作的一个方法是:在设置NCCL_DEBUG=TRACE环境变量的情况下运行vllm,例如NCCL_DEBUG=TRACE vllm serve ...,然后检查日志中的NCCL版本和所用网络。若在日志中发现[send] via NET/Socket,说明NCCL使用了原始TCP套接字,这对跨节点张量并行效率不高。若发现[send] via NET/IB/GDRDMA,则说明NCCL使用了支持GPUDirect RDMA的InfiniBand,这种方式效率更高。
启用GPUDirect RDMA¶
要在vLLM中启用GPUDirect RDMA功能,请配置以下设置:
IPC_LOCK安全上下文:在容器的安全上下文中添加IPC_LOCK能力,以锁定内存页面并防止交换到磁盘。- 共享内存通过
/dev/shm:在pod规范中挂载/dev/shm以便为进程间通信(IPC)提供共享内存。
如果使用Docker,请按以下方式设置容器:
如果使用Kubernetes,请按以下方式设置pod规格:
...
spec:
containers:
- name: vllm
image: vllm/vllm-openai
securityContext:
capabilities:
add: ["IPC_LOCK"]
volumeMounts:
- mountPath: /dev/shm
name: dshm
resources:
limits:
nvidia.com/gpu: 8
requests:
nvidia.com/gpu: 8
volumes:
- name: dshm
emptyDir:
medium: Memory
...
高效的张量并行需要快速的节点间通信,最好通过高速网络适配器如InfiniBand实现。要启用InfiniBand,请在run_cluster.sh中添加诸如--privileged -e NCCL_IB_HCA=mlx5的标志。具体集群设置请咨询系统管理员。
要确认InfiniBand是否正常工作,请启用详细的NCCL日志:
在日志中搜索传输方法。包含[send] via NET/Socket的条目表示原始TCP套接字,在跨节点张量并行场景下性能较差。包含[send] via NET/IB/GDRDMA的条目表示支持GPUDirect RDMA的InfiniBand,可提供高性能。
验证节点间GPU通信
启动Ray集群后,请验证跨节点的GPU间通信。正确配置可能并非易事。更多信息请参阅故障排查脚本。若需为通信配置添加额外的环境变量,请将其追加到run_cluster.sh中,例如-e NCCL_SOCKET_IFNAME=eth0。建议在集群创建时设置环境变量,因为这些变量会传播到所有节点。相比之下,在shell中设置环境变量仅影响本地节点。更多信息请参阅 Issue #6803。
预下载Hugging Face模型
如果您使用Hugging Face模型,建议在启动vLLM前先下载模型。将模型下载到每个节点的相同路径下,或将模型存储在所有节点均可访问的分布式文件系统中。然后传递模型路径代替仓库ID。否则,通过在run_cluster.sh后追加-e HF_TOKEN=来提供Hugging Face令牌。
提示
即使集群有足够的GPU,也可能出现错误信息Error: No available node types can fulfill resource request。当节点有多个IP地址且vLLM无法选择正确的地址时,经常会出现此问题。通过在run_cluster.sh中设置VLLM_HOST_IP(每个节点使用不同的值),确保vLLM和Ray使用相同的IP地址。使用ray status和ray list nodes来验证所选的IP地址。更多信息请参阅 Issue #7815。