bert-base-chinese部署监控方案:Prometheus+Grafana跟踪GPU显存与推理延迟

1. 监控方案概述

在实际的AI模型部署中,仅仅能够运行模型是远远不够的。我们需要实时了解模型的运行状态,特别是GPU资源使用情况和推理性能指标。本文将介绍如何为bert-base-chinese模型搭建完整的监控系统,让你能够:

  • 实时监控GPU显存使用情况
  • 跟踪每次推理的延迟时间
  • 设置告警阈值,及时发现异常
  • 通过可视化仪表盘直观查看各项指标

这个监控方案基于Prometheus和Grafana两大开源工具,无需额外付费,部署简单,效果专业。

2. 环境准备与组件安装

2.1 安装必要的监控组件

首先,我们需要安装几个关键的监控组件:

# 安装Prometheus客户端库
pip install prometheus-client

# 安装GPU监控工具
pip install nvidia-ml-py

# 安装Grafana(可选,也可以使用docker方式)
# 这里我们使用docker-compose方式部署整个监控栈

2.2 创建监控脚本

在bert-base-chinese模型目录下创建监控脚本:

# monitor_metrics.py
import time
import psutil
from prometheus_client import start_http_server, Gauge, Histogram
try:
    import pynvml
    pynvml.nvmlInit()
    HAS_GPU = True
except:
    HAS_GPU = False

# 定义监控指标
GPU_MEMORY_USAGE = Gauge('gpu_memory_usage', 'GPU memory usage in MB')
INFERENCE_LATENCY = Histogram('inference_latency', 'Inference latency in seconds')
CPU_USAGE = Gauge('cpu_usage', 'CPU usage percentage')
MEMORY_USAGE = Gauge('memory_usage', 'System memory usage percentage')

def collect_metrics():
    """收集系统指标"""
    # CPU使用率
    CPU_USAGE.set(psutil.cpu_percent())
    
    # 内存使用率
    memory = psutil.virtual_memory()
    MEMORY_USAGE.set(memory.percent)
    
    # GPU显存使用(如果有GPU)
    if HAS_GPU:
        try:
            handle = pynvml.nvmlDeviceGetHandleByIndex(0)
            info = pynvml.nvmlDeviceGetMemoryInfo(handle)
            GPU_MEMORY_USAGE.set(info.used / 1024 / 1024)  # 转换为MB
        except:
            pass

def monitor_inference(func):
    """监控推理延迟的装饰器"""
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        latency = time.time() - start_time
        INFERENCE_LATENCY.observe(latency)
        return result
    return wrapper

if __name__ == '__main__':
    # 启动指标服务器(端口8000)
    start_http_server(8000)
    print("监控指标服务器已启动,访问 http://localhost:8000/metrics")
    
    # 持续收集指标
    while True:
        collect_metrics()
        time.sleep(5)

3. 集成监控到模型推理

3.1 修改原有测试脚本

现在我们需要修改原有的test.py脚本,集成监控功能:

# test_with_monitor.py
from transformers import BertTokenizer, BertForMaskedLM, BertModel
import torch
from monitor_metrics import monitor_inference, collect_metrics
import threading
import time

# 初始化模型和分词器
tokenizer = BertTokenizer.from_pretrained('/root/bert-base-chinese')
model = BertForMaskedLM.from_pretrained('/root/bert-base-chinese')
feature_model = BertModel.from_pretrained('/root/bert-base-chinese')

# 将模型移动到GPU(如果可用)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model.to(device)
feature_model.to(device)

@monitor_inference
def cloze_test(text):
    """完型填空任务"""
    inputs = tokenizer(text, return_tensors='pt')
    inputs = {k: v.to(device) for k, v in inputs.items()}
    
    with torch.no_grad():
        outputs = model(**inputs)
    
    return outputs

@monitor_inference  
def similarity_test(text1, text2):
    """语义相似度计算"""
    # 编码两个句子
    inputs1 = tokenizer(text1, return_tensors='pt', padding=True, truncation=True)
    inputs2 = tokenizer(text2, return_tensors='pt', padding=True, truncation=True)
    
    inputs1 = {k: v.to(device) for k, v in inputs1.items()}
    inputs2 = {k: v.to(device) for k, v in inputs2.items()}
    
    with torch.no_grad():
        outputs1 = feature_model(**inputs1)
        outputs2 = feature_model(**inputs2)
    
    # 计算余弦相似度
    similarity = torch.cosine_similarity(
        outputs1.last_hidden_state.mean(dim=1),
        outputs2.last_hidden_state.mean(dim=1)
    )
    
    return similarity.item()

@monitor_inference
def feature_extraction(text):
    """特征提取"""
    inputs = tokenizer(text, return_tensors='pt')
    inputs = {k: v.to(device) for k, v in inputs.items()}
    
    with torch.no_grad():
        outputs = feature_model(**inputs)
    
    return outputs.last_hidden_state.cpu().numpy()

def run_demo():
    """运行演示任务"""
    print("开始运行BERT演示任务...")
    
    # 完型填空示例
    print("\n1. 完型填空演示:")
    text = "中国的首都是[MASK]京。"
    result = cloze_test(text)
    print(f"输入: {text}")
    
    # 语义相似度示例
    print("\n2. 语义相似度演示:")
    similarity = similarity_test("今天天气真好", "今天的天气很不错")
    print(f"相似度得分: {similarity:.4f}")
    
    # 特征提取示例
    print("\n3. 特征提取演示:")
    features = feature_extraction("自然语言处理")
    print(f"特征向量形状: {features.shape}")

def metrics_collector():
    """指标收集线程"""
    while True:
        collect_metrics()
        time.sleep(5)

if __name__ == '__main__':
    # 启动指标收集线程
    metrics_thread = threading.Thread(target=metrics_collector, daemon=True)
    metrics_thread.start()
    
    # 运行演示任务
    run_demo()
    
    print("\n监控指标已启动,请访问 http://localhost:8000/metrics")
    print("按Ctrl+C停止程序")
    
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        print("程序已停止")

4. 部署Prometheus和Grafana

4.1 使用Docker Compose部署监控栈

创建docker-compose.yml文件:

version: '3'

services:
  prometheus:
    image: prom/prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/etc/prometheus/console_libraries'
      - '--web.console.templates=/etc/prometheus/console_templates'
      - '--storage.tsdb.retention.time=200h'
      - '--web.enable-lifecycle'

  grafana:
    image: grafana/grafana
    ports:
      - "3000:3000"
    volumes:
      - grafana_data:/var/lib/grafana
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
    depends_on:
      - prometheus

volumes:
  prometheus_data:
  grafana_data:

4.2 配置Prometheus

创建prometheus.yml配置文件:

global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: 'bert-model'
    static_configs:
      - targets: ['host.docker.internal:8000']
    metrics_path: '/metrics'
    scrape_interval: 5s

  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

5. 配置Grafana监控仪表盘

5.1 创建GPU监控面板

启动所有服务后,访问Grafana(http://localhost:3000),使用admin/admin登录,然后:

  1. 添加Prometheus数据源(URL: http://prometheus:9090)
  2. 创建新的仪表盘
  3. 添加以下监控面板:

GPU显存使用面板

  • Query: gpu_memory_usage
  • Visualization: Stat
  • Unit: megabytes

推理延迟分布面板

  • Query: histogram_quantile(0.95, rate(inference_latency_bucket[5m]))
  • Visualization: Graph
  • Unit: seconds

CPU和内存使用面板

  • Queries: cpu_usagememory_usage
  • Visualization: Gauge

5.2 设置告警规则

在Grafana中设置重要的告警规则:

  1. GPU显存告警:当显存使用超过90%时发送告警
  2. 推理延迟告警:当95%分位延迟超过1秒时发送告警
  3. 服务宕机告警:当指标停止上报时发送告警

6. 实际运行与效果验证

6.1 启动监控系统

# 1. 启动监控组件
docker-compose up -d

# 2. 运行带监控的模型脚本
cd /root/bert-base-chinese
python test_with_monitor.py

# 3. 在另一个终端中运行指标收集器
python monitor_metrics.py

6.2 查看监控效果

访问以下地址查看监控效果:

  • Grafana仪表盘: http://localhost:3000
  • Prometheus界面: http://localhost:9090
  • 原始指标: http://localhost:8000/metrics

6.3 压力测试与监控验证

为了验证监控系统的有效性,可以运行压力测试脚本:

# stress_test.py
from test_with_monitor import cloze_test, similarity_test, feature_extraction
import threading
import time

def run_stress_test():
    """运行压力测试"""
    test_texts = [
        "人工智能是[MASK]来发展的重要方向。",
        "机器学习需要大量的[MASK]据。",
        "深度学习在图像识别领域取得了重大[MASK]破。"
    ]
    
    # 模拟并发请求
    def worker():
        for i in range(20):
            for text in test_texts:
                cloze_test(text)
                similarity_test("测试句子A", "测试句子B")
            time.sleep(0.1)
    
    # 启动多个工作线程
    threads = []
    for i in range(4):
        t = threading.Thread(target=worker)
        threads.append(t)
        t.start()
    
    for t in threads:
        t.join()

if __name__ == '__main__':
    print("开始压力测试...")
    run_stress_test()
    print("压力测试完成")

7. 方案总结

通过本文介绍的Prometheus+Grafana监控方案,我们为bert-base-chinese模型搭建了完整的性能监控体系。这个方案具有以下优点:

核心价值

  • 实时监控GPU资源使用,避免显存溢出
  • 跟踪推理延迟,及时发现性能瓶颈
  • 历史数据记录,便于性能分析和优化
  • 灵活的告警机制,及时发现问题

实践建议

  1. 在生产环境中,建议将监控数据持久化到外部存储
  2. 根据实际业务需求调整监控指标和告警阈值
  3. 定期检查监控系统的运行状态,确保监控不中断
  4. 结合业务指标(如QPS、错误率等)进行综合监控

扩展可能性

  • 添加业务指标监控(请求量、成功率等)
  • 集成日志监控和追踪系统
  • 添加自动扩缩容机制基于监控指标
  • 建立性能基线和健康检查机制

这个监控方案不仅适用于bert-base-chinese模型,也可以轻松适配其他AI模型的部署监控需求,为你提供全面的模型运行可视化管理能力。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐