動画ファイルから議事録を自動生成するスキルを運用しています。音声文字起こし部分に openai-whisper(OpenAI 公式の Whisper CLI)を使っていましたが、faster-whisper に移行したところ、処理速度とメモリ効率が大きく改善しました。
この記事では、移行の動機、具体的な変更内容、得られた効果をまとめます。
移行の動機
openai-whisper は OpenAI が公開している公式実装で、whisper コマンド一発で文字起こしができる手軽さが魅力です。しかし実際に運用してみると、以下の点が気になっていました。
- 処理が遅い: 長時間の動画(1 時間超)では文字起こしに相当な時間がかかる
- メモリ消費が大きい: PyTorch ベースのため、モデルロード時のメモリ使用量が多い
faster-whisper は CTranslate2 ベースの再実装で、最大 4 倍の高速化と低メモリ消費を謳っています。
変更内容
依存パッケージの変更
# Before
pip install openai-whisper
# After
pip install faster-whisperopenai-whisper は PyTorch に依存するため、インストール時のダウンロードサイズも大きくなりがちです。faster-whisper は CTranslate2 ベースで、依存関係が軽量です。
CLI から Python スクリプトへ
openai-whisper では whisper CLI コマンドをそのまま呼んでいましたが、faster-whisper は Python ライブラリとして提供されているため、ラッパースクリプトを作成しました。
import argparse
def format_time(seconds):
h = int(seconds // 3600)
m = int((seconds % 3600) // 60)
s = seconds % 60
return f"{h:02d}:{m:02d}:{s:05.2f}"
def main():
parser = argparse.ArgumentParser(
description="Transcribe audio using faster-whisper."
)
parser.add_argument("audio_path", help="Path to the audio file to transcribe.")
parser.add_argument("--language", default="ja", help="Language code (default: ja)")
parser.add_argument("--model", default="large-v3", help="Whisper model name (default: large-v3)")
parser.add_argument("--output", default="meeting_audio.txt", help="Output text file path")
parser.add_argument("--device", default="cpu", help="Device to use (default: cpu)")
parser.add_argument("--compute-type", default="int8", help="Compute type for quantization (default: int8)")
parser.add_argument("--beam-size", type=int, default=5, help="Beam size (default: 5)")
args = parser.parse_args()
from faster_whisper import WhisperModel
print(f"Loading model '{args.model}' on {args.device} ({args.compute_type})...", flush=True)
model = WhisperModel(args.model, device=args.device, compute_type=args.compute_type)
print(f"Transcribing '{args.audio_path}' (language={args.language})...", flush=True)
segments, info = model.transcribe(
args.audio_path, language=args.language, beam_size=args.beam_size
)
print(f"Detected language: {info.language} (probability {info.language_probability:.2f})", flush=True)
lines = []
for segment in segments:
line = segment.text.strip()
print(f"[{format_time(segment.start)} -> {format_time(segment.end)}] {line}", flush=True)
lines.append(line)
with open(args.output, "w", encoding="utf-8") as f:
f.write("\n".join(lines) + "\n")
print(f"\nTranscription saved to '{args.output}'", flush=True)
if __name__ == "__main__":
main()ポイントは以下の通りです。
int8量子化: デフォルトで INT8 量子化を有効化し、CPU 環境でもメモリ効率を最適化large-v3モデル: openai-whisper のturboモデルからlarge-v3に変更。faster-whisper の最適化により、大きいモデルでも実用的な速度で動作する
利用方法の変更
# Before
whisper meeting_audio.wav --language ja --model turbo > meeting_audio.log 2>&1
# After
python scripts/transcribe.py meeting_audio.wav --language ja --model large-v3 > meeting_audio.log 2>&1バックグラウンド実行して tail -f meeting_audio.log で進捗を確認する運用は変わりません。ただし、完了の検知方法が変わりました。
# Before: ログの更新が止まったら完了(判定が曖昧)
ps aux | grep whisper
# After: "Transcription saved to" が出力されたら完了(明確)
ps aux | grep transcribe.pyまとめ
| 項目 | openai-whisper | faster-whisper |
|---|---|---|
| エンジン | PyTorch | CTranslate2 |
| 速度 | 基準 | 最大 4 倍高速 |
| メモリ | 多い | 少ない(INT8 量子化対応) |
| インターフェース | CLI コマンド | Python ライブラリ |
| モデル | turbo | large-v3 |
移行作業自体はシンプルで、ラッパースクリプトの作成を含めても短時間で完了しました。openai-whisper の処理速度やメモリ消費に不満がある場合は、faster-whisper への移行を検討する価値があります。
以上、音声文字起こしは速いほど正義、現場からお送りしました。