1. AI 服务监控的独特挑战
相比传统的 HTTP API 服务,AI 服务(尤其是 LLM API)的监控更加复杂:普通服务的延迟通常在 10-500ms 之间,而 LLM 推理延迟可能从 500ms(小模型)到 30s(长上下文生成)不等,直接用「平均延迟」判断健康状况极具误导性。此外,Token 消耗成本、并发排队长度、KV 缓存命中率和模型排队等待时间是 AI 服务特有的关键指标,传统 APM 工具(如 New Relic、Datadog)的预设仪表盘往往无法覆盖。
本方案选择 Prometheus + Grafana + Loki + DCGM Exporter 的组合,以最低的成本构建完整的 AI 可观测性体系。这套方案已经在我们的 DeepSeek V3 推理集群上稳定运行,覆盖了 200+ 并发用户的监控需求。
2. Prometheus 指标设计与采集
AI 服务的指标可以分为三层:基础设施层(GPU/NPU、CPU、内存、网络)、模型服务层(QPS、延迟分位数、Token 速率、排队深度)和应用层(业务成功率、用户满意度、成本消耗)。以下命令展示了完整的 Prometheus 安装和 AI 专用指标配置:
# 1. 安装 Prometheus + Grafana(使用 Docker Compose)
cat > /opt/monitoring/docker-compose.yml << 'EOF'
version: "3.8"
services:
prometheus:
image: prom/prometheus:v2.47.0
ports: ["9090:9090"]
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- ./alerts:/etc/prometheus/alerts
- prom_data:/prometheus
command:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.retention.time=30d"
- "--storage.tsdb.max-block-duration=2h"
restart: always
grafana:
image: grafana/grafana:10.2.0
ports: ["3000:3000"]
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin-ai-monitor
- GF_USERS_ALLOW_SIGN_UP=false
volumes:
- grafana_data:/var/lib/grafana
- ./dashboards:/etc/grafana/provisioning/dashboards
restart: always
loki:
image: grafana/loki:2.9.0
ports: ["3100:3100"]
volumes:
- ./loki-config.yml:/etc/loki/local-config.yaml
- loki_data:/loki
restart: always
dcgm-exporter:
image: nvcr.io/nvidia/k8s/dcgm-exporter:3.3.0
ports: ["9400:9400"]
cap_add:
- SYS_ADMIN
- SYS_PTRACE
devices:
- /dev/nvidia0:/dev/nvidia0
- /dev/nvidia-uvm:/dev/nvidia-uvm
- /dev/nvidia-uvm-tools:/dev/nvidia-uvm-tools
restart: always
node-exporter:
image: prom/node-exporter:v1.7.0
ports: ["9100:9100"]
pid: host
restart: always
volumes:
prom_data:
grafana_data:
loki_data:
EOF
# 2. 启动监控栈
cd /opt/monitoring && docker compose up -d
# 3. 验证 Prometheus 已启动
curl -s http://localhost:9090/api/v1/query?query=up | python3 -m json.tool | head -20
Prometheus 的核心 AI 服务指标需要从 FastAPI 应用中暴露。我们推荐使用 prometheus-fastapi-instrumentator 库自动采集 HTTP 请求指标,并手动添加 LLM 特有指标:
# 4. 在 LLM API 服务端集成 Prometheus 埋点
pip install prometheus-fastapi-instrumentator prometheus_client
# 在 FastAPI 应用中添加(/opt/llm-service/app.py 片段)
from prometheus_fastapi_instrumentator import Instrumentator
from prometheus_client import Histogram, Counter, Gauge
# LLM 特有指标
LLM_LATENCY = Histogram(
"llm_request_latency_seconds",
"LLM inference latency by model",
["model", "stream"],
buckets=[0.1, 0.25, 0.5, 1, 2, 5, 10, 20, 30, 60]
)
LLM_TOKENS = Counter(
"llm_tokens_total",
"Total tokens generated",
["model", "type"] # type ∈ {prompt, completion}
)
LLM_QUEUE_DEPTH = Gauge(
"llm_request_queue_depth",
"Current number of queued LLM requests"
)
# 记录推理延迟
@LLM_LATENCY.time()
async def generate_response(model: str, messages: list, stream: bool = False):
start = time.time()
response = await call_llm_api(model, messages, stream=stream)
elapsed = time.time() - start
LLM_LATENCY.labels(model=model, stream=str(stream)).observe(elapsed)
# 统计 Token 数(基于 tiktoken 或返回的 usage 字段)
LLM_TOKENS.labels(model=model, type="completion").inc(response["usage"]["completion_tokens"])
LLM_TOKENS.labels(model=model, type="prompt").inc(response["usage"]["prompt_tokens"])
return response
3. Grafana 仪表盘:6 张关键面板
仪表盘的设计原则是「分层展示」:顶层是业务健康度(SLO 状态),上层是系统健康度(延迟/错误率),底层是资源健康度(GPU/CPU/内存)。以下是 6 张核心 Grafana 面板的查询语句和控制建议:
| 面板名称 | 核心查询 | 告警阈值 | 查看频率 |
|---|---|---|---|
| LLM 延迟分位数 | histogram_quantile(0.95, sum(rate(llm_request_latency_seconds_bucket[5m])) by (le, model)) | P95 > 5s | 实时 |
| QPS 与并发 | sum(rate(llm_requests_total[1m])) by (model, status) | 错误率 > 5% | 实时 |
| GPU 利用率 | DCGM_FI_DEV_GPU_UTIL / 100 | sustained > 98% | 5 分钟 |
| 显存占用 | DCGM_FI_DEV_FB_USED / 1024 | > 75GB per GPU | 5 分钟 |
| Token 消耗/小时 | sum(rate(llm_tokens_total[1h])) | 环比激增 > 200% | 每小时 |
| 缓存命中率 | sum(rate(llm_cache_hits_total[5m])) / (sum(rate(llm_cache_hits_total[5m])) + sum(rate(llm_cache_misses_total[5m]))) | < 50% | 每小时 |
4. Loki 日志聚合:AI 调试利器
AI 应用的排错与传统服务有本质区别。用户反馈「答案不对」,我们无法仅凭错误堆栈定位问题——需要查看完整的 Prompt 上下文、模型版本、温度参数和 RAG 检索结果。因此,LLM API 的日志必须包含「会话上下文」级别的信息。我们使用 Grafana Loki 作为日志聚合方案,配合结构化的 JSON 日志格式:
# 5. 在 FastAPI 中添加结构化日志
import structlog
logger = structlog.get_logger()
@app.post("/v1/chat/completions")
async def chat(request: ChatRequest):
# ... 业务逻辑 ...
logger.info(
"llm_request_completed",
user_id=request.user_id,
model=request.model,
prompt_tokens=resp["usage"]["prompt_tokens"],
completion_tokens=resp["usage"]["completion_tokens"],
latency_ms=round(elapsed * 1000),
finish_reason=resp["choices"][0].get("finish_reason")
)
Loki 的 LogQL 查询语言支持对 JSON 字段的过滤和聚合。例如,要查找所有耗时超过 10 秒的 LLM 请求:
{app="llm-service"} |= "llm_request_completed" | json | latency_ms > 10000 | line_format "{{.timestamp}} | user={{.user_id}} | model={{.model}} | latency={{.latency_ms}}ms | tokens={{.completion_tokens}}"
5. GPU/NVIDIA DCGM 指标集成
GPU 是 AI 服务最昂贵的资源,也是最容易出问题的环节。NVIDIA DCGM(Data Center GPU Manager)exporter 可以提供 GPU 利用率、显存占用、温度、功耗和 NVLink 带宽等关键指标。以下命令展示了 DCGM 关键指标的告警规则配置:
# 6. DCGM 关键指标说明
# 可通过 curl http://localhost:9400/metrics 查看所有指标
# 核心指标:
# DCGM_FI_DEV_GPU_UTIL - GPU 利用率 (0-100)
# DCGM_FI_DEV_FB_USED - 已用显存 (MB)
# DCGM_FI_DEV_FB_TOTAL - 总显存 (MB)
# DCGM_FI_DEV_GPU_TEMP - GPU 温度 (°C)
# DCGM_FI_DEV_POWER_USAGE - 实时功耗 (W)
# DCGM_FI_PROF_GR_ENGINE_ACTIVE - 图形引擎活跃时间比例
# 7. 创建 GPU 告警规则
cat > /opt/monitoring/alerts/gpu_alerts.yml << 'EOF'
groups:
- name: gpu_alerts
rules:
- alert: GPUTemperatureHigh
expr: DCGM_FI_DEV_GPU_TEMP > 85
for: 5m
labels: {severity: "critical"}
annotations:
summary: "GPU {{ $labels.gpu }} 温度过高 {{ $value }}°C"
description: "GPU {{ $labels.gpu }} 的温度持续高于 85°C,需要检查散热或负载"
- alert: GPUMemoryLeak
expr: DCGM_FI_DEV_FB_USED / DCGM_FI_DEV_FB_TOTAL > 0.95
for: 10m
labels: {severity: "critical"}
annotations:
summary: "GPU {{ $labels.gpu }} 显存泄漏风险"
description: "GPU {{ $labels.gpu }} 显存使用率已达 {{ $value | humanizePercentage }}"
- alert: GPUPowerLimitBreach
expr: DCGM_FI_DEV_POWER_USAGE > 350
for: 3m
labels: {severity: "warning"}
annotations:
summary: "GPU {{ $labels.gpu }} 功耗超限"
description: "GPU {{ $labels.gpu }} 功耗 {{ $value }}W 超过 350W 限制"
EOF
# 8. 在 prometheus.yml 中引用规则文件
# 重启 Prometheus 加载新规则
docker compose restart prometheus
# 9. 验证告警规则加载成功
curl -s http://localhost:9090/api/v1/rules | python3 -c "import sys,json; d=json.load(sys.stdin); print(f'✓ Loaded {len(d[\"data\"][\"groups\"])} rule groups')"
通过 Prometheus + Grafana + Loki + DCGM 的组合,我们的 AI 服务监控体系实现了「从芯片到业务」的全链路可见性。这套方案的成本仅为 Datadog 同类功能的 1/10,且可根据业务需求灵活扩展指标和告警规则。对于任何生产级 AI 应用,可观测性都不是「可选项」,而是「必选项」。