分布式推理和服务
如何决定分布式推理策略?¶
在深入分布式推理和服务的细节之前,让我们先明确何时使用分布式推理以及有哪些可用的策略。通常的做法是:
- 单 GPU(无分布式推理):如果您的模型适合单个 GPU,则可能不需要使用分布式推理。只需使用单个 GPU 运行推理即可。
- 单节点多 GPU(张量并行推理):如果您的模型太大无法放入单个 GPU,但可以放入具有多个 GPU 的单个节点中,则可以使用张量并行。张量并行大小是您希望使用的 GPU 数量。例如,如果您在单个节点中有 4 个 GPU,可以将张量并行大小设置为 4。
- 多节点多 GPU(张量并行加流水线并行推理):如果您的模型太大无法放入单个节点,则可以将张量并行与流水线并行结合使用。张量并行大小是您希望在每个节点中使用的 GPU 数量,流水线并行大小是您希望使用的节点数量。例如,如果您在 2 个节点中有 16 个 GPU(每个节点 8 个 GPU),可以将张量并行大小设置为 8,流水线并行大小设置为 2。
简而言之,您应该增加 GPU 和节点的数量,直到有足够的 GPU 内存来容纳模型。张量并行大小应为每个节点中的 GPU 数量,流水线并行大小应为节点数量。
添加足够的 GPU 和节点来容纳模型后,可以先运行 vLLM,它会打印一些日志,例如 # GPU blocks: 790
。将该数字乘以 16
(块大小),即可大致得到当前配置下可以服务的最大 token 数量。如果这个数字不令人满意,例如您想要更高的吞吐量,可以进一步增加 GPU 或节点的数量,直到块的数量足够为止。
注意
有一个极端情况:如果模型适合具有多个 GPU 的单个节点,但 GPU 数量无法均匀地除以模型大小,则可以使用流水线并行,它沿层拆分模型并支持不均匀拆分。在这种情况下,张量并行大小应为 1,流水线并行大小应为 GPU 数量。
在单节点上运行 vLLM¶
vLLM 支持分布式张量并行和流水线并行推理和服务。目前,我们支持 Megatron-LM 的张量并行算法。我们使用 Ray 或 Python 原生多进程管理分布式运行时。在单节点部署时可以使用多进程,多节点推理目前需要 Ray。
当不在 Ray placement group 中运行且同一节点上有足够的 GPU 可用于配置的 tensor_parallel_size
时,默认将使用多进程,否则将使用 Ray。可以通过 LLM
类的 distributed_executor_backend
参数或 --distributed-executor-backend
API 服务器参数覆盖此默认设置。设置为 mp
表示多进程,设置为 ray
表示 Ray。对于多进程情况,不需要安装 Ray。
要使用 LLM
类运行多 GPU 推理,请将 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 服务器:
在多节点上运行 vLLM¶
如果单个节点没有足够的 GPU 来容纳模型,您可以使用多个节点来运行模型。重要的是确保所有节点上的执行环境相同,包括模型路径、Python 环境。推荐的方法是使用 docker 镜像来确保相同的环境,并通过将它们映射到相同的 docker 配置来隐藏主机之间的异构性。
第一步是启动容器并将它们组织成一个集群。我们提供了助手脚本 examples/online_serving/run_cluster.sh 来启动集群。请注意,此脚本在没有管理权限的情况下启动 docker,而在运行分析和跟踪工具时,需要这些权限才能访问 GPU 性能计数器。为此,可以通过在 docker run 命令中使用 --cap-add
选项为 docker 容器添加 CAP_SYS_ADMIN
。
选择一个节点作为头节点,然后运行以下命令:
bash run_cluster.sh \
vllm/vllm-openai \
ip_of_head_node \
--head \
/path/to/the/huggingface/home/in/this/node \
-e VLLM_HOST_IP=ip_of_this_node
在其余的工作节点上,运行以下命令:
bash run_cluster.sh \
vllm/vllm-openai \
ip_of_head_node \
--worker \
/path/to/the/huggingface/home/in/this/node \
-e VLLM_HOST_IP=ip_of_this_node
然后您就获得了一个由容器组成的 Ray 集群。请注意,您需要保持运行这些命令的 shell 处于活动状态以维持集群。任何 shell 断开连接都将终止集群。此外,请注意,参数 ip_of_head_node
应该是头节点的 IP 地址,所有工作节点都可以访问。每个工作节点的 IP 地址应在 VLLM_HOST_IP
环境变量中指定,并且每个工作节点应不同。请检查您集群的网络配置,确保节点可以通过指定的 IP 地址相互通信。
警告
建议将 VLLM_HOST_IP
设置为 vLLM 集群的私有网络段上的地址。此处发送的流量未加密。端点之间还以一种格式交换数据,如果恶意方访问网络,可能会被利用来执行任意代码。请确保此网络不会被任何不受信任方访问。
警告
由于这是一个由容器组成的 Ray 集群,所有后续命令都应在容器内执行,否则您将在主机上执行命令,而主机未连接到 Ray 集群。要进入容器,可以使用 docker exec -it node /bin/bash
。
然后,在任何节点上,使用 docker exec -it node /bin/bash
进入容器,执行 ray status
和 ray list nodes
来检查 Ray 集群的状态。您应该看到正确的节点和 GPU 数量。
之后,在任何节点上,再次使用 docker exec -it node /bin/bash
进入容器。在容器内,您可以像往常一样使用 vLLM,就像所有 GPU 都在一个节点上一样:vLLM 将能够利用 Ray 集群中所有节点的 GPU 资源,因此,只需在此节点上运行 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
您也可以只使用张量并行而无需流水线并行,只需将张量并行大小设置为集群中的 GPU 总数即可。例如,如果您在 2 个节点中有 16 个 GPU(每个节点 8 个 GPU),可以将张量并行大小设置为 16:
为了让张量并行具有高性能,您应该确保节点之间的通信高效,例如使用 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 Socket,这对于跨节点张量并行效率不高。如果您在日志中找到 [send] via NET/IB/GDRDMA
,则表示 NCCL 使用带 GPU-Direct RDMA 的 InfiniBand,这效率很高。
警告
启动 Ray 集群后,最好也检查一下节点之间的 GPU-GPU 通信。这可能设置起来不简单。请参考 健全性检查脚本 获取更多信息。如果您需要为通信配置设置一些环境变量,可以将其添加到 run_cluster.sh
脚本中,例如 -e NCCL_SOCKET_IFNAME=eth0
。请注意,在 shell 中设置环境变量(例如 NCCL_SOCKET_IFNAME=eth0 vllm serve ...
)仅对同一节点内的进程有效,对其他节点中的进程无效。创建集群时设置环境变量是推荐的方法。请参阅 问题 #6803 获取更多信息。
警告
请确保您已将模型下载到所有节点(使用相同的路径),或者模型已下载到可由所有节点访问的分布式文件系统。
当您使用 huggingface repo id 来引用模型时,您应该将您的 huggingface token 添加到 run_cluster.sh
脚本中,例如 -e HF_TOKEN=
。推荐的方法是先下载模型,然后使用路径引用模型。
警告
如果您持续收到错误消息 Error: No available node types can fulfill resource request
,但集群中有足够的 GPU,很可能是您的节点有多个 IP 地址,vLLM 无法找到正确的 IP 地址,尤其是在使用多节点推理时。请确保 vLLM 和 ray 使用相同的 IP 地址。您可以在 run_cluster.sh
脚本中将 VLLM_HOST_IP
环境变量设置为正确的 IP 地址(每个节点不同!),并检查 ray status
和 ray list nodes
查看 Ray 使用的 IP 地址。请参阅 问题 #7815 获取更多信息。