이 작업에 맞는 GPU
- GA102 20GB시간당 190원
large-v3로 배치 처리를 하거나 변환 작업을 여러 개 함께 돌려도 메모리가 넉넉해요.
- RTX 3090 24GB시간당 230원
변환한 회의록을 같은 서버에서 LLM으로 요약하는 작업까지 이어서 할 수 있어요.
- RTX 3060 Ti 8GB준비 중
large-v3를 float16으로 한 파일씩 변환하는 정도는 대체로 충분해요.
내 모델에 필요한 메모리는 LLM VRAM 계산기로 확인할 수 있어요.
이런 작업에 맞아요
Whisper는 OpenAI가 공개한 음성 인식 모델이에요. 한국어를 지원하고, 모델을 내려받아 내 서버에서 직접 돌릴 수 있어요. 쌓여 있는 회의 녹음, 강의, 인터뷰를 텍스트나 SRT 자막으로 한꺼번에 바꿀 때 써요.
large 모델은 CPU에서 느려서, 수십 시간 분량이라면 GPU 서버에서 일괄 변환하는 편이 현실적이에요.
Whisper와 faster-whisper 비교
openai-whisper가 원본 구현이고, faster-whisper는 같은 모델을 더 빠르고 메모리를 덜 쓰게 다시 구현한 라이브러리예요. 대량 변환에는 faster-whisper를 많이 써요.
| 항목 | openai-whisper | faster-whisper |
|---|---|---|
| 설치 | pip install openai-whisper | pip install faster-whisper |
| 오디오 읽기 | 시스템에 ffmpeg가 설치돼 있어야 해요 | PyAV에 든 FFmpeg로 읽어서 따로 설치하지 않아도 돼요 |
| 정밀도 선택 | FP16, FP32 | float16, int8_float16, int8 등 |
| 무음 구간 거르기 | 기본 기능에는 없어요 | vad_filter=True로 켜요 |
large-v3를 float16으로 한 파일씩 변환하면 8GB GPU로도 돌아가요. 배치 처리를 켜거나 작업을 여러 개 동시에 돌리면 그만큼 메모리가 더 필요해요.
설치와 기본 예시
볼륨이 /mnt/data에 연결돼 있다고 가정해요. 모델은 처음 실행할 때 Hugging Face에서 내려받으니, HF_HOME을 볼륨에 두면 다음 서버에서 다시 받지 않아도 돼요.
python3 -m venv ~/stt-env
source ~/stt-env/bin/activate
pip install faster-whisper
export HF_HOME=/mnt/data/hf-cachefrom faster_whisper import WhisperModel
model = WhisperModel("large-v3", device="cuda", compute_type="float16")
segments, info = model.transcribe("meeting.m4a", language="ko", vad_filter=True)
for segment in segments:
print(f"[{segment.start:7.1f}s -> {segment.end:7.1f}s] {segment.text.strip()}")language="ko": 언어 자동 감지를 건너뛰어요. 녹음 앞부분의 음악이나 영어 때문에 언어를 잘못 감지하는 일을 막아요.vad_filter=True: 무음 구간을 걸러서, 긴 무음에서 같은 문장이 반복되는 오류를 줄여요.compute_type="float16": 메모리를 더 아끼려면int8_float16을 써 보세요.initial_prompt: 회사 이름, 제품명, 전문 용어가 든 문장을 넣으면 표기를 맞추는 데 도움이 될 수 있어요.
libcudnn 파일을 찾지 못한다는 오류가 나면 faster-whisper 저장소의 GPU 요구 사항을 확인하세요. 필요한 cuBLAS와 cuDNN 버전이 faster-whisper 버전마다 달라요.
폴더 전체를 한 번에 변환하기
아래 스크립트는 모델을 한 번만 불러온 뒤 /mnt/data/audio의 음성 파일마다 같은 이름의 텍스트 파일과 SRT 자막을 만들어요.
from pathlib import Path
from faster_whisper import WhisperModel
INPUT_DIR = Path("/mnt/data/audio")
OUTPUT_DIR = Path("/mnt/data/transcripts")
EXTENSIONS = {".m4a", ".mp3", ".wav", ".mp4", ".webm"}
def srt_time(seconds: float) -> str:
ms = int(round(seconds * 1000))
h, ms = divmod(ms, 3_600_000)
m, ms = divmod(ms, 60_000)
s, ms = divmod(ms, 1000)
return f"{h:02d}:{m:02d}:{s:02d},{ms:03d}"
model = WhisperModel("large-v3", device="cuda", compute_type="float16")
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
for audio in sorted(INPUT_DIR.iterdir()):
if audio.suffix.lower() not in EXTENSIONS:
continue
txt_path = OUTPUT_DIR / f"{audio.stem}.txt"
if txt_path.exists():
continue # 이미 변환한 파일은 건너뛰어요
segments, info = model.transcribe(str(audio), language="ko", vad_filter=True)
lines, blocks = [], []
for i, seg in enumerate(segments, start=1):
text = seg.text.strip()
lines.append(text)
blocks.append(f"{i}\n{srt_time(seg.start)} --> {srt_time(seg.end)}\n{text}\n")
(OUTPUT_DIR / f"{audio.stem}.srt").write_text("\n".join(blocks), encoding="utf-8")
txt_path.write_text("\n".join(lines), encoding="utf-8")
print(f"{audio.name}: {info.duration / 60:.1f}분 변환 완료")faster-whisper 1.1 이후에는 한 파일 안의 구간을 묶어 처리하는 BatchedInferencePipeline도 있어요. 긴 파일이 더 빨리 끝나지만 메모리를 더 쓰니, 기본 방식으로 결과를 확인한 뒤 바꿔 보세요.
ffmpeg가 필요한 경우
faster-whisper는 m4a, mp3, wav 같은 흔한 형식을 시스템 ffmpeg 없이 읽어요. 영상에서 오디오만 뽑거나, 읽히지 않는 형식을 바꿀 때 ffmpeg를 쓰세요.
sudo apt install -y ffmpeg
ffmpeg -i lecture.mp4 -vn -ac 1 -ar 16000 lecture.wav녹음 파일과 개인정보
회의와 상담 녹음에는 이름, 연락처, 내부 정보가 담기기 쉬워요. Whisper를 직접 돌리면 음성을 외부 음성 인식 API로 보내지 않고 내 서버 안에서 처리해요. Shelf의 GPU 서버와 볼륨은 국내 시설에 있어서 음성 파일과 결과를 해외로 옮기지 않아도 돼요.
대신 접근 관리는 직접 해야 해요. SSH 키와 권한을 관리하고, 변환이 끝난 원본 음성은 보관 기간이 지나면 지우세요. 법령이나 사내 보안 기준을 충족하는지는 서버 위치만으로 정해지지 않으니 조직 기준으로 따로 확인하세요.
서버 생성부터 삭제까지 작업 흐름
서버를 생성해요
분량에 맞는 GPU를 고르고, 음성 파일을 둘 볼륨을 연결해요.
음성 파일을 올려요
내 PC에서
rsync -avP ./audio/ <사용자>@<서버 주소>:/mnt/data/audio/로 볼륨에 올리고, SSH로 접속해요.tmux 안에서 일괄 변환을 실행해요
SSH 연결이 끊겨도 변환이 계속되도록
tmux에서 스크립트를 실행하고, 로그는 볼륨에 남겨요.결과를 내려받아요
/mnt/data/transcripts의 텍스트와 SRT 파일을 내려받아요. 요약이 필요하면 LLM API 서버로 이어서 처리하세요.서버를 삭제해요
중지만 하면 GPU가 할당된 채로 같은 요금이 나가니, 결과를 받았다면 삭제하세요. 더 필요 없는 원본 음성은 볼륨에서도 지우세요.
tmux new -s stt
source ~/stt-env/bin/activate
export HF_HOME=/mnt/data/hf-cache
mkdir -p /mnt/data/transcripts
python transcribe_folder.py 2>&1 | tee /mnt/data/transcripts/run.logShelf에서는
- 음성 파일과 결과는 영구 볼륨에 두세요. 서버를 삭제해도 남고, 다른 GPU 서버에 연결해 다시 올리지 않고 쓸 수 있어요. 볼륨은 따로 저장 요금이 있어요.
- 볼륨은 백업 서비스가 아니에요. 중요한 회의록은 다른 곳에도 보관하세요.
- 이용 요금은 서버를 생성한 시점부터 1시간 단위로 계산돼요. GPU별 요금은 요금 안내에서 볼 수 있어요.
자주 묻는 질문
Whisper의 한국어 인식은 얼마나 정확한가요?
녹음 품질, 말하는 속도, 전문 용어에 따라 크게 달라요. 잡음이 많거나 여러 사람이 동시에 말하는 구간에서는 오류가 늘어나니, 공식 회의록이나 자막으로 쓰기 전에 사람이 검토하세요.
누가 말했는지도 구분할 수 있나요?
Whisper에는 화자 분리 기능이 없어요. 화자별 회의록이 필요하면 pyannote 같은 화자 분리 도구의 결과를 Whisper의 구간 시간과 합쳐야 해요.
