跳到內容

分散式推理和部署

單模型副本的分散式推理策略

要為單模型副本選擇分散式推理策略,請遵循以下指南:

  • 單 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=8pipeline_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 伺服器:

vllm serve facebook/opt-13b \
     --tensor-parallel-size 4

要啟用流水線並行,請新增 --pipeline-parallel-size。例如,要在 8 個 GPU 上執行帶有流水線並行和張量並行的 API 伺服器:

# Eight GPUs total
vllm serve gpt2 \
     --tensor-parallel-size 4 \
     --pipeline-parallel-size 2

多節點部署

如果單個節點缺乏足夠的 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 statusray 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 總數:

vllm serve /path/to/the/model/in/the/container \
     --tensor-parallel-size 16

分散式部署故障排除

為了使張量並行表現出色,請確保節點之間的通訊高效,例如,透過使用高速網絡卡,如 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,請按如下方式設定容器:

docker run --gpus all \
    --ipc=host \
    --shm-size=16G \
    -v /dev/shm:/dev/shm \
    vllm/vllm-openai

如果您使用 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 日誌:

NCCL_DEBUG=TRACE vllm serve ...

在日誌中搜索傳輸方法。包含 [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 statusray list nodes 來驗證所選的 IP 地址。有關更多資訊,請參閱 Issue #7815