分布式推理和部署¶
单模型副本的分布式推理策略¶
要为单模型副本选择分布式推理策略,请遵循以下指南:
- 单 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 cache size
行报告了 GPU KV 缓存中可以一次存储的令牌总数。Maximum concurrency
行估计了在每个请求需要指定数量的令牌(在上面的示例中为 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 部署到多个节点上。多节点部署需要 Ray 作为运行时引擎。确保每个节点提供相同的执行环境,包括模型路径和 Python 包。建议使用容器镜像,因为它们提供了一种方便的方式来保持环境一致并隐藏主机异构性。
使用容器设置 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 <container_name> /bin/bash
。
一旦 Ray 集群运行,就可以像在单节点设置中一样使用 vLLM。Ray 集群中的所有资源都对 vLLM 可见,因此在单个节点上运行一个 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,请将附加参数(如 --privileged -e NCCL_IB_HCA=mlx5
)添加到 run_cluster.sh
脚本。有关所需标志的更多信息,请联系您的系统管理员。确认 InfiniBand 是否工作的一种方法是运行 vllm
并设置 NCCL_DEBUG=TRACE
环境变量,例如 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,请将 --privileged -e NCCL_IB_HCA=mlx5
等标志附加到 run_cluster.sh
。对于集群特定设置,请咨询您的系统管理员。
要确认 InfiniBand 操作,请启用详细的 NCCL 日志:
在日志中搜索传输方法。包含 [send] via NET/Socket
的条目表示原始 TCP 套接字,其在跨节点张量并行中表现不佳。包含 [send] via NET/IB/GDRDMA
的条目表示带有 GPUDirect RDMA 的 InfiniBand,它提供高性能。
验证节点间 GPU 通信
启动 Ray 集群后,验证节点间的 GPU 到 GPU 通信。正确的配置可能并非易事。有关更多信息,请参阅故障排除脚本。如果您需要额外的环境变量用于通信配置,请将它们附加到 run_cluster.sh
,例如 -e NCCL_SOCKET_IFNAME=eth0
。建议在集群创建期间设置环境变量,因为这些变量会传播到所有节点。相比之下,在 shell 中设置环境变量只会影响本地节点。有关更多信息,请参阅 Issue #6803。
预下载 Hugging Face 模型
如果您使用 Hugging Face 模型,建议在启动 vLLM 之前下载模型。在每个节点上将模型下载到相同路径,或将模型存储在所有节点可访问的分布式文件系统上。然后传入模型路径而不是仓库 ID。否则,通过将 -e HF_TOKEN=<TOKEN>
附加到 run_cluster.sh
来提供 Hugging Face 令牌。
提示
即使集群有足够的 GPU,也可能出现错误消息 Error: No available node types can fulfill resource request
。当节点有多个 IP 地址且 vLLM 无法选择正确的 IP 地址时,通常会发生此问题。通过在 run_cluster.sh
中设置 VLLM_HOST_IP
(每个节点使用不同的值)来确保 vLLM 和 Ray 使用相同的 IP 地址。使用 ray status
和 ray list nodes
来验证所选的 IP 地址。有关更多信息,请参阅 Issue #7815。