使用 KubeRay 进行管道并行#
本教程提供了分步指南,介绍如何在支持分布式推理的多节点 Kubernetes 集群上配置和部署 vLLM 服务引擎,并结合 KubeRay。它还解释了如何启用管道并行来启动 vLLM 服务引擎。
目录#
先决条件#
一个具有多个 GPU 支持节点的 Kubernetes 集群,如 00-a-install-multinode-kubernetes-env 教程 中所述。
使用 00-b-install-kuberay-operator 教程 在 Kubernetes 环境中安装 KubeRay Operator。
系统上安装了 Helm。
拥有 HuggingFace 令牌 (
HF_TOKEN) 的访问权限。建议对 Ray 有基本了解。有关更多信息,请参阅 官方 Ray 文档。
步骤 1:Ray 和 KubeRay 的基本解释#
Ray 是一个专为分布式工作负载(如分布式训练和推理)设计的框架。它通过运行多个进程(通常是容器或 Pod)来高效地分发和同步任务。
Ray 将这些进程组织成一个 Ray 集群,该集群由一个主节点和多个工作节点组成。“节点”一词在此处指的是一个逻辑进程,可以部署为容器或 Pod。
KubeRay 是一个 Kubernetes Operator,可简化在 Kubernetes 环境中创建和管理 Ray 集群的过程。没有 KubeRay,设置 Ray 节点需要手动配置。
使用 KubeRay,您可以轻松地在 Kubernetes 上部署 Ray 集群。这些集群支持 vLLM 的分布式推理,并支持张量并行和管道并行。
步骤 2:准备配置文件#
找到示例配置文件 tutorials/assets/values-15-a-minimal-pipeline-parallel-example-raycluster.yaml。
打开文件并更新以下字段
在 yaml 文件中,将
hf_token: <YOUR HF TOKEN>替换为您实际的 Hugging Face token。
对 values-15-a-minimal-pipeline-parallel-example-raycluster.yaml 中关键项的解释#
raySpec:使用 KubeRay 启用管道并行时必需。
headNode:指定 KubeRay 主节点的资源要求,必须相应定义。
requestCPU:为 KubeRay 主 Pod 请求的 CPU 资源量。
requestMemory:为 KubeRay 主 Pod 分配内存。加载模型需要足够的内存。
requestGPU:定义为 KubeRay 主 Pod 分配的 GPU 数量。目前,Ray 主节点也必须同时参与张量并行和管道并行。之所以需要这样,是因为
vllm serve ...命令在 Ray 主节点上执行,而 vLLM 要求运行此命令的 Pod 至少有一个可见的 GPU。
name:您的模型部署的唯一标识符。
repository:包含模型服务引擎镜像的 Docker 仓库。
tag:指定要使用的模型镜像版本。
modelURL:指向 Hugging Face 或其他托管服务上模型的 URL。
replicaCount:总共的 KubeRay 工作节点 Pod 数量。
requestCPU:为每个 KubeRay 工作节点 Pod 请求的 CPU 资源量。
requestMemory:为每个 KubeRay 工作节点 Pod 分配内存。加载模型需要足够的内存。
requestGPU:指定为每个 KubeRay 工作节点 Pod 分配的 GPU 数量。
vllmConfig:包含特定于模型的配置。
tensorParallelSize:指定分配给每个工作节点 Pod 的 GPU 数量。此值必须与requestGPU和raySpec.headNode.requestGPU相同。pipelineParallelSize:指示管道并行的级别。此值必须等于replicaCount + 1,代表 Ray 集群节点总数,包括主节点和工作节点。重要提示
所需的 GPU 总数为
pipelineParallelSize × tensorParallelSize。此总数必须与以下各项的总和完全匹配:
replicaCount × requestGPU(分配给 Ray 工作节点 Pod 的 GPU 总数),以及raySpec.headNode.requestGPU(分配给 Ray 主节点 Pod 的 GPU 数量)。
Ray 主节点的
requestGPU值必须与每个工作节点的值相同。tensorParallelSize定义了分配给每个 Ray 节点(包括主节点和工作节点)的 GPU 数量,并且在所有节点之间必须保持一致。pipelineParallelSize代表 Ray 节点的总数,因此必须设置为 replicaCount + 1(即工作节点数量加上主节点)。
shmSize:配置共享内存大小,以确保在张量和管道并行执行期间,进程间通信有足够的内存可用。
hf_token:用于向 Hugging Face 模型中心进行身份验证的 Hugging Face token。
示例片段#
在下面的示例中,我们配置了总共两个 Ray 节点,每个节点配备两个 GPU(一个主节点和一个工作节点)来服务 distilgpt2 模型。我们将张量并行大小设置为 2,因为每个节点包含两个 GPU,并将管道并行大小设置为 2,对应于正在使用的两个 Ray 节点。
servingEngineSpec:
runtimeClassName: ""
modelSpec:
- name: "distilgpt2"
repository: "vllm/vllm-openai"
tag: "latest"
modelURL: "distilbert/distilgpt2"
replicaCount: 1
requestCPU: 2
requestMemory: "20Gi"
requestGPU: 2
vllmConfig:
tensorParallelSize: 2
pipelineParallelSize: 2
shmSize: "20Gi"
raySpec:
headNode:
requestCPU: 2
requestMemory: "20Gi"
requestGPU: 2
hf_token: <YOUR HF TOKEN>
步骤 3:应用配置#
使用 Helm 部署配置
helm repo add vllm https://vllm-project.github.io/production-stack
helm install vllm vllm/vllm-stack -f tutorials/assets/values-15-a-minimal-pipeline-parallel-example-raycluster.yaml
预期输出
您应该会看到显示 Helm Chart 成功部署的输出。
NAME: vllm
LAST DEPLOYED: Sun May 11 15:10:34 2025
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
步骤 4:验证部署#
检查 Pod 的状态
kubectl wait --for=condition=ready pod -l environment=router,release=router --namespace=default --timeout=60s && \ kubectl get pods
预期输出
您应该会看到以下 Pod:
pod/vllm-deployment-router-8666bf6464-v97v8 condition met NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES kuberay-operator-f89ddb644-858bw 1/1 Running 0 12h 192.168.165.203 insudevmachine <none> <none> vllm-deployment-router-8666bf6464-v97v8 1/1 Running 0 12h 192.168.165.206 insudevmachine <none> <none> vllm-distilgpt2-raycluster-head-wvqj5 1/1 Running 0 12h 192.168.190.20 instance-20250503-060921 <none> <none> vllm-distilgpt2-raycluster-ray-worker-fdvnh 1/1 Running 0 12h 192.168.165.207 insudevmachine <none> <none>
在此示例中,production stack 部署在一个由两个节点组成的 Kubernetes 环境中,每个节点配备两个 GPU。
Ray 主节点和工作节点被调度在不同的节点上。总共使用了四个 GPU,每个节点贡献两个 GPU。
vllm-deployment-router Pod 作为请求路由器,将传入流量导向相应的模型服务 Pod。
vllm-distilgpt2-raycluster-head Pod 负责运行主要的 vLLM 命令。
vllm-distilgpt2-raycluster-ray-worker-* Pod 服务模型并处理推理请求。
验证服务是否正确暴露
kubectl get services
预期输出
确保同时存在服务引擎和服务路由器的服务。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kuberay-operator ClusterIP 10.97.0.153 <none> 8080/TCP 13h kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 13h vllm-distilgpt2-engine-service ClusterIP 10.106.237.111 <none> 80/TCP 12h vllm-distilgpt2-raycluster-head-svc ClusterIP None <none> 8000/TCP,8080/TCP 12h vllm-router-service ClusterIP 10.97.229.184 <none> 80/TCP 12h
vllm-*-engine-service暴露了 Ray 集群的主节点。vllm-*-router-service负责模型服务 Pod 的路由和负载均衡。
测试健康检查端点
要验证服务是否正常运行,请执行以下命令:
kubectl port-forward svc/vllm-router-service 30080:80 curl https://:30080/v1/models
注意: 端口转发必须在一个单独的 Shell 会话中执行。如果部署配置正确,您应该会收到类似于以下内容的响应:
{ "object": "list", "data": [ { "id": "distilbert/distilgpt2", "object": "model", "created": 1747465656, "owned_by": "vllm", "root": null } ] }您还可以执行基本的推理测试来验证管道并行是否按预期工作。请使用以下 curl 命令:
curl -X POST https://:30080/v1/completions \ -H "Content-Type: application/json" \ -d '{ "model": "distilbert/distilgpt2", "prompt": "Once upon a time,", "max_tokens": 10 }'
成功的响应应类似于以下输出:
{ "id": "cmpl-92c4ceef0f1c42c9bba10da8306bf86c", "object": "text_completion", "created": 1747465724, "model": "distilbert/distilgpt2", "choices": [ { "index": 0, "text": "? Huh, are you all red?\n\n", "logprobs": null, "finish_reason": "length", "stop_reason": null, "prompt_logprobs": null } ], "usage": { "prompt_tokens": 5, "total_tokens": 15, "completion_tokens": 10, "prompt_tokens_details": null } }您还可以监视每个 Ray 主节点和工作节点 Pod 的 GPU 使用情况。
kubectl exec -it vllm-distilgpt2-raycluster-head-wvqj5 -- /bin/bash root@vllm-distilgpt2-raycluster-head-wvqj5:/vllm-workspace# nvidia-smi Sat May 17 00:10:48 2025 +-----------------------------------------------------------------------------------------+ | NVIDIA-SMI 550.90.07 Driver Version: 550.90.07 CUDA Version: 12.4 | |-----------------------------------------+------------------------+----------------------+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+========================+======================| | 0 NVIDIA L4 Off | 00000000:00:03.0 Off | 0 | | N/A 76C P0 35W / 72W | 20313MiB / 23034MiB | 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ | 1 NVIDIA L4 Off | 00000000:00:04.0 Off | 0 | | N/A 70C P0 33W / 72W | 20305MiB / 23034MiB | 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ +-----------------------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=========================================================================================| | 0 N/A N/A 8 C /usr/bin/python3 0MiB | | 1 N/A N/A 1082 C ray::RayWorkerWrapper 0MiB | +-----------------------------------------------------------------------------------------+ ########################################################################################### kubectl exec -it vllm-distilgpt2-raycluster-ray-worker-fdvnh -- /bin/bash Defaulted container "vllm-ray-worker" out of: vllm-ray-worker, wait-gcs-ready (init) root@vllm-distilgpt2-raycluster-ray-worker-fdvnh:/vllm-workspace# nvidia-smi Sat May 17 00:12:06 2025 +-----------------------------------------------------------------------------------------+ | NVIDIA-SMI 550.90.07 Driver Version: 550.90.07 CUDA Version: 12.4 | |-----------------------------------------+------------------------+----------------------+ | GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+========================+======================| | 0 NVIDIA L4 Off | 00000000:00:03.0 Off | 0 | | N/A 76C P0 40W / 72W | 20065MiB / 23034MiB | 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ | 1 NVIDIA L4 Off | 00000000:00:04.0 Off | 0 | | N/A 72C P0 38W / 72W | 20063MiB / 23034MiB | 0% Default | | | | N/A | +-----------------------------------------+------------------------+----------------------+ +-----------------------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=========================================================================================| | 0 N/A N/A 243 C ray::RayWorkerWrapper 0MiB | | 1 N/A N/A 244 C ray::RayWorkerWrapper 0MiB | +-----------------------------------------------------------------------------------------+
结论#
在本教程中,您使用 KubeRay 在多节点 Kubernetes 环境中配置和部署了 vLLM 服务引擎,并支持跨多个 GPU 的管道并行。此外,您还学习了如何验证部署并监视相关 Pod 以确保其正常运行。有关进一步的自定义和配置选项,请参阅 values.yaml 文件和 Helm Chart 文档。
要使用单个 Helm release 部署 Ray 集群和标准的 Kubernetes 部署,请参阅位于 tutorials/assets/values-15-b-minimal-pipeline-parallel-example-multiple-modelspec.yaml 的示例配置文件。