4、模型性能监控:推理延迟(P50/P95/P99)、吞吐量(QPS)、模型加载时间、批处理效率

模型部署上线之后,最怕什么?

我个人最怕的不是模型精度掉点,而是用户反馈「转圈圈」。你想想看,一个推荐系统如果每次请求都要等两三秒,用户早跑了。所以性能监控这块,我把它看作是AI系统的「生命体征监测仪」。

4.1 推理延迟:P50/P95/P99 到底看哪个?

先说延迟。很多团队只盯着平均延迟看,这是个坑。平均延迟会把异常值抹平,让你觉得系统「还行啊」,实际上可能已经有一批用户在骂娘了。

我习惯用三个分位值来监控:

指标 含义 我关注的重点
P50(中位数) 50%的请求在这个时间内完成 代表大多数用户的体验,日常优化看这个
P95 95%的请求在这个时间内完成 排除极端情况后的真实体验上限
P99 99%的请求在这个时间内完成 长尾用户感受,SLA违约的判定依据

我的经验法则:

P50 控制在 50ms 以内,用户基本无感。

P95 别超过 200ms,否则开始有人抱怨。

P99 一旦突破 500ms,立刻触发告警。

为什么会这样?因为P99的波动往往意味着资源瓶颈或者某台机器出了问题。我曾经遇到过一台GPU风扇坏了导致降频,P50看起来只涨了10ms,但P99直接飙到了1.2秒。如果只盯着平均值,这个隐患可能要等到用户投诉才知道。

4.2 吞吐量(QPS):别被峰值冲昏头

吞吐量,说白了就是系统每秒能处理多少请求。这个指标要和延迟一起看,单看QPS没有意义。

我见过一个团队,把QPS优化到了2000,结果P99延迟到了3秒。这有什么意义呢?系统是在「硬扛」,每处理一个请求都在排队。

我的监控策略:

  • 设定一个「健康QPS阈值」——在这个QPS下,P99延迟不超过200ms
  • 超过这个阈值,要么扩容,要么限流
  • 别等到QPS打满才告警,留20%的余量

举个例子,我去年维护的一个OCR服务,单机健康QPS是150。有一次流量突增到180,P99从180ms跳到了450ms。还好提前设了告警,我们立刻切了两台备用节点上去,用户基本无感。

4.3 模型加载时间:容易被忽视的冷启动问题

这个坑我踩过好几次。

模型加载时间,指的是从发起加载请求到模型真正可用之间的耗时。很多人觉得「加载一次就好了嘛,后面都是推理」,但实际情况是:

  • 服务重启、滚动更新时,模型要重新加载
  • 多模型部署时,每个模型都要加载
  • GPU显存不够时,模型可能需要动态卸载和加载

我曾经踩过的坑:

有一次做模型热更新,新模型加载花了8秒,而旧模型已经卸载了。这8秒内所有请求都报错。后来我强制要求:新模型加载完成并预热之后,再卸载旧模型。加载时间超过5秒的模型,必须做预热推理(比如先跑10个假请求),否则推理延迟会异常高。

监控模型加载时间,我一般设两个阈值:

  • 警告阈值:加载时间超过预期的1.5倍
  • 严重阈值:加载时间超过预期的3倍,或者加载失败

4.4 批处理效率:GPU的「满汉全席」

GPU推理和CPU推理最大的不同,就是批处理。单张图片推理可能耗时10ms,但把32张图片打包一起推理,可能只需要30ms。这就是批处理的魅力。

但批处理不是越大越好。我习惯监控两个指标:

指标 说明 我的建议值
批处理大小(batch size) 每次推理打包的样本数 根据模型和显存调整,一般16~64
批处理等待时间 凑齐一个batch需要等多久 不超过50ms,否则用户感知到延迟

批处理效率的核心矛盾:

batch size 越大,GPU利用率越高,但凑齐样本的等待时间越长。

batch size 越小,延迟越低,但GPU利用率下降,吞吐量上不去。

说白了,这是一个「延迟 vs 吞吐量」的权衡。

我个人的做法是动态批处理:

  • 设置一个最大等待时间(比如30ms)
  • 到了30ms,不管凑了多少样本,直接推理
  • 如果样本量已经达到最大batch size,也直接推理

这样既保证了延迟可控,又尽量提高了GPU利用率。

一个小技巧:

监控批处理的实际填充率。比如你设了batch size=64,但实际平均每次只填了40个样本,说明你的流量不够或者等待时间太短。这时候可以适当增加等待时间,或者减小batch size,避免浪费GPU算力。

4.5 把这些指标串起来

嗯,到这里你应该发现了,这几个指标是互相影响的:

  • 模型加载时间长了,会影响服务的可用性
  • 批处理效率低了,会拉低吞吐量
  • 吞吐量上去了,延迟可能跟着涨

我建议搭建一个统一的监控看板,把这些指标放在一起看。比如:

# 伪代码示例:性能监控数据结构
{
  "model_name": "resnet50_v2",
  "inference_latency_ms": {
    "p50": 12,
    "p95": 28,
    "p99": 45
  },
  "throughput_qps": 320,
  "model_load_time_s": 2.3,
  "batch_efficiency": {
    "batch_size": 32,
    "avg_fill_rate": 0.78,
    "avg_wait_time_ms": 22
  }
}

每次发布新模型版本,我都会对比这些指标。如果某个指标恶化超过10%,我会回滚或者重新优化。记住,性能监控不是为了看数字,而是为了在用户发现问题之前,我们自己先发现问题。

一句话总结:

延迟看分位值,吞吐量看健康阈值,加载时间防冷启动,批处理效率找平衡点。这四个维度盯住了,你的AI系统至少不会在性能上翻车。