
使用 FastAPI 和 RabbitMQ 构建端到端微服务:综合指南
在 Kubernetes 上运行 AI 推理工作负载有其独特的特点和挑战,Gateway API 推理扩展项目旨在解决这些挑战。我最近写了关于 kgateway v2.0.0 中引入的新功能。在这篇博客中,我们将深入探讨它的工作原理。
大多数人将 Kubernetes 上的请求路由与 Gateway API、Ingress 或服务网格(我们称之为 L7 路由器)联系在一起。这些实现方式非常相似:你指定一些路由规则,评估请求的属性(如头信息、路径等),L7 路由器决定将请求发送到哪个后端端点。这个过程使用某种负载均衡算法(如轮询、最少请求、环哈希等)。
传统的负载均衡算法可能不适合 AI/LLM 模型后端。与典型的无状态 Web API 不同,基于 GPU 的 LLM 有不同的运行方式,需要更细致的方法,这能节省很多成本。如果我们能够利用模型和 GPU 的实时指标来做出更智能的路由和负载均衡决策呢?例如,如果后端 LLM 已经加载了特定的微调(LoRA)适配器,那么对这些模型的请求应该路由到这些端点,而不是那些缺少适配器的端点,从而避免按需加载带来的不必要 GPU 开销。同样,如果后端已经被排队的请求压垮,发送更多请求只会降低性能。如果所有后端 LLM 都处于高负载状态,我们是否可以实施负载削减(在适当情况下)以保障系统稳定性?
这正是 Gateway API 推理扩展项目的目标。它引入了两个新的 Kubernetes 自定义资源定义(CRD):InferenceModel 和 InferencePool,以及一个可以扩展 L7 路由的“端点选择器”概念。这个端点选择器利用底层 LLM 的指标,为 L7 路由基础设施做出更智能的路由和负载均衡决策。例如,kgateway 和 Istio 等项目可以将其集成到自己的实现中。
推理扩展扩展了 Gateway API 推理扩展引入了两个新的自定义资源定义(CRD):InferenceModel 和 InferencePool。通过使用这两个新资源以及端点选择器,L7 路由基础设施变成了一个“推理网关”,使你能够以“模型即服务”的思维自托管 GenAI/LLM。
InferenceModel CRD 旨在为 AI 工程师提供服务,允许他们定义逻辑模型推理端点。它将用户面向的模型名称映射到后端模型,并为流量分配提供灵活性。例如,假设你想将名为 llama2 的模型暴露给客户端,但后端模型可能名为 vllm-llama2-7b-2024-11-20 或 vllm-llama2-7b-2024-12-10。使用 InferenceModel,你可以实现这一点并在这些模型之间分配流量。也许你想引入一个新的模型,如 vllm-llama2-7b-2025-03-24。
apiVersion: inference.networking.x-k8s.io/v1alpha2
kind: InferenceModel
metadata:
name: inferencemodel-llama2
spec:
modelName: llama2
criticality: Critical
poolRef:
name: vllm-llama2-7b-pool
targetModels:
- name: vllm-llama2-7b-2024-11-20
weight: 75
- name: vllm-llama2-7b-2025-03-24
weight: 25
此外,它允许工作负载所有者指定请求的重要性,确保实时服务优先于尽力而为的批处理作业。下面我们将根据 LLM 指标看到这一点的具体表现。
另一方面,InferencePool CRD 面向管理模型服务基础设施的平台运营者。它表示一组模型服务实例,并作为 AI 工作负载的专用后端服务。换句话说,你可以通过 InferencePool 将请求直接路由到一组推理端点。该池通过指定使用哪个端点选择器来管理感知推理的端点选择,基于实时指标(如请求队列深度和 GPU 内存可用性)做出智能路由决策。
apiVersion: inference.networking.x-k8s.io/v1alpha2
kind: InferencePool
metadata:
name: vllm-llama2-7b-pool
spec:
targetPortNumber: 8000
selector:
app: vllm-llama2-7b
extensionRef:
name: vllm-llama2-7b-endpoint-picker
要设置路由,使得对推理网关的请求发送到后端 LLM,我们首先需要创建一个将流量路由到 InferencePool 的 HTTPRoute。
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: llm-route
spec:
parentRefs:
- name: inference-gateway
rules:
- backendRefs:
- group: inference.networking.x-k8s.io
kind: InferencePool
name: vllm-llama2-7b
matches:
- path:
type: PathPrefix
value: /
现在,当请求到达推理网关时,它将根据 HTTPRoute 中的内容进行匹配,然后将请求发送到 InferencePool。在这里事情变得有趣。使用 Envoy 支持的 L7 路由器(如 kgateway 或 Istio),通常路由策略和负载均衡将选择请求发送到的端点。但在 InferencePool 中,请求首先会进入一个专用的扩展“端点选择扩展选择器”(ESE)。这个 ESE 将根据 LLM 的指标选择合适的后端 LLM 端点。让我们更深入地了解它的工作原理。
当请求到达端点选择扩展(ESE)时,它会从请求体中提取 modelName。目前,ESE 期望请求体遵循 OpenAI API 格式。一旦识别出 modelName,ESE 将其与可用 InferenceModel 对象的 modelName 字段进行比较,以确定相应的后端模型名称或 LoRA 适配器。例如,如果 ESE 检测到请求的模型名称为 llama2,它将找到匹配的 InferenceModel,并将请求路由到相应的端点,如 vllm-llama2-7b-2024-11-20 或 vllm-llama2-7b-2025-03-24。
选择特定模型的端点的逻辑在 ESE 中定义为一系列“过滤器”。这些过滤器评估以下标准,以决定最终的端点:
过滤流程以“这是一个重要请求吗?”开始。如果请求是 Critical 请求,它将检查是否有 LLM 端点的等待队列小于 50。如果找到这些端点,它将检查这些端点是否加载了模型所需的 LoRA 适配器。如果找到一个通过这些过滤器的端点,它就是返回的端点。如果没有找到加载了正确 LoRA 适配器的端点,它会找到下一个最佳选项,即可以加载请求的 LoRA 适配器的端点。
如果过滤器看到一个 Sheddable 请求,它将寻找 KV 缓存利用率低于 80% 且等待队列少于 5 的 LLM。如果找不到满足该条件的 LLM 端点,则丢弃该 Sheddable 请求。
让我们看几个场景:
给定以下 Pod:
对于一个需要 LoRA-X 的重要请求:
给定以下 Pod:
对于一个非重要请求:
给定以下 Pod:
对于一个需要 LoRA-Y 的重要请求:
Gateway API 推理扩展项目引入了一些强大的模型选择和负载均衡功能,旨在提高在 Kubernetes 上运行时 GPU 和 LLM 的利用率。GPU 供应紧张且价格昂贵。推理扩展项目可以显著改善请求处理,为组织节省大量资金。项目网站上有一些初步数字,下一篇博客文章中我将提供更多负载测试数据。