系统学习 AI 学习路径:从 GPU 运行时到推理、微调与 RAG 评估

版本信息最后核对:2026-10-25

inference-autoscaling

推理服务自动扩缩容:HPA/KEDA 指标、排队与并发、冷启动、GPU 容量和缩容抖动的排查路径。

现象

推理服务的扩缩容问题通常以两种相反的形式出现:高峰期扩容不及时,请求排队、TTFT 变长、超时和重试增多;低谷期副本不降,GPU 空转,成本居高不下。也可能出现第三种:副本数在短时间内反复上下,服务刚扩容就缩容,缩完又立刻扩容。

Kubernetes 侧常见信号包括 HPA 的 TARGETS 显示 <unknown>、副本数长时间不变、kubectl describe hpa 出现指标获取失败、新 Pod 长时间 Pending 或 ContainerCreating、就绪探针失败。应用侧则表现为等待队列持续增长、GPU 利用率不高但延迟很高,或者扩容后吞吐没有提升。

自动扩缩容不是“把 maxReplicas 调大”这么简单。它依赖指标能代表瓶颈、单副本容量可测、新副本能及时就绪、集群有资源可分配。任何一环缺失,扩容都不会按预期生效。

快速判断

先回答一个问题:当前瓶颈是单副本处理能力,还是副本数量?如果单副本已经打满 GPU、队列仍在增长,增加副本才有意义;如果单副本 GPU 利用率不高,增加副本可能只是增加空转。

kubectl get hpa -A
kubectl describe hpa <name> -n <namespace>
kubectl get scaledobject -n <namespace>
kubectl describe scaledobject <name> -n <namespace>
kubectl get pods -n <namespace> -o wide
kubectl top pods -n <namespace>
kubectl get events -n <namespace> --sort-by=.lastTimestamp | tail -30

观察点:

判断表:

线索 更可能的方向
TARGETS 为 <unknown> 或 HPA 不动作 指标链路断了,不是容量问题
CPU 很低但队列持续增长 指标选错,CPU 不代表推理瓶颈
队列增长、GPU 利用率高、延迟上升 容量不足,需要副本或更强单副本
扩容后 Pod 一直 Pending 集群 GPU、配额、污点或亲和性不足
扩容后吞吐不升、单 Pod 仍排队 单副本瓶颈或下游依赖限制
新 Pod 启动很久才 Ready 冷启动:镜像、模型下载、编译、预热
副本数频繁上下 阈值过窄、指标抖动、缩容窗口过短
低谷仍有大量副本 指标滞后、最小值过高、缩容策略保守

再回答四个问题:

  1. 扩缩容依据的指标是否直接反映瓶颈?CPU、内存、GPU 利用率、队列长度和并发数的含义不同。
  2. 单副本的饱和吞吐是多少?没有这个基线,就无法判断该加副本还是调单副本参数。
  3. 新副本多久能接流量?冷启动时间决定了扩容是否来得及。
  4. 集群还有没有可分配的 GPU?maxReplicas 不等于集群一定能提供这么多副本。

常见原因

指标选错或不可用

推理瓶颈通常在 GPU 计算、KV Cache 或请求队列,而默认 HPA 常按 CPU 利用率扩缩。CPU 不高但 GPU 已满时,HPA 不会扩容;CPU 因 tokenizer 或日志升高时,又可能扩出无用的副本。metrics-server 未部署、custom metrics API 未注册、KEDA 触发器鉴权失败,会让指标直接不可用。

阈值与行为配置

目标值过低会导致副本过多,过高会长期排队;容差、扩缩容速率限制、缩容稳定窗口和冷却时间不匹配流量形态,会造成抖动。多指标时 HPA 取各指标建议副本数的最大值,任何一个指标异常都可能主导决策。

冷启动

镜像拉取、模型下载、权重加载、图编译、缓存预热和探针初始延迟,都会让新副本在流量高峰时迟迟不能服务。缩容到零的配置虽然省钱,但首次请求要承担完整冷启动。

集群容量与调度

maxReplicas 只是上限,节点池没有 GPU、ResourceQuota 不足、节点有污点、Pod 亲和性与拓扑约束过严、PVC 挂载慢,都会让新副本 Pending。集群自动扩缩器申请新节点也需要时间,GPU 机型还可能受供应限制。

单副本瓶颈

批处理参数、KV Cache 容量、tokenizer CPU、下游依赖、网络带宽都可能限制单副本吞吐。此时增加副本能线性提升总吞吐的前提是瓶颈确实在副本内且可水平扩展。

缩容抖动

流量尖峰、指标采集窗口短、缩容后连接迁移和缓存丢失,会让副本刚缩就再次扩容。长连接、流式响应和会话粘性也会让缩容变得危险。

排查步骤

第一步:确认指标链路

先看 HPA 能否读到指标,再看指标是否代表瓶颈。检查 metrics-server、custom metrics API、KEDA 的 ScaledObject 状态和触发器错误。指标读不到时,调阈值没有意义。

第二步:测单副本容量

固定模型、输入输出长度和并发,逐级加压,记录吞吐、TTFT、TPOT、排队数和 GPU 利用率,找到饱和点。这个基线决定扩容目标和单副本参数,不要用不同输入分布的压测结果直接比较。

第三步:记录扩容时序

从流量上升到副本 Ready 逐步打点:指标采集延迟、HPA 决策、Pod 创建、镜像拉取、模型加载、预热、探针通过、开始接流量。找出耗时最长的一段,再决定是优化冷启动还是提前扩容。

第四步:检查调度与配额

kubectl describe node <gpu-node> | grep -A8 'Allocated resources'
kubectl get resourcequota -n <namespace>
kubectl get events -n <namespace> | grep -i -E 'failed|pending|insufficient'

确认 GPU 资源、显存、CPU 和内存请求是否可满足,节点池上限和自动扩缩器状态是否正常,污点与容忍、亲和性是否阻止调度。

第五步:观察缩容行为

查看缩容稳定窗口、冷却时间、速率限制和最小副本数。确认缩容时是否有长连接被中断、缓存是否被清空、是否会触发重新排队。缩容后立即扩容通常说明窗口太短或指标抖动。

第六步:核对成本

按副本、GPU 型号和空闲时长统计成本,区分“必要的容量”和“缩不掉的空转”。成本优化不能只看副本数,还要看单副本利用率和缩容到零的冷启动代价。

第七步:灰度调参

一次只改一个参数:目标值、最小/最大副本、稳定窗口、冷却时间或指标类型。在预发或小流量环境用阶梯负载验证,记录扩容时延、P95、错误率和成本,再推广。

修复与验证

验证要做阶梯压测:从低负载逐步升到峰值,再降回低负载,观察扩容是否及时、缩容是否平稳、P95 和错误率是否达标、成本是否符合预算。只在稳定状态看副本数,无法发现冷启动和抖动问题。

修改 HPA/KEDA 配置、缩容到零、调整节点池都属于高风险操作:先在预发验证,保留旧配置和回滚步骤,避免在流量高峰执行。缩容到零前要确认请求超时、冷启动预算和用户体验可接受。

预防

相关命令

参考链接

读完自测

合上页面,先回答,再展开对照。

  1. HPA 按 CPU 扩缩,但 GPU 已满、CPU 不高,为什么副本不增加?
  2. 扩容后 Pod 一直 Pending,应该先查哪些对象?
  3. 缩容后马上又扩容,通常说明什么?
答案
  1. 因为 HPA 只看 CPU 指标,CPU 未达到目标值就不会触发扩容;而推理瓶颈在 GPU 或请求队列,CPU 不能代表实际压力。应改用队列长度、并发数、GPU 相关指标或 KEDA 外部触发器,并先确认指标链路可用。
  2. 先看 Pod 事件和节点状态:是否有 Insufficient GPU、节点污点与容忍不匹配、亲和性过严、ResourceQuota 不足、PVC 挂载失败;再看节点池是否达到上限、集群自动扩缩器是否在申请新节点。maxReplicas 允许并不代表集群有资源。
  3. 通常说明缩容条件过于激进或指标抖动:缩容稳定窗口太短、冷却时间不足、流量尖峰被误判为持续下降,或者缩容后连接迁移和缓存丢失造成延迟上升,触发再次扩容。应加长稳定窗口、使用平滑指标,并对长连接做 draining。
微信小程序码:扫码打开命令速查小程序

小程序版

微信扫码,随时查命令