跳到主要内容

仪表盘视为噪点的周一早晨 AI 性能下降

· 阅读需 11 分钟
Tian Pan
Software Engineer

打开你的 AI 功能延迟和质量看板,眯起眼睛仔细看。曲线大部分时间是平缓的,偶尔会有一些峰值,你的团队几个月来一直称之为“噪音”或“供应商异常”。现在,按小时和星期几来拆分这些数据。噪音显现出了真面目:在东部时间每个周一上午 9 点到 11 点之间,你的 p95 延迟比周六晚上高出 30–60%,缓存命中率下降 10–20 个点,重试率翻倍,每个任务的 token 支出也在悄然攀升。看板没有撒谎,它只是在做平均。

大多数团队发现这种模式的方式就像发现缓慢漏水一样:通过回溯没人能解释的季度账单。直觉是将其归结为供应商的不稳定性,给推理厂商提个工单,然后就此作罢。但这种模式其实与你的 LLM 供应商无关。事实是,你的 AI 功能现在构建在一堆共享的、对时间敏感的系统之上——模型 API、embedding API、你的 agent 调用的 SaaS 工具、接收 webhook 的客户自身基础设施——而其中每一个系统的周期性负载模式都会发生叠加。你继承了整个依赖链的昼夜曲线,而你的看板向你展示的是所有这些曲线的平均值。

你在不经意间继承的周期性负载

从周日晚上到周一早晨,会发生三件你的测试环境永远看不到的事情。

第一,你的推理供应商的共享基础设施开始处理你所在地理区域的工作时间流量。如果你部署在 us-east,曲线会在东部时间早上 6 点左右随着东海岸的苏醒而开始攀升,并在上午 10 点到下午 2 点之间达到顶峰,然后随着西海岸下班而回落。主要模型 API 的公共延迟追踪器在群体层面清晰地展示了这一点——首 token 延迟(first-token latency)和尾部延迟(tail latency)都随着昼夜周期波动,工作日的数值明显比深夜或周末要差。你的 p50 可能会掩盖这一点,但你的 p99 不会。

第二,你的提示词缓存(prompt cache)命中率发生了变化。提示词缓存是大多数团队在成本和延迟方面拥有的最大杠杆,现代目标是将缓存读取量占总输入 token 的比例维持在 80% 到 95% 之间。但缓存命中率取决于哪些前缀(prefixes)是热的,而哪些前缀是热的又取决于最近的流量。如果你的周末流量由一种工作流主导(比如个人用户运行个人查询),而你的周一早晨流量由另一种工作流主导(比如企业客户通过同一个 agent 运行批量报告),前缀分布就会在一夜之间发生变化。周六凌晨 3 点效率为 91% 的缓存,到周一上午 10 点效率可能降至 76%,因为工作集(working set)改变了。你正在为你未定价的那部分流量支付全额的输入 token 费用。

第三,你的 agent 调用的 SaaS API——日历、CRM、支付、工单、搜索、内部服务——都会在周一早晨迎来各自的峰值。它们的 p99 延迟被拉长,速率限制(rate-limit)预算变得拥挤。它们偶尔出现的 503 错误变成了常态。你的 agent 工具调用(tool-calling)的延迟尾部并不是 agent 本身的属性,而是任何给定计划中最慢的依赖项的属性,而在周一早晨,最慢的依赖项明显比周六慢得多。

将这三者结合起来,你就会得到一个周一早晨体验与周末体验有质的差异的功能。单个因素看起来都不剧烈,但叠加后的效果却很显著。

为什么你的评估(Evals)捕捉不到它

大多数评估流水线(eval pipelines)都是“夜猫子”。它们在凌晨 2 点运行,因为那时候团队不使用集群,速率限制宽松,工具依赖项很安静,模型响应迅速。到早晨,数据指标显示为绿色。领导层看到的是一条稳定的曲线。评估工具完成了它的任务。

只是评估工具采样的是一周中最平静的时段,并将其称为基准线。在夜间评估中获得 91 分的模型,正被要求处理它从未见过的负载——不同的前缀分布、不同的延迟预算、不同的依赖可靠性。评估所验证的“低成本模型优先”级联策略在生产环境中做出了不同的选择,因为凌晨 3 点胜出的成本质量权衡,在上午 10 点就失效了,因为此时重型模型的回退(fallback)正排在其他所有人的重型模型回退之后。

解决方法不是运行更多的评估,而是将评估流量在周周期内进行分层。选择一组典型的任务样本,在周六凌晨 3 点、周一上午 10 点、周三下午 2 点和周五晚上 8 点针对生产环境运行。给结果贴上时间段标签。现在你就有了一个“周一早晨是什么样”的校准锚点,当看板的聚合数据是一片绿色但用户仍在抱怨时,团队可以以此为依据。

你可能缺失的可观测性切片

如果你的 AI 功能看板不能让你将“小时”和“星期几”作为第一等维度进行切片,那么在最可能让你赔钱的故障模式面前,你就像在盲目飞行。代码上的改动很小,但在可解释性上的提升很大:

  • 按小时和星期几分解的质量指标,使用热力图(heatmap)可视化而不是折线图。聚合后的曲线会掩盖热力图所揭示的问题。
  • 日历维度下的缓存命中率热力图。命中率下降的单元格正是每个任务成本和延迟悄然恶化的时刻。随着流量组合的演变,观察它们每周的变化。
  • 按上游供应商分解的重试率和工具错误率。聚合后的重试率会撒谎,因为它们将 0.5% 的基准水平与每周一同一时间的 4% 峰值混为一谈。按供应商、按小时的分解会告诉你哪个依赖项才是真正的问题所在。
  • “尾部乘数”(tail multiplier)指标,即你的 p99 延迟除以 p50 延迟,按小时切片。该乘数比任何单一数字对负载条件都敏感得多,其变化是上游层级拥塞的早期信号。

这一切都不需要新工具。它只需要你已经收集的指标加上时间段和星期几的维度索引,并且有人制作了热力图。

周期性负载对路由的影响

如果你运行模型级联(Model cascade)——先使用廉价模型,在置信度或评估器关口未通过时回退到更强大的模型——那么你所运行的路由策略,其经济效益是随时间变化的,且可能尚未建模。

教科书式的框架认为级联可以省钱:大多数查询由廉价层处理,只有难题才会升级。这种框架假设升级率大致恒定。但在实践中,升级率呈现周周期性。周一会带来不同的意图类别、来自度过周末的企业用户更复杂的查询,以及运行周初自动化任务的客户带来的更多边缘情况。廉价层的成功率会下降,升级率会上升,周一早晨的账单会比流量标称值相同的周六账单明显高得多。如果你的路由策略是根据周末或深夜数据调整的,那么它在周中负载最重的时段就会权重失衡。

容量预留(Capacity reservations)也呈现相同的形状。你向推理提供商预留的专用吞吐量是根据中位数负载确定的。真正关键的峰值——那些迫使你以 5 倍单价使用按需容量的峰值——集中在每周的五六个小时内。大多数团队在按小时拆分支出之前,根本意识不到账单中有多大比例是在这些小时内产生的。当他们这样做时,答案往往是:超过一半的按需支出集中在不到 10% 的时间里。

必然的结果是:在工作日营业时间最优的模型组合,并非在晚上和周末最优的模型组合。如果静态路由策略将所有时间等同视之,那么它在两端都在浪费钱——凌晨 3 点支付了过多的容量费用,而上午 10 点则配置不足。

周二早晨的陷阱

周一早晨故障模式最隐蔽的特性是:等到团队开始处理它时,它已经消失了。工程团队在周二早晨查看问题。过去 24 小时的仪表盘看起来很正常。延迟回到了基准线。缓存命中率也恢复了。团队得出结论,认为无法复现并关闭了工单。

一周后,同样的情况再次发生。另一名团队成员在周二早晨查看,得出同样的结论。这种模式是不可见的,因为团队总是通过一个排除掉故障期的窗口来观察。

解决方法是流程性的,而非技术性的。在周一下午处理周一早晨的问题,并将仪表盘显式地限定在过去 24 小时内,并按小时切分。或者更好的是,构建一个警报,其检测逻辑寻找模式本身——例如营业时间缓存命中率降至阈值以下、营业时间尾部倍数(Tail multiplier)超过阈值、每个上游供应商的重试率升至阈值以上——而不是针对会被周期性负载在数学上掩盖的跨日平滑平均值进行报警。

成本视角也是如此。周一早晨峰值期间的重试风暴(Retry storms)所产生的费用,通常会超过廉价模型级联在这一周其余时间节省下来的费用。一个不了解这一点的团队是在针对一个指标进行优化,而该指标的分母包含了最平静的小时,分子则由最嘈杂的小时主导。

架构层面的认识

LLM 功能并非独立系统。它们是共享上游服务的复合体——模型 API、嵌入 API、向量数据库、检索索引、下游工具、客户集成——而这些服务中的每一个都有自己的周期性负载曲线。复合体继承了所有这些曲线。

在实践中,这意味着标准的 SRE 策略手册(SRE playbook)移植得并不完整。微服务团队二十年来一直了解昼夜负载曲线,并围绕它们构建了容量规划、报警和路由。源自模型研究背景的 AI 团队通常没有这种经历,肌肉记忆尚未转移。AI 团队构建的仪表盘是模型研究人员想要的——准确性、延迟、吞吐量、综合质量。这不是 SRE 想要的仪表盘——周期性负载模式、尾部倍数、按小时计的每个依赖项错误率、容量利用率热力图。

The teams that learn this fast are the ones whose AI feature reached the scale where the bill stops being a research budget and starts being a real line item. 能够快速领悟这一点的团队,是那些 AI 功能规模已经大到账单不再是研究预算,而是成为真正的财务支出项的团队。没有领悟到的团队则会花费一个季度去追逐那些根本不是 Bug 的“海森堡 Bug”(Heisenbugs)——它们只是在共享的、对时间敏感的技术栈之上运行随机系统的必然结果,而仪表盘却通过平均值抹平了这种周期性。

第一项改进是最廉价的。在你现有的质量和延迟仪表盘中添加“小时”轴。看看你一直在平均处理的内容。周一早晨的真面目将是你首先看到的东西。

References:Let's stay in touch and Follow me for more thoughts and updates