1. 生产环境里 vLLM 推理服务为什么总在半夜崩
vLLM 推理服务在生产环境跑起来不难,难的是让它连续跑几周不出事。我见过太多团队把模型部署完、接口调通就上线,结果某天凌晨显存悄悄涨满,进程被 OOM Killer 干掉,第二天早上才发现服务已经挂了三小时。这类问题在 GPU 推理场景里特别典型,因为 vLLM 依赖 PagedAttention 动态管理 KV Cache,显存占用会随并发请求数实时波动,光看"服务还活着"根本不够。
这篇要解决的就是这件事:给 vLLM 推理服务搭一套能长期盯着的生产环境监控方案,覆盖 GPU 指标采集、Prometheus 抓取、告警规则、压测验证的完整链路。适合已经在跑 vLLM、或者准备上生产环境的运维和算法工程同学。ROCm 场景和 CUDA 场景我都会提到,因为 AMD Instinct 系列在 ROCm 7.x 下的监控路径和 NVIDIA 有区别,dcgm-exporter 的部署方式也不一样。
核心思路是:用 TaoToken 统一管理推理服务调用侧的 Key,把监控和调用鉴权解耦,这样监控体系只关心指标,Key 的轮换、配额、审计交给 TaoToken 处理。下面从指标定义开始,一步步给可复制的配置。
2. 先搞清楚 vLLM 生产监控要看哪些指标
监控不是指标越多越好,堆一堆没人看的曲线只会增加维护成本。对 vLLM 推理服务来说,真正决定"长期稳定"的指标就那么几类。
硬件层是底线。GPU 核心温度、板卡功耗、显存使用率这三项必须实时采。温度超过额定值 85% 就该警告,超过 95% 要能自动熔断,否则硬件可能永久损坏。显存使用率是最关键的,vLLM 一旦显存耗尽直接 OOM 崩溃,而且崩溃前往往没有明显征兆,只能靠趋势预判。
算力层看 SM 利用率(AMD 平台对应 CU 占用率)。这个指标单独看没意义,要和请求队列长度、延迟一起看。如果 SM 利用率长期偏低但请求堆积,说明有算子瓶颈或调度延迟;如果持续满载,就该考虑扩容了。
业务层看首字延迟(TTFT)和总生成耗时。这两个指标直接对应体验,长尾延迟往往比平均值更能暴露问题。我建议把 TTFT 的 P99 单独拉一个面板,很多隐性故障都是从 P99 先恶化的。
把这些指标纳入统一视图后,下一步是解决"怎么采"。ROCm 生态里 DCGM 提供标准硬件遥测接口,dcgm-exporter 负责把数据转成 Prometheus 能抓的格式。CUDA 场景同理,只是设备节点和驱动不同。
3. TaoToken 前置:统一 Key 让监控和调用解耦
在讲采集配置之前,先说清楚 TaoToken 在这套方案里的位置。很多团队的监控脚本、压测工具、告警回调都要调 vLLM 的推理接口,如果每个工具各自维护一套 Key,轮换时就是灾难。TaoToken 的作用是把这些调用统一到一个 Key 管理体系下。
你可以先去官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 了解整体能力,然后在控制台 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 创建项目、生成 API Key。Key 生成后,压测脚本、监控探针、告警验证工具都用同一个 Key 调推理接口,配额和审计在 TaoToken 侧统一看。
具体操作路径:登录后进 API Keys 页面 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,新建一个 Key,命名建议带上用途,比如vllm-monitor-prod。这样后面排查"哪个工具在打请求"时一眼能认出来。
接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,里面有各语言的调用示例。API 端点统一走 https://taotoken.net/api ,注意这个地址不带 UTM 参数,配置里直接写就行。
注意:TaoToken 是调用侧的 Key 管理,不替代 vLLM 本身的部署。vLLM 服务还是跑在你自己的 GPU 机器上,TaoToken 管的是"谁在调、调了多少、有没有超配额"。
如果你后面要做长期编码或 Agent 类的自动化运维脚本,可以看 Coding Plan https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,把监控告警的自动处置逻辑挂上去。单纯验证模型输出是否正常,用模型对话 https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 手动测几条就行。
4. 可复制的监控配置骨架
这一节给完整配置,Prometheus 抓取项和告警规则都能直接抄。
4.1 dcgm-exporter 部署(ROCm 场景)
先确认宿主机 ROCm 驱动正常,跑一下rocm-smi能看到卡信息。然后容器化部署 dcgm-exporter:
docker run -d --name dcgm-exporter \ --restart unless-stopped \ --gpus all \ -v /dev/kfd:/dev/kfd \ -v /dev/dri:/dev/dri \ -v /var/lib/dcgm-exporter:/var/lib/dcgm-exporter \ -p 9400:9400 \ rocm/dcgm-exporter:latest \ -f /etc/dcgm-exporter/default-counters.csv \ --collect-interval 15000--collect-interval 15000是 15 秒采集一次,生产环境建议 15 到 30 秒,太密会增加系统开销。ROCm 场景必须映射/dev/kfd和/dev/dri,否则 exporter 读不到硬件寄存器。CUDA 场景换成--gpus all加 NVIDIA 的 dcgm-exporter 镜像即可。
启动后验证:
curl -s http://localhost:9400/metrics | grep -E "DCGM_FI_DEV_(GPU_TEMP|POWER_USAGE|FB_USED)"能返回带gpu="0"标签的指标行就说明采集通了。
4.2 Prometheus 抓取配置
在prometheus.yml里加抓取任务:
scrape_configs: - job_name: 'dcgm-gpu' scrape_interval: 15s static_configs: - targets: ['gpu-node-01:9400', 'gpu-node-02:9400'] metric_relabel_configs: - source_labels: [gpu] target_label: gpu_id - source_labels: [UUID] target_label: gpu_uuidmetric_relabel_configs这段是关键,把 GPU 的 UUID 注入标签,多卡环境下才能按卡维度筛选。没有这步,两台机器各 8 张卡的数据会混在一起,排查单卡故障时很痛苦。
4.3 告警规则片段
显存告警不要用静态阈值,vLLM 的显存随并发波动,瞬时冲高是正常的。用持续时间条件过滤误报:
groups: - name: vllm-gpu-alerts rules: - alert: GPUMemoryHigh expr: DCGM_FI_DEV_FB_USED / DCGM_FI_DEV_FB_TOTAL > 0.92 for: 60s labels: severity: critical annotations: summary: "GPU {{ $labels.gpu_id }} 显存使用率超 92% 持续 60 秒" - alert: GPUTempWarning expr: DCGM_FI_DEV_GPU_TEMP > 85 for: 30s labels: severity: warning annotations: summary: "GPU {{ $labels.gpu_id }} 温度 {{ $value }}℃ 偏高" - alert: GPUTempCritical expr: DCGM_FI_DEV_GPU_TEMP > 95 for: 10s labels: severity: critical annotations: summary: "GPU {{ $labels.gpu_id }} 温度 {{ $value }}℃ 触发熔断阈值"温度分两级:85℃ 警告,提示查机房空调或风扇;95℃ 严重,应该自动触发熔断或重启实例。for字段控制持续时间,显存用 60 秒过滤突发流量,温度用 30 秒和 10 秒,因为温度上升快,等太久硬件就伤了。
4.4 复合告警:反直觉的故障信号
单独看一个指标容易漏报,加一条复合规则:
- alert: GPULowUtilHighLatency expr: | DCGM_FI_DEV_GPU_UTIL < 10 and vllm_request_latency_p99 > 5 for: 120s labels: severity: warning annotations: summary: "GPU 利用率低但延迟高,疑似驱动挂死或 PCIe 异常"SM 利用率低于 10% 但延迟却升高,通常意味着底层驱动挂死或通信异常。这类反直觉的告警能在用户感知到故障前提前发现问题。
5. 压测触发与指标核对:确认监控真的生效
配置写完不代表监控生效,必须做一次可验证的压测,看指标是否按预期变化。
5.1 用 TaoToken Key 发起压测
写个简单的压测脚本,用前面创建的 Key 调推理接口:
import time import requests from concurrent.futures import ThreadPoolExecutor API_URL = "https://taotoken.net/api/v1/chat/completions" API_KEY = "你的TaoToken Key" def send_request(i): headers = {"Authorization": f"Bearer {API_KEY}"} payload = { "model": "your-vllm-model", "messages": [{"role": "user", "content": f"压测请求 {i},请生成 200 字回复"}], "max_tokens": 200 } start = time.time() resp = requests.post(API_URL, json=payload, headers=headers, timeout=60) return time.time() - start, resp.status_code with ThreadPoolExecutor(max_workers=32) as pool: results = list(pool.map(send_request, range(200))) latencies = [r[0] for r in results] print(f"P50: {sorted(latencies)[100]:.2f}s") print(f"P99: {sorted(latencies)[198]:.2f}s")32 并发打 200 个请求,观察 GPU 指标变化。
5.2 核对指标
压测期间在 Prometheus 里查:
DCGM_FI_DEV_FB_USED / DCGM_FI_DEV_FB_TOTAL应该能看到显存使用率明显上升。压测结束后等 30 秒,显存应该回落。如果压测停了显存不降,说明有显存泄漏,要查 vLLM 版本是否有已知 Bug。
同时看 TTFT 的 P99:
histogram_quantile(0.99, rate(vllm_time_to_first_token_bucket[5m]))压测期间 P99 会升高,压测结束回落。如果 P99 持续高位不降,检查--max-model-len参数是否设得过大,导致 PagedAttention 块分配效率下降。
5.3 触发一次告警验证
想确认告警链路通,可以临时把显存告警阈值调到 0.5,跑压测让它触发,看告警是否按预期发出。验证完记得改回 0.92。这一步很多人跳过,结果真出事时发现告警根本没配好。
6. 本篇常见错排查
dcgm-exporter 起不来,日志报 device not found:ROCm 场景九成是/dev/kfd或/dev/dri没映射。检查docker run命令里这两个 volume 是否都在,宿主机ls -l /dev/kfd确认设备存在。
Prometheus 抓不到指标,target 显示 down:先curl http://gpu-node-01:9400/metrics确认 exporter 本身能返回数据,再查 Prometheus 到目标机器的网络和防火墙。9400 端口默认只监听容器内,确认-p 9400:9400映射正确。
多卡数据混在一起分不清哪张卡:metric_relabel_configs里的 UUID 标签没配。加上source_labels: [UUID]那段,重启 Prometheus 后按gpu_uuid筛选。
显存告警频繁误报:for字段设太短。vLLM 显存随并发波动,瞬时冲高正常,把for调到 60s 以上,过滤突发流量。
压测后显存不回落:可能是显存泄漏。先确认 vLLM 版本,升级到最新稳定版;再检查是否有请求异常中断导致 KV Cache 没释放。长期看,把显存趋势纳入周度复盘,对比历史同期数据能提前发现泄漏苗头。
告警发了但没人收到:Alertmanager 的路由配置没接。Prometheus 只负责触发告警,实际发送要配 Alertmanager 的 receiver,邮件、Webhook、钉钉都要单独配。
7. 把监控接入和 Key 管理收口到一处
整套方案跑通后,你会发现监控体系里最容易被忽略的是调用侧的 Key 管理。压测脚本、监控探针、告警验证工具、自动处置脚本,每个都要调推理接口,Key 散落各处,轮换时容易漏。用 TaoToken 把这些调用统一到一个 Key 体系下,配额和审计在控制台一眼能看全。
接入配置直接参考文档 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 端点用 https://taotoken.net/api 。Key 在 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 管理,建议按用途分 Key,比如监控探针一个、压测一个、自动处置一个,出问题时能快速定位是哪个环节在打请求。
监控体系的终点不是看板,是持续优化。建议建立周度复盘,对比历史显存水位和吞吐量,评估资源配置是否合理。闲时显存仍高位就查泄漏,SM 利用率长期闲置就考虑缩容。数据驱动的运维,才是 vLLM 推理服务在生产环境长期稳定的根本。