GTE-large部署教程:Prometheus+Grafana监控GPU利用率与API响应延迟
2026/4/17 7:14:07 网站建设 项目流程

GTE-large部署教程:Prometheus+Grafana监控GPU利用率与API响应延迟

1. 为什么需要监控这个模型服务

你刚把 GTE-large 文本向量模型跑起来了,网页能打开、API 能调通、NER 和情感分析结果也看着挺准——但接下来呢?
如果它突然变慢了,你第一时间知道吗?
如果 GPU 显存悄悄涨到 98%,而你还在等一个 30 秒没返回的/predict请求,问题出在哪?
如果用户反馈“问答功能时好时坏”,你是重启服务,还是翻日志查了 20 分钟才发现是某次批量请求把显存打满了?

这不是理论问题。真实场景中,一个没被监控的 AI 服务,就像一辆没装仪表盘的车——能开,但不知道油还剩多少、发动机温度是否异常、刹车响应是否延迟。

本文不讲怎么训练 GTE-large,也不重复 ModelScope 模型下载步骤。我们聚焦一个工程落地中最容易被跳过的环节:让这个基于 Flask 的多任务 Web 应用,真正“可观察”(observable)
你会亲手完成三件事:
把 Prometheus 嵌入 Flask 应用,自动采集 GPU 利用率、显存占用、API 响应时间、请求成功率;
用 Grafana 搭建专属监控看板,一眼看清“哪个任务最耗 GPU”、“哪类请求延迟最高”;
避开常见坑:Flask 多进程下指标冲突、GPU 指标采集权限问题、Grafana 面板数据断连。

全程基于你已有的项目结构(/root/build/),不新增模型、不重写业务逻辑,只加监控能力。


2. 环境准备与监控组件安装

2.1 确认基础依赖已就位

你的项目已在运行,说明以下组件已安装:

  • Python 3.8+
  • flask,torch,transformers,modelscope
  • NVIDIA 驱动 +nvidia-smi可用(验证命令:nvidia-smi -L

注意:若nvidia-smi报错或无输出,请先在宿主机安装驱动和 CUDA 工具包。容器环境需确保以--gpus all启动,并挂载/dev/nvidia*设备。

2.2 安装监控核心组件

/root/build/目录下执行:

pip install prometheus-client psutil nvidia-ml-py3
  • prometheus-client: 提供 Flask 中间件和指标注册能力;
  • psutil: 获取进程级 CPU/内存信息(辅助诊断);
  • nvidia-ml-py3: 官方 Python 封装,安全读取 GPU 状态(比解析nvidia-smi输出更稳定)。

验证安装:运行python -c "import pynvml; pynvml.nvmlInit(); print('OK')",无报错即成功。

2.3 修改启动脚本,启用监控端点

编辑/root/build/start.sh,将原启动命令:

python app.py

替换为:

# 启用 Prometheus 指标暴露端口 9090(与 Flask 的 5000 端口分离) python app.py --monitor-port 9090

并在app.py开头添加参数解析支持(插入在import之后、if __name__ == "__main__":之前):

import argparse import sys parser = argparse.ArgumentParser() parser.add_argument("--monitor-port", type=int, default=9090, help="Port for Prometheus metrics") args = parser.parse_args()

同时,将 Flask 启动行改为:

if __name__ == "__main__": app.run(host='0.0.0.0', port=5000, debug=False) # 生产环境必须关 debug

关键点:监控端口(9090)与业务端口(5000)严格分离。避免 Prometheus 抓取器干扰业务流量,也防止业务异常导致监控失联。


3. 在 Flask 应用中嵌入监控指标

3.1 注册核心指标对象

app.py顶部import区块后,添加:

from prometheus_client import Counter, Histogram, Gauge, make_wsgi_app from werkzeug.middleware.dispatcher import DispatcherMiddleware import threading import time import pynvml # 初始化 NVML(仅需一次) pynvml.nvmlInit() # 1. 请求计数器:按 task_type 和 HTTP 状态码维度 REQUEST_COUNT = Counter( 'gte_api_requests_total', 'Total HTTP Requests', ['task_type', 'status_code'] ) # 2. 响应延迟直方图:按 task_type 统计 P90/P95 延迟 REQUEST_DURATION = Histogram( 'gte_api_request_duration_seconds', 'API Request Duration', ['task_type'], buckets=(0.1, 0.25, 0.5, 1.0, 2.0, 5.0, 10.0) ) # 3. GPU 指标:单卡场景下使用 device 0 GPU_UTILIZATION = Gauge('gpu_utilization_percent', 'GPU Utilization %', ['device']) GPU_MEMORY_USED = Gauge('gpu_memory_used_bytes', 'GPU Memory Used Bytes', ['device']) GPU_MEMORY_TOTAL = Gauge('gpu_memory_total_bytes', 'GPU Memory Total Bytes', ['device']) # 4. 进程指标(可选,辅助定位 OOM) PROCESS_MEMORY = Gauge('process_memory_bytes', 'Flask Process Memory Usage')

3.2 添加请求中间件,自动记录请求指标

app.py中,@app.route('/predict', methods=['POST'])路由函数上方,插入如下装饰器函数(推荐放在app实例创建后、路由定义前):

@app.before_request def before_request(): # 记录请求开始时间 request.start_time = time.time() @app.after_request def after_request(response): # 获取 task_type(从 request.json 或默认值) task_type = "unknown" try: if request.endpoint == 'predict' and request.method == 'POST': data = request.get_json() task_type = data.get("task_type", "unknown") if data else "unknown" except: pass # 计算耗时并记录 duration = time.time() - request.start_time REQUEST_DURATION.labels(task_type=task_type).observe(duration) # 记录状态码 REQUEST_COUNT.labels(task_type=task_type, status_code=response.status_code).inc() return response

3.3 启动 GPU 指标采集线程(后台常驻)

app.py底部if __name__ == "__main__":块内,app.run(...)之前,添加:

def collect_gpu_metrics(): """每 3 秒采集一次 GPU 指标""" handle = pynvml.nvmlDeviceGetHandleByIndex(0) # 假设单卡 while True: try: util = pynvml.nvmlDeviceGetUtilizationRates(handle) mem_info = pynvml.nvmlDeviceGetMemoryInfo(handle) GPU_UTILIZATION.labels(device='0').set(util.gpu) GPU_MEMORY_USED.labels(device='0').set(mem_info.used) GPU_MEMORY_TOTAL.labels(device='0').set(mem_info.total) except Exception as e: # 忽略临时错误,避免线程崩溃 pass time.sleep(3) # 启动采集线程(守护线程,随主进程退出) threading.Thread(target=collect_gpu_metrics, daemon=True).start()

3.4 暴露 Prometheus 指标端点

app.py中,在所有路由定义之后、if __name__ == "__main__":之前,添加:

# 创建 /metrics 子应用 metrics_app = make_wsgi_app() # 将 metrics_app 挂载到主 Flask 应用 app.wsgi_app = DispatcherMiddleware(app.wsgi_app, { '/metrics': metrics_app })

此时访问http://<your-ip>:9090/metrics即可看到原始指标文本,包含gte_api_requests_totalgte_api_request_duration_seconds_bucketgpu_utilization_percent等。


4. 部署 Prometheus 与 Grafana

4.1 一键启动 Prometheus(Docker 方式)

在服务器上执行(无需 root):

mkdir -p /root/prometheus && cd /root/prometheus cat > prometheus.yml << 'EOF' global: scrape_interval: 10s scrape_configs: - job_name: 'gte-api' static_configs: - targets: ['host.docker.internal:9090'] # 若 Prometheus 在容器中运行,指向宿主机 # 若 Prometheus 与 Flask 同在宿主机,改为 targets: ['localhost:9090'] EOF docker run -d \ --name prometheus \ -p 9090:9090 \ -v $(pwd)/prometheus.yml:/etc/prometheus/prometheus.yml \ -v $(pwd)/data:/prometheus \ --restart=always \ prom/prometheus:latest \ --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

验证:浏览器打开http://<your-ip>:9090/targets,状态应为 UP;http://<your-ip>:9090/graph输入gte_api_requests_total应有数据。

4.2 一键启动 Grafana(Docker 方式)

docker run -d \ --name grafana \ -p 3000:3000 \ -v grafana-storage:/var/lib/grafana \ --restart=always \ -e "GF_SECURITY_ADMIN_PASSWORD=admin" \ grafana/grafana-oss:latest

首次登录:http://<your-ip>:3000,账号admin/ 密码admin→ 登录后强制修改密码。

4.3 在 Grafana 中配置数据源与看板

  1. 添加 Prometheus 数据源
    Settings → Data Sources → Add data source → Prometheus → URL 填http://<your-ip>:9090→ Save & test。

  2. 导入预置看板(推荐)
    Dashboard → Import → 输入以下 JSON(复制粘贴),Name 填 “GTE-large Service Monitor”:

{ "dashboard": { "panels": [ { "title": "GPU 利用率(实时)", "targets": [{"expr": "gpu_utilization_percent{device=\"0\"}"}], "type": "graph" }, { "title": "GPU 显存使用(MB)", "targets": [{"expr": "gpu_memory_used_bytes{device=\"0\"} / 1024 / 1024"}], "type": "graph" }, { "title": "API 请求总量(按任务类型)", "targets": [{"expr": "sum by (task_type) (rate(gte_api_requests_total[1h]))"}], "type": "stat" }, { "title": "P95 响应延迟(秒)", "targets": [{"expr": "histogram_quantile(0.95, sum(rate(gte_api_request_duration_seconds_bucket[1h])) by (le, task_type))"}], "type": "graph" } ] } }

效果:4 个核心面板实时显示 GPU 负载、请求分布、关键延迟。你立刻能回答:“现在 NER 任务平均要 1.2 秒,但 P95 达到 4.7 秒,且 GPU 利用率持续 95% —— 很可能显存瓶颈。”


5. 实战验证与典型问题排查

5.1 快速验证监控是否生效

  1. 启动 Flask 应用:bash /root/build/start.sh
  2. 发送 3 类请求(各 2 次):
    curl -X POST http://localhost:5000/predict -H "Content-Type: application/json" -d '{"task_type":"ner","input_text":"张三在北京工作"}' curl -X POST http://localhost:5000/predict -H "Content-Type: application/json" -d '{"task_type":"sentiment","input_text":"这个产品太棒了!"}' curl -X POST http://localhost:5000/predict -H "Content-Type: application/json" -d '{"task_type":"qa","input_text":"北京是中国的首都|北京是哪个国家的首都?"}'
  3. 等待 30 秒,刷新 Grafana 看板 → 所有面板应有数据波动。

5.2 常见问题与解决

现象原因解决方案
http://<ip>:9090/metrics返回 404Flask 未正确挂载/metrics检查app.wsgi_app = DispatcherMiddleware(...)是否在app.run()之前执行;确认make_wsgi_app()导入无误
Grafana 中 GPU 指标始终为 0pynvml未初始化或设备索引错误collect_gpu_metrics()函数开头加print(pynvml.nvmlDeviceGetName(handle)),确认设备名输出正常;多卡环境改用pynvml.nvmlDeviceGetHandleByIndex(i)循环采集
Prometheus 抓取失败(State: DOWN)Docker 网络隔离导致host.docker.internal不可达将 Prometheus 的targets改为宿主机真实 IP(如172.16.1.100:9090),或启动时加--add-host=host.docker.internal:host-gateway
/predict接口变慢监控线程抢占 CPU?collect_gpu_metricstime.sleep(3)已足够宽松;实际延迟主要来自模型推理本身,监控开销 < 1ms,可忽略

进阶提示:若需告警(如 GPU 利用率 > 90% 持续 5 分钟),可在 Prometheus 中配置 Alert Rules,并通过邮件/Webhook 推送。本文聚焦可观测性基础,告警属于下一阶段。


6. 总结:监控不是锦上添花,而是上线必选项

部署一个大模型 Web 服务,从来不是git clonepip installbash start.sh就结束了。
真正的闭环,是当你看到 Grafana 上那条陡然拉升的 GPU 利用率曲线时,能立刻判断:“是新来的 QA 请求触发了显存泄漏”,而不是盲目重启;
是当运营同事说“分类功能最近不准”,你能打开看板,发现classification任务的 P95 延迟从 0.8 秒飙升至 6.2 秒,进而定位到某批脏数据导致模型反复重试;
是当服务器告警磁盘满,你第一反应不是删日志,而是查process_memory_bytes指标——确认是 Flask 进程内存缓慢增长,而非日志文件。

本文带你走完了从零到一的监控链路:
🔹 在现有 Flask 代码中轻量嵌入 Prometheus 指标(无侵入式改造);
🔹 用pynvml稳定采集 GPU 状态(避开nvidia-smi解析风险);
🔹 通过 Docker 一键拉起 Prometheus+Grafana(无需运维介入);
🔹 导入即用看板,5 分钟获得生产级可观测性。

下一步,你可以:
→ 将/metrics端点加上 Basic Auth(防未授权访问);
→ 用gunicorn替换app.run(),开启多 worker 并发(注意指标线程安全);
→ 把 Grafana 看板导出为 JSON,纳入 CI/CD 流水线自动部署。

监控不会让模型更准,但它让你永远清楚——它为什么不准。

--- > **获取更多AI镜像** > > 想探索更多AI镜像和应用场景?访问 [CSDN星图镜像广场](https://ai.csdn.net/?utm_source=mirror_blog_end),提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询