将前缀缓存卸载到 CPU 内存
概览
本指南提供了通过 vLLM 原生卸载连接器和 LMCache 连接器将前缀缓存卸载到 CPU RAM 的方案。
先决条件
-
所有前提条件请参考 上级目录。
-
请在本地系统中安装适当的客户端工具以使用本指南。
-
确保您的集群基础设施足以 部署大规模推理。
-
为安装创建一个命名空间。
export NAMESPACE=llm-d-pfc-cpu # or any other namespace (shorter names recommended)
kubectl create namespace ${NAMESPACE} -
在目标命名空间中创建名为 `llm-d-hf-token` 的 Secret,其键为 `HF_TOKEN`,并匹配有效的 HuggingFace 令牌以拉取模型。
安装
cd guides/tiered-prefix-cache/cpu
1. 部署 Gateway 和 HTTPRoute
使用 gateway 方案 部署 Gateway 和 HTTPRoute。
2. 部署 vLLM 模型服务器
- 卸载连接器 (Offloading Connector)
- LMCache 连接器
3. 部署 InferencePool
要部署 InferencePool,请在下方选择您的提供商。
- GKE
- Istio
- Kgateway
GKE
此命令在 GKE 上部署 InferencePool,并启用 GKE 特定的监控。
helm install llm-d-infpool \
-n ${NAMESPACE} \
-f ./manifests/inferencepool/values.yaml \
--set "provider.name=gke" \
--set "inferenceExtension.monitoring.gke.enable=true" \
oci://us-central1-docker.pkg.dev/k8s-staging-images/gateway-api-inference-extension/charts/inferencepool \
--version v1.2.0
Istio
此命令通过 Istio 部署 InferencePool,并启用 Prometheus 监控。
helm install llm-d-infpool \
-n ${NAMESPACE} \
-f ./manifests/inferencepool/values.yaml \
--set "provider.name=istio" \
--set "inferenceExtension.monitoring.prometheus.enable=true" \
oci://us-central1-docker.pkg.dev/k8s-staging-images/gateway-api-inference-extension/charts/inferencepool \
--version v1.2.0
Kgateway
此命令通过 Kgateway 部署 InferencePool。
helm install llm-d-infpool \
-n ${NAMESPACE} \
-f ./manifests/inferencepool/values.yaml \
--set "provider.name=kgateway" \
oci://us-central1-docker.pkg.dev/k8s-staging-images/gateway-api-inference-extension/charts/inferencepool \
--version v1.2.0
为了启用分层前缀缓存,我们自定义了 InferencePool 配置(见 manifests/inferencepool/values.yaml)。我们配置了两个前缀缓存评分器:一个用于 GPU 缓存,另一个用于 CPU 缓存。
对于 CPU 缓存,我们必须手动配置 lruCapacityPerServer,因为 vLLM 目前不发送 CPU block 指标。
当前的权重配置为 2:2:1:1(队列评分器 : KV 缓存利用率评分器 : GPU 前缀缓存评分器 : CPU 前缀缓存评分器)。目前的 CPU 卸载会将 GPU 缓存条目复制到 CPU,从本质上使 CPU 缓存成为 GPU 的超集。此权重配置确保了 GPU 和 CPU 前缀缓存评分器的组合权重等于 2。
您可以根据具体需求调整这些值,特别是 GPU 和 CPU 评分器之间的比例。当前的配置在我们的 基准测试 中表现出了性能提升。
验证安装
您可以通过检查所创建资源的状态来验证安装。
检查 Gateway
kubectl get gateway -n ${NAMESPACE}
您应该看到类似于以下内容的输出,其中 PROGRAMMED 状态为 True。
NAME CLASS ADDRESS PROGRAMMED AGE
llm-d-inference-gateway gke-l7-regional-external-managed <redacted> True 16m
检查 HTTPRoute
kubectl get httproute -n ${NAMESPACE}
NAME HOSTNAMES AGE
llm-d-route 17m
检查 InferencePool
kubectl get inferencepool -n ${NAMESPACE}
NAME AGE
llm-d-infpool 16m
检查 Pod
kubectl get pods -n ${NAMESPACE}
您应该看到 InferencePool 的 endpoint pod 和模型服务器 pod 处于 Running 状态。
NAME READY STATUS RESTARTS AGE
llm-d-infpool-epp-xxxxxxxx-xxxxx 1/1 Running 0 16m
llm-d-model-server-xxxxxxxx-xxxxx 1/1 Running 0 11m
llm-d-model-server-xxxxxxxx-xxxxx 1/1 Running 0 11m
清理
移除部署
helm uninstall llm-d-infpool -n ${NAMESPACE}
kubectl delete -k ./manifests/vllm/offloading-connector -n ${NAMESPACE}
kubectl delete -k ../../../../recipes/gateway/gke-l7-regional-external-managed -n ${NAMESPACE}
kubectl delete namespace ${NAMESPACE}
附录
基准测试
以下基准测试结果展示了使用 vLLM 原生 CPU 卸载和 LMCache CPU 卸载的性能提升。
基准测试设置
-
硬件
- 共使用了 16 个 H100 GPU,每个 GPU 带有 80GB 的 HBM。
- GPU 分布在 4 个
a3-highgpu-4g实例中,每个实例有 4 个 GPU。
-
vLLM 配置
gpu_memory_utilization设置为0.65以减轻基准测试工具的压力。在生产配置中,这通常设置为更高的值,例如 0.9。- 启用了 CPU 卸载,
num_cpu_blocks设置为41000,提供约 100GB 的 CPU 缓存。
-
LMCache 配置
- 对于 LMCache 设置,
LMCACHE_MAX_LOCAL_CPU_SIZE设置为 100 GB。
- 对于 LMCache 设置,
基准测试是使用 inference-perf 工具进行的,具有以下硬件、内存和工作负载配置
-
工作负载
- 在 45 个请求的恒定并发下测试了两种不同的工作负载。
- 高缓存
组数 (num_groups): 45系统提示词长度 (system_prompt_len): 30,000问题长度 (question_len): 256输出长度 (output_len): 1024每组提示词数量 (num_prompts_per_group): 10
- 低缓存
组数 (num_groups): 45系统提示词长度 (system_prompt_len): 8000问题长度 (question_len): 256输出长度 (output_len): 1024每组提示词数量 (num_prompts_per_group): 10
-
内存计算
Qwen/Qwen3-32B模型的 KVCache 大小约为每 token 0.0002 GB。- 当
gpu_memory_utilization为 0.65 时,每个引擎有 9271 个可用 GPU block。 - 每个引擎可用于 KVCache 的 HBM 约为 24.3GB(9271 blocks * 2.62 MB/block)。
- 整个系统用于 KVCache 的总可用 HBM 为 193.4 GB(8 引擎 * 24.3 GB/引擎)。
关键结论
- 在高缓存场景下(KVCache 大小超过可用 HBM),vLLM 原生 CPU 卸载连接器和 LMCache 连接器都能显著提升性能。
- 在低缓存场景下(KVCache 完全可以装入 GPU 的 HBM),所有卸载配置的性能都与基准线(Baseline)相似。然而,各项指标的一致轻微下降表明,即使没有被实际利用,启用 CPU 卸载也会带来少量的开销。
高缓存性能
下表对比了在 KVCache 大于可用 HBM 时,基准 vLLM 与使用 CPU 卸载连接器的 vLLM 的性能。
| HBM < KVCache < HBM + CPU RAM | 平均 TTFT(秒) | P90 TTFT(秒) | 平均端到端延迟(秒) | P90 端到端延迟(秒) | 总吞吐量(token/秒) |
|---|---|---|---|---|---|
| 基准 vLLM | 9.0 | 20.9 | 37.8 | 49.7 | 38534.8 |
| vLLM + CPU 卸载 100GB | 6.7 (-25.6%) | 20.2 (-3.3%) | 30.9 (-18.3%) | 44.2 (-11.1%) | 46751.0 (+21.3%) |
| vLLM + LMCache CPU 卸载 100GB | 6.5 (-27.8%) | 18.8 (-10.0%) | 30.8 (-18.5%) | 43.0 (-13.5%) | 46910.6 (+21.7%) |
低缓存性能
下表显示,当 KVCache 可以装入 HBM 时,所有配置的性能相似,这表明 CPU 卸载机制带来的开销极小但可测量。
| KVCache < HBM | 平均 TTFT(秒) | P90 TTFT(秒) | 平均端到端延迟(秒) | P90 端到端延迟(秒) | 总吞吐量(token/秒) |
|---|---|---|---|---|---|
| 基准 vLLM | 0.12 | 0.09 | 18.4 | 19.6 | 23389.6 |
| vLLM + CPU 卸载 100GB | 0.13 | 0.11 | 18.6 | 20.6 | 23032.6 |
| vLLM + LMCache CPU 卸载 100GB | 0.15 | 0.10 | 18.9 | 19.6 | 22772.5 |
此内容自动同步自 llm-d/llm-d 仓库 main 分支下的 guides/tiered-prefix-cache/cpu/README.md。