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 vs 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() vs whisper.load_model()
  2. 반환: 튜플 (segments, info) vs dict
  3. 세그먼트: 객체 이터레이터 vs 리스트
  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
  • 여러 파일은 배치
  • 알면 언어 지정
  • 여러 번은 모델 재사용
자세한 내용은 Whisper Python 예제, Whisper 정확도 팁, Whisper 전사 서식을 참고하세요.

전문 음성-텍스트 솔루션이 필요하면 SayToWords에서 최적화된 AI 전사와 다양한 출력 형식을 확인하세요.

지금 무료로 체험하기

지금 바로 저희 AI 음성·오디오·영상 서비스를 체험해 보세요! 고정밀 음성-텍스트 전사, 다국어 번역, 지능형 화자 분리를 제공할 뿐 아니라, 동영상 자동 자막 생성, 오디오·영상 콘텐츠의 스마트 편집, 음성·영상 동기 분석까지 지원합니다. 회의 기록, 숏폼 영상 제작, 팟캐스트 제작 등 모든 상황을 완전히 커버합니다. 지금 무료 체험을 시작해 보세요!