
Whisper で実現するリアルタイムストリーミング:低レイテンシ音声認識ガイド (2026)
Eric King
Author
Whisper で実現するリアルタイムストリーミング:低レイテンシ音声認識ガイド
OpenAI Whisper は、高い精度と多言語対応を備えたオープンソースの音声認識モデルです。Whisper 自体はストリーミング用に設計されたモデルではありませんが、適切なパイプラインを組むことで、低レイテンシなリアルタイム音声認識システムを構築できます。これはライブ字幕、会議の文字起こし、配信、音声アシスタントなどに最適です。
このガイドでは、Whisper をリアルタイム動作させるためのアーキテクチャ、テクニック、トレードオフ、および参考コードを解説します。
ストリーミングが難しい理由
従来の Whisper は、連続したストリームではなく、完結した音声セグメントを入力として想定しています。主な課題は次のとおりです。
- インクリメンタルなデコード — 部分的な音声を処理する
- 低レイテンシ — できるだけ早く結果を返す
- チャンク境界でのアーティファクト
- GPU 利用率と応答性のバランス
これらを解決するために、オーバーラップ付きのスライディングウィンドウとインクリメンタルなバッファリングを組み合わせて使用します。
アーキテクチャ概要
Whisper を用いたリアルタイムストリーミングは、一般的に次のコンポーネントで構成されます。
Audio Source → Audio Buffer → Segmenter → Whisper Inference → Post-processing → Consumer
- Audio Source — マイク / ブラウザ / 電話回線など
- Segmenter — オーバーラップするチャンクを生成
- Whisper Inference — GPU / CPU 上のモデル
- Post-processing — テキストとタイムスタンプをマージ
低レイテンシのためのセグメンテーション
クライアントからは継続的に音声が送られてきます。モデルに長すぎる音声を渡さないために、次のように制御します。
- ウィンドウ長: 1〜5 秒
- オーバーラップ: 0.5〜1 秒
- バッファサイズ: 許容レイテンシに依存
ウィンドウを小さくすると、レイテンシは下がりますが、オーバーヘッドは増加します。
ストリーミング向けモデルの選び方
| Model | VRAM | Latency | Accuracy |
|---|---|---|---|
| tiny | 1–2 GB | ⭐⭐⭐⭐ | ❌ |
| base | 2–4 GB | ⭐⭐⭐ | ⭐⭐ |
| small | 4–8 GB | ⭐⭐ | ⭐⭐⭐ |
| medium | 8–12 GB+ | ⭐ | ⭐⭐⭐⭐ |
ストリーミングにおけるバランスの良い選択:
base または small基本的なストリーミングワークフロー(擬似コード)
import whisper
import sounddevice as sd
import numpy as np
model = whisper.load_model("small").to("cuda")
BUFFER = []
WINDOW = 3 # seconds
OVERLAP = 1 # seconds
RATE = 16000
def callback(indata, frames, time, status):
global BUFFER
BUFFER.extend(indata.flatten().tolist())
# When buffer length > window, process
if len(BUFFER) >= RATE * WINDOW:
segment = BUFFER[:RATE * WINDOW]
BUFFER = BUFFER[int(RATE * (WINDOW - OVERLAP)):]
audio = np.array(segment)
result = model.transcribe(audio, fp16=True)
print("--- partial →", result["text"])
この処理は、オーバーラップを活用しながら部分的なトランスクリプトを継続的に出力します。
オーバーラップ処理とテキスト結合
オーバーラップを入れることで、チャンク境界で単語が欠落する問題を軽減できます。
例として:
セグメント:
- 0〜3 秒
- 2〜5 秒
- 4〜7 秒
その後に行うこと:
- オーバーラップ部分の重複テキストを削除
- タイムスタンプを調整
- 連続したテキストストリームを生成
ブラウザでのリアルタイム処理
ブラウザからは、WebRTC や Web Audio API を使って音声をストリーミングできます。
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const processor = audioContext.createScriptProcessor(4096, 1, 1);
source.connect(processor);
processor.connect(audioContext.destination);
processor.onaudioprocess = (e) => {
const chunk = e.inputBuffer.getChannelData(0);
sendToServer(chunk); // WebSocket/Socket.io
};
デプロイパターン
☁️ サーバーレス(クラウド)
- クライアントが WebSocket 経由で音声を送信
- AWS Lambda(短い音声向け)や GPU サーバーで処理
- Whisper は GPU インスタンス上で動作
- オートスケールによるスケーラビリティ
🖥️ 専用 GPU サーバー
- 常時稼働の GPU
- 低レイテンシ
- 24/7 サービスに最適
🌀 ハイブリッド
- エッジ側で音声取得 + 小さなモデルでの事前フィルタリング
- 本格的な文字起こしは GPU サーバーで実行
レイテンシを下げるテクニック
🟡 1. ウィンドウサイズを小さくする
バッチが小さくなる → 部分結果が早く返る
🔵 2. バッファをオーバーラップさせる
単語の取りこぼしを減らせる
🟢 3. FP16 / BF16 を使う
推論を高速化
🔴 4. 複数ユーザーをバッチ処理する
サーバーが多くのストリームを扱う場合、バッチ化によってスループットを向上できる
モニタリングとメトリクス
次の指標をモニタリングしましょう。
- セグメントごとのレイテンシ
- 誤り率(Word Error Rate, WER)
- GPU 使用率
- 部分結果と最終結果の精度差
ダッシュボードには Prometheus / Grafana などを利用できます。
トレードオフ
| Goal | Tradeoff |
|---|---|
| Low latency | Lower context → less accuracy |
| High accuracy | Larger windows → higher latency |
| Small model | Faster, less accurate |
| Big model | Slower, more accurate |
ユースケース例
- ライブ配信のリアルタイム字幕
- 会議や授業の文字起こし
- 対話型の音声アプリ
- カンファレンスやウェビナー向けサービス
まとめ
Whisper を使ったリアルタイムストリーミングは十分に実現可能ですが、次のポイントのバランスを取る必要があります。
- ウィンドウサイズ
- オーバーラップ量
- モデルサイズ
- ハードウェア性能
適切な設計を行えば、本番環境でも通用する低レイテンシかつ高精度なストリーミング文字起こしを実現できます。
