最佳实践:P/D 分离
概览
本指南演示如何利用 vLLM 对 P/D 分离的支持以及 NIXL 来部署 Llama-70B。本指南已在以下环境验证:
- 配备 InfiniBand 网络连接的 8xH200 集群
- GKE 上配备 RoCE 网络连接的 8xH200 集群
警告:我们仍在调查并优化其他硬件和网络配置的性能
在此示例中,我们将演示 Llama-3.3-70B-Instruct-FP8 的部署,配置如下:
- 4 个 TP=1 的 Prefill 工作节点
- 1 个 TP=4 的 Decode 工作节点
P/D 最佳实践
P/D 分离在平衡吞吐量和交互性方面提供了更大的灵活性(参考)。特别是由于消除了 Prefill 阶段对 Decode 阶段的干扰,P/D 分离可以实现更低的逐标记延迟 (ITL),从而提高交互性。对于给定的 ITL 目标,P/D 分离可通过以下方式提高总体吞吐量:
- 针对计算密集型(P)和延迟敏感型(D)工作负载分别优化工作节点
- 通过更广泛的并行性减少模型副本数量(从而增加 KV 缓存 RAM)
然而,P/D 分离并不适用于所有工作负载。我们建议针对具有以下特征的工作负载探索 P/D 分离:
- 大型模型(例如 Llama-70B+,而非 Llama-8B)
- 较长的输入序列长度(例如 10k ISL | 1k OSL,而非 200 ISL | 200 OSL)
- 具有广泛专家并行 (EP) 机会的稀疏 MoE 架构
因此,在调优 P/D 部署时,我们建议关注以下参数:
- 异构并行:部署并行度较低但副本数较多的 P 节点,以及并行度较高但副本数较少的 D 节点
- xPyD 比例:调优 P 节点与 D 节点的比例,以确保与您的 ISL|OSL 比例保持平衡
对于利用广泛 EP 的极大型模型,当 ISL|OSL 比例也较高时,KV 缓存传输的流量可能会与专家并行产生竞争。我们建议在尝试使用 TCP 之前,先从用于 KV 缓存传输的 RDMA 开始,因为 TCP 传输需要对 NIXL 下的 UCX 进行更多调优。
硬件要求
本指南要求 8 个任意类型的 Nvidia GPU,并且工作负载中的所有 Pod 之间均需通过 InfiniBand 或 RoCE 实现 RDMA。
先决条件
-
请在本地系统中安装适当的客户端工具以使用本指南。
-
确保您的集群基础设施足以 部署大规模推理
-
配置并部署您的 Gateway 控制平面。
-
在系统中安装 监控栈。
-
为安装创建一个命名空间。
export NAMESPACE=llm-d-pd # or any other namespace (shorter names recommended)
kubectl create namespace ${NAMESPACE} -
在目标命名空间中创建名为 `llm-d-hf-token` 的 Secret,其键为 `HF_TOKEN`,并匹配有效的 HuggingFace 令牌以拉取模型。
安装
使用 helmfile 来组合并安装技术栈。部署该技术栈的命名空间将衍生自 ${NAMESPACE} 环境变量。如果您未设置此变量,在本示例中将默认为 llm-d-pd。
部署
cd guides/pd-disaggregation
helmfile apply -n ${NAMESPACE}
注意: 您可以设置 $RELEASE_NAME_POSTFIX 环境变量来更改版本名称。这是我们支持并发安装的方式。例如:RELEASE_NAME_POSTFIX=pd-2 helmfile apply -n ${NAMESPACE}
注意: 本指南默认使用 Istio 作为提供商,请参阅 网关选项 以安装特定提供商。
Gateway 选项
要指定您的网关选择,可以使用 -e <gateway option> 标志,例如:
helmfile apply -e kgateway -n ${NAMESPACE}
要查看支持哪些 Gateway 选项,请参考我们的 Gateway 提供商先决条件文档。每个提供商的 Gateway 配置都在 gateway-configurations 目录中进行跟踪。
您还可以自定义 Gateway,更多信息请参阅我们的 Gateway 自定义文档。
基础设施提供商详情
本指南在分离式服务中使用通过 InfiniBand 或 RoCE 的 RDMA 进行 KV 缓存传输。配置加速器网络所需的资源属性尚未通过 Kubernetes 动态资源分配 (DRA) 实现标准化,因此在 Helm chart 中按基础设施提供商进行了参数化。如果您的提供商有自定义设置,则需要在部署前更新 chart。
安装 HTTPRoute
请遵循特定提供商的说明来安装 HTTPRoute。
为 "kgateway" 或 "istio" 安装
kubectl apply -f httproute.yaml -n ${NAMESPACE}
为 "gke" 安装
kubectl apply -f httproute.gke.yaml -n ${NAMESPACE}
验证安装
- 首先,您应该能够列出所有 helm release,以查看已安装到所选命名空间中的 3 个 chart。
helm list -n ${NAMESPACE}
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
gaie-pd llm-d-pd 1 2025-08-24 12:54:51.231537 -0700 PDT deployed inferencepool-v1.2.0 v1.2.0
infra-pd llm-d-pd 1 2025-08-24 12:54:46.983361 -0700 PDT deployed llm-d-infra-v1.3.6 v0.3.0
ms-pd llm-d-pd 1 2025-08-24 12:54:56.736873 -0700 PDT deployed llm-d-modelservice-v0.3.17 v0.3.0
- 通过此示例,您开箱即用应拥有以下资源
kubectl get all -n ${NAMESPACE}
NAME READY STATUS RESTARTS AGE
pod/gaie-pd-epp-54444ddc66-qv6ds 1/1 Running 0 2m35s
pod/infra-pd-inference-gateway-istio-56d66db57f-zwtzn 1/1 Running 0 2m41s
pod/ms-pd-llm-d-modelservice-decode-84bf6d5bdd-jzfjn 2/2 Running 0 2m30s
pod/ms-pd-llm-d-modelservice-prefill-86f6fb7cdc-8kfb8 1/1 Running 0 2m30s
pod/ms-pd-llm-d-modelservice-prefill-86f6fb7cdc-g6wmp 1/1 Running 0 2m30s
pod/ms-pd-llm-d-modelservice-prefill-86f6fb7cdc-jx2w2 1/1 Running 0 2m30s
pod/ms-pd-llm-d-modelservice-prefill-86f6fb7cdc-vzcb8 1/1 Running 0 2m30s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/gaie-pd-epp ClusterIP 10.16.0.255 <none> 9002/TCP,9090/TCP 2m35s
service/gaie-pd-ip-bb618139 ClusterIP None <none> 54321/TCP 2m35s
service/infra-pd-inference-gateway-istio LoadBalancer 10.16.3.74 10.16.4.3 15021:31707/TCP,80:34096/TCP 2m41s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/gaie-pd-epp 1/1 1 1 2m36s
deployment.apps/infra-pd-inference-gateway-istio 1/1 1 1 2m42s
deployment.apps/ms-pd-llm-d-modelservice-decode 1/1 1 1 2m31s
deployment.apps/ms-pd-llm-d-modelservice-prefill 4/4 4 4 2m31s
NAME DESIRED CURRENT READY AGE
replicaset.apps/gaie-pd-epp-54444ddc66 1 1 1 2m36s
replicaset.apps/infra-pd-inference-gateway-istio-56d66db57f 1 1 1 2m42s
replicaset.apps/ms-pd-llm-d-modelservice-decode-84bf6d5bdd 1 1 1 2m31s
replicaset.apps/ms-pd-llm-d-modelservice-prefill-86f6fb7cdc 4 4 4 2m31s
注意: 这假设您的 ${NAMESPACE} 中没有其他指南部署,并且您没有通过 ${RELEASE_NAME} 环境变量更改默认 Release 名称。
使用该组件栈
有关开始发起推理请求的说明,请参阅 我们的文档
调优选择性 PD
在 Prefill-Decode 分离的上下文中,选择性 PD 是 inference-scheduler 中的一项功能,尽管它默认是禁用的。此功能允许即使在部署了 P/D 的情况下也仅路由到 Decode 节点。要启用它,您需要在 GAIE values 文件 中为 pd-profile-handler 插件设置 threshold(阈值)值。您可以在此处查看该值
cat gaie-pd/values.yaml | yq '.inferenceExtension.pluginsCustomConfig."pd-config.yaml"' | yq '.plugins[] | select(.type == "pd-profile-handler")'
type: pd-profile-handler
parameters:
threshold: 0 # update this
hashBlockSize: 5
您可能希望使用选择性 PD 的一些场景包括:
- 当提示词足够短,以至于将推理拆分为 Prefill 和 Decode 阶段、然后在两个 GPU 之间开启 KV 传输的工作量,大于在同一个 Decode 推理节点上完成两个阶段的工作量时。
- 当 Prefill 单元处于满负荷状态时。
有关此插件的信息,请参阅我们的 pd-profile-handler 文档(位于 inference-scheduler 中)
清理
移除部署
# Remove the model services
helmfile destroy -n ${NAMESPACE}
# Remove the infrastructure
helm uninstall ms-pd -n ${NAMESPACE}
helm uninstall gaie-pd -n ${NAMESPACE}
helm uninstall infra-pd -n ${NAMESPACE}
注意:如果您设置了 $RELEASE_NAME_POSTFIX 环境变量,您的发布名称将与上述命令不同:infra-$RELEASE_NAME_POSTFIX、gaie-$RELEASE_NAME_POSTFIX 和 ms-$RELEASE_NAME_POSTFIX。
清理 HTTPRoute
请按照特定提供商的说明删除 HTTPRoute。
清理 "kgateway" 或 "istio"
kubectl delete -f httproute.yaml -n ${NAMESPACE}
清理 "gke"
kubectl delete -f httproute.gke.yaml -n ${NAMESPACE}
自定义
有关自定义指南的信息以及构建自己的指南的技巧,请参阅 我们的文档
此内容自动同步自 llm-d/llm-d 仓库 main 分支上的 guides/pd-disaggregation/README.md。