OpenAIが2022年にリリースしたWhisperは、音声認識の民主化を大きく前進させたモデルです。多言語対応、高精度、オープンソースという3つの特徴を兼ね備えており、商用利用も可能なライセンスで公開されています。筆者も複数のプロジェクトでWhisperを活用してきましたが、日本語の認識精度は従来のOSSモデルと比較して格段に向上していますと実感しています。本記事では、Whisperを使った音声認識アプリケーションの構築手法を、実装例を交えて解説します。
Whisperには複数のモデルサイズが用意されています。用途に応じた適切な選択が、アプリケーションの品質と性能を左右します。
日本語の音声認識においては、smallモデルでもかなりの精度が得られます。ただし、専門用語が多い業務コンテンツではmedium以上を推奨します。
まずはWhisperの環境を構築します。Pythonの仮想環境を作成し、必要なパッケージをインストールしましょう。
python -m venv whisper-env
source whisper-env/bin/activate
pip install openai-whisper
pip install torch torchvision torchaudio
最もシンプルな使い方は、コマンドラインからの実行です。
whisper audio.mp3 --model small --language ja
Pythonスクリプトからの利用も簡単にできます。以下は基本的な音声認識の実装例です。
import whisper
model = whisper.load_model("small")
result = model.transcribe("audio.mp3", language="ja")
print(result["text"])
# セグメントごとのタイムスタンプ付き出力
for segment in result["segments"]:
start = segment["start"]
end = segment["end"]
text = segment["text"]
print(f"[{start:.2f} - {end:.2f}] {text}")
transcribeメソッドの戻り値には、全体のテキストだけでなく、セグメントごとの情報が含まれています。これにより、字幕生成などのユースケースにも対応できます。
本家Whisperの実行速度に不満がある場合、faster-whisperの利用を検討するとよいです。CTranslate2を使って推論を最適化しており、本家の4〜8倍の速度で動作します。
pip install faster-whisper
from faster_whisper import WhisperModel
model = WhisperModel("small", device="cuda", compute_type="float16")
segments, info = model.transcribe("audio.mp3", language="ja")
print(f"検出言語: {info.language} (確率: {info.language_probability:.2f})")
for segment in segments:
print(f"[{segment.start:.2f} - {segment.end:.2f}] {segment.text}")
compute_typeにfloat16やint8を指定することで、メモリ使用量を削減しつつ高速に推論できます。GPU環境ではfloat16、CPU環境ではint8が実用的な選択です。
FastAPIを使って、音声認識機能をREST APIとして提供する実装例を紹介します。
from fastapi import FastAPI, UploadFile, File
from faster_whisper import WhisperModel
import tempfile
import os
app = FastAPI()
model = WhisperModel("small", device="cpu", compute_type="int8")
@app.post("/transcribe")
async def transcribe_audio(file: UploadFile = File(...)):
with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmp:
content = await file.read()
tmp.write(content)
tmp_path = tmp.name
try:
segments, info = model.transcribe(tmp_path, language="ja")
results = []
full_text = ""
for segment in segments:
results.append({
"start": round(segment.start, 2),
"end": round(segment.end, 2),
"text": segment.text
})
full_text += segment.text
return {
"text": full_text,
"segments": results,
"language": info.language
}
finally:
os.unlink(tmp_path)
このAPIは、音声ファイルをアップロードすると、認識結果をJSON形式で返す。本番運用では、ファイルサイズの制限やキューイングの仕組みを追加することが望ましい。
Whisperの認識精度をさらに高めるためのテクニックをいくつか紹介します。
transcribeメソッドのinitial_promptパラメータに、認識対象のコンテキスト情報を渡すことで精度が向上する場合があります。
result = model.transcribe(
"meeting.mp3",
language="ja",
initial_prompt="本日の議題はKubernetesクラスタの移行計画についてです。"
)
専門用語が多い音声では、この手法が特に有効です。プロンプトに専門用語を含めることで、モデルがその単語を正しく認識しやすくなります。
ノイズの多い音声には、事前にノイズ除去を適用することで認識精度が向上します。noisereduceライブラリが手軽に使える。また、音量の正規化も効果的です。
faster-whisperにはSilero VAD(Voice Activity Detection)が統合されており、無音区間を自動的にスキップできます。これにより処理速度が向上し、無音部分での誤認識も減少します。
音声認識アプリケーションを本番運用する際に考慮すべき点をまとめる。
Whisperは音声認識のハードルを大幅に下げたが、適切な設計と運用の工夫があってこそ、その能力を最大限に引き出せる。まずは小さなプロトタイプから始めて、自分のユースケースに最適な構成を見つけていくことを勧める。