分散式推理和部署¶
單模型副本的分散式推理策略¶
要為單模型副本選擇分散式推理策略,請遵循以下指南:
- 單 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。