SenseVoice-small-ONNX部署教程:Prometheus+Grafana监控指标接入方案

📅 发布时间:2026/7/7 1:31:17 👁️ 浏览次数:
SenseVoice-small-ONNX部署教程:Prometheus+Grafana监控指标接入方案
SenseVoice-small-ONNX部署教程PrometheusGrafana监控指标接入方案1. 引言如果你已经部署了SenseVoice-small-ONNX语音识别服务可能会好奇我的服务运行得怎么样每秒能处理多少请求识别准确率如何有没有出现错误这些问题单靠看日志是没法直观回答的。今天我就带你给这个语音识别服务装上“仪表盘”——用PrometheusGrafana实现全面的监控指标可视化。这不是什么高深的技术而是一个能让你的服务运维从“盲人摸象”变成“一目了然”的实用方案。通过这篇教程你将学会如何为SenseVoice-small-ONNX服务暴露监控指标如何用Prometheus采集这些指标数据如何用Grafana创建漂亮的监控仪表盘如何监控服务的核心性能指标整个过程就像给你的汽车装上了仪表盘速度、油耗、发动机状态全都清清楚楚。2. 为什么需要监控语音识别服务在深入技术细节之前我们先聊聊为什么需要监控。你可能觉得服务能跑起来就行了但实际运营中监控能帮你解决很多问题。2.1 监控能帮你发现什么性能瓶颈某个时段的请求突然变慢是CPU不够用了还是内存泄漏了服务质量识别准确率有没有下降错误率有没有上升资源使用服务占用了多少内存GPU利用率高不高业务洞察哪些时间段请求最多哪些语言的识别需求最大2.2 PrometheusGrafana为什么是首选Prometheus是目前最流行的监控系统之一它专门为微服务设计采用“拉取”模式采集数据配置简单功能强大。Grafana则是数据可视化的王者能把枯燥的数字变成直观的图表支持各种数据源包括Prometheus。这两个工具组合在一起就像给服务装上了“眼睛”和“大脑”让你能实时看到服务的状态还能设置警报有问题第一时间知道。3. 环境准备与依赖安装开始之前确保你已经部署了SenseVoice-small-ONNX服务。如果还没部署可以参考之前的教程先完成部署。3.1 安装PrometheusPrometheus的安装很简单我们直接下载二进制包# 创建Prometheus工作目录 mkdir -p /opt/prometheus cd /opt/prometheus # 下载Prometheus这里以2.45.0版本为例 wget https://github.com/prometheus/prometheus/releases/download/v2.45.0/prometheus-2.45.0.linux-amd64.tar.gz # 解压 tar -xzf prometheus-2.45.0.linux-amd64.tar.gz cd prometheus-2.45.0.linux-amd64 # 创建配置文件 cat prometheus.yml EOF global: scrape_interval: 15s # 每15秒采集一次数据 evaluation_interval: 15s # 每15秒评估一次规则 scrape_configs: - job_name: prometheus static_configs: - targets: [localhost:9090] - job_name: sensevoice static_configs: - targets: [localhost:8000] # SenseVoice服务地址 EOF3.2 安装GrafanaGrafana的安装同样简单# 添加Grafana仓库 sudo apt-get install -y software-properties-common sudo add-apt-repository deb https://packages.grafana.com/oss/deb stable main wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add - # 安装Grafana sudo apt-get update sudo apt-get install -y grafana # 启动Grafana服务 sudo systemctl daemon-reload sudo systemctl start grafana-server sudo systemctl enable grafana-server3.3 为SenseVoice服务添加监控端点我们需要修改SenseVoice服务让它暴露Prometheus格式的监控指标。创建一个新的Python文件monitor.py# monitor.py - 监控指标收集模块 from prometheus_client import Counter, Histogram, Gauge, generate_latest, CONTENT_TYPE_LATEST from prometheus_client import start_http_server import time from functools import wraps # 定义监控指标 # 请求相关指标 REQUEST_COUNT Counter( sensevoice_requests_total, Total number of requests, [method, endpoint, status] ) REQUEST_LATENCY Histogram( sensevoice_request_duration_seconds, Request latency in seconds, [method, endpoint] ) # 识别相关指标 TRANSCRIBE_COUNT Counter( sensevoice_transcribe_total, Total number of transcriptions, [language, status] ) TRANSCRIBE_DURATION Histogram( sensevoice_transcribe_duration_seconds, Transcription duration in seconds, [language] ) AUDIO_DURATION Histogram( sensevoice_audio_duration_seconds, Audio duration in seconds ) # 资源相关指标 MODEL_LOAD_TIME Gauge( sensevoice_model_load_time_seconds, Model loading time in seconds ) MEMORY_USAGE Gauge( sensevoice_memory_usage_bytes, Memory usage in bytes ) # 装饰器监控请求 def monitor_request(endpoint_name): def decorator(func): wraps(func) async def wrapper(*args, **kwargs): start_time time.time() method POST if endpoint_name transcribe else GET try: response await func(*args, **kwargs) status success REQUEST_COUNT.labels(methodmethod, endpointendpoint_name, statusstatus).inc() return response except Exception as e: status error REQUEST_COUNT.labels(methodmethod, endpointendpoint_name, statusstatus).inc() raise e finally: duration time.time() - start_time REQUEST_LATENCY.labels(methodmethod, endpointendpoint_name).observe(duration) return wrapper return decorator # 启动监控服务器 def start_monitoring_server(port8000): 启动Prometheus指标服务器 start_http_server(port) print(f✅ Monitoring server started on port {port}) print(f Metrics available at http://localhost:{port}/metrics)4. 集成监控到SenseVoice服务现在我们需要把监控模块集成到现有的SenseVoice服务中。修改你的app.py文件# app.py - 集成监控的完整服务 import os import argparse import uvicorn from fastapi import FastAPI, UploadFile, File, Form, HTTPException from fastapi.responses import JSONResponse from fastapi.middleware.cors import CORSMiddleware import gradio as gr import soundfile as sf import numpy as np from typing import List, Optional import tempfile import time # 导入监控模块 from monitor import ( monitor_request, TRANSCRIBE_COUNT, TRANSCRIBE_DURATION, AUDIO_DURATION, MODEL_LOAD_TIME, MEMORY_USAGE, start_monitoring_server ) # 启动监控服务器在8000端口 start_monitoring_server(port8000) app FastAPI(titleSenseVoice Small ONNX API) # 添加CORS中间件 app.add_middleware( CORSMiddleware, allow_origins[*], allow_credentialsTrue, allow_methods[*], allow_headers[*], ) # 模型初始化 from funasr_onnx import SenseVoiceSmall model_path /root/ai-models/danieldong/sensevoice-small-onnx-quant # 记录模型加载时间 load_start time.time() model SenseVoiceSmall( model_path, batch_size10, quantizeTrue ) load_time time.time() - load_start MODEL_LOAD_TIME.set(load_time) print(f✅ Model loaded in {load_time:.2f} seconds) # 支持的语言 SUPPORTED_LANGUAGES { auto: 自动检测, zh: 中文, en: 英语, yue: 粤语, ja: 日语, ko: 韩语 } app.get(/health) async def health_check(): 健康检查端点 return {status: healthy, model: sensevoice-small-onnx} app.post(/api/transcribe) monitor_request(transcribe) async def transcribe_audio( file: UploadFile File(...), language: str Form(auto), use_itn: bool Form(True) ): 语音转写API start_time time.time() # 验证语言参数 if language not in SUPPORTED_LANGUAGES: raise HTTPException(status_code400, detailf不支持的语言: {language}) # 保存上传的音频文件 with tempfile.NamedTemporaryFile(suffix.wav, deleteFalse) as tmp_file: content await file.read() tmp_file.write(content) tmp_path tmp_file.name try: # 获取音频时长 audio_info sf.info(tmp_path) audio_duration audio_info.duration AUDIO_DURATION.observe(audio_duration) # 执行语音识别 result model([tmp_path], languagelanguage, use_itnuse_itn) if not result or len(result) 0: raise HTTPException(status_code500, detail识别失败) transcription result[0] # 记录识别指标 transcribe_duration time.time() - start_time TRANSCRIBE_COUNT.labels(languagelanguage, statussuccess).inc() TRANSCRIBE_DURATION.labels(languagelanguage).observe(transcribe_duration) # 记录内存使用 import psutil process psutil.Process() memory_info process.memory_info() MEMORY_USAGE.set(memory_info.rss) return JSONResponse({ text: transcription, language: language, duration: audio_duration, processing_time: transcribe_duration, use_itn: use_itn }) except Exception as e: TRANSCRIBE_COUNT.labels(languagelanguage, statuserror).inc() raise HTTPException(status_code500, detailstr(e)) finally: # 清理临时文件 if os.path.exists(tmp_path): os.unlink(tmp_path) # Gradio界面 def create_gradio_interface(): def transcribe_ui(audio_file, language, use_itn): if audio_file is None: return 请上传音频文件 # 调用API进行转写 import requests files {file: open(audio_file, rb)} data {language: language, use_itn: use_itn} try: response requests.post( http://localhost:7860/api/transcribe, filesfiles, datadata ) result response.json() return result[text] except Exception as e: return f识别失败: {str(e)} # 创建界面 with gr.Blocks(titleSenseVoice 语音识别) as demo: gr.Markdown(# SenseVoice 语音识别) gr.Markdown(上传音频文件支持中文、英文、粤语、日语、韩语) with gr.Row(): with gr.Column(): audio_input gr.Audio( label上传音频, typefilepath ) language_select gr.Dropdown( choiceslist(SUPPORTED_LANGUAGES.keys()), valueauto, label选择语言, infoauto: 自动检测语言 ) itn_toggle gr.Checkbox( label启用逆文本正则化 (ITN), valueTrue, info将三转为3百分之十转为10% ) submit_btn gr.Button(开始识别, variantprimary) with gr.Column(): text_output gr.Textbox( label识别结果, lines10, placeholder识别结果将显示在这里... ) submit_btn.click( fntranscribe_ui, inputs[audio_input, language_select, itn_toggle], outputstext_output ) return demo if __name__ __main__: parser argparse.ArgumentParser() parser.add_argument(--host, typestr, default0.0.0.0) parser.add_argument(--port, typeint, default7860) args parser.parse_args() # 创建Gradio应用 demo create_gradio_interface() # 启动服务 print(f Starting SenseVoice service on {args.host}:{args.port}) print(f Monitoring metrics at http://localhost:8000/metrics) print(f Web UI at http://{args.host}:{args.port}) print(f API Docs at http://{args.host}:{args.port}/docs) # 使用uvicorn运行 uvicorn.run(app, hostargs.host, portargs.port)5. 配置Prometheus采集指标现在我们的服务已经暴露了监控指标接下来配置Prometheus来采集这些数据。5.1 修改Prometheus配置编辑Prometheus的配置文件/opt/prometheus/prometheus-2.45.0.linux-amd64/prometheus.ymlglobal: scrape_interval: 15s evaluation_interval: 15s # 告警规则配置 rule_files: # - first_rules.yml # - second_rules.yml scrape_configs: # Prometheus自身监控 - job_name: prometheus static_configs: - targets: [localhost:9090] scrape_interval: 30s # SenseVoice语音识别服务监控 - job_name: sensevoice static_configs: - targets: [localhost:8000] # 监控指标端点 scrape_interval: 15s metrics_path: /metrics # SenseVoice API服务监控 - job_name: sensevoice-api static_configs: - targets: [localhost:7860] scrape_interval: 30s metrics_path: /health # 系统资源监控可选 - job_name: node-exporter static_configs: - targets: [localhost:9100] scrape_interval: 30s5.2 启动Prometheus# 进入Prometheus目录 cd /opt/prometheus/prometheus-2.45.0.linux-amd64 # 启动Prometheus后台运行 nohup ./prometheus --config.fileprometheus.yml prometheus.log 21 # 检查是否启动成功 curl http://localhost:9090 # 查看日志 tail -f prometheus.log5.3 验证指标采集访问Prometheus的Web界面http://localhost:9090在Expression输入框中输入sensevoice_应该能看到我们定义的所有指标sensevoice_requests_total- 请求总数sensevoice_request_duration_seconds- 请求延迟sensevoice_transcribe_total- 识别总数sensevoice_transcribe_duration_seconds- 识别耗时sensevoice_audio_duration_seconds- 音频时长sensevoice_model_load_time_seconds- 模型加载时间sensevoice_memory_usage_bytes- 内存使用量6. 配置Grafana仪表盘现在数据已经采集到了我们需要用Grafana来可视化这些数据。6.1 登录Grafana并添加数据源首先访问Grafanahttp://localhost:3000 默认用户名/密码admin/admin首次登录会要求修改密码然后添加Prometheus数据源点击左侧菜单的Configuration齿轮图标选择Data Sources点击Add data source选择Prometheus配置URL为http://localhost:9090点击Save Test应该显示Data source is working6.2 创建SenseVoice监控仪表盘我们来创建一个完整的监控仪表盘。点击左侧菜单的Create加号图标→Dashboard→Add new panel。面板1请求统计标题请求统计总览查询语句sum(rate(sensevoice_requests_total[5m])) by (endpoint)可视化Stat统计单位req/s请求/秒颜色模式Background面板2请求成功率标题请求成功率查询语句sum(rate(sensevoice_requests_total{statussuccess}[5m])) by (endpoint) / sum(rate(sensevoice_requests_total[5m])) by (endpoint) * 100可视化Gauge仪表盘单位percent0-100阈值绿色95黄色90-95红色90面板3识别延迟分布标题识别延迟P95查询语句histogram_quantile(0.95, sum(rate(sensevoice_transcribe_duration_seconds_bucket[5m])) by (le, language))可视化Time series时间序列单位seconds秒显示每个语言一条线面板4各语言识别量标题各语言识别量查询语句sum(rate(sensevoice_transcribe_total[5m])) by (language)可视化Bar chart柱状图单位req/s排序Descending降序面板5音频时长分布标题音频时长分布查询语句histogram_quantile(0.5, rate(sensevoice_audio_duration_seconds_bucket[5m]))可视化Stat统计单位seconds秒计算Last最新值面板6内存使用标题内存使用查询语句sensevoice_memory_usage_bytes可视化Time series时间序列单位bytes字节转换自动转换为MB或GB面板7错误率趋势标题错误率趋势查询语句sum(rate(sensevoice_requests_total{statuserror}[5m])) by (endpoint) / sum(rate(sensevoice_requests_total[5m])) by (endpoint) * 100可视化Time series时间序列单位percent百分比显示每个端点一条线6.3 保存仪表盘配置完所有面板后点击右上角的Save按钮输入仪表盘名称SenseVoice语音识别监控选择文件夹可选点击Save现在你的仪表盘就创建完成了可以随时访问 http://localhost:3000 查看实时监控数据。7. 设置告警规则监控不仅要看还要能及时告警。我们来设置一些关键的告警规则。7.1 创建告警规则文件在Prometheus目录下创建告警规则文件# /opt/prometheus/prometheus-2.45.0.linux-amd64/sensevoice_alerts.yml groups: - name: sensevoice_alerts rules: # 高错误率告警 - alert: HighErrorRate expr: | sum(rate(sensevoice_requests_total{statuserror}[5m])) by (endpoint) / sum(rate(sensevoice_requests_total[5m])) by (endpoint) * 100 5 for: 2m labels: severity: warning annotations: summary: 高错误率检测到 description: {{ $labels.endpoint }} 的错误率超过5%当前值为 {{ $value }}% # 高延迟告警 - alert: HighLatency expr: | histogram_quantile(0.95, rate(sensevoice_transcribe_duration_seconds_bucket[5m])) 2 for: 2m labels: severity: warning annotations: summary: 高延迟检测到 description: 语音识别延迟超过2秒当前P95延迟为 {{ $value }}秒 # 服务不可用告警 - alert: ServiceDown expr: | up{jobsensevoice} 0 for: 1m labels: severity: critical annotations: summary: 服务不可用 description: SenseVoice监控端点不可达 # 内存使用过高告警 - alert: HighMemoryUsage expr: | sensevoice_memory_usage_bytes 2 * 1024 * 1024 * 1024 # 2GB for: 5m labels: severity: warning annotations: summary: 内存使用过高 description: SenseVoice服务内存使用超过2GB当前值为 {{ $value | humanize1024 }}7.2 更新Prometheus配置修改prometheus.yml添加告警规则global: scrape_interval: 15s evaluation_interval: 15s rule_files: - sensevoice_alerts.yml # 添加这行 scrape_configs: # ... 原有的配置不变重启Prometheus使配置生效# 找到Prometheus进程ID ps aux | grep prometheus # 重启Prometheus pkill prometheus cd /opt/prometheus/prometheus-2.45.0.linux-amd64 nohup ./prometheus --config.fileprometheus.yml prometheus.log 21 7.3 配置Grafana告警通知在Grafana中配置告警通知渠道点击左侧菜单Alerting铃铛图标→Contact points点击Add contact point选择通知类型如Email、Slack、Webhook等配置相关参数点击Save然后创建通知策略点击Notification policies设置默认策略或创建特定策略关联到刚才创建的Contact point8. 实际效果展示配置完成后让我们看看监控系统能给我们带来什么价值。8.1 实时监控仪表盘访问Grafana仪表盘你会看到一个类似汽车仪表盘的界面左上角实时请求量每秒处理多少请求右上角请求成功率绿色表示健康红色表示有问题中间识别延迟趋势图可以看到不同时间段的性能变化下方各语言识别量分布了解业务重点右侧系统资源使用情况内存、CPU等8.2 关键指标解读请求成功率这是最重要的指标之一。正常情况下应该保持在99%以上。如果降到95%以下说明服务可能有问题。识别延迟SenseVoice-small-ONNX的典型延迟是70ms10秒音频。如果延迟突然增加到2秒以上可能是服务器负载过高网络问题音频文件异常各语言分布可以看到哪些语言的使用频率最高。比如中文可能占70%英文20%其他语言10%。这有助于优化资源分配。内存使用模型加载后内存使用应该相对稳定。如果内存持续增长可能有内存泄漏。8.3 告警效果当出现问题时你会收到告警通知。比如高错误率告警错误率超过5%持续2分钟你会收到邮件或Slack通知高延迟告警P95延迟超过2秒提醒你检查服务器性能服务不可用告警监控端点无法访问可能是服务崩溃了9. 总结通过这篇教程我们为SenseVoice-small-ONNX语音识别服务搭建了一套完整的监控系统。让我总结一下关键收获9.1 监控带来的价值问题快速发现不用等用户投诉自己就能第一时间发现问题。性能优化依据通过数据分析找到性能瓶颈针对性优化。容量规划参考根据历史数据预测未来需求合理规划资源。服务质量保障确保服务始终在健康状态运行。9.2 关键配置要点指标暴露在服务代码中添加Prometheus客户端暴露关键指标数据采集配置Prometheus定期拉取指标数据可视化展示用Grafana创建直观的监控仪表盘告警设置定义关键指标的告警阈值和通知方式9.3 下一步建议如果你想让监控系统更完善可以考虑添加业务指标除了技术指标还可以监控业务指标比如每日识别总时长各行业客户使用情况识别准确率需要人工标注对比集成更多数据源服务器监控CPU、内存、磁盘、网络数据库监控连接数、查询性能日志监控错误日志、访问日志设置自动化响应自动重启失败的服务自动扩容缩容自动清理临时文件监控不是一次性的工作而是一个持续优化的过程。随着业务发展你需要不断调整监控指标和告警阈值让系统更好地为业务服务。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。