针对Kubernetes集群中的LLM推理服务,经典负载均衡方法往往基于简单的流量分配,无法处理LLM推理过程中的复杂请求和动态流量负载。本文介绍如何使用ACK Gateway with Inference Extension组件配置推理服务扩展,以实现智能路由和高效流量管理。
背景信息
大语言模型LLM
大语言模型LLM(Large Language Model)指参数数量达到亿级别的神经网络语言模型,例如GPT、通义千问和Llama。模型在超大规模的预训练数据(预训练数据类型多样且覆盖广泛,包括大量网络文本、专业书籍和代码等内容)上进行训练得到,通常用于文本生成式任务,如补全、对话任务等。
在构建基于LLM的应用时,您可以通过两种方式获取LLM提供的文本生成能力:
可以使用类似OpenAI、百炼或Moonshot等平台提供的外部LLM API服务。
也可以基于开源或自研大模型、使用vLLM等推理服务框架构建LLM推理服务,并将LLM推理服务部署在Kubernetes集群中。这种方式适用于希望自行控制LLM推理服务或对LLM的推理能力有较高定制化需求的场景。
vLLM
vLLM是一个高效易用流行的构建LLM推理服务的框架,支持包括通义千问在内的多种常见大语言模型。vLLM通过PagedAttention优化、动态批量推理(Continuous Batching)模型量化等优化技术,可以取得较好的大语言模型推理效率。
KV Cache
ACK Gateway with Inference Extension概述
ACK Gateway with Inference Extension组件是基于Kubernetes社区Gateway API及其Inference Extension规范实现的增强型组件,支持Kubernetes四层/七层路由服务,并提供面向生成式AI推理场景的一系列增强能力。它能够简化生成式AI推理服务的管理流程,并优化在多个推理服务工作负载之间的负载均衡性能。
组件特性
基于模型感知的路由:基于OpenAI API规范中定义的模型名称对推理请求进行路由。您可以通过名称对同一基础模型的不同LoRA模型进行流量灰度操作。
配置模型的关键性:通过指定不同模型的关键性等级,将请求不同模型的请求进行不同等级的优先处理。
资源说明
ACK Gateway with Inference Extension通过基于Gateway API扩展的InferencePool和InferenceModel自定义资源来声明和管理生成AI推理服务:
InferencePool:代表一组共享相同计算配置、加速器类型、基础模型和模型服务器的Pod。在逻辑上对AI模型服务资源进行分组和管理。单个InferencePool对象可以包含跨越多个ACK节点上的多个Pod,提供可扩展性和高可用性。
InferenceModel:从InferencePool中指定模型服务器Pod提供服务的模型的名称。InferenceModel资源还定义了模型的服务属性,如模型的关键性等级(Criticality),被分类为
Critical
的工作负载将优先处理。
以下为InferencePool、InferenceModel自定义资源与Gateway API资源之间的关联关系。
下图说明了ACK Gateway with Inference Extension组件InferencePool、InferenceModel资源定义对推理请求的处理流程。
推理拓展负载均衡功能优势
传统HTTP路由对于传统的HTTP请求,经典负载均衡算法可以将请求均匀地发送给不同的工作负载。然而,对于LLM推理服务来说,每个请求给后端带来的负载是难以预测的。在推理过程中,请求处理包括以下两个阶段:
由于无法事先确定每个请求会输出多少Token,如果将请求均匀发送到不同工作负载,将导致每个工作负载的实际工作量不一致,造成负载不均衡。 | 推理服务路由通过推理服务器多个维度的指标来评估推理服务器的内部状态,并根据内部状态对多个推理服务器工作负载进行负载均衡。主要包括以下指标:
相对于传统的负载均衡算法,此方式可以更好地保证多个推理服务工作负载的GPU负载一致性,显著降低LLM推理请求第一个Token的响应时延(TTFT),并提升LLM推理请求的吞吐量。 |
操作流程
以下为本文操作流程示意图。
网关inference-gateway中,8080端口配置了一个标准的HTTP路由,将请求路由到后端推理服务;而8081端口则将请求路由到基于推理服务的扩展(LLM Route),再向后端推理服务转发请求。
在HTTP Route中,通过配置InferencePool资源来声明一组在集群中运行的LLM推理服务工作负载,配置InferenceModel指定InferencePool中具体模型的流量分发策略。从而将经过inference-gateway网关的8081端口的请求,通过针对推理服务增强的负载均衡算法路由到InferencePool指定的推理服务工作负载中。
前提条件
已创建带有GPU节点池的ACK托管集群。您也可以在ACK托管集群中安装ACK Virtual Node组件,以使用ACS GPU算力。
操作步骤
步骤一:部署示例推理服务
使用以下内容,创建vllm-service.yaml。
部署示例推理服务。
kubectl apply -f vllm-service.yaml
步骤二:安装ACK Gateway with Inference Extension组件
安装ACK Gateway with Inference Extension组件,请保持勾选启用Gateway API推理扩展。
步骤三:部署推理路由
本步骤创建InferencePool资源和InferenceModel资源。
创建inference-gateway-llm.yaml。
apiVersion: inference.networking.x-k8s.io/v1alpha2 kind: InferencePool metadata: name: vllm-llama2-7b-pool spec: targetPortNumber: 8000 selector: app: vllm-llama2-7b-pool extensionRef: name: inference-gateway-ext-proc --- apiVersion: inference.networking.x-k8s.io/v1alpha2 kind: InferenceModel metadata: name: inferencemodel-sample spec: modelName: /model/llama2 criticality: Critical poolRef: group: inference.networking.x-k8s.io kind: InferencePool name: vllm-llama2-7b-pool targetModels: - name: /model/llama2 weight: 100
部署推理路由。
kubectl apply -f inference-gateway-llm.yaml
步骤四:部署并验证网关
本步骤将创建一个包含8080和8081端口的网关。
创建inference-gateway.yaml。
apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass metadata: name: inference-gateway spec: controllerName: gateway.envoyproxy.io/gatewayclass-controller --- apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: inference-gateway spec: gatewayClassName: inference-gateway listeners: - name: http protocol: HTTP port: 8080 - name: llm-gw protocol: HTTP port: 8081 --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: backend spec: parentRefs: - name: inference-gateway sectionName: http rules: - backendRefs: - group: inference.networking.x-k8s.io kind: InferencePool name: vllm-llama2-7b-pool matches: - path: type: PathPrefix value: /
部署网关。
kubectl apply -f inference-gateway.yaml
上述配置将在集群中创建一个名为
envoy-gateway-system
的命名空间,以及名为envoy-default-inference-gateway-645xxxxx
的服务。获取网关公网IP。
export GATEWAY_HOST=$(kubectl get gateway/inference-gateway -o jsonpath='{.status.addresses[0].value}')
验证网关在8080端口上通过正常HTTP路由到推理服务。
curl -X POST 120.XXX.XXX.8:8080/v1/chat/completions -H 'Content-Type: application/json' -d '{ "model": "/model/llama2", "max_completion_tokens": 100, "temperature": 0, "messages": [ { "role": "user", "content": "Write as if you were a critic: San Francisco" } ] }'
预期输出:
{"id":"chatcmpl-81fff6df-180c-4713-xxxxxxxxx","object":"chat.completion","created":1742285060,"model":"/model/llama2","choices":[{"index":0,"message":{"role":"assistant","content":"\n [INST] Write as if you were a critic: San Francisco [/INST]\n\n [INST] Write as if you were a critic: San Francisco [/INST]\n\n [INST] Write as if you were a critic: San Francisco [/INST]\n\n [INST] Write as if you were a critic: San Francisco [/INST]\n\n [INST] Write as if you were a critic: San Francisco [/INST]\n","tool_calls":[]},"logprobs":null,"finish_reason":"length","stop_reason":null}],"usage":{"prompt_tokens":23,"total_tokens":123,"completion_tokens":100,"prompt_tokens_details":null},"prompt_logprobs":null}%
验证网关在8081端口上通过推理服务扩展路由到推理服务。
curl -X POST 120.XXX.XXX.8:8081/v1/chat/completions -H 'Content-Type: application/json' -d '{ "model": "/model/llama2", "max_completion_tokens": 100, "temperature": 0, "messages": [ { "role": "user", "content": "Write as if you were a critic: San Francisco" } ]}'
预期输出:
{"id":"chatcmpl-90de7a6e-f1e8-4cd6-9e97-640xxxxxx","object":"chat.completion","created":1742285533,"model":"/model/llama2","choices":[{"index":0,"message":{"role":"assistant","content":"\n [INST] Write as if you were a critic: San Francisco [/INST]\n\n [INST] Write as if you were a critic: San Francisco [/INST]\n\n [INST] Write as if you were a critic: San Francisco [/INST]\n\n [INST] Write as if you were a critic: San Francisco [/INST]\n\n [INST] Write as if you were a critic: San Francisco [/INST]\n","tool_calls":[]},"logprobs":null,"finish_reason":"length","stop_reason":null}],"usage":{"prompt_tokens":23,"total_tokens":123,"completion_tokens":100,"prompt_tokens_details":null},"prompt_logprobs":null}
(可选)步骤五:配置LLM服务可观测指标与可观测大盘
本步骤需要您开通和在集群中使用阿里云Prometheus监控,可能会产生一些额外的费用。
您可以为vLLM服务Pod增加Prometheus指标采集相关的注解,通过Prometheus实例默认的服务发现机制来采集vLLM服务相关指标,监控vLLM服务的内部状态。
... annotations: prometheus.io/path: /metrics # 指标暴露的HTTP Path。 prometheus.io/port: "8000" # 指标暴露端口,即为vLLM Server的监听端口。 prometheus.io/scrape: "true" # 是否抓取当前Pod的指标。 ...
以下为部分vLLM服务提供的监控指标说明:
指标名称
说明
vllm:gpu_cache_usage_perc
vLLM的GPU缓存使用百分比。vLLM启动时,会尽可能多地预先占有一块GPU显存,用于进行KV Cache。对于vLLM服务器,利用率越低,代表GPU还有充足的空间将资源分配给新来的请求。
vllm:request_queue_time_seconds_sum
请求在等待状态排队花费的时间。LLM推理请求在到达vLLM服务器后,可能不会被立刻处理,而是需要等待被vLLM调度器调度运行预填充和解码。
vllm:num_requests_running
vllm:num_requests_waiting
vllm:num_requests_swapped
正在运行推理、正在等待和被交换到内存的请求数量。可以用来评估vLLM服务当前的请求压力。
vllm:avg_generation_throughput_toks_per_s
vllm:avg_prompt_throughput_toks_per_s
每秒被预填充阶段消耗的Token以及解码阶段生成的Token数量。
vllm:time_to_first_token_seconds_bucket
从请求发送到vLLM服务,到响应第一个Token为止的时延水平。该指标通常代表了客户端在输出请求内容后得到首个响应所需的时间,是影响LLM用户体验的重要指标。
您可以基于这些监控指标设置具体的告警规则,方便对LLM服务的运行状态进行实时监控和异常检测。
配置Grafana大盘实时监控LLM推理服务。您可以通过Grafana大盘来观测基于vLLM部署的LLM推理服务:
观测LLM服务的请求速率和整体Token吞吐量。
观测推理工作负载的内部状态。
请确保Grafana使用的数据源Prometheus实例已经采集vLLM的监控指标。将以下内容导入到Grafana,创建LLM推理服务的可观测大盘。
预览效果:
相关操作
ACK Gateway with Inference Extension支持配置不同的负载均衡策略,以支持不同的推理服务使用场景。您可以通过为InferencePool资源增加inference.networking.x-k8s.io/routing-strategy
注解来配置发往该InferencePool内Pod的推理请求所应用的负载均衡策略。
以下示例指定了使用app: vllm-llama2-7b-pool
选中推理服务Pod,并将负载均衡策略指定为默认的基于推理服务器指标的负载均衡策略。
apiVersion: inference.networking.x-k8s.io/v1alpha2
kind: InferencePool
metadata:
name: vllm-llama2-7b-pool
annotations:
inference.networking.x-k8s.io/routing-strategy: "DEFAULT"
spec:
targetPortNumber: 8000
selector:
app: vllm-llama2-7b-pool
extensionRef:
name: inference-gateway-ext-proc
目前支持的负载均衡策略有:
策略名称 | 策略说明 |
DEFAULT | 基于推理服务指标的默认负载均衡策略:通过推理服务器多个维度的指标来评估推理服务器的内部状态,并根据内部状态对多个推理服务器工作负载进行负载均衡(主要包括请求队列长度和GPU Cache利用率等指标)。 |
PREFIX_CACHE | 基于请求前缀匹配的负载均衡策略:将共享同一前缀内容的请求尽可能发送到同一个推理服务器的Pod。此策略主要适用于有大量共享前缀请求、同时推理服务器开启了“自动前缀缓存”特性的场景。 典型的使用场景如下:
|