监控与可观测
Prometheus/Grafana 与 drift。
30 分钟
监控与可观测
这一课你将能做到
- 给 FastAPI 推理服务打 Prometheus 指标:QPS、延迟直方图、预测分布计数
- 用 Docker 拉起 Prometheus + Grafana,建一个能看到 p99 延迟的面板
- 用 Evidently 对比训练数据与线上近期数据,生成数据漂移报告并读懂 PSI/KS 结论
为什么要学
模型上线后有三个「悄悄变坏」的方式:服务变慢(系统层)、预测分布漂移(数据层)、业务指标下滑(效果层)。第 8 课的探针只能告诉你容器活着,不能告诉你模型判得还准不准——而模型劣化往往在用户抱怨之前已持续数周。
监控就是给模型装仪表盘和预警器。人话:后端监控看「服务死没死」,ML 监控还要看「模型的输入世界变了没有」。本站判题超时模型的典型事故是:站点上线了 Rust 语言支持,提交特征分布突变,模型对所有 Rust 提交给出离谱预测——没有漂移监控,这件事要等运营报障才发现。
先建立图像
三层监控体系:
① 系统层(Prometheus/Grafana):QPS、p99 延迟、错误率、容器资源
→ 回答「服务还能不能用」
② 数据层(Evidently):特征分布 vs 训练基线的漂移
→ 回答「输入世界变了没有」
③ 效果层(业务指标 + 延迟标签回填):线上准确率/F1、超时拦截率
→ 回答「模型判得还准不准」
闭环:③或②报警 → 第 6 课编排器触发重训 → 第 5 课门禁 → 晋升
跟着做
步骤 1:给推理服务打指标
pip install prometheus-client evidently
# src/serve.py(在原服务上叠加指标)
import time
import joblib
import pandas as pd
from fastapi import FastAPI, Request
from prometheus_client import Counter, Histogram, make_asgi_app
app = FastAPI(title="判题超时预测服务")
model = joblib.load("models/timeout-v1.joblib")
PREDICTS = Counter(
"model_predicts_total", "预测次数",
["model", "bucket"]) # bucket: low/mid/high 概率分段
LATENCY = Histogram(
"model_predict_latency_seconds", "预测耗时",
buckets=(0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5))
@app.post("/predict")
def predict(code_lines: int, loop_depth: int,
lang_java: int, problem_rank: int):
start = time.perf_counter()
X = pd.DataFrame([dict(code_lines=code_lines, loop_depth=loop_depth,
lang_java=lang_java, problem_rank=problem_rank)])
proba = float(model.predict_proba(X)[0, 1])
LATENCY.observe(time.perf_counter() - start)
bucket = "high" if proba > 0.8 else "mid" if proba > 0.3 else "low"
PREDICTS.labels(model="timeout-v1", bucket=bucket).inc()
# 生产环境:此处把 X + proba 异步写入预测日志表,供效果回填与漂移检测
return {"timeout_probability": round(proba, 4)}
app.mount("/metrics", make_asgi_app()) # 暴露 /metrics 给 Prometheus
步骤 2:Prometheus 抓取 + Grafana 面板
# prometheus.yml
global: { scrape_interval: 15s }
scrape_configs:
- job_name: timeout-api
static_configs:
- targets: ["host.docker.internal:8000"] # Linux 用宿主机 IP
docker run -d --name prom -p 9090:9090 \
-v $(pwd)/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus
docker run -d --name grafana -p 3000:3000 grafana/grafana
# Grafana(localhost:3000, admin/admin) 添加数据源 http://prom:9090 后建面板:
# p99 延迟: histogram_quantile(0.99, rate(model_predict_latency_seconds_bucket[5m]))
# QPS: rate(model_predicts_total[5m])