vLLM Prometheus 指标解析——构建大模型推理服务的实时性能监控看板
vLLM Prometheus 指标解析——构建大模型推理服务的实时性能监控看板
一、推理服务的可观测性盲区:当延迟从 200ms 变成 2 秒才开始排查就晚了
大模型推理服务上线后,最危险的局面是"用户投诉了才开始看日志"。推理延迟的恶化通常是渐进的:连续批处理(Continuous Batching)中的调度效率下降、KV Cache 碎片化导致的显存利用率降低、请求队列积压引发的排队延迟——这些问题往往在 P50 延迟上表现正常,直到 P99 延迟从 500ms 膨胀到 3 秒才会触发用户可感知的卡顿。
vLLM 自 0.3.0 版本开始内建了 Prometheus metrics 端点(/metrics),暴露了调度器状态、请求生命周期、KV Cache 使用率等核心指标。但这些指标数量超过 50 个,如果不理解每项指标的物理含义和告警阈值,把数据接入 Grafana 也只是"另一种形式的不理解"。
构建有效的监控看板,第一步不是配 Grafana Panel,而是搞清楚哪些指标是超前导指标(Leading Indicators),能在用户感知到延迟恶化之前就发出告警。
flowchart TD A["vLLM 推理服务<br/>:8000/metrics"] --> B[Prometheus 采集] B --> B1["scrape_interval: 15s"] B1 --> C[指标分类] C --> C1["请求生命周期<br/>TTFT / TPOT / E2E 延迟"] C --> C2["调度器状态<br/>运行/等待/交换队列深度"] C --> C3["KV Cache<br/>使用率 / 命中率 / 碎片率"] C --> C4["吞吐量<br/>tokens/sec / requests/sec"] C1 --> D[Grafana 看板] C2 --> D C3 --> D C4 --> D D --> D1["Panel 1: 延迟分位数趋势<br/>(P50/P95/P99)"] D --> D2["Panel 2: 队列积压告警<br/>(waiting > 10)"] D --> D3["Panel 3: KV Cache 水位<br/>(usage > 85%)"] D1 --> E{告警规则} D2 --> E D3 --> E E --> E1["P99 TTFT > 2s → PagerDuty"] E --> E2["队列积压 > 50 → Slack 告警"] E --> E3["KV Cache > 90% → 自动扩容触发"]二、核心指标分类与物理含义
2.1 请求生命周期指标
请求生命周期是用户直接感知的维度,包含了从请求入队到最后一个 token 生成完成的完整耗时:
| Prometheus 指标名 | 类型 | 物理含义 |
|---|---|---|
vllm:time_to_first_token_seconds | Histogram | 从请求到达队列到首个 token 生成的时间 |
vllm:time_per_output_token_seconds | Histogram | 每生成一个 output token 的平均耗时 |
vllm:e2e_request_latency_seconds | Histogram | 端到端请求延迟(含排队+推理+输出) |
vllm:request_success_total | Counter | 成功完成的请求总数 |
vllm:request_prompt_tokens | Histogram | 请求 prompt 的 token 数分布 |
vllm:request_generation_tokens | Histogram | 请求生成的 output token 数分布 |
TTFT 是最关键的体验指标。在一次 benchmark 中,当并发用户数从 10 增加到 50 时,P50 TTFT 从 45ms 增加到 120ms(增长 2.7 倍),但 P99 TTFT 从 80ms 骤增至 2400ms(增长 30 倍)。这说明在并发压力下,TTFT 的尾延迟恶化速度远快于中位数。仅监控平均值会严重低估用户体验退化。
2.2 调度器状态指标
vLLM 的调度器维护着三个请求队列——运行中(Running)、等待调度(Waiting)、已交换到 CPU(Swapped)。这些队列的长度是预测延迟恶化的前导指标:
# Grafana PromQL 查询示例:当前等待队列中的请求数 # 当此值 > 10 时发出警告,> 50 时发出紧急告警 vllm:num_requests_waiting # 被交换到 CPU 内存的请求数(表示 GPU 显存已满) # 非零值意味着部分请求无法在 GPU 上执行,TTFT 将显著增加 vllm:num_requests_swappedvllm:num_requests_swapped > 0就是一个非常明确的危险信号——它意味着 GPU 显存无法容纳当前活跃请求的 KV Cache,部分序列被交换到了 CPU 内存。CPU-GPU 之间的 KV Cache 传输延迟通常在数十毫秒级别,这会直接体现在 TTFT 的恶化上。
2.3 KV Cache 指标
KV Cache 是推理服务最核心的显存资源。它的使用率和碎片化程度决定了系统能同时容纳多少并行请求:
| 指标 | 告警阈值建议 | 触发后果 |
|---|---|---|
vllm:gpu_cache_usage_perc | > 85% 警告, > 95% 紧急 | 新请求可能被 Swapped,TTFT 恶化 |
vllm:gpu_prefix_cache_hit_rate | < 60% 注意 | Prefix Caching 效率低,检查请求模式变化 |
vllm:num_preemptions_total | 持续增长 | 调度器频繁抢占,抖动增加 |
KV Cache 占用率(%)通过 vLLM 内部逐 token 分配的块使用情况计算:
# vLLM metrics 中 KV Cache 占用率的计算逻辑(伪代码) # gpu_cache_usage_perc = (已分配的 KV blocks / GPU 总 KV blocks) * 100 # 每个 block 通常固定为 16 个 token 的 KV Cache三、Grafana 看板的构建策略
监控看板的设计遵循"从概览到细节"的钻取逻辑。
第一层:服务健康概览。包含 4 个核心数字面板——当前请求 QPS、P50 TTFT、P99 TTFT、KV Cache 占用率。这四个数字能在 3 秒内告诉你服务是否健康。
第二层:延迟趋势图。使用 Histogram 的分位数查询展示 P50/P95/P99 的时间序列。关键是将 TTFT 和 TPOT 分开展示,因为它们的恶化原因通常是不同的——TTFT 恶化通常与调度延迟相关,TPOT 恶化通常与计算效率相关。
第三层:调度器内部状态。展示 Running/Waiting/Swapped 三个队列的时序图。这个 Panel 是提前发现性能回退的关键——Waiting 队列开始增长时,延迟可能还未恶化,但已经处于临界状态。
第四层:请求分布分析。展示 prompt token 数和 output token 数的分布直方图。如果某段时间内 prompt 平均长度突然增加(例如从 500 tokens 增长到 2000 tokens),TTFT 会相应恶化,但这不是服务性能问题而是负载特征变化。
四、告警规则的设计要点与实际踩坑
告警规则的设计需要区分"症状告警"和"根因告警"。症状告警(如 P99 TTFT > 2s)告诉你出问题了,但不知道哪里出了问题。根因告警(如 waiting 队列 > 50)告诉你哪个环节出了故障。有效的告警体系需要两者结合。
在实践中,一个常见的错误是将 KV Cache 占用率的告警阈值设得太低(如 70%)。vLLM 在正常负载下,KV Cache 占用率通常在 60-80% 之间波动。如果阈值设在 70%,几乎每小时都会触发一次误报。建议将警告阈值设为 85%,紧急阈值设为 95%。
另一个常见问题是 Histogram 分位数的精度。Prometheus 的histogram_quantile()函数在尾部分位数的计算上存在显著误差,尤其是当 Histogram 的 buckets 在尾部配置较稀疏时。对于 P99 延迟监控,建议增加 500ms 到 5s 之间的 buckets 密度:
# vLLM TTFT histogram buckets 配置建议 # 针对大模型推理场景(TTFT 通常在 50ms-3s 之间) buckets: [0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1.0, 1.5, 2.0, 3.0, 5.0, 10.0] # 在 0.2s-3s 的关键区间增加了更多 bucket,提升 P95/P99 的估算精度五、总结
vLLM 的 Prometheus metrics 覆盖了推理服务最核心的可观测维度:请求生命周期(TTFT/TPOT/E2E)、调度器状态(队列深度)、KV Cache 资源(使用率/命中率/抢占数)。构建监控看板的核心步骤是:
第一步,识别前导指标。Waiting 队列深度和 KV Cache 占用率是"延迟恶化"的前导信号,在用户感知到延迟变化之前就应该触发告警。
第二步,构建分层看板。从服务概览(4 个核心数字)到延迟趋势到调度器内部状态,支持从宏观到微观的快速钻取。
第三步,校准告警阈值。基于实际负载的 baseline 设定阈值,而非使用泛化的经验值。在 P99 延迟的 Histogram 上增加尾部分位数的 buckets 密度。
这些指标本质上是对推理服务内部状态的实时映射。监控不是为了"知道出问题了",而是为了"在出问题之前发现隐患"。
