voice-changerのメトリクス収集:PrometheusとGrafanaによる監視システム構築
1. はじめに:リアルタイム音声変換システムの監視課題
リアルタイムボイスチェンジャー(Realtime Voice Changer)は、ライブ配信やオンライン会議などのシーンで即時音声変換を提供するシステムです。このような低遅延性が要求されるアプリケーションでは、システムのパフォーマンス低下やエラー発生がユーザーエクスペリエンスに直結するため、継続的な監視が不可欠です。
本記事では、voice-changerにPrometheusとGrafanaを導入した監視システムを構築する方法を詳しく解説します。このシステムにより、以下のことが可能になります:
- 音声変換リクエストの処理時間を追跡
- モデルロード回数やエラー発生状況を可視化
- システムリソース使用率のリアルタイム監視
- 異常検知とアラート通知
2. 監視指標の設計と選定
voice-changerの監視には、以下の4つのカテゴリーから指標を選定することを推奨します。
2.1 業務指標(Business Metrics)
| 指標名 | タイプ | 説明 | 収集頻度 |
|---|---|---|---|
voice_changer_requests_total | Counter | 音声変換リクエストの総数 | リクエスト毎 |
voice_changer_active_users | Gauge | アクティブユーザー数 | 1分毎 |
voice_changer_model_usage_total | Counter | モデル毎の使用回数 | リクエスト毎 |
2.2 システム指標(System Metrics)
| 指標名 | タイプ | 説明 | 収集頻度 |
|---|---|---|---|
voice_changer_processing_seconds | Histogram | 音声変換処理時間 | リクエスト毎 |
voice_changer_memory_usage_bytes | Gauge | メモリ使用量 | 5秒毎 |
voice_changer_cpu_usage_percent | Gauge | CPU使用率 | 5秒毎 |
2.3 エラー指標(Error Metrics)
| 指標名 | タイプ | 説明 | 収集頻度 |
|---|---|---|---|
voice_changer_errors_total | Counter | エラー発生総数 | エラー発生時 |
voice_changer_model_load_errors_total | Counter | モデルロードエラー数 | エラー発生時 |
voice_changer_audio_processing_errors_total | Counter | 音声処理エラー数 | エラー発生時 |
2.4 リソース指標(Resource Metrics)
| 指標名 | タイプ | 説明 | 収集頻度 |
|---|---|---|---|
voice_changer_gpu_memory_usage_bytes | Gauge | GPUメモリ使用量 | 10秒毎 |
voice_changer_gpu_utilization_percent | Gauge | GPU利用率 | 10秒毎 |
voice_changer_disk_io_operations_total | Counter | ディスクI/O操作数 | 1分毎 |
3. Prometheusエクスポーターの実装
3.1 必要なライブラリのインストール
まず、Prometheusクライアントライブラリをインストールします:
pip install prometheus-client
3.2 メトリクス定義ファイルの作成
server/prometheus_metrics.py ファイルを作成し、以下の内容を追加します:
from prometheus_client import Counter, Histogram, Gauge
import time
# 業務指標
REQUEST_COUNT = Counter(
'voice_changer_requests_total',
'Total number of voice change requests',
['model_type'] # モデルタイプでラベル付け
)
# システム指標
PROCESSING_TIME = Histogram(
'voice_changer_processing_seconds',
'Voice change processing time in seconds',
buckets=[0.01, 0.05, 0.1, 0.5, 1.0, 2.0]
)
# エラー指標
ERROR_COUNT = Counter(
'voice_changer_errors_total',
'Total number of errors encountered',
['error_type'] # エラータイプでラベル付け
)
# モデル指標
MODEL_LOAD_COUNT = Counter(
'voice_changer_model_loads_total',
'Total number of model load operations',
['model_type']
)
# システムリソース指標
MEMORY_USAGE = Gauge(
'voice_changer_memory_usage_bytes',
'Memory usage in bytes'
)
GPU_MEMORY_USAGE = Gauge(
'voice_changer_gpu_memory_usage_bytes',
'GPU memory usage in bytes',
['gpu_id']
)
# デコレータ関数 - 処理時間計測
def measure_processing_time(func):
def wrapper(*args, **kwargs):
start_time = time.time()
try:
result = func(*args, **kwargs)
return result
finally:
PROCESSING_TIME.observe(time.time() - start_time)
return wrapper
# デコレータ関数 - リクエストカウント
def count_requests(model_type):
def decorator(func):
def wrapper(*args, **kwargs):
REQUEST_COUNT.labels(model_type=model_type).inc()
return func(*args, **kwargs)
return wrapper
return decorator
# エラーカウント関数
def count_error(error_type):
ERROR_COUNT.labels(error_type=error_type).inc()
3.3 アプリケーションへのメトリクス収集コードの埋め込み
3.3.1 サーバー起動コードの修正(MMVCServerSIO.py)
# 既存のimport文に追加
from prometheus_client import start_http_server
from prometheus_metrics import (
REQUEST_COUNT, PROCESSING_TIME, ERROR_COUNT,
MODEL_LOAD_COUNT, MEMORY_USAGE, GPU_MEMORY_USAGE,
measure_processing_time, count_requests, count_error
)
# サーバー起動部分にPrometheusエクスポーターの起動を追加
def localServer(logLevel: str = "critical", key_path: str | None = None, cert_path: str | None = None):
try:
# Prometheusエクスポーターをポート9090で起動
start_http_server(9090)
logger.info("Prometheus exporter started on port 9090")
uvicorn.run(
f"{os.path.basename(__file__)[:-3]}:app_socketio",
host=HOST,
port=int(PORT),
reload=False if hasattr(sys, "_MEIPASS") else True,
ssl_keyfile=key_path,
ssl_certfile=cert_path,
log_level=logLevel,
)
except Exception as e:
logger.error(f"[Voice Changer] Web Server Launch Exception, {e}")
count_error("server_launch") # エラーカウントを増加
3.3.2 音声変換処理コードの修正(VoiceChangerManager.py)
# 既存のimport文に追加
from prometheus_metrics import (
PROCESSING_TIME, REQUEST_COUNT, ERROR_COUNT,
MODEL_LOAD_COUNT, measure_processing_time, count_requests
)
import psutil
import torch
# モデルロード関数に計測コードを追加
def generateVoiceChanger(self, val: int | StaticSlot):
start_time = time.time()
try:
slotInfo = self.modelSlotManager.get_slot_info(val)
if slotInfo is None:
logger.info(f"[Voice Changer] model slot is not found {val}")
ERROR_COUNT.labels(error_type="model_not_found").inc()
return
model_type = slotInfo.voiceChangerType
MODEL_LOAD_COUNT.labels(model_type=model_type).inc()
# 既存のモデル生成コード...
# ...
# GPUメモリ使用量を記録
if torch.cuda.is_available():
for i in range(torch.cuda.device_count()):
GPU_MEMORY_USAGE.labels(gpu_id=i).set(torch.cuda.memory_allocated(i))
logger.info(f"[Voice Changer] model {model_type} loaded successfully")
return True
except Exception as e:
logger.error(f"[Voice Changer] model load error: {e}")
ERROR_COUNT.labels(error_type="model_load").inc()
return False
# 音声変換関数にデコレータを適用
@measure_processing_time
@count_requests(model_type="rvc") # モデルタイプに合わせて調整
def changeVoice(self, receivedData: AudioInOut):
try:
if self.settings.passThrough is True: # パススルー
return receivedData, []
if hasattr(self, "voiceChanger") is True:
# メモリ使用量を記録
process = psutil.Process()
MEMORY_USAGE.set(process.memory_info().rss)
return self.voiceChanger.on_request(receivedData)
else:
logger.info("Voice Change is not loaded. Did you load a correct model?")
ERROR_COUNT.labels(error_type="model_not_loaded").inc()
return np.zeros(1).astype(np.int16), []
except Exception as e:
logger.error(f"[Voice Changer] voice change error: {e}")
ERROR_COUNT.labels(error_type="voice_processing").inc()
return np.zeros(1).astype(np.int16), []
4. Prometheusの設定
4.1 Prometheusのインストール
Prometheusをインストールするには、公式サイトからバイナリをダウンロードするか、Dockerを使用します。
# Dockerを使用する場合
docker pull prom/prometheus
4.2 設定ファイルの作成
prometheus.ymlファイルを作成し、以下の設定を追加します:
global:
scrape_interval: 5s # デフォルトの収集間隔
evaluation_interval: 5s
rule_files:
# - "alert.rules.yml" # 後でアラートルールを追加する場合はコメントを外す
scrape_configs:
- job_name: 'voice_changer'
static_configs:
- targets: ['localhost:9090'] # voice-changerのPrometheusエクスポーター
- job_name: 'node_exporter'
static_configs:
- targets: ['localhost:9100'] # Node Exporter
4.3 Prometheusの起動
# Dockerを使用する場合
docker run -d -p 9090:9090 \
-v /path/to/prometheus.yml:/etc/prometheus/prometheus.yml \
--name prometheus prom/prometheus
4.4 Node Exporterの導入
システムリソースを監視するために、Node Exporterをインストールします:
# Dockerを使用する場合
docker run -d -p 9100:9100 \
--name node-exporter \
-v /proc:/host/proc:ro \
-v /sys:/host/sys:ro \
-v /:/rootfs:ro \
prom/node-exporter:latest
5. Grafanaの設定とダッシュボード作成
5.1 Grafanaのインストールと起動
# Dockerを使用する場合
docker run -d -p 3000:3000 \
--name grafana \
grafana/grafana:latest
5.2 Prometheusデータソースの設定
- Grafanaにアクセスし(http://localhost:3000)、初期ユーザー名(admin)とパスワード(admin)でログイン
- 「Add your first data source」をクリックし、「Prometheus」を選択
- URLフィールドに「http://prometheus:9090」を入力(Docker Composeを使用している場合)
- 通常のインストールの場合は「http://localhost:9090」を使用
- 「Save & Test」をクリックして接続を確認
5.3 ダッシュボードの作成
以下の手順でvoice-changer専用のダッシュボードを作成します:
- 「Create」→「Dashboard」をクリック
- 「Add new panel」をクリック
- 各パネルに以下のクエリを設定
5.3.1 リクエスト数パネル
- Title: 音声変換リクエスト数
- Type: Graph
- Query:
rate(voice_changer_requests_total[5m]) - Legend format: {{model_type}}
- Axes: Left Y: Requests/sec
5.3.2 処理時間パネル
- Title: 音声変換処理時間
- Type: Graph
- Query:
histogram_quantile(0.95, sum(rate(voice_changer_processing_seconds_bucket[5m])) by (le)) - Legend format: 95th Percentile
- Axes: Left Y: Seconds
5.3.3 エラー率パネル
- Title: エラー率
- Type: Graph
- Query:
rate(voice_changer_errors_total[5m]) / rate(voice_changer_requests_total[5m]) * 100 - Legend format: Error Rate (%)
- Axes: Left Y: Percentage
5.3.4 システムリソースパネル
- Title: メモリ使用量
- Type: Graph
- Query:
voice_changer_memory_usage_bytes / 1024 / 1024 - Legend format: Memory Usage (MB)
- Axes: Left Y: MB
5.4 ダッシュボードのJSONエクスポート/インポート
作成したダッシュボードはJSON形式でエクスポートして保存し、必要に応じてインポートできます。これは他の環境に簡単にダッシュボードを複製するのに便利です。
6. Docker Composeによる環境構築
監視システム全体をDocker Composeで管理することを推奨します。以下はdocker-compose.ymlの例です:
version: '3.8'
services:
voice-changer:
build: .
ports:
- "18888:18888"
volumes:
- ./model_dir:/app/model_dir
- ./pretrain:/app/pretrain
environment:
- PYTHONUNBUFFERED=1
depends_on:
- prometheus
restart: unless-stopped
prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus-data:/prometheus
restart: unless-stopped
node-exporter:
image: prom/node-exporter:latest
ports:
- "9100:9100"
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
restart: unless-stopped
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
volumes:
- grafana-data:/var/lib/grafana
depends_on:
- prometheus
restart: unless-stopped
volumes:
prometheus-data:
grafana-data:
7. アラートルールの設定
重要な指標に対してアラートルールを設定します。
7.1 Prometheusのアラートルール
alert.rules.ymlファイルを作成します:
groups:
- name: voice_changer_alerts
rules:
- alert: HighErrorRate
expr: rate(voice_changer_errors_total[5m]) / rate(voice_changer_requests_total[5m]) > 0.05
for: 2m
labels:
severity: critical
annotations:
summary: "High error rate on voice changer"
description: "Error rate is above 5% (current value: {{ $value }})"
- alert: SlowProcessingTime
expr: histogram_quantile(0.95, sum(rate(voice_changer_processing_seconds_bucket[5m])) by (le)) > 1.0
for: 5m
labels:
severity: warning
annotations:
summary: "Slow processing time"
description: "95th percentile processing time is above 1 second (current value: {{ $value }})"
- alert: HighMemoryUsage
expr: voice_changer_memory_usage_bytes / 1024 / 1024 > 2048
for: 5m
labels:
severity: warning
annotations:
summary: "High memory usage"
description: "Memory usage is above 2GB (current value: {{ $value }})"
Prometheus設定ファイルにこのルールファイルを追加します:
rule_files:
- "alert.rules.yml"
7.2 Grafanaのアラート設定
Grafanaでアラート通知チャネルを設定します:
- 「Alerting」→「Notification channels」をクリック
- 「Add channel」をクリック
- 必要な通知方法(Slack、Email、PagerDutyなど)を設定
- 作成したダッシュボードのパネルでアラートルールを設定
8. メトリクス収集の最適化
大量のリクエストを処理する本番環境では、以下の最適化を検討してください:
8.1 メトリクスのサンプリング
高頻度で発生するイベントのメトリクスはサンプリングを行います:
# サンプリング率10%でメトリクスを収集
if random.random() < 0.1:
PROCESSING_TIME.observe(time.time() - start_time)
8.2 ヒストグラムのバケット調整
業務特性に合わせてヒストグラムのバケットを調整します:
PROCESSING_TIME = Histogram(
'voice_changer_processing_seconds',
'Voice change processing time in seconds',
buckets=[0.01, 0.03, 0.05, 0.1, 0.3, 0.5, 0.7, 1.0, 2.0]
)
8.3 スクレイピング間隔の最適化
Prometheusのスクレイピング間隔を業務要件に合わせて調整します:
global:
scrape_interval: 10s # デフォルトを10秒に設定
scrape_configs:
- job_name: 'voice_changer'
scrape_interval: 5s # voice-changerは5秒に設定
static_configs:
- targets: ['localhost:9090']
9. まとめと次のステップ
本記事では、voice-changerにPrometheusとGrafanaを導入した監視システムの構築方法を詳しく解説しました。このシステムにより、音声変換サービスのパフォーマンスと安定性を継続的に監視し、問題を早期に検知することができるようになります。
次のステップとして、以下のことを検討してください:
- ユーザー体験指標の追加:ユーザー満足度に関連する指標を収集する
- 自動スケーリングとの連携:Prometheusのメトリクスに基づいてサーバーリソースを自動的に調整する
- 長期的なパフォーマンス分析:データを長期保存し、パフォーマンスの傾向を分析する
- モデルバージョン間の比較:異なるモデルバージョンのパフォーマンスを比較するフレームワークを構築する
これらの取り組みにより、voice-changerをさらに安定したサービスにすることができます。
ハンズオン用コマンドまとめ
# 必要なパッケージのインストール
pip install prometheus-client psutil
# Docker Composeで監視環境を起動
docker-compose up -d
# メトリクスエンドポイントの確認
curl http://localhost:9090/metrics
# Grafanaにアクセス
open http://localhost:3000
監視システムを活用して、voice-changerの品質向上と安定運用を実現してください!
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



