freeCodeCamp.org

How to Diagnose and Fix AI Inference Latency on Kubernetes

7.1内容质量

TL;DR · AI 摘要

How to Diagnose and Fix AI Inference Latency on Kubernetes September 30, 2026 / AI Gursimar Singh It's Thursday, around...

核心要点

  • 主题聚焦:How to Diagnose and Fix AI Inference Latency on
  • 来源:freeCodeCamp.org,建议结合原文判断细节。
  • AI 分析暂不可用,本条为保底评分与摘要。
#AI#编程#前端#后端#云计算
打开原文

如何在 Kubernetes 上诊断和修复 AI 推理延迟

2026年9月30日

/

#AI

Gursimar Singh

星期四,大约下午两点十五分。你们团队两周前上线了一个内部助手。演示效果足够好,以至于财务部门有人问它是否能阅读合同。消息传开后,今天第一次,所有人都同时在使用它。

支持渠道出现了六种不同语气的相同投诉。系统是不是宕机了?我的界面卡住了。早上还正常。有人上传了一张加载指示器的截图,没有说明文字,你怀疑他们正享受这个时刻。

于是你打开了仪表盘。

节点就绪。Pod 正在运行。CPU 使用率 20%。没有重启,没有 CrashLoopBackOff,也没有触发任何告警。从 Kubernetes 提供的每一个信号来看,系统都是健康的。

它并不健康。有人正在等待第一个字的回答,已经等了十一秒,他们即将回到旧方式操作,而且不会再回来了。

本文要解决的正是这种故障。不是宕机。而是一种静默故障:所有组件从技术角度看都正常,但产品仍然无法使用。

目录

  • 你的第一反应是错误的
  • 你并不是唯一遇到这个问题的人
  • 部署时没人告诉你的事情
  • 十一秒去哪了 第一阶段:路由:你的负载均衡器在猜 第二阶段:队列:没人来帮忙 第三阶段:预填充:GPU 存在但毫无用处 第四阶段:解码:你的入口网关正在切断用户 在这四个阶段之下:突发流量和无人负责的问题
  • 同时,平台并未停滞不前
  • 首先要了解问题的根源
  • 火灾平息后的应对措施:容量、性能、部署、弹性、责任归属
  • 你的监控系统仍未告诉你的四件事
  • 仍未解决的问题
  • 周一早晨
  • 回到星期四

你的第一反应是错误的

那一刻的直觉是怀疑模型本身。可能是版本错误、量化不当、上下文过长,或者有人修改了系统提示。

但几乎从不涉及模型本身。

跟踪一个请求的完整流程,你会发现四个阶段。请求被路由到副本。它在队列中等待。模型读取提示。模型流式传输回答。只有最后两个阶段涉及你付费使用的模型功能。前两个阶段是排队和路由,换句话说,属于基础设施。

当人们说他们的模型很慢时,模型本身通常没有问题。等待发生在其他地方。

同一项研究还提到,一些组织要求响应时间必须低于250毫秒,同时保持99.9%的可用性。请仔细阅读这句话,因为从字面意义上理解,这几乎是不可能实现的。没有任何一个有意义的大型语言模型响应能在四分之一秒内完成。这实际上指的是第一个token生成时间(即答案第一个字出现所需的时间),而这也是你应该始终关注的正确指标。一旦token开始以可读速度连续生成,人们就不会再关注时间了。真正让用户流失的是等待第一个token出现时的沉默期。

部署时没人告诉你的事

这就是解释所有其他问题的部分。

一个普通的网页请求是短暂的、小规模的,其成本大致与上一次请求相当。Kubernetes调度假设了这一点。服务负载均衡也假设了这一点。水平Pod自动扩展器同样假设了这一点。你的入口控制器默认超时设置也假设了这一点。没有人明确写出这个假设,因为在过去的十五年里,这一直是一个显而易见的事实。

而大型语言模型请求在三个层面打破了这个假设。

它分为两个完全不同的阶段运行。预填充阶段:模型一次性读取整个提示内容。这个阶段是计算密集型的、突发性的,决定了用户需要盯着空白屏幕等待多久。然后是解码阶段:逐个生成token,每个token都需要之前所有token的累积状态。这个状态就是键值缓存(KV cache),它与模型权重一起存储在GPU内存中,并随着答案长度增加而持续增长。

因此,请求并不短暂,可能持续长达一分钟。它们的成本也不相同,一个包含粘贴文档的提示可能比一个简短语句的成本高50倍。而且,真正稀缺的资源是GPU内存,它不会出现在你继承的任何单一仪表板上。

这就是为什么你的监控系统显示一切正常。它测量的是错误的机器。

那11秒去哪儿了

沿着请求的四个阶段追踪,故障模式会按顺序显现。这六个问题是最常被从业者提及的,它们与请求路径完美对应。

第一阶段:路由——你的负载均衡器在猜

当请求成本出现差异时,轮询算法就不再公平了。三个包含重提示的请求可能被分配到同一个Pod,而相邻的Pod却在处理简短语句。负载较高的Pod队列增长,尾部延迟上升,而整个集群的平均延迟仍然看起来完全正常,这就是为什么今天之前没人注意到这个问题。

长连接会加剧这种情况。使用HTTP/2或keepalive时,客户端会打开一个连接并沿此连接发送所有请求,而Kubernetes服务是按连接而非请求进行负载均衡的。所有流量都会固定到某个后端节点并持续停留。

还有一个大多数团队从未考虑过的成本。如果某个副本的KV缓存中已经包含该提示的前缀,路由到该副本会跳过实际的预填充工作。由于大多数生产环境中的提示都包含一个长系统前缀,这并不是边缘情况,而是你大部分流量的常态。轮询算法每次都会随机地浪费这个优势。

第二阶段:队列——没人来帮忙

你的自动扩展器可以增加容量。但它的响应会很慢,原因很不体面:新副本需要从网络下载一个多GB的服务镜像,获取20GB到70GB的模型权重,并将它们加载到GPU内存中。这需要数分钟而非数秒,这还假设节点上已经有可用的GPU卡。如果没有,还要加上节点配置时间,并加上你的云服务提供商今天是否在该区域有库存。

还有一个叠加在第一个问题上的第二个问题:信号通常不准确。CPU在此处无法提供任何信息,因为当GPU工作时CPU处于空闲状态。GPU利用率的指标也差不多:它会报告在采样窗口期间执行了内核,无论是处理一个请求的服务器还是处理六十个请求的服务器,读数都显示为100%。它无法告诉你是否有任何人在等待。

队列深度可以做到这一点。vLLM已经将运行和等待的请求数量作为Prometheus指标暴露出来。基于这些指标进行扩展:

code
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: llm-server
spec:
  scaleTargetRef:
    name: llm-server
  minReplicaCount: 2
  maxReplicaCount: 8
  cooldownPeriod: 600
  triggers:
    - type: prometheus
      metadata:
        serverAddress: http://prometheus.monitoring:9090
        query: sum(vllm:num_requests_waiting{app="llm-server"})
        threshold: "5"

检查指标名称是否与你的vLLM版本匹配。在多个版本中这些指标名称被重命名过,且失败时不会发出任何提示。

那里有两个值是刻意设置的。最小值设为2,因为冷启动时你不能指望在零副本时就能提供服务。十分钟的冷却时间,因为急于扩展会导致不久后再次经历冷启动。

这导致了关于自动扩展推理的令人不安的结论:反应式扩展始终会延迟,延迟时间等于你的冷启动所需时间,没有任何触发器能解决这个问题。解决方案是保持比感觉舒适的更多备用容量。始终运行额外的副本,在认为需要之前就提前扩展,缓慢地进行缩容。这也意味着“扩展到零”不适合面向用户的推理服务。将其保留给批处理任务,因为没有人会坐在那里等待响应。

第三阶段:预填充(Prefill)——GPU存在但毫无用处

Kubernetes以毫核为单位分配CPU,以整个GPU卡为单位分配GPU。一个Pod请求一张卡,无论它需要使用10%还是全部,都会获得整张卡。

浪费是显而易见的问题。碎片化才是让周四变得糟糕的问题。一个16位的700亿参数模型需要约140GB的权重,因此一个副本需要在一个节点上使用多个GPU。你可能有六个空闲GPU分布在四个节点上(分布为2-2-1-1),但副本会永远处于Pending状态。纸面上有容量,但无法使用,也没有告警,因为没有东西损坏。

共享一张GPU卡有三个选项,每个选项都有需要提前了解的陷阱。时间片划分容易启用,但不提供内存隔离,一个贪婪的Pod可能会导致邻居Pod崩溃。适合开发,不适合任何面向用户的服务。MIG提供真正的硬件隔离,但切片几何形状固定,这意味着在拥有工作负载之前必须预测工作负载组合。动态资源分配是结构上正确的解决方案,它能将加速器请求正确纳入核心Kubernetes API。

这些功能默认都是关闭的。每个都需要某个了解工作负载的人做出明确决策,而这个人通常在集群构建时并不在场。

第四阶段:解码(Decode)——你的入口控制器正在阻止用户

许多入口控制器默认带有60秒的读取超时和启用了响应缓冲。

超时会在句子中间终止长生成过程。用户会报告这是崩溃,而你无法复现,因为你的测试提示很短。缓冲会保留令牌并成批释放,这会破坏模型运行正常时流式传输的感觉。

只需要两行配置,但它们是为一个已不存在的工作负载编写的。

在这四点之下:突发流量与无人负责的问题

内部AI工具不会持续接收流量。它们会遇到突发的流量高峰:比如早上9点所有人开始工作时、公司全员会议后的一个小时,或者有人在繁忙的Slack频道分享链接并说这个工具其实很不错时。固定的副本数量只能应对其中一种情况。大多数团队在安静的一周内设置一次,之后就不再调整,因此同一天内既会出现资源浪费,又可能遭遇系统崩溃。

第六种故障模式并非技术问题,而是其他五种问题能持续数个季度的根本原因。

平台工程团队负责集群,集群状态正常。从他们的角度来看,工作已经完成且完成得不错。应用开发人员能看到延迟很高,却无法查明原因,因为所有原因都涉及调度、扩展和路由,而这些是他们既无法控制也无法监控的。MLOps团队负责模型制品,但几乎不涉及决定模型在周四下午2:15表现的因素。

三个团队都在讲真话,而问题恰恰存在于他们轮班制度之间的空白地带:那里没有配置任何告警,也没有任何仪表盘进行监控。

同时,平台并未停滞不前

这个故事令人鼓舞的一面是,上述空白已被认知,修复方案也已逐步推出。

动态资源分配将加速器硬件请求引入Kubernetes核心API,使调度器能够基于设备本身进行判断,而非计算不透明的单位数量。Kueue增加了作业排队功能和多租户GPU配额,与CPU和内存配额并行管理,这是防止研究作业占用用户依赖端点资源的方法。Gateway API推理扩展和llm-d实现了模型感知路由:请求优先级、基于实时模型指标的动态负载均衡,以及缓存状态感知。最后一个功能直接解决了第一阶段中猜测式负载均衡的问题。

已发布的基准测试展示了规模效应:Kueue将多阶段工作负载的总耗时减少高达15%,动态加速器切片使平均作业完成时间缩短36%,Gateway API配合llm-d在高负载情况下将首个令牌生成的尾部延迟提升高达90%。

将这些数据视为容量余量而非预测值。高达90%的提升是在特意选择的配置下测得的,你的实际收益完全取决于基线水平的糟糕程度。如果你已经在使用带预热缓存的最少未完成请求数均衡策略,提升可能微乎其微。如果你目前使用的是默认入口后的标准轮询策略,提升可能非常显著,因为这种基线确实非常糟糕。

方向才是关键。最大的公开提升体现在首个令牌生成的尾部延迟上,而这项指标恰好是半数受访实践者认定的最严重问题。有人已经为人们抱怨的问题构建了修复方案。

调查数据解释了原因。超过半数的企业根本不训练模型,且每天部署模型的仅占7%。与此同时,82%的容器用户在生产环境中运行Kubernetes,66%的生成式AI托管组织已在其环境中提供该服务。行业多年来为几乎无人需要的工作负载设计系统,而其他人却默默下载权重并将其部署在端点后。

真正达成一致的并非运行AI的场所,而是一种标准的运行方式,具体位置可协商确定。这正是为何你今天面临的问题是部署位置、路由和容量,而非与模型形状相关的任何问题。

火灾平息后的应对措施

从可用到可靠的关键在于五个方面:容量、性能、部署位置、弹性和所有权。

容量

当单个请求包含50个令牌而下一个请求包含8000个令牌时,每秒请求数毫无意义。应以每秒令牌数进行规划,并分别跟踪提示和完成过程,因为它们会对系统不同部分产生压力。提示令牌在预填充阶段是计算爆发,完成令牌在解码阶段则是持续的内存占用,会持续占用GPU内存直到响应结束。

使用最糟糕的真实提示和最糟糕的真实并发量进行负载测试,并以此数值为基础进行规划。基于短提示构建的基准测试会给出令人安心的数字,但这些数字在第一周就会消失。

在供应方面,应将GPU视为需要提前预留的资源,而非按需请求。保持一个承诺的基准并在此基础上进行突发扩展。在需要的当天晚上之前,了解提供商的配额和区域库存情况,并使用Kueue确保一个团队不会悄悄消耗整个资源池。

性能

最重要的两个指标是:首个令牌生成时间(TTFT)和令牌间延迟。TTFT是用户发送提示到看到回答第一个字之间等待的时间,这决定了用户是否信任产品。令牌间延迟是之后每个字之间的间隔,这决定了回答是否读起来流畅。

在p95和p99百分位数上跟踪这两个指标,而非平均值。这些是百分位数指标。p95表示95%的请求都在该时间范围内完成,因此展示了最慢的1/20用户所经历的情况。p99则对最慢的1/100用户做同样分析。平均值可能看起来健康,但这些用户可能需要等待很长时间,而他们正是最终放弃的用户。

接下来,优化服务层。这是加载模型并处理请求的软件,例如vLLM。这是以最小努力和成本获得最大改进的地方。持续批处理可以在不使早期请求等待批处理填满的情况下保持GPU忙碌。量化可以在质量折让可接受的情况下将内存占用减少约一半,释放的内存可转化为并发请求。将最大上下文长度设置为产品实际需要的长度,而非模型支持的最大长度。如果模型支持128K而实际最长真实提示只有6K,你就是在为从未发生的情况保留KV缓存。只需一行配置,就能显著提高有效并发量。

保持权重的就近性。节点本地的 NVMe 或区域本地缓存可将 40GB 的网络拉取转化为快速的本地读取,直接为冷启动、自动扩展延迟以及周四下午经历的高峰时段延迟提供支持。这是列表中最具杠杆效应但最不显眼的解决方案。

尊重拓扑结构。通过 NVLink 连接的显卡与仅共享 PCIe 总线的显卡行为差异显著,对于分片模型而言,这种互联方式位于每个生成 token 的关键路径上。

诚实地面对地理因素。如果用户位于伦敦而 GPU 位于弗吉尼亚,每个 token 都需要跨越大西洋。即使模型经过精细调优,长网络路径仍会使产品变慢。

弹性

仅在模型加载完成且真正具备服务能力时,就绪状态才应通过。使用具有宽松失败阈值的启动探针,否则存活检查可能在加载权重过程中终止 Pod,导致重启循环,表现为神秘故障并耗费一小时。

设置 Pod 中断预算,确保常规节点升级不会一次性移除一半的副本。

将终止宽限期设置为超过 30 秒的默认值,并添加 preStop 钩子。生成过程可能轻松超过这个时间,否则每次发布都会中断正在进行的流,用户会将部署体验为随机故障。

主动降低负载。当队列深度超过阈值时,返回快速的“请重试”响应,而非接受一个会挂起两分钟的请求。这在工程师看来似乎不正确,但对用户而言是正确的。人们会原谅快速的诚实重试,但没人会原谅冻结的屏幕。

预留回退方案:第二区域、覆盖常见场景的较小模型,或灾难边缘的外部 API。鉴于 45.5% 的从业者仅运行单一区域,这是列表中最常被跳过的项目,也因此最可能成为下一次事故的诱因。

所有权

达成数字共识并记录下来:首个 token 生成时间、token 间延迟、错误率、排队时间。将它们放在同一仪表盘中,同时展示集群和模型指标,确保两个团队打开相同链接,而非维护各自版本的现实。

明确划分责任。平台团队负责实现目标的能力:容量、调度、路由、扩展、部署。应用团队负责模型的配置和调用方式:上下文长度、批处理参数、提示大小、重试行为。当指标偏离时,双方团队共同参与,从同一图表开始对话,而非各自持不同数据。

你的监控仍然没有告诉你的四件事

延迟、流量、错误和饱和度仍然是必要指标,但已不再充分。还有四个指标需要加入监控面板。

按提示和完成部分拆分的令牌消耗率,因为这才是你真正的容量单位。按租户和查询类型统计的每请求成本,因为拥有八块 GPU 并不能说明某个功能对每个用户的成本。输出质量,跟踪幻觉率和安全边界偏移,因为损害质量的延迟优化并非真正的胜利。模型归因,记录生成响应所使用的检查点和提示版本,因为当质量变化时,你需要知道具体发生了什么改变。

最后一个指标揭示了一个值得关注的转变:模型仓库已与容器仓库平起平坐,提示和代理配置正越来越多地作为 GitOps 工件,在与其他所有内容相同的交付管道中进行版本控制。

提示现在已成为代码。它会改变生产环境的行为,可能引发问题,应像其他任何代码一样经过审查、版本控制和回滚。许多团队仍在通过网页控制台编辑提示,却在周二发现质量发生了变化。

仍未解决的问题

底层技术已趋于统一,其速度就是证据。2025年末启动的Kubernetes AI一致性计划最初有18个平台参与,大约四个月后扩展到31个平台,并覆盖到智能代理工作负载,包括主要的超大规模云服务商、企业及私有云发行版、GPU新云和边缘网络。几乎在所有方面都存在分歧的公司,却在这个问题上达成了共识。

上层技术却完全没有统一。AI网关、评估平台、代理控制平面、代理可观测性。这些技术在商业产品中的发展速度远超任何标准组织,且正好位于最有趣的业务逻辑即将进入的领域。

需要明确指出风险。你可能在Kubernetes层完全可移植,却在实际构建的层完全被锁定。你的Pod可以在云之间完美迁移,但代理定义、评估套件和网关策略却始终停留在原地,因为没有标准的迁移目标。

这并不是避免使用这些工具的理由。它们确实解决了现实问题。这是要明确知道你的哪些组件具备退出能力、哪些不具备,并将这个决策写下来,而不是在续约谈判时才发现。

周一早晨

从一个指标开始。测量从Pod创建到首次生成令牌的冷启动端到端时间,并记录数值。这个数值就是你的自动扩展基准,你的最小副本数可以直接由此得出。

在p99级别上将首次生成令牌时间和队列深度显示在主仪表板上。用队列深度触发器和尊重冷启动的最小值替换基于CPU的自动扩展。将入口读取超时和缓冲区设置与真实的长流式响应进行对比,而不是测试提示。调整终止宽限期,确保部署不会中断用户。

接下来几周内:对GPU节点进行污点标记,将权重移动到节点本地或区域本地存储,将最大上下文长度设置为实际使用值,并检查是否仍在使用轮询算法。你很可能还在使用。

在季度结束前,决定谁负责端到端延迟指标,并在与其他团队成员在场的情况下大声说出这个决定。

回到周四

仪表板从未撒谎。它只是在回答不同的问题。

它只是告诉你容器是否存活,而它们确实存活了。但它无法告诉你请求正在一个路由不佳的批量处理后排队,新副本四分钟内没有出现,六个GPU空闲却无法使用,或入口正在缓冲本应流式传输的令牌。标准工具包中的任何内容都未针对这些问题进行设计。

在Kubernetes上让模型做出响应可能只需一个下午。但当所有人同时登录时让模型良好响应,则属于另一门学科,这更像普通基础设施工程,而非当前对话所暗示的那样。调度、路由、容量、所有权。在任何AI标签出现之前很久,我们就在解决这些问题了。这些技能已经存在于团队中,只需指向正确的指标即可。

绿色集群是工作开始的地方。关键在于输入提示语的人所看到的内容。

希望你享受了这个过程并学到了新知识。我始终欢迎在LinkedIn上提出建议和进行讨论。通过私信联系我。

如果你喜欢我的写作并希望激励我,请在GitHub上点赞,并在LinkedIn上为我相关的技能点赞。

下次再见,祝你探索愉快!

合作伙伴推荐课程

(opens in a new tab)

ADVERTISEMENT

  • Udemy 上的 Microsoft 365 Copilot 提示工程 Valentin Despa 5 星(2)评价 1小时 初学者 证书 查看课程 (opens in a new tab)
  • Coursera 上的 AI 基础设施:网络技术 Google Cloud 培训 6周,每周1小时 中级 证书 查看课程 (opens in a new tab)
  • Coursera 上的 CI/CD、部署与可观测性 Microsoft 11周,每周1小时 中级 证书 查看课程 (opens in a new tab)

更多提示工程课程请访问 Class Central

→

阅读更多文章 .

如果你读到这里,请感谢作者以表达你的支持。说声谢谢

免费学习编程。freeCodeCamp 的开源课程已帮助超过40,000人成为开发者。立即开始