faster-whisper를 사용하여 CPU 기반의 월 25달러짜리 무료 무제한 전사 도구를 구축한 방법
요약
faster-whisper와 CTranslate2를 활용하여 CPU 환경에서도 효율적인 무제한 음성 전사 도구를 구축하는 방법을 소개합니다. 큐 격리(Queue Isolation) 전략을 통해 기존 워커의 부하를 방지하고 시스템 안정성을 확보하는 아키텍처를 다룹니다.
핵심 포인트
- faster-whisper를 사용하여 CPU 환경에서 표준 Whisper 대비 약 4배 빠른 속도 구현
- 큐 격리(Queue Isolation)를 통해 전사 작업이 기존 소음 제거 작업에 미치는 영향 차단
- int8 양자화를 적용하여 메모리 점유율을 절반으로 줄이고 추론 속도 최적화
- 독립적인 서비스와 Redis 네임스페이스를 활용한 시스템 안정성 확보
모든 무료 전사 (transcription) 도구는 제한을 둡니다. Otter는 월 300분으로 제한하며, Turboscribe는 하루 3개 파일로 제한합니다. Notta는 월 120분으로 제한합니다. 이들은 모두 동일한 이유로 이렇게 운영합니다. 전사 작업은 실행 비용이 많이 들며, 누군가는 그 비용을 지불해야 하기 때문입니다.
저는 제한이 없는 도구를 만들었습니다. 어떻게 작동하는지 소개하겠습니다.
배경
이 글은 제가 공개적으로 구축하고 있는 무료 비디오 및 오디오 도구 제품군인 VidClean에 관한 시리즈의 세 번째 포스트입니다. 첫 번째 포스트에서는 전체 스택 (FastAPI, ARQ, Railway, Cloudflare R2)을 다루었습니다. 두 번째 포스트에서는 CPU에서 DeepFilterNet3 배경 소음 제거를 실행하는 방법을 다루었습니다. 이번 포스트에서는 이미 작동 중인 도구들을 망가뜨리지 않고 Whisper 전사 기능을 추가하는 방법을 다룹니다.
기존 워커 (worker)에 단순히 Whisper를 추가할 수 없는 이유
제 백엔드는 이미 두 개의 무거운 모델을 실행하고 있습니다. 배경 소음 제거 및 음성 향상을 위한 DeepFilterNet3입니다. 두 모델 모두 워커당 한 번에 하나의 무거운 작업만 허용하는 Redis 세마포어 (semaphore) 뒤에 보호되어 있습니다. 이는 여러 사용자가 동시에 파일을 제출할 때 발생하는 메모리 부족 (out-of-memory) 충돌을 방지합니다.
Whisper를 추가하는 단순한 접근 방식은 동일한 워커 내에서 DF3와 함께 로드하는 것입니다. 문제는 30분짜리 전사 작업이 30분 동안 무거운 잠금 (lock)을 유지하여, 대기열에 있는 모든 무음 제거 및 소음 감소 작업을 차단한다는 점입니다. 무음 제거가 핵심 기능인 무료 도구에서 이는 용납될 수 없습니다.
해결책은 큐 격리 (queue isolation)입니다. Whisper는 자체적인 Railway 서비스, 자체적인 ARQ 큐, 그리고 자체적인 Redis 네임스페이스 (namespace)를 가집니다. 전사 작업은 DF3 워커를 절대 건드리지 않습니다. 두 시스템은 완전히 독립적으로 실행됩니다.
증거는 타이밍에 있습니다. 저는 동시 작업으로 이를 테스트했습니다. 전사 작업과 무음 제거 작업이 1초 이내에 동시에 실행되었습니다. 무음 제거 작업은 6초 만에 완료되었습니다. 전사 작업은 그로부터 36초 후에 완료되었습니다. 차단도, 대기도 없었습니다.
CPU에서의 faster-whisper
CPU에서 실행되는 표준 Whisper는 느립니다.
OpenAI의 자체 모델은 일반적인 서버 CPU에서 대략 1배의 실시간 속도로 실행되며, 이는 30분 길이의 파일을 처리하는 데 30분이 걸린다는 것을 의미합니다.
faster-whisper (CTranslate2)는 이를 변화시킵니다. CTranslate2는 Transformer 모델을 위해 최적화된 추론 엔진 (Inference Engine)으로, 표준 구현보다 대략 4배 더 빠르게 실행됩니다. Railway의 2 vCPU 할당량에서 10분 길이의 파일은 약 34분 만에 처리됩니다. 30분 길이의 파일은 약 812분 만에 완료됩니다.
중요한 설정 사항:
from faster_whisper import WhisperModel
model = WhisperModel(
"small",
device="cpu",
compute_type="int8",
cpu_threads=2,
num_workers=1,
download_root="/tmp/whisper-models"
)
compute_type="int8"은 모델 가중치 (Weights)를 8비트 정수 (8-bit integers)로 양자화 (Quantize)합니다. 이는 메모리 점유율을 절반으로 줄이고, 명확한 음성에서의 정확도 손실을 최소화하면서 추론 속도를 더욱 높여줍니다. cpu_threads=2는 2 vCPU 할당량과 일치하도록 설정한 것입니다.
모델 크기는 244MB이며 워커 (Worker) 시작 시 다운로드됩니다. 첫 부팅 시에는 모델을 HuggingFace에서 가져오는 동안 약 30초의 추가 시간이 소요됩니다. 캐시 (Cache)된 이후의 후속 부팅은 더 빠릅니다.
VAD — 90분 길이의 파일을 처리하는 방법
90분 길이의 녹음 파일이 90분 내내 연속적인 음성인 것은 아닙니다. 문장 사이에는 휴지기 (Pause), 공백 (Gap), 채우기용 침묵 (Filler silence)이 존재합니다. 표준 Whisper는 이 모든 것을 처리합니다. faster-whisper에는 비음성 구간 (Non-speech segments)을 완전히 건너뛰는 VAD (Voice Activity Detection) 필터가 있습니다.
segments, info = model.transcribe(
wav_path,
vad_filter=True,
language=language,
beam_size=5
)
vad_filter=True를 설정하면 자연스러운 휴지기가 포함된 90분 길이의 설교는 실제 음성인 65~70분 분량만 처리하면 될 수도 있습니다. 실질적인 효과는 다음과 같습니다: 긴 파일이 더 빨리 완료되며, Whisper가 문장 사이의 주변 소음 (Ambient room noise)을 전사하려고 시도하지 않기 때문에 전사 결과 (Transcript)가 더 깔끔해집니다.
최대 파일 길이는 백엔드에서 90분으로 제한됩니다. 이보다 긴 파일은 모델 작업이 시작되기 전에 오류와 함께 깔끔하게 실패 처리됩니다.
하나의 작업으로 생성되는 세 가지 출력 형식
Whisper는 시작 시간, 종료 시간, 전사된 텍스트를 포함하는 세그먼트 (segments) 목록을 반환합니다. 이 단일 세그먼트 목록으로부터 세 가지 출력 파일이 생성됩니다:
Plain text (.txt): 타임스탬프가 없는 깔끔한 산문 형식으로, 읽기 및 복사/붙여넣기에 용이합니다.
SRT (.srt): HH:MM:SS,mmm 타임스탬프가 포함된 번호가 매겨진 큐 (cues) 형식으로, 모든 비디오 편집기 및 자막 도구에서 지원하는 형식입니다.
VTT (.vtt): HH:MM:SS.mmm 타임스탬프를 사용하는 WEBVTT 형식으로, 브라우저가 HTML5 비디오 트랙에 사용하는 형식입니다.
세 가지 형식 모두 별도의 객체로 Cloudflare R2에 업로드되며, 각각 개별적인 사전 서명된 다운로드 URL (presigned download URLs)로 반환됩니다. 한 번의 업로드로 세 번의 다운로드가 가능합니다.
실제 수치
전용 전사 워커 (transcription worker)는 기존 인프라에 월 약 812달러를 추가합니다. 무음 제거 (silence removal), 배경 소음 (background noise), 음성 향상 (speech enhancement), 전사 (transcription) 및 기타 14가지 도구를 포함한 전체 스위트의 총 비용은 월 약 2530달러입니다. GPU는 사용하지 않습니다. 유료 전사 API도 사용하지 않습니다. 분당 과금 방식도 아닙니다.
제한 없는 포지셔닝
모든 경쟁사는 GPU 인프라를 운영하며 마진을 보호하기 위해 무료 사용량을 제한해야 하므로 무료 티어에 상한선을 둡니다. CPU 추론 (inference)은 더 느리지만 비용 구조가 완전히 다릅니다. Railway CPU 인스턴스에서 faster-whisper small을 실행하는 비용은 작업당 1센트의 아주 작은 부분에 불과합니다. 따라서 사용량을 제한해야 할 경제적 압박이 없습니다.
다음 단계
Burned-in captions: FFmpeg를 통해 SRT를 실행하여 비디오에 자막을 직접 렌더링하는 기능입니다. 새로운 모델이나 새로운 인프라 없이 단 하나의 FFmpeg 명령어로 가능합니다. 이 기능과 /add-subtitles 경로의 전용 자막 페이지가 로드맵의 다음 단계입니다.
faster-whisper 설정, 큐 격리 (queue isolation) 방식, 또는 VAD (Voice Activity Detection) 구성에 대해 질문이 있다면 댓글을 남겨주세요.
vidclean.net/transcribe에서 직접 체험해 보실 수 있습니다. 무료이며, 계정이 필요 없고, 시간 제한도 없습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기