
Faster-Whisper 가이드: CTranslate2로 더 빠른 음성-텍스트 변환
Eric King
Author
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 Whisper | Faster-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 MB | 2.3× 빠름 |
| Faster-whisper (INT8, beam=5) | ~59s | ~2926 MB | 2.4× 빠름 |
| Faster-whisper (FP16, batch=8) | ~17s | ~6090 MB | 8.4× 빠름 |
| Faster-whisper (INT8, batch=8) | ~16s | ~4500 MB | 8.9× 빠름 |
CPU(Intel Core i7-12700K)
| 설정 | 시간 | RAM 사용 | 속도 향상 |
|---|---|---|---|
| OpenAI Whisper (FP32, beam=5) | ~6m 58s | ~2335 MB | 기준 |
| Faster-whisper (FP32, beam=5) | ~2m 37s | ~2257 MB | 2.7× 빠름 |
| Faster-whisper (INT8, beam=5) | ~1m 42s | ~1477 MB | 4.1× 빠름 |
| Faster-whisper (FP32, batch=8) | ~1m 06s | ~4230 MB | 6.3× 빠름 |
| Faster-whisper (INT8, batch=8) | ~51s | ~3608 MB | 8.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)
주요 차이
- 로딩:
WhisperModel()vswhisper.load_model() - 반환: 튜플
(segments, info)vs dict - 세그먼트: 객체 이터레이터 vs 리스트
- device/compute_type: 명시 필요
- 전체 텍스트: 세그먼트 결합
마이그레이션 헬퍼
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 가속 사용 가능
✅ 메모리 절감 중요
✅ 배치로 여러 파일
✅ 리소스 제한(INT8)
✅ 실시간·준실시간
✅ GPU 가속 사용 가능
✅ 메모리 절감 중요
OpenAI Whisper를 쓸 때
✅ 기존 코드 최대 호환
✅ 파인튜닝 모델(통합 쉬움)
✅ 단순 API 선호
✅ OpenAI 쪽 실험 기능 먼저
✅ 학습·개발(문서·예제 많음)
✅ 파인튜닝 모델(통합 쉬움)
✅ 단순 API 선호
✅ OpenAI 쪽 실험 기능 먼저
✅ 학습·개발(문서·예제 많음)
결론
Faster-whisper는 같은 정확도로 OpenAI Whisper보다 훨씬 빠릅니다. 설정에 따라 CPU에서 2~4배, 배치 시 GPU에서 최대 약 8배 속도를 기대할 수 있습니다.
요약:
- CPU·제한 환경은 INT8
- VRAM 여유 있으면 GPU FP16
- 여러 파일은 배치
- 알면 언어 지정
- 여러 번은 모델 재사용
전문 음성-텍스트 솔루션이 필요하면 SayToWords에서 최적화된 AI 전사와 다양한 출력 형식을 확인하세요.
