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 GPU5 分钟
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%每小时
💡 仪表盘导入:Grafana 官方提供的「AI / ML Observability」仪表盘模板(ID: 12856)可以直接导入,覆盖了 OpenAI API 的延迟、Token 用量和错误率监控。我们在此基础上增加了 DCGM GPU 指标面板和 Redis 缓存命中率面板,实现了全链路的可视化。

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')"
🚨 GPU 安全红线:当 GPU 温度持续超过 95°C 时,NVIDIA 驱动会触发硬降频(Thermal Throttling),导致推理延迟翻倍甚至服务中断。必须在 85°C 时触发预警,90°C 时触发紧急扩容或负载均衡。同时,建议在机架层面部署温湿度监控和自动散热联动,这属于基础设施层的保障。

通过 Prometheus + Grafana + Loki + DCGM 的组合,我们的 AI 服务监控体系实现了「从芯片到业务」的全链路可见性。这套方案的成本仅为 Datadog 同类功能的 1/10,且可根据业务需求灵活扩展指标和告警规则。对于任何生产级 AI 应用,可观测性都不是「可选项」,而是「必选项」。