🕌

Whisper × BlackHole でリアルタイム字幕を試してみた

に公開

概要

Whisper と BlackHole を組み合わせて、
「リアルタイムで字幕を出す仕組みを動かしたとき、どこまで精度や速度が出るのか?」
を検証してみました。

自前で構築した方が精度や遅延の面で優位に立てるかも?と思ったのですが、
実際に試してみると Chrome の自動字幕の完成度には及びませんでした。

なぜやろうと思ったか

MTG(ミーティング)中に聞き逃した内容を、
リアルタイム字幕で見返せたら便利だなと思ったのがきっかけです。

既存の自動文字起こしツールは精度や遅延に不満があり、
「自分で構築した方が性能が出るのでは?」
と思い、BlackHole × faster-whisper × GPT-4o mini の構成で挑戦しました。

使用技術

目的 技術 / ライブラリ
仮想オーディオ入力 BlackHole (2ch)
音声録音 sounddevice
音声認識 faster-whisper
テキスト整形 GPT-4o mini
言語 Python 3.10
環境 macOS Sonoma / M3 MacBook Pro

構成と実行手順

  1. 必要なツールのインストール
brew install ffmpeg blackhole-2ch
python3 -m venv venv
source venv/bin/activate
pip install faster-whisper sounddevice numpy openai
  1. BlackHole の設定
    BlackHole をインストール後、Audio MIDI 設定で複数出力装置を作成し、
    「BlackHole 2ch」とスピーカーを同時出力に設定します。

  2. OpenAI APIキーを設定
    OpenAI の API を使って、Whisper で出力されたテキストを GPT-4o mini で自然な日本語に整形します。
    まずは API キーを環境変数に登録します。

export OPENAI_API_KEY="sk-xxxxxxxxxxxxxxxxxxxxxxxx"

.zshrc に追記しておくと、毎回設定しなくてもOKです。

  1. スクリプトを実行
    仮想環境を有効化した状態で、以下を実行します。(コードの掲載は省略しています)
python (スクリプト名).py

実行すると、以下のようなログが出力されます。

🧠 Loading faster-whisper model 'large-v3' (compute_type=int8) ...
✅ Model loaded.
🎙 Recording on device #1 ... (Ctrl+C で停止)
📝 (Whisperの文字起こし結果がここに表示される)

コード概要

スクリプト全体はシンプルな構造ですが、
録音・認識・整形・出力をそれぞれ独立したスレッドで並行実行しています。
処理の役割は次の4つです

  1. 録音ループ – sounddeviceでBlackHole経由の音声を取得
  2. Whisperワーカー – faster-whisperで並列文字起こし
  3. GPT整形ワーカー – gpt-4o-miniで句読点・文整形(非同期)
  4. 出力ループ – 整形結果をリアルタイムに出力

全体の処理フローは次の通りです:

 [音声入力 (BlackHole)]
   │
   ▼
 record_loop → audio_queue
   │
   ▼
 whisper_worker → text_queue
   │
   ▼
 gpt_worker → print_loop
   │
   ▼
 コンソールに字幕表示

コード全文は300行ほど(長いのでここでは省略しました)。
録音 → 推論 → 整形 → 出力が独立スレッドで動きます。

実際に試してみた結果

検証には、実際の業務プロモーション動画として公開されている
Canly(カンリー)公式YouTube動画こちら)を使用しました。
ナレーション主体の音声で、発話テンポ・イントネーションともに自然なため、
実際のビジネス会話やPR動画に近い条件で検証できます。

実行環境

  • faster-whisper モデル:large-v3 / int8
  • GPT整形モデル:gpt-4o-mini
  • 入力デバイス:BlackHole 2ch(YouTube音声を経由)
  • 再生:MacBook Pro上でYouTubeを再生
  • 録音:ターミナルで python blackhole_realtime.py 実行中に同時録音

実験手順と挙動

動画を最初から再生し、途中で一時停止したタイミングで
Whisper と Chrome の出力結果を比較しました。


比較結果

Chromeの自動字幕(Live Caption)

こちらはChromeの字幕機能で出力されたものです。
リアルタイム性が高く、自然な文脈で句読点も挿入されています。

Chrome自動字幕結果

Whisper + GPT整形(自作リアルタイム文字起こし)

こちらはBlackHole経由で取得した音声を
faster-whisper + GPT-4o mini で処理した結果です。
Chrome字幕のキャプチャとほぼ同じタイミングでキャプチャを行っており
その時点で出力された内容になります。

Whisper出力結果

↓さらに時間を数十秒経た結果(Whisperが内部バッファを処理し、残りの音声をまとめて出力)

比較して分かったこと

項目 Chrome 自動字幕 Whisper + GPT整形
精度 非常に高い。助詞・句読点も自然 単語精度は高いが、文途中で分割されやすい
遅延 約1〜2秒(ほぼリアルタイム) 数十秒〜場合によっては数分遅れ(内部バッファ処理後に出力)
文脈処理 連続的に更新(ストリーミング) バッファ処理後にまとめて出力
実行環境 ブラウザのみで完結 ローカルGPU/CPUを使用
整形 自然な句読点・構文補正 GPT整形で自然化するが時々冗長化

所感

最初は「自作でChromeを超えたい」という思いから始めたものの、
実際に試してみて感じたのは、
“Googleに近づくための道筋”が少し見えた ということでした。

Whisperは精度・多言語対応に優れ、
GPT整形によって文としての自然さも向上します。
この2つを組み合わせることで、
まだ未完成ながらも“手の届くところで動く字幕システム”が実現できました。

ローカル実行でリアルタイム文字起こしを実現できるのは、
数年前なら考えられなかったことです。
今回の取り組みは「完成品」ではなく、
“音声×生成AIのリアルタイム処理”の可能性を探る第一歩 でした。


改善の方向性(今後の展望)

今回の構成では、リアルタイム性の面でまだ課題がありましたが、
以下のような工夫を加えることで、さらに改善できる可能性があります

課題 改善案
遅延が大きい Whisperをストリーミング対応に変更する
文単位のまとまり待ち GPT整形を非同期・逐次処理に変更する
モデル処理が重い smallerモデルの並列化で高速化
処理タイミングが詰まる バッファリング・キュー制御の最適化

これらを組み合わせることで、Chromeのようなリアルタイム性にさらに近づけるかもしれません。
今後は、軽量化モデルやストリーミング出力を活用しながら、
“本当にリアルタイムで使える文字起こしシステム” を目指したいと思います。


カンリーテックブログ

Discussion