核心内容摘要
Moondream2与TensorFlow Serving集成:生产级部署
通义千问
2.
B-Instruct日志监控缺失Prometheus集成实战
为什么需要监控Qwen
2.
B-Instruct服务你刚用 vLLM Open WebUI 成功跑起了通义千问
2.
B-Instruct界面流畅、响应迅速输入“写一封客户感谢信”秒出结果——一切看起来都很完美。
但当它被接入内部客服系统、每天处理上千次请求时你是否想过某个用户连续发了10条长文本模型是不是悄悄卡在了推理队列里GPU显存突然飙到98%是正常负载还是内存泄漏接口响应时间从300ms跳到
4s但WebUI界面上没有任何告警模型明明在线API却返回503日志里只有一行模糊的Request timeout找不到根因这就是典型的服务“黑盒化”困境能用但不可见可用但不可控。
通义千问
2.
B-Instruct本身不提供内置指标暴露能力vLLM默认也不开放Prometheus兼容的/metrics端点Open WebUI更专注交互而非可观测性。
三者组合起来就像一辆没有仪表盘的高性能跑车——引擎轰鸣速度飞快但油量、水温、转速全靠猜。
而真实生产环境需要的不是“能跑”而是“可管、可查、可预警”。
本文不讲大道理直接带你把Prometheus监控能力“焊”进这套部署栈从零添加指标采集、配置Grafana看板、设置响应延迟告警全程可复制、可验证、不改一行模型代码。
1 Qwen
2.
B-Instruct的可观测性现状先说清楚现状避免踩坑vLLM支持指标导出但需显式启用默认关闭Open WebUI不暴露任何后端指标它只是前端代理所有推理压力实际落在vLLM上Qwen
2.
B-Instruct模型本身无监控逻辑它只负责“算”不负责“报”关键指标必须从vLLM层抓取请求吞吐RPS、平均延迟、排队等待时间、GPU显存占用、解码token速率这意味着你的监控锚点只有一个——vLLM服务进程。
其他组件如Nginx反向代理、Open WebUI容器只需做基础健康检查核心业务指标全部来自vLLM。
部署环境准备与vLLM指标启用我们假设你已通过Docker Compose完成基础部署结构如下# docker-compose.yml简化版 services: vllm: image: vllm/vllm-openai:latest command: --model qwen
2.
b-instruct --tensor-parallel-size 1 --gpu-memory-utilization
9 --enforce-eager --port 8000 ports: - 8000:8000 # 缺少关键配置指标暴露 webui: image: ghcr.io/open-webui/open-webui:main ports: - 3000:8080当前配置下vLLM只开放了OpenAI兼容API/v1/chat/completions但没开指标端点。
要让Prometheus能爬必须加两样东西
1 启用vLLM内置Prometheus指标vLLM自
0.
0起原生支持Prometheus只需两个参数--enable-metrics开启指标收集--metrics-export-port 8001指定独立指标端口避免与API端口冲突修改后的vLLM服务配置services: vllm: image: vllm/vllm-openai:latest command: --model qwen
2.
b-instruct --tensor-parallel-size 1 --gpu-memory-utilization
9 --enforce-eager --port 8000 --enable-metrics --metrics-export-port 8001 ports: - 8000:8000 - 8001:8001 # 新增暴露指标端口 environment: - VLLM_LOG_LEVELINFO重启服务后访问http://localhost:8001/metrics你会看到类似内容# HELP vllm:gpu_cache_usage_ratio GPU KV cache usage ratio # TYPE vllm:gpu_cache_usage_ratio gauge vllm:gpu_cache_usage_ratio{gpu0}
324 # HELP vllm:request_success_total Total number of successful requests # TYPE vllm:request_success_total counter vllm:request_success_total 142 # HELP vllm:time_in_queue_seconds Time spent in the request queue # TYPE vllm:time_in_queue_seconds histogram vllm:time_in_queue_seconds_bucket{le
005} 120 vllm:time_in_queue_seconds_bucket{le
01} 135 ...这些就是你的“数据金矿”从GPU缓存使用率到请求排队时间分布全部以标准Prometheus格式暴露。
2 验证指标可采集性别急着配Prometheus先用curl确认端点可用# 检查HTTP状态码和响应头 curl -I http://localhost:8001/metrics # 查看前20行指标确认有数据 curl http://localhost:8001/metrics | head -20如果返回200 OK且输出包含vllm:前缀的指标说明vLLM已就绪。
若超时请检查Docker网络是否允许vllm容器内访问8001端口宿主机防火墙是否拦截了8001端口--metrics-export-port是否与--port冲突必须不同
Prometheus服务部署与目标发现现在vLLM已“开口说话”下一步是让Prometheus“听懂”它。
1 最小化Prometheus配置创建prometheus.yml仅关注核心需求global: scrape_interval: 15s evaluation_interval: 15s scrape_configs: - job_name: vllm-qwen25 static_configs: - targets: [host.docker.internal:8001] # 关键指向vLLM指标端点 metrics_path: /metrics scheme: http注意host.docker.internal这是Docker Desktop为容器提供的宿主机别名。
如果你用Linux服务器部署需替换为宿主机真实IP如
192.
168.
100:8001或改用Docker网络别名见下文。
2 Docker Compose集成Prometheus将Prometheus加入同一编排文件实现网络互通# docker-compose.yml追加 prometheus: image: prom/prometheus:latest volumes: - ./prometheus.yml:/etc/prometheus/prometheus.yml command: - --config.file/etc/prometheus/prometheus.yml - --storage.tsdb.path/prometheus - --web.console.libraries/usr/share/prometheus/console_libraries - --web.console.templates/usr/share/prometheus/consoles ports: - 9090:9090 depends_on: - vllm关键点在于网络默认Docker Compose会为所有服务创建一个共享网络因此vllm容器可通过服务名直接访问。
但Prometheus要爬vllm的指标端口需确保vllm的8001端口在内部网络暴露已在上一步配置ports。
更新后的scrape_configs更健壮scrape_configs: - job_name: vllm-qwen25 static_configs: - targets: [vllm:8001] # 直接用服务名无需host.docker.internal metrics_path: /metrics scheme: http启动全部服务docker-compose up -d访问http://localhost:9090/targets你应该看到vllm-qwen25状态为UPLast Scrape显示最近采集时间。
3 必须监控的5个核心指标别被上百个指标吓到。
对Qwen
2.
B-Instruct服务这5个指标决定生死指标名Prometheus查询语句为什么关键健康阈值请求成功率rate(vllm:request_success_total[5m]) / rate(vllm:request_total[5m])反映服务可用性低于95%需告警≥98%P95请求延迟histogram_quantile(
95, rate(vllm:request_latency_seconds_bucket[5m]))用户感知最敏感的指标≤
2s7B模型1k上下文GPU显存使用率vllm:gpu_memory_utilization_ratio{gpu0}显存溢出会导致OOM崩溃90%请求排队时长P90histogram_quantile(
90, rate(vllm:time_in_queue_seconds_bucket[5m]))队列堆积预示过载≤
3s每秒生成Token数rate(vllm:generation_tokens_total[5m])衡量实际吞吐能力≥80 tokens/sRTX 4090在Prometheus表达式浏览器中逐个验证确认数据持续上报。
Grafana可视化看板搭建Prometheus是数据库Grafana才是你的驾驶舱。
我们用一个轻量级Docker镜像快速启动
1 启动Grafana并导入预置看板grafana: image: grafana/grafana-enterprise:latest volumes: - grafana-storage:/var/lib/grafana - ./grafana/provisioning:/etc/grafana/provisioning environment: - GF_SECURITY_ADMIN_PASSWORDadmin - GF_USERS_ALLOW_SIGN_UPfalse ports: - 3001:3000 depends_on: - prometheus创建./grafana/provisioning/datasources/datasource.ymlapiVersion: 1 datasources: - name: Prometheus type: prometheus url: http://prometheus:9090 isDefault: true启动后访问http://localhost:3001用admin/admin登录进入Dashboards → New Dashboard。
2 手动构建核心监控面板面板1服务健康总览Top LineTitle:Qwen
2.
B-Instruct Service HealthVisualization: StatQuery:100 * (rate(vllm:request_success_total[5m]) / rate(vllm:request_total[5m]))Unit:percentThresholds:green: 98, yellow: 95, red: 90面板2延迟热力图Latency HeatmapTitle:Request Latency DistributionVisualization: HeatmapQuery:rate(vllm:request_latency_seconds_bucket[5m])X-axis:le(bucket label)Y-axis:TimeWhy: 直观看出延迟是否集中在低区间理想还是拖尾严重异常面板3GPU资源水位GaugeTitle:GPU Memory UtilizationVisualization: GaugeQuery:max(vllm:gpu_memory_utilization_ratio)Min:0, Max:1Thresholds:green:
7, yellow:
85, red:
95面板4实时吞吐与生成速率Time SeriesLeft Y:rate(vllm:request_total[5m])RPSRight Y:rate(vllm:generation_tokens_total[5m])tokens/sLegend: - RPS / Tokens/sWhy: 对比请求量与实际生成量若RPS飙升但tokens/s停滞说明模型卡在prefill阶段小技巧在Grafana中按住Shift拖拽时间范围可快速对比“今天”和“昨天”同一时段数据定位周期性问题。
告警规则配置与实战验证监控不告警等于没监控。
我们用Prometheus Alertmanager实现精准告警。
1 定义Qwen
5专属告警规则创建alerts.ymlgroups: - name: qwen25-alerts rules: - alert: Qwen25HighLatency expr: histogram_quantile(
95, rate(vllm:request_latency_seconds_bucket[5m]))
5 for: 2m labels: severity: warning service: qwen25-vllm annotations: summary: Qwen
2.
B high latency detected description: P95 latency is s (
5s) for 2 minutes - alert: Qwen25GPUMemoryCritical expr: vllm:gpu_memory_utilization_ratio{gpu0}
97 for: 1m labels: severity: critical service: qwen25-vllm annotations: summary: Qwen
5 GPU memory usage critical description: GPU memory utilization is - alert: Qwen25RequestFailureRateHigh expr: 100 * (rate(vllm:request_failure_total[5m]) / rate(vllm:request_total[5m])) 5 for: 3m labels: severity: warning service: qwen25-vllm annotations: summary: Qwen
5 high request failure rate description: Failure rate is % (5%)
2 集成Alertmanager极简版在prometheus.yml中添加alerting: alertmanagers: - static_configs: - targets: [alertmanager:9093] rule_files: - alerts.yml新增Alertmanager服务alertmanager: image: prom/alertmanager:latest volumes: - ./alertmanager.yml:/etc/alertmanager/alertmanager.yml command: - --config.file/etc/alertmanager/alertmanager.yml ports: - 9093:9093创建alertmanager.yml邮件告警示例global: smtp_smarthost: smtp.gmail.com:587 smtp_from: your-emailgmail.com smtp_auth_username: your-emailgmail.com smtp_auth_password: your-app-password route: receiver: email-notifications receivers: - name: email-notifications email_configs: - to: adminyourcompany.com生产环境请用企业微信/钉钉机器人替代邮件避免Gmail限制。
3 告警触发测试手动制造一次高延迟用curl发送一个超长上下文请求如120k tokens观察Alertmanager UIhttp://localhost:9093是否出现待触发告警。
等待2分钟确认告警进入Firing状态。
6.
总结从“能用”到“可控”的关键跨越回顾整个过程你其实只做了三件事打开vLLM的指标开关加--enable-metrics --metrics-export-port成本为零收益巨大让Prometheus找到它通过Docker网络直连服务名无需暴露端口到公网用Grafana和Alertmanager翻译数据把原始指标变成人话——“GPU快满了”、“响应变慢了”、“错误变多了”。
这并非炫技而是生产级AI服务的底线要求。
当你下次接到“模型变慢”的反馈时不再需要SSH进服务器翻日志而是打开Grafana看板3秒定位是GPU瓶颈、还是请求队列积压、或是网络抖动。
更重要的是这套方案完全适配Qwen
2.
B-Instruct的特性它的128K上下文意味着单次请求可能耗尽显存GPU监控必不可少它的高代码生成能力HumanEval 85常被用于自动化脚本稳定性要求极高它的商用许可允许你将其嵌入内部系统而内部系统必须满足可观测性规范。
监控不是给技术团队看的而是给业务兜底的。
当客服机器人因模型延迟导致用户流失当数据分析脚本因OOM中断日报生成——那些在Grafana里跳动的数字就是你提前亮起的红灯。