大概三个月前,我负责的一个OCR识别服务经历了一次让人后背发凉的升级。新版本的模型在离线评测集上准确率提升了将近三个点,压测的吞吐也过得去,于是我选在一个业务低峰期的周四下午做了灰度发布。结果半小时后,业务方在群里甩过来一个录屏:客户端转圈八秒钟才返回结果,用户已经开始投诉了。我的第一反应是查日志、看报错,结果服务一切正常,模型也正常返回,只是"变慢了"——准确率提高了,单次推理耗时却从原来的600ms涨到了2.8秒。更尴尬的是,当时整个项目居然没有一个现成的监控面板能告诉我这2.8秒到底消耗在哪一个环节。就是从那一刻起,我开始系统性做这套AI模型推理延迟监控方案。这篇文章把我踩过的坑、验证过的做法、以及最终沉淀下来的监控体系完整梳理一遍,给同样在折腾AI应用、大模型服务、ML基础设施的朋友们一条可以直接参考的落地路径。
1. 为什么监控延迟比监控准确率更难:一次事故复盘
1.1 那次让业务喊停的模型升级
事故之后我做了复盘,发现最核心的问题不是"新模型变慢了"这件事本身,而是我们对这个慢根本没有感知能力。准确率可以用离线评测集来验证,跑一遍脚本就出数字;吞吐可以用压测工具来摸底,平均QPS、平均耗时一拉就有。但推理延迟是一个在真实流量下才会暴露的动态指标,它与输入的分布、并发的高低、当前机器的资源状态强相关。
离线评测和压测都存在同一个盲区:它们使用的输入数据太"干净"了。评测集的图片分辨率、文本长度、图像内容都是固定的,压测时并发可控、请求均匀、不存在突刺,所以算出来的"平均延迟"掩盖了长尾问题。真实生产流量完全不是这样:同一个模型,用户传来的图片有的300x300,有的4000x3000,有的文本十几个字,有的上下文几万token,最终的单次推理耗时可能相差几十倍。
当时我们看到的数字很典型:压测阶段服务端平均耗时650ms,P99大概1.2s,看起来完全可接受。但灰度之后生产流量的P99直接飙到8秒以上,整条链路的瓶颈根本不在模型本身,而在于请求排队、预处理时间和上下文组装时间。这些环节在压测脚本里几乎是零开销,到了生产环境却变成了延迟的主要贡献者。所以后来我特别强调一个原则:评估一个推理服务能不能上线,不能只看准确率和吞吐,必须把延迟的P50、P95、P99作为硬性发布门槛。
1.2 延迟指标远不止"快慢":TTFT、TPOT与端到端
很多第一次接触推理延迟监控的朋友会问:不就是一个请求从发出到返回的时间吗?把它记下来,求个平均不就行了?实际上,对于不同形态的AI应用,需要观测的延迟指标差异非常大。
对于传统的小模型推理服务(OCR、目标检测、向量编码),通常看两个数字就够了:服务端端到端时延和模型前向推理耗时。但对于大语言模型、多模态生成这种流式服务,必须拆分得更细,至少包含四个维度:
- TTFT(Time To First Token):从请求发出到返回第一个输出token的时间。这个指标直接决定用户"点完按钮后白屏多久",是对话式体验最敏感的指标。
- TPOT(Time Per Output Token):生成模式下每个token的平均产出时间,相当于模型的"吐字速度"。对话流畅度主要看它。
- 端到端时延:从客户端发起到完整响应落地的总时长。
- 排队时延:请求到达服务后、进入实际推理前的等待时间。这个时间往往被忽略,但在高并发下恰恰是P99爆炸的主要来源。
如果你做的应用还串联了RAG检索、多轮对话历史处理,那么检索耗时、Prompt组装耗时也要单独埋点。道理很简单:用户报障说的是"整个功能变慢了",但工程上必须知道"慢在哪一段",否则排查起来就是大海捞针。我在事故之后做的第一件事,就是拉着后端把请求生命周期从头到尾理了一遍,然后在每个边界都打上时间戳。这一步做完,监控面板才终于有了可以依托的骨架。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 延迟到底卡在哪:推理链路的逐段拆解
2.1 从客户端到GPU:一个请求的完整生命周期
我习惯把一次推理请求从发出到返回拆成七个阶段,每个阶段都有独立的监控埋点。你可以对照自己项目的架构做裁剪,但拆解思路是一样的。
| 链路阶段 | 做什么 | 典型耗时量级 | 关键监控指标 |
|---|---|---|---|
| 1. 客户端网络传输 | 用户到网关的网络往返 | 10ms~500ms | 客户端测速、网络请求耗时 |
| 2. 网关接入 | 鉴权、路由、限流 | 1ms~30ms | 网关处理时延、拒绝次数 |
