Faster-Whisper ガイド:CTranslate2 でより速い音声テキスト化

Faster-Whisper ガイド:CTranslate2 でより速い音声テキスト化


Faster-Whisper ガイド:CTranslate2 でより速い音声テキスト化

Faster-whisper は、高速なトランスフォーマ推論エンジン CTranslate2 を用いた OpenAI Whisper モデルの高性能な再実装です。2〜4 倍速い文字起こしをほぼ同等の精度で実現し、本番環境やバッチ処理に適しています。
本ガイドでは faster-whisper の要点(インストール、利用例、最適化、標準の OpenAI Whisper を選ぶ場合)をまとめます。

Faster-whisper とは

Faster-whisper は、CTranslate2 により推論を高速化した OpenAI Whisper の最適化実装です。元モデルと同じ精度を保ちつつ、速度を大きく改善し、メモリ使用量も抑えます。

主な特徴

  • OpenAI Whisper と比べ 推論が 2〜4 倍速い
  • 量子化により メモリ使用量を削減
  • オリジナル Whisper モデルと 同じ精度
  • 最適化バックエンドによる GPU / CPU 対応
  • 複数ファイルの バッチ処理
  • 単語レベルのタイムスタンプ
  • 量子化オプション(FP32、FP16、INT8、INT8_FLOAT16)
  • フィルタ用の 音声活動検出(VAD)

仕組み

Faster-whisper は Whisper モデルを CTranslate2 形式に変換し、推論用に最適化された C++ コードで実行します。これにより次が可能になります。
  • 最適化 BLAS による 高速な行列演算
  • オーバーヘッド削減による メモリ管理の改善
  • メモリ削減のための 量子化
  • スループット向上のための バッチ処理

Faster-whisper と OpenAI Whisper

性能比較

項目OpenAI WhisperFaster-whisper
速度基準2〜4 倍速い
メモリ多い少ない(量子化時)
精度高い同じ(同一モデル)
GPUありあり(最適化済み)
CPUありあり(最適化済み)
量子化限定的完全(INT8、FP16 など)
バッチ手動組み込み
インストール簡単簡単(CTranslate2 を含む)

Faster-whisper を選ぶとき

faster-whisper が向いている場合:
  • 本番負荷で より速い文字起こし が必要
  • 複数ファイル をバッチで処理する
  • リソースが限られた 環境(INT8 を使う)
  • リアルタイム/準リアルタイム アプリを作る
  • デプロイで メモリを抑えたい
OpenAI Whisper のままがよい場合:
  • 既存コードとの 互換性を最優先 する
  • ファインチューン済みモデル を使う(faster-whisper は変換が必要)
  • より単純な API を好む(faster-whisper も近いが)
  • OpenAI Whisper に先に出る 実験機能 が必要

インストール

前提

  • Python 3.9+(必須)
  • FFmpeg(任意:faster-whisper は PyAV を使いますが、形式によっては FFmpeg が必要なことも)
  • NVIDIA GPU(任意:GPU 加速用)

基本インストール

pip で faster-whisper をインストールします。
pip install faster-whisper
自動的に次も入ります。
  • faster-whisper パッケージ
  • ctranslate2(CTranslate2 推論エンジン)
  • pyav(音声デコード、FFmpeg 依存の代替)

GPU インストール(NVIDIA CUDA)

GPU 加速には CUDA ライブラリが必要です。
CUDA 12(推奨):
pip install nvidia-cublas-cu12 nvidia-cudnn-cu12==9.*
ライブラリパスを設定します。
export LD_LIBRARY_PATH=$(python3 -c 'import os; import nvidia.cublas.lib; import nvidia.cudnn.lib; print(os.path.dirname(nvidia.cublas.lib.__file__) + ":" + os.path.dirname(nvidia.cudnn.lib.__file__))')
CUDA 11(レガシー):
CUDA 11 の場合は古い CTranslate2 を使います。
pip install ctranslate2==3.24.0 faster-whisper

インストールの確認

from faster_whisper import WhisperModel

# Test basic import
print("Faster-whisper installed successfully!")

基本的な使い方

シンプルな文字起こし

from faster_whisper import WhisperModel

# Load model (automatically downloads if not present)
model = WhisperModel("base", device="cpu", compute_type="int8")

# Transcribe audio
segments, info = model.transcribe("audio.mp3")

# Print detected language
print(f"Detected language: {info.language} (probability: {info.language_probability:.2f})")

# Print transcription
for segment in segments:
    print(f"[{segment.start:.2f}s -> {segment.end:.2f}s] {segment.text}")

全文を取得

from faster_whisper import WhisperModel

model = WhisperModel("base")
segments, info = model.transcribe("audio.mp3")

# Collect all text
full_text = " ".join([segment.text for segment in segments])
print(full_text)

単語タイムスタンプ付き

from faster_whisper import WhisperModel

model = WhisperModel("base", device="cpu", compute_type="int8")

segments, info = model.transcribe(
    "audio.mp3",
    word_timestamps=True,
    beam_size=5
)

for segment in segments:
    print(f"[{segment.start:.2f}s - {segment.end:.2f}s] {segment.text}")
    
    # Word-level timestamps
    for word in segment.words:
        print(f"  {word.word} [{word.start:.2f}s - {word.end:.2f}s]")

デバイスと compute タイプ

デバイス

  • device="cpu" — CPU 推論(どこでも可)
  • device="cuda" — GPU 推論(NVIDIA GPU と CUDA が必要)

compute タイプ

ハードウェアと速度/精度のトレードオフで選びます。
compute タイプ速度メモリ精度用途
int8最速最小やや低いCPU、省リソース
int8_float16非常に速い高いVRAM が少ない GPU
float16速い高いGPU(推奨)
float32最も遅い最大最高最高精度

ハードウェア別の例

CPU(Intel/AMD):
# Best for CPU: INT8
model = WhisperModel("base", device="cpu", compute_type="int8")
GPU(NVIDIA):
# Best for GPU: FP16
model = WhisperModel("large-v2", device="cuda", compute_type="float16")
VRAM が限られた GPU:
# Use INT8_FLOAT16 for large models
model = WhisperModel("large-v2", device="cuda", compute_type="int8_float16")
最高精度:
# Use FP32 (slower but most accurate)
model = WhisperModel("large-v2", device="cuda", compute_type="float32")

高度な機能

1. バッチ処理

複数の音声ファイルを効率よく処理します。
from faster_whisper import WhisperModel
from pathlib import Path

model = WhisperModel("base", device="cuda", compute_type="float16")

audio_files = ["audio1.mp3", "audio2.mp3", "audio3.mp3"]

for audio_file in audio_files:
    print(f"Transcribing: {audio_file}")
    segments, info = model.transcribe(audio_file)
    
    text = " ".join([seg.text for seg in segments])
    print(f"Result: {text[:100]}...")
    print()

2. 音声活動検出(VAD)

無音や非音声区間を除きます。
from faster_whisper import WhisperModel

model = WhisperModel("base")

segments, info = model.transcribe(
    "audio.mp3",
    vad_filter=True,  # Enable VAD filtering
    vad_parameters=dict(
        min_silence_duration_ms=500,  # Minimum silence duration
        threshold=0.5  # VAD threshold
    )
)

for segment in segments:
    print(f"[{segment.start:.2f}s] {segment.text}")

3. 言語の指定

精度と速度を上げるために言語を指定します。
from faster_whisper import WhisperModel

model = WhisperModel("base")

# Specify language (faster and more accurate)
segments, info = model.transcribe(
    "audio.mp3",
    language="en"  # English
)

# Or let it auto-detect
segments, info = model.transcribe("audio.mp3")  # Auto-detect
print(f"Detected: {info.language}")

4. ビームサイズなどのパラメータ

from faster_whisper import WhisperModel

model = WhisperModel("base")

segments, info = model.transcribe(
    "audio.mp3",
    beam_size=5,  # Higher = more accurate but slower (default: 5)
    best_of=5,    # Number of candidates to consider
    temperature=0.0,  # Lower = more deterministic
    condition_on_previous_text=True,  # Use context from previous segments
    initial_prompt="This is a technical meeting about AI and machine learning."
)

5. カスタムモデルパス

ローカルや変換済みモデルを使います。
from faster_whisper import WhisperModel

# Use local model directory
model = WhisperModel(
    "base",
    device="cpu",
    compute_type="int8",
    download_root="./models"  # Custom download directory
)

# Or specify full path to converted model
model = WhisperModel(
    "/path/to/converted/model",
    device="cuda",
    compute_type="float16"
)

ベンチマーク

GPU(NVIDIA RTX 3070 Ti)

約 13 分の音声を文字起こし:
構成時間VRAM 使用量高速化
OpenAI Whisper (FP16, beam=5)~2m 23s~4708 MB基準
Faster-whisper (FP16, beam=5)~1m 03s~4525 MB2.3× 高速
Faster-whisper (INT8, beam=5)~59s~2926 MB2.4× 高速
Faster-whisper (FP16, batch=8)~17s~6090 MB8.4× 高速
Faster-whisper (INT8, batch=8)~16s~4500 MB8.9× 高速

CPU(Intel Core i7-12700K)

構成時間RAM 使用量高速化
OpenAI Whisper (FP32, beam=5)~6m 58s~2335 MB基準
Faster-whisper (FP32, beam=5)~2m 37s~2257 MB2.7× 高速
Faster-whisper (INT8, beam=5)~1m 42s~1477 MB4.1× 高速
Faster-whisper (FP32, batch=8)~1m 06s~4230 MB6.3× 高速
Faster-whisper (INT8, batch=8)~51s~3608 MB8.2× 高速

要点

  • バッチ処理 が最も効く(GPU で 8 倍以上)
  • INT8 量子化 でメモリ約 40% 削減、精度低下は小さい
  • 大モデル/バッチでは GPU 加速 が重要
  • 小モデル・単一ファイルなら CPU + INT8 も実用的

完全例:本番向け文字起こし

from faster_whisper import WhisperModel
from pathlib import Path
import json
from datetime import datetime

class TranscriptionService:
    """Production-ready transcription service using faster-whisper."""
    
    def __init__(self, model_size="base", device="cpu", compute_type="int8"):
        """Initialize the transcription service."""
        print(f"Loading model: {model_size} on {device} ({compute_type})")
        self.model = WhisperModel(
            model_size,
            device=device,
            compute_type=compute_type
        )
        print("Model loaded successfully!")
    
    def transcribe_file(self, audio_path, output_format="txt", **kwargs):
        """
        Transcribe an audio file.
        
        Args:
            audio_path: Path to audio file
            output_format: Output format (txt, json, srt, vtt)
            **kwargs: Additional transcription parameters
        """
        audio_path = Path(audio_path)
        if not audio_path.exists():
            raise FileNotFoundError(f"Audio file not found: {audio_path}")
        
        print(f"Transcribing: {audio_path.name}")
        
        # Transcribe
        segments, info = self.model.transcribe(
            str(audio_path),
            word_timestamps=True,
            **kwargs
        )
        
        # Collect results
        result = {
            "file": str(audio_path),
            "language": info.language,
            "language_probability": info.language_probability,
            "duration": info.duration,
            "segments": []
        }
        
        full_text_parts = []
        for segment in segments:
            segment_data = {
                "start": segment.start,
                "end": segment.end,
                "text": segment.text,
                "words": [
                    {
                        "word": word.word,
                        "start": word.start,
                        "end": word.end,
                        "probability": word.probability
                    }
                    for word in segment.words
                ]
            }
            result["segments"].append(segment_data)
            full_text_parts.append(segment.text)
        
        result["text"] = " ".join(full_text_parts)
        
        # Save based on format
        output_path = audio_path.parent / f"{audio_path.stem}_transcript"
        
        if output_format == "txt":
            self._save_txt(result, output_path.with_suffix(".txt"))
        elif output_format == "json":
            self._save_json(result, output_path.with_suffix(".json"))
        elif output_format == "srt":
            self._save_srt(result, output_path.with_suffix(".srt"))
        elif output_format == "vtt":
            self._save_vtt(result, output_path.with_suffix(".vtt"))
        
        print(f"✓ Transcription saved: {output_path}.{output_format}")
        return result
    
    def _save_txt(self, result, path):
        """Save as plain text."""
        with open(path, "w", encoding="utf-8") as f:
            f.write(result["text"])
    
    def _save_json(self, result, path):
        """Save as JSON."""
        with open(path, "w", encoding="utf-8") as f:
            json.dump(result, f, indent=2, ensure_ascii=False)
    
    def _save_srt(self, result, path):
        """Save as SRT subtitles."""
        with open(path, "w", encoding="utf-8") as f:
            for i, seg in enumerate(result["segments"], start=1):
                start = self._format_srt_time(seg["start"])
                end = self._format_srt_time(seg["end"])
                f.write(f"{i}\n{start} --> {end}\n{seg['text']}\n\n")
    
    def _save_vtt(self, result, path):
        """Save as WebVTT."""
        with open(path, "w", encoding="utf-8") as f:
            f.write("WEBVTT\n\n")
            for seg in result["segments"]:
                start = self._format_vtt_time(seg["start"])
                end = self._format_vtt_time(seg["end"])
                f.write(f"{start} --> {end}\n{seg['text']}\n\n")
    
    def _format_srt_time(self, seconds):
        """Format time for SRT."""
        hours = int(seconds // 3600)
        minutes = int((seconds % 3600) // 60)
        secs = int(seconds % 60)
        millis = int((seconds % 1) * 1000)
        return f"{hours:02d}:{minutes:02d}:{secs:02d},{millis:03d}"
    
    def _format_vtt_time(self, seconds):
        """Format time for VTT."""
        hours = int(seconds // 3600)
        minutes = int((seconds % 3600) // 60)
        secs = int(seconds % 60)
        millis = int((seconds % 1) * 1000)
        return f"{hours:02d}:{minutes:02d}:{secs:02d}.{millis:03d}"

# Usage
if __name__ == "__main__":
    # Initialize service
    service = TranscriptionService(
        model_size="base",
        device="cpu",  # Change to "cuda" for GPU
        compute_type="int8"  # Use "float16" for GPU
    )
    
    # Transcribe file
    result = service.transcribe_file(
        "meeting.mp3",
        output_format="json",
        beam_size=5,
        language="en"
    )
    
    print(f"\nLanguage: {result['language']}")
    print(f"Duration: {result['duration']:.2f}s")
    print(f"Text: {result['text'][:200]}...")

ベストプラクティス

1. モデルサイズの選び方

# For speed (CPU)
model = WhisperModel("tiny", device="cpu", compute_type="int8")

# For balance
model = WhisperModel("base", device="cpu", compute_type="int8")

# For accuracy (GPU recommended)
model = WhisperModel("large-v2", device="cuda", compute_type="float16")

2. ハードウェアに合わせる

CPU のみ:
model = WhisperModel("base", device="cpu", compute_type="int8")
VRAM に余裕がある GPU:
model = WhisperModel("large-v2", device="cuda", compute_type="float16")
VRAM が少ない GPU:
model = WhisperModel("medium", device="cuda", compute_type="int8_float16")

3. 複数ファイルはバッチで

# Process multiple files efficiently
audio_files = ["file1.mp3", "file2.mp3", "file3.mp3"]
model = WhisperModel("base", device="cuda", compute_type="float16")

for audio_file in audio_files:
    segments, info = model.transcribe(audio_file)
    # Process results...

4. ノイズが多いときは VAD

segments, info = model.transcribe(
    "noisy_audio.mp3",
    vad_filter=True,
    vad_parameters=dict(
        min_silence_duration_ms=1000,
        threshold=0.5
    )
)

5. 言語が分かるときは指定

# Faster and more accurate when language is known
segments, info = model.transcribe(
    "audio.mp3",
    language="en"  # Specify instead of auto-detect
)

6. モデルインスタンスの再利用

# Load model once, reuse for multiple files
model = WhisperModel("base")

# Process multiple files with same model
for audio_file in audio_files:
    segments, info = model.transcribe(audio_file)

OpenAI Whisper からの移行

コード比較

OpenAI Whisper:
import whisper

model = whisper.load_model("base")
result = model.transcribe("audio.mp3")
print(result["text"])
Faster-whisper:
from faster_whisper import WhisperModel

model = WhisperModel("base", device="cpu", compute_type="int8")
segments, info = model.transcribe("audio.mp3")
text = " ".join([seg.text for seg in segments])
print(text)

主な違い

  1. 読み込み: WhisperModel()whisper.load_model()
  2. 戻り値: タプル (segments, info) と dict
  3. セグメント: オブジェクトのイテレータとリスト
  4. device / compute_type: 明示が必要
  5. 全文: セグメントを結合

移行用ヘルパー

def convert_to_whisper_format(segments, info):
    """Convert faster-whisper output to OpenAI Whisper format."""
    return {
        "text": " ".join([seg.text for seg in segments]),
        "language": info.language,
        "segments": [
            {
                "id": i,
                "start": seg.start,
                "end": seg.end,
                "text": seg.text,
                "words": [
                    {
                        "word": word.word,
                        "start": word.start,
                        "end": word.end
                    }
                    for word in seg.words
                ] if hasattr(seg, 'words') else []
            }
            for i, seg in enumerate(segments)
        ]
    }

# Usage
segments, info = model.transcribe("audio.mp3", word_timestamps=True)
result = convert_to_whisper_format(segments, info)
# Now compatible with OpenAI Whisper format

トラブルシューティング

問題 1:CUDA のメモリ不足

症状: 大きなモデルで GPU メモリが足りない。
対処:
# Use smaller model
model = WhisperModel("base", device="cuda", compute_type="float16")

# Or use INT8 quantization
model = WhisperModel("large-v2", device="cuda", compute_type="int8_float16")

# Or use CPU
model = WhisperModel("large-v2", device="cpu", compute_type="int8")

問題 2:CPU が遅い

症状: CPU 上の文字起こしが遅い。
対処:
# Use INT8 quantization
model = WhisperModel("base", device="cpu", compute_type="int8")

# Use smaller model
model = WhisperModel("tiny", device="cpu", compute_type="int8")

# Reduce beam size
segments, info = model.transcribe("audio.mp3", beam_size=1)

問題 3:CUDA ライブラリが見つからない

症状: RuntimeError: CUDA runtime not found
対処:
# Install CUDA libraries
pip install nvidia-cublas-cu12 nvidia-cudnn-cu12==9.*

# Set library path
export LD_LIBRARY_PATH=$(python3 -c 'import os; import nvidia.cublas.lib; import nvidia.cudnn.lib; print(os.path.dirname(nvidia.cublas.lib.__file__) + ":" + os.path.dirname(nvidia.cudnn.lib.__file__))')

問題 4:モデルダウンロード失敗

症状: タイムアウトや失敗。
対処:
# Specify download directory
model = WhisperModel(
    "base",
    download_root="./models",  # Custom directory
    local_files_only=False
)

# Or download manually from Hugging Face
# Then use local path
model = WhisperModel("/path/to/local/model")

使い分け

Faster-whisper がよいとき

本番 で速度が必要
バッチ で複数ファイル
リソース制約(INT8)
リアルタイム/準リアルタイム
GPU 加速 あり
メモリ削減 が重要

OpenAI Whisper がよいとき

✅ 既存コードとの 最大互換
ファインチューン済み(統合が簡単)
シンプルな API 志向
✅ OpenAI 側の 実験機能 が先
学習・開発(ドキュメント/例が多い)

まとめ

Faster-whisper は、同じ精度のまま OpenAI Whisper より大きく高速化できます。設定次第で CPU で 2〜4 倍バッチ時は GPU で最大約 8 倍 の速度が期待できます。
覚えておくこと:
  • CPU/省リソースは INT8
  • VRAM に余裕があれば GPU は FP16
  • 複数ファイルは バッチ
  • 分かるなら 言語を指定
  • 複数回は モデルを使い回す

プロ向けの音声テキスト化をお探しなら、SayToWords で最適化された AI 文字起こしと複数出力形式をご覧ください。

今すぐ無料で試す

当社のAI音声・オーディオ/ビデオサービスを今すぐお試しください。高精度な音声文字起こし、多言語翻訳、話者分離に対応するだけでなく、自動動画字幕生成、音声・映像コンテンツのインテリジェント編集、音声と映像を組み合わせた同期解析も実現します。会議記録、ショート動画制作、ポッドキャスト制作など、あらゆるシーンをこれ一つでカバーできます。今すぐ無料トライアルを始めましょう!