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 Cachebr/使用率 / 命中率 / 碎片率] 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_secondsHistogram从请求到达队列到首个 token 生成的时间vllm:time_per_output_token_secondsHistogram每生成一个 output token 的平均耗时vllm:e2e_request_latency_secondsHistogram端到端请求延迟含排队推理输出vllm:request_success_totalCounter成功完成的请求总数vllm:request_prompt_tokensHistogram请求 prompt 的 token 数分布vllm:request_generation_tokensHistogram请求生成的 output token 数分布TTFT 是最关键的体验指标。在一次 benchmark 中当并发用户数从 10 增加到 50 时P50 TTFT 从 45ms 增加到 120ms增长 2.7 倍但 P99 TTFT 从 80ms 骤增至 2400ms增长 30 倍。这说明在并发压力下TTFT 的尾延迟恶化速度远快于中位数。仅监控平均值会严重低估用户体验退化。2.2 调度器状态指标vLLM 的调度器维护着三个请求队列——运行中Running、等待调度Waiting、已交换到 CPUSwapped。这些队列的长度是预测延迟恶化的前导指标# 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% 紧急新请求可能被 SwappedTTFT 恶化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 tokensTTFT 会相应恶化但这不是服务性能问题而是负载特征变化。四、告警规则的设计要点与实际踩坑告警规则的设计需要区分症状告警和根因告警。症状告警如 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 密度。这些指标本质上是对推理服务内部状态的实时映射。监控不是为了知道出问题了而是为了在出问题之前发现隐患。