跳到内容

并行与扩展

单个模型副本的分布式推理策略

要为单个模型副本选择分布式推理策略,请使用以下指南:

  • 单个 GPU (无分布式推理): 如果模型适合单个 GPU,则可能不需要分布式推理。直接在该 GPU 上运行推理。
  • 单节点多 GPU 使用张量并行推理: 如果模型太大而无法放入单个 GPU,但在具有多个 GPU 的单个节点上可以容纳,请使用张量并行。例如,在使用具有 4 个 GPU 的节点时,设置 tensor_parallel_size=4
  • 多节点多 GPU 使用张量并行和流水线并行推理: 如果模型太大而无法放入单个节点,请结合使用张量并行流水线并行。将 tensor_parallel_size 设置为每个节点的 GPU 数量,将 pipeline_parallel_size 设置为节点数量。例如,在使用每个节点有 8 个 GPU 的 2 个节点时,设置 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 缓存一次可以存储的 token 总数。Maximum concurrency 行提供了每秒可服务请求数量的估计,前提是每个请求都需要指定数量的 token (在上例中为 40,960)。每个请求的 token 数量取自模型的最大序列长度 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 来覆盖默认值。对于 multiprocessing,使用 mp;对于 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 部署到多个节点上。确保每个节点提供相同的执行环境,包括模型路径和 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 性能计数器。要启用管理权限,请将 --cap-add=CAP_SYS_ADMIN 标志添加到 Docker 命令。

选择一个节点作为主节点并运行:

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 \
    --distributed-executor-backend ray

或者,您可以将 tensor_parallel_size 设置为集群中 GPU 的总数。

vllm serve /path/to/the/model/in/the/container \
     --tensor-parallel-size 16 \
     --distributed-executor-backend ray

使用多进程运行 vLLM

除了 Ray 之外,多节点 vLLM 部署还可以使用 multiprocessing 作为运行时引擎。下面是一个跨 2 个节点 (每个节点 8 个 GPU) 部署模型,使用 tp_size=8pp_size=2 的示例。

选择一个节点作为主节点并运行:

vllm serve /path/to/the/model/in/the/container \
  --tensor-parallel-size 8 --pipeline-parallel-size 2 \
  --nnodes 2 --node-rank 0 \
  --master-addr <HEAD_NODE_IP>

在另一个工作节点上运行:

vllm serve /path/to/the/model/in/the/container \
  --tensor-parallel-size 8 --pipeline-parallel-size 2 \
  --nnodes 2 --node-rank 1 \
  --master-addr <HEAD_NODE_IP> --headless

优化张量并行通信

高效的张量并行需要快速的节点间通信,最好通过高速网络适配器,如 InfiniBand。要设置使用 InfiniBand 的集群,请将附加参数 (如 --privileged -e NCCL_IB_HCA=mlx5) 追加到 examples/online_serving/run_cluster.sh 帮助脚本。有关所需标志的更多信息,请咨询您的系统管理员。

启用 GPUDirect RDMA

GPUDirect RDMA (Remote Direct Memory Access) 是一项 NVIDIA 技术,它允许网络适配器直接访问 GPU 内存,绕过 CPU 和系统内存。这种直接访问可减少延迟和 CPU 开销,这对于跨节点 GPU 之间的大数据传输非常有利。

要启用 GPUDirect RDMA 与 vLLM,请配置以下设置:

  • 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
...

确认 GPUDirect RDMA 操作

要确认您的 InfiniBand 网卡正在使用 GPUDirect RDMA,请运行带有详细 NCCL 日志的 vLLM:NCCL_DEBUG=TRACE vllm serve ...

然后查找 NCCL 版本和使用的网络。

  • 如果在日志中找到 [send] via NET/IB/GDRDMA,则 NCCL 正在使用支持 GPUDirect RDMA 的 InfiniBand,这高效的。
  • 如果在日志中找到 [send] via NET/Socket,则 NCCL 使用了原始 TCP 套接字,这对于跨节点张量并行效率不高

预下载 Hugging Face 模型

如果您使用 Hugging Face 模型,建议在启动 vLLM 之前下载模型。将模型下载到每个节点上的同一路径,或将模型存储在所有节点都可以访问的分布式文件系统上。然后,在传递给模型的参数中使用该路径代替存储库 ID。否则,通过将 -e HF_TOKEN=<TOKEN> 追加到 run_cluster.sh 来提供 Hugging Face 令牌。

分布式部署故障排查

有关分布式调试的信息,请参阅分布式部署故障排除