113-大模型可观测性-Prometheus-Grafana-推理服务监控告警
文章目录
【113.Python+AI】大模型服务的可观测性:Prometheus + Grafana监控你的推理服务
📖 文章简介: 本文系统讲解大模型推理服务的可观测性建设,解决"服务上线后变成黑盒,出问题靠用户投诉才发现"的运维盲区。文章从AI服务与传统Web服务的监控差异切入——除了延迟和错误率,Token生成速度、KV Cache水位、队列长度这些AI特有指标才是健康的晴雨表;随后给出完整的指标体系设计:五类核心指标(延迟分布TTFT/TPOT、吞吐Token生成速度、容量KV Cache使用率/GPU利用率、稳定性错误率/超时率、业务请求量按模型按调用方)的采集方法与告警阈值建议;落地部分讲透vLLM原生Prometheus端点的接入(/metrics直接挂载)、Grafana看板的Panel布局(四象限布局:流量-延迟-容量-错误)、以及六条保命告警规则的配置(P99延迟超标、KV Cache水位超80%、错误率突增、GPU掉卡、Token速度腰斩、队列积压);最后聊业务层观测的补充——成本统计与badcase采样的落地。配以Mermaid流程图展示从指标采集到告警触达的完整链路,适合把推理服务推上生产后需要7×24保障的工程师阅读参考。

🎬 个人主页: 源码骑士
❄ 专栏传送门: 《Android开发基础》《python基础课程》
⭐️热衷从源码视角拆解技术底层原理,将复杂架构讲得通俗易懂
🎬 源码骑士的简介:
5年Android Framework系统开发经验,曾主导多项系统级性能优化专项
技术栈覆盖Android系统全链路(Binder/Handler/AMS/WMS/启动流程)及Java后端全家桶(Spring + MyBatis + Redis + Oracle)
累计产出原创技术文章100+篇,文章以流程图为特色,被读者评价为"看一篇胜过啃一周源码"
导入语
推理服务上线了,老板问:"服务稳吗?"你说:“挺稳的,没人报障。”——这不是监控,这是拿用户当人肉告警器。
AI服务的故障有个讨厌的特点:它很少"死透",更多的是"带病运行"。 显卡没挂、进程没崩,但延迟从500ms悄悄爬到3秒;KV Cache水位逼近红线,再有10个并发就要OOM;某个模型回答质量下降——这些问题用户能忍一两天才投诉,等你看到时已经烧掉了一周的体验分。
传统Web监控那套(QPS、错误率、CPU)照搬到AI服务上会失灵——AI服务有自己独特的生命体征:首字延迟、Token生成速度、KV Cache水位。这篇文章就把这套专属监控体系建起来:指标怎么选、怎么采、看板怎么摆、告警怎么配。
1 ~> AI 服务的五类核心指标
1.1 指标全景
| 类别 | 指标 | 健康参考线 | 异常含义 |
|---|---|---|---|
| 延迟 | TTFT(首字延迟) | P99 < 1s | 排队过长/前处理慢 |
| TPOT(每token延迟) | P99 < 100ms | 算力不足/显存换页 | |
| 吞吐 | Token生成速度(tokens/s) | 基线±20% | 腰斩=严重降级 |
| 容量 | KV Cache使用率 | < 80% | 逼近OOM |
| GPU利用率/显存 | 利用率60~90% | 过低=浪费,100%=过载 | |
| 稳定性 | 错误率/超时率 | < 0.5% | 引擎异常 |
| 业务 | 请求量(按模型×调用方) | 趋势观测 | 突增=容量预警 |
1.2 两个AI特有指标要理解透
TTFT(Time To First Token,首字延迟):
用户发送 → 看到第一个字蹦出来的时间
组成:排队时间 + prompt预处理(prefill)时间
→ 它直接决定用户觉得"卡不卡",是体验第一指标
TPOT(Time Per Output Token,逐token延迟):
第一个字之后,每个字的间隔
决定回答"流得快不快"
→ TTFT管第一印象,TPOT管全程体感
一个服务可以TTFT漂亮但TPOT拉胯(首字秒出、后面一个字一个字挤)——两个指标分开看,才能定位问题在prefill阶段还是decode阶段。
2 ~> 采集:vLLM 原生支持,一行接入
第108篇部署的vLLM自带Prometheus端点,接入成本几乎为零:
# prometheus.yml
scrape_configs:
- job_name: vllm
scrape_interval: 15s
static_configs:
- targets: ["gpu01:8000", "gpu02:8000"] # 所有vLLM实例
vLLM原生暴露的关键指标(直接可用):
vllm:time_to_first_token_seconds → TTFT分布
vllm:time_per_output_token_seconds → TPOT分布
vllm:gpu_cache_usage_perc → KV Cache水位(第111篇的那本账!)
vllm:num_requests_running → 正在处理的请求数
vllm:num_requests_waiting → 排队长度(积压预警)
vllm:request_success_total → 成功计数(算错误率)
自建网关(第109篇)补充业务维度指标:
# 网关层埋点:按模型×调用方记账
from prometheus_client import Counter, Histogram
REQ_COUNT = Counter("gateway_requests_total", "请求数",
["model", "caller"])
REQ_LATENCY = Histogram("gateway_latency_seconds", "端到端延迟",
["model"])
# 在处理函数里打点
REQ_COUNT.labels(model=req.model, caller=caller["owner"]).inc()
分工原则:引擎指标看"机器健不健康"(vLLM端点),业务指标看"服务好不好用"(网关埋点)——两层都要有,缺一层就是半个瞎子。
2.1 监控链路全景
3 ~> Grafana 看板:四象限布局
看板不是指标的堆砌,是排障动线的预设。推荐四象限布局,一眼扫完就知道问题在哪一层:
┌─────────────────────┬─────────────────────┐
│ ① 流量象限 │ ② 延迟象限 │
│ QPS趋势 │ TTFT P50/P99 │
│ 按模型分面的请求量 │ TPOT P99 │
│ 在线/排队请求数 │ 端到端延迟热力图 │
├─────────────────────┼─────────────────────┤
│ ③ 容量象限 │ ④ 错误象限 │
│ KV Cache水位 │ 错误率/超时率 │
│ GPU利用率+显存 │ 5xx按模型分布 │
│ Token生成速度 │ 故障转移次数 │
└─────────────────────┴─────────────────────┘
排障动线:先看④有没有错 → 再看②慢不慢
→ 慢了看③容量满没满 → 最后看①流量是否异常
四象限的设计逻辑:错误、延迟、容量、流量,刚好对应"坏了→慢了→满了→多了"四种故障模式——按这个顺序扫一遍,30秒内完成初判。
4 ~> 告警规则:六条保命线
# alert_rules.yml 核心六条
groups:
- name: llm_service
rules:
# 1. 延迟超标——体验红线
- alert: HighTTFT
expr: histogram_quantile(0.99, vllm:time_to_first_token_seconds_bucket) > 2
for: 5m
annotations:
summary: "TTFT P99 超过2秒,用户体验受损"
# 2. KV Cache水位——OOM前最后的预警(第111篇的账本)
- alert: KVCacheHigh
expr: vllm:gpu_cache_usage_perc > 0.8
for: 5m
annotations:
summary: "KV Cache水位超80%,逼近OOM"
# 3. 队列积压——容量不够的明确信号
- alert: QueueBacklog
expr: vllm:num_requests_waiting > 10
for: 10m
annotations:
summary: "排队请求持续超过10个,考虑扩容"
# 4. 错误率突增
- alert: ErrorRateHigh
expr: rate(gateway_errors_total[5m]) / rate(gateway_requests_total[5m]) > 0.01
annotations:
summary: "错误率超1%,引擎或网关异常"
# 5. Token速度腰斩——"带病运行"探测器
- alert: ThroughputDrop
expr: rate(vllm:generation_tokens_total[10m]) < 0.5 * rate(vllm:generation_tokens_total[1h] offset 1d)
annotations:
summary: "Token生成速度相比昨日同期腰斩"
# 6. 实例失联
- alert: InstanceDown
expr: up{job="vllm"} == 0
for: 1m
annotations:
summary: "vLLM实例失联"
告警纪律两条:告警必须可行动(收到告警不知道该怎么办的,不如不配);分级触达(水位类发钉钉群、实例失联打电话——别让半夜的电话只为一条"水位75%"响起)。
5 ~> 别忘了业务层观测
技术指标之外,AI服务还要盯两件传统监控管不到的事:
1. 成本观测
按 模型×调用方×日 聚合Token消耗(第110篇的账本)
→ Grafana加一张成本趋势Panel
→ 某调用方用量突增300%?先问是不是脚本写死了循环
2. 质量观测(badcase采样)
每天随机抽1%的问答对入库,人工或LLM-as-Judge抽检
→ 指标全绿但回答变蠢的情况,只有这个能发现
→ 模型版本升级后必做对比抽检
一句话:技术指标保证"服务活着",质量观测保证"服务聪明"。 前者告警驱动,后者抽检驱动,两条腿缺一不可。
思考 && 总结
- AI监控有专属指标: TTFT管第一印象、TPOT管全程体感、KV Cache水位管OOM预警——照搬传统Web监控是半个瞎子。
- 采集成本极低: vLLM原生/metrics端点直接挂Prometheus;引擎指标看机器健康,网关埋点看服务质量,两层齐备。
- 看板四象限: 流量-延迟-容量-错误对应"多了-慢了-满了-坏了"四种故障模式,按动线30秒完成初判。
- 告警六条保命线: TTFT超标、KV水位、队列积压、错误率、吞吐腰斩、实例失联;可行动+分级触达是纪律。
- 别忘业务层: 成本Panel防账单失控,badcase抽检防"指标全绿但回答变蠢"——活着和聪明是两件事。
可观测性就位,本地部署板块的所有零件——Ollama、量化、llama.cpp、vLLM、网关、多模型路由、显存管理、监控——全部到齐。下一篇是板块实战:把它们组装成一个"自用模型API平台",Ollama+vLLM+Nginx统一对外服务。
结尾
各位小伙伴,本文的内容到这里就全部结束了,源码骑士在这里再次感谢您的阅读!
源码骑士 — Android Framework & 全栈开发
👀 关注:跟博主一起从源码视角深耕底层原理,见证每一次成长
❤️ 点赞:让优质内容被更多人看见,让知识传递更有力量
⭐ 收藏:把核心知识点存好,在需要时随时查、随时用
💬 评论:分享你的经验或疑问,评论区一起交流避坑
🔄 一键四连:不要忘记给博主"一键四连"哦!
🗡️ 寄语:技术之路难免有困惑,但同行的人会让前进更有方向
结语:没有监控的服务是在黑夜里开车——仪表盘亮起来的那一刻,你才从"祈祷不出事"变成了"知道自己在哪"。不要忘记给博主"一键四连"哦!
更多推荐
所有评论(0)