从云原生走向 AI 原生:一套面向未来的架构方法论 → 阅读《AI 原生基础设施》

vLLM 生产化部署:多副本、路由与可观测

草稿

单实例 vLLM 只是一个引擎。生产推理服务是一组副本,加一个懂 KV 缓存的路由器,加一套能回答“现在健康吗”的监控。

vLLM一章解决了单实例的资源契约:并发、显存水位线、Goodput。但生产环境还要回答三个新问题:实例挂了怎么办(多副本与故障转移)、请求该发给哪个副本(路由)、整个服务现在健康吗(可观测)。本章用 vLLM 官方参考实现 production-stack(Apache 2.0 许可,vLLM 社区维护)把这三块一次性立起来:应用代码保持 OpenAI 兼容接口不变,从单实例扩展到多副本部署。

从单实例到生产栈:缺的三块

能力单实例 vLLM生产栈(production-stack)
容量与容错单点,挂了即不可用多副本引擎,路由器自动剔除不健康实例
请求分发无(客户端直连)路由器按模型、会话、缓存局部性分发
可观测引擎自身指标Prometheus + Grafana 全链路面板
部署与升级手工Helm 声明式
扩展方向多模型共栈、KV 缓存卸载(LMCache)
表 1: 单实例与生产栈的能力对照

栈由三个组件构成:

  1. Serving engine:一组 vLLM 引擎 Deployment,可以跑同一个模型的多个副本,也可以跑不同模型(模型感知路由)。
  2. Request router:流量的唯一入口。通过 Kubernetes API 做服务发现与故障转移;支持多种路由算法(轮询、会话感知等,以官方文档为准);为每个引擎实例导出 QPS、TTFT、排队/运行中请求数等指标。
  3. Observability stack:Prometheus 采集加 Grafana 展示,开箱提供健康实例数、请求延迟分布、TTFT 分布、GPU KV 使用率与缓存命中率等面板。

路由器是这个栈的灵魂,原因要用LLM 推理的物理层来解释:会话内请求携带着相同或不断增长的前缀,落到同一个引擎实例上才能命中已算好的 KV 缓存块;随机轮询会把前缀缓存的收益打散。所以“会话感知路由”不是锦上添花,而是把物理层的容量账(前缀缓存可省一个数量级的显存与 TTFT)在多副本层面兑现的机制。

动手实验:用 Helm 部署最小生产栈

实验目标

单机 Kubernetes 与 GPU Operator的集群上,用三条命令部署“路由器 + 双引擎 + 监控”的最小生产栈,跑通 OpenAI 兼容请求,并在仪表盘上亲眼看到 KV 缓存命中率。

前置条件与成本预估

  • 一个带 GPU 的 Kubernetes 集群(上手篇的 minikube 集群即可),已装 Helm。
  • 磁盘空间:镜像约 20 GiB(引擎镜像随模型变化);模型权重默认从 Hugging Face 拉取(最小示例为 1B 级小模型)。
  • 成本:本地集群为零;云上集群约一小时实例费。

操作步骤

# 步骤 1:添加官方 Helm 仓库并部署最小示例
git clone https://github.com/vllm-project/production-stack.git
cd production-stack
helm repo add vllm https://vllm-project.github.io/production-stack
helm install vllm vllm/vllm-stack -f tutorials/assets/values-01-minimal-example.yaml

# 步骤 2:等待全部组件就绪
kubectl get pods --watch
# 预期:vllm 引擎、router、Prometheus、Grafana 全部 Running

# 步骤 3:将路由器端口转发到本地,发送 OpenAI 兼容请求
kubectl port-forward service/vllm-router-service 8080:80 &
curl http://localhost:8080/v1/chat/completions -H "Content-Type: application/json" -d '{
  "model": "facebook/opt-125m",
  "messages": [{"role": "user", "content": "Hello!"}]
}'
# 服务名以 kubectl get svc 输出为准,最小部署通常为 vllm-router-service

# 步骤 4:查看仪表盘(Grafana 端口转发后浏览器打开,登录凭据见仓库 helm/README)
kubectl get svc   # 找到 Grafana 服务并 port-forward

验证清单

  • 引擎、路由器、监控组件全部 Running
  • 步骤 3 的请求返回了合法的 chat completion
  • Grafana 面板能看到健康实例数、TTFT 分布、GPU KV 使用率
  • 用同一会话连发多条请求,KV 缓存命中率上升(会话感知路由生效的直接证据)
  • 删除任意一个引擎 Pod,请求不中断,面板健康实例数自动减少再恢复(故障转移生效)

原理速览

路由器通过 Kubernetes API watch 引擎 Pod 的生死,这决定了故障转移是秒级的、不需要人工改配置;会话感知路由把同会话请求钉在同一个引擎上,让分页 KV的前缀缓存跨请求复用;Prometheus 抓取的是路由器聚合后的每实例指标,所以面板天然支持多副本对比。这套“服务发现、路由、指标”三件套,就是自服务 GPU 平台里推理网关背后的骨架。

清理与止损

helm uninstall vllm
kubectl delete pvc -l app.kubernetes.io/instance=vllm   # 清理模型缓存卷(若创建)

云集群不用时按从免费开始一章的 terminate 纪律关停。

路由策略怎么选

策略机制适用代价
轮询逐个分发给健康实例无状态负载、压测前缀缓存收益被打散
会话感知同会话固定到同一实例多轮对话、Agent 调用副本间负载可能不均
模型感知按请求中的模型名分发一栈多模型需要模型别名管理
表 2: 路由策略对比(以官方文档为准,算法持续演进)

验收路由质量的指标不是“请求成功了”,而是 KV 缓存命中率:命中率上不去,说明会话被路由打散了,物理层的容量账(前缀缓存)没有兑现。

这条路线的下一步:缓存卸载与 PD 分离

参考栈本身也在快速演进,两个方向值得跟踪:

  • KV 缓存卸载(LMCache):把 KV 块卸载到主机内存或远端存储,等价于给引擎加了一层“显存的 swap”,官方教程提供了开关式的启用方法。
  • 预填充与解码分离(disaggregated prefill):这正是LLM 推理的物理层讨论分块预填充时预告的方向,预填充与解码拆到不同实例,用集群层化解 TTFT 与 ITL 的冲突;该项目已将其列入路线图。

参考栈的定位是“起点的最佳实践”,而不是终点:多模型共栈、按 vLLM 指标自动伸缩都在路线图上。副本数固定的问题,正是下一章的主题。

总结

生产化把 vLLM 从“引擎”变成“服务”:Helm 三条命令立起多副本、路由与监控;会话感知路由让 KV 缓存复用在多副本下依然成立;KV 命中率与 TTFT 分布是这一层最值得盯的两个验收指标。至此推理侧还剩最后一个问题:负载有潮汐,副本数不能写死。下一章GPU 推理自动伸缩解决它:从并发指标到队列事件,再到缩容到零与四层冷启动账。

参考资料

创建于 2026/09/15 更新于 2026/09/15 2230 字 阅读约 5 分钟