Google Colab과 faster-whisper로 MP3에서 스크립트를 추출하는 방법을 단계별로 설명합니다. 모델 선택, VAD 설정, SRT/VTT/DOCX 내보내기까지 실무 팁을 담았습니다.
🎧 Whisper 기반 클라우드 전사(Colab)
이 노트북은 Google Colab에서 한국어 음성을 Whisper로 전사하여 TXT / SRT / VTT / CSV 형식으로 내보냅니다.
사용 방법
- 상단 메뉴에서 런타임 → 모두 실행을 누르세요.
- 중간에 파일 업로드 셀에서 MP3 파일을 선택합니다.
- 완료 후 하단 셀에서 결과 파일을 다운로드하거나 Google Drive에 저장하세요.
> 아래 노트북은 Whisper(faster-whisper)를 사용하며, GPU가 있으면 자동으로 감지하여 속도를 높입니다. 언어는 기본 ‘ko’로 설정되어 한국어 인식에 최적화되어 있어요.
# ====== 설치 & 환경 점검 ======
from pathlib import Path
# 표준 라이브러리 임포트 (파이썬/OS/프로세스/플랫폼 정보)
import sys, subprocess, os, platform
# pip install 를 파이썬에서 호출하는 헬퍼 함수 (-q 는 로그 최소화)
def pipi(pkg):
subprocess.run([sys.executable, '-m', 'pip', 'install', '-q', pkg], check=True)
# 현재 파이썬/플랫폼 버전 출력 (디버깅용)
print('Python', sys.version)
print('Platform', platform.platform())
# PyTorch 로드 실패시 설치 후 임포트.
# CUDA(GPU) 사용 가능 여부 출력
try:
import torch
except Exception:
pipi('torch')
import torch
print('Torch CUDA available:', torch.cuda.is_available())
# 전사용 패키지 설치
# * `faster-whisper`: Whisper의 빠른 추론 구현
# * `pydub`: 오디오 유틸(이번 노트북에서는 주로 ffmpeg 체크용)
# * `python-docx`: Word 문서 출력
# * `pandas`: 표 형태 데이터 처리
# * `tqdm`: 진행바(필수는 아님)
pipi('faster-whisper==1.0.3')
pipi('pydub')
pipi('python-docx')
pipi('pandas')
pipi('tqdm')
# ffmpeg 설치(Colab에는 보통 내장)
# ffmpeg 존재 여부 확인(오디오 디코딩에 필요). Colab엔 대개 기본 내장.
try:
subprocess.run(['ffmpeg', '-version'], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print('ffmpeg OK')
except Exception:
print('ffmpeg 설치 필요. Colab에서는 보통 기본 제공됩니다.')
Python 3.12.11 (main, Jun 4 2025, 08:56:18) [GCC 11.4.0]
Platform Linux-6.1.123+-x86_64-with-glibc2.35
Torch CUDA available: False
ffmpeg OK
# ====== 파일 업로드 ======
from google.colab import files
# Colab의 파일 업로더 UI 표시.
# 1개 이상 업로드했는지 검증.
up = files.upload()
assert len(up) > 0, '오디오 파일을 업로드하세요.'
# 업로드된 파일명 추출(첫 번째 파일 사용).
# 확인 메시지 출력.
audio_filename = list(up.keys())[0]
print('업로드 완료:', audio_filename)
# ====== 설정 ======
# `Path` 임포트(v2에서 추가).
# Whisper 관련 기본 설정:
# * `model_size`: 모델 크기(정확도↔속도/메모리 트레이드오프)
# * `language`: `ko`로 고정(자동감지는 `None`)
# * `beam_size`: 탐색 폭(클수록 정확도↑/속도↓)
# * `vad_filter`: 무성 구간 제거 필터
# * `word_timestamps`: 단어 수준 타임스탬프 포함
model_size = 'large-v3' # 'small', 'medium', 'large-v3' 등 선택 가능
language = 'ko' # 한국어 고정; 자동 감지를 원하면 None 으로 변경
beam_size = 5
vad_filter = True # VAD(음성활동감지)로 잡음 구간 억제
word_timestamps = True # 단어 단위 타임스탬프
# 출력 파일명 접두어 생성(원본 파일명 + `_whisper`).
from datetime import datetime
stem = Path(audio_filename).stem
out_prefix = f"{stem}_whisper"
# ====== 전사 실행 ======
# v2에서 `import torch`를 선행(안정성).
# 필요한 라이브러리 로드.
from faster_whisper import WhisperModel
import pandas as pd
import torch
from tqdm import tqdm
# GPU 있으면 `cuda`+`float16`, 없으면 `cpu`+`int8`(메모리 절약)로 자동 설정.
compute_type = 'float16' if (hasattr(torch, 'cuda') and torch.cuda.is_available()) else 'int8'
device = 'cuda' if torch.cuda.is_available() else 'cpu'
print('Device:', device, 'Compute type:', compute_type)
# Whisper 모델 로드
model = WhisperModel(model_size, device=device, compute_type=compute_type)
# 오디오 전사 수행.
# 감지된 언어/확률 출력(언어를 `ko`로 고정했어도 메타 확인용).
segments, info = model.transcribe(
audio_filename,
language=language,
beam_size=beam_size,
vad_filter=vad_filter,
word_timestamps=word_timestamps,
)
print('감지 언어:', info.language, '확신도:', round(info.language_probability, 3))
# 결과 저장용 구조 초기화(SRT/VTT 헤더 포함).
rows = []
srt_lines = []
vtt_lines = ['WEBVTT\n']
# 초 단위를 **SRT 시각 포맷**(HH\:MM\:SS,mmm)으로 변환.
def srt_ts(t):
h = int(t//3600); m = int((t%3600)//60); s = t - h*3600 - m*60
ms = int(round((s - int(s)) * 1000))
return f"{h:02d}:{m:02d}:{int(s):02d},{ms:03d}"
# 초 단위를 **VTT 시각 포맷**(HH\:MM\:SS.mmm)으로 변환.
def vtt_ts(t):
h = int(t//3600); m = int((t%3600)//60); s = t - h*3600 - m*60
ms = int(round((s - int(s)) * 1000))
return f"{h:02d}:{m:02d}:{int(s):02d}.{ms:03d}"
# 각 세그먼트(문장 단위)에 대해 텍스트/시작/끝 시간 추출.
# 판다스 테이블용 행 구성.
idx = 1
for seg in segments:
text = (seg.text or '').strip()
start = float(seg.start)
end = float(seg.end)
rows.append({
'index': idx,
'start': start,
'end': end,
'start_srt': srt_ts(start),
'end_srt': srt_ts(end),
'text': text,
})
# SRT 블록(번호/타임스탬프/문장/빈줄) 작성
srt_lines.append(str(idx))
srt_lines.append(f"{srt_ts(start)} --> {srt_ts(end)}")
srt_lines.append(text if text else '...')
srt_lines.append('')
# VTT 라인 추가 후 인덱스 증가.
vtt_lines.append(f"{vtt_ts(start)} --> {vtt_ts(end)}")
vtt_lines.append(text if text else '...')
vtt_lines.append('')
idx += 1
# 결과물 파일 경로 설정.
df = pd.DataFrame(rows)
txt_path = f"{out_prefix}.txt"
srt_path = f"{out_prefix}.srt"
vtt_path = f"{out_prefix}.vtt"
csv_path = f"{out_prefix}.csv"
# TXT/SRT/VTT/CSV 파일 저장.
# CSV는 Excel 호환을 위해 `utf-8-sig`.
with open(txt_path, 'w', encoding='utf-8') as f:
f.write('\n'.join(df['text']))
with open(srt_path, 'w', encoding='utf-8') as f:
f.write('\n'.join(srt_lines))
with open(vtt_path, 'w', encoding='utf-8') as f:
f.write('\n'.join(vtt_lines))
df.to_csv(csv_path, index=False, encoding='utf-8-sig')
# 생성 결과 요약 출력.
print('생성 파일:', txt_path, srt_path, vtt_path, csv_path)
# ====== (선택) Word 파일(.docx)로 내보내기 ======
# Word 문서 시작/제목/파일명/빈 줄.
from docx import Document
doc = Document()
doc.add_heading('전사 결과', level=1)
doc.add_paragraph(f'파일명: {audio_filename}')
doc.add_paragraph('')
# 각 세그먼트를 **\[시작\~끝] 텍스트** 형식으로 문단 추가(시간 범위는 볼드).
for _, r in df.iterrows():
p = doc.add_paragraph()
p.add_run(f"[{r['start_srt']} ~ {r['end_srt']}] ").bold = True
p.add_run(r['text'])
# docx 저장 및 경로 출력.
docx_path = f"{out_prefix}.docx"
doc.save(docx_path)
print('생성 파일:', docx_path)
생성 파일:XXXX_whisper.docx
# ====== (선택) Google Drive 저장 ======
# 드라이브 마운트(처음 1번은 권한 승인 필요).
from google.colab import drive
drive.mount('/content/drive')
# 저장 폴더 생성(없으면 자동 생성).
import shutil, os
target_dir = '/content/drive/MyDrive/whisper_outputs'
os.makedirs(target_dir, exist_ok=True)
# 생성된 파일들을 드라이브 폴더로 복사.
for p in [txt_path, srt_path, vtt_path, csv_path, docx_path]:
if os.path.exists(p):
shutil.copy(p, target_dir)
print('Drive 저장 위치:', target_dir)
Mounted at /content/drive
Drive 저장 위치: /content/drive/MyDrive/whisper_outputs
# ====== 결과 다운로드 링크 ======
# Colab 파일 다운로드 창을 띄워, 결과물을 로컬로 저장.
from google.colab import files
for p in [txt_path, srt_path, vtt_path, csv_path, docx_path]:
if os.path.exists(p):
files.download(p)
자주 바꾸는 옵션 요약
정확도 vs 속도/메모리
`model_size`: `'large-v3'`(정확도↑ 메모리↑) → 느리면 `'medium'`/`'small'`.
`compute_type`: 자동(`float16`/`int8`); CPU라 느리면 모델 축소 권장.
언어
`language = 'ko'` → 다국어 혼합이면 `None`으로 자동감지.
세부 품질
`beam_size = 5`(정확도↑/속도↓), `vad_filter = True`(잡음 억제), `word_timestamps = True`(단어 타임스탬프).
'프로그래밍 Programming' 카테고리의 다른 글
pgAdmin4에서 GCP PostgreSQL 연결 시 Connection refused 오류 해결 방법 (0) | 2025.05.30 |
---|---|
구글 클라우드 VM에 설치한 PostgreSQL, pgAdmin4로 쉽게 원격 연결하는 방법 (0) | 2025.05.30 |
원격 데스크톱 연결 프로토콜 오류 (코드: 0x112f) 때문에 원격 세션이 끊어집니다 (0) | 2025.05.30 |
FastAPI + SQLite/PostgreSQL 조합에 있어 PostgreSQL 설치 및 외부접속 허용 (0) | 2025.05.29 |
Linux 초보자를 위한 필수 개념: apt update와 apt upgrade 차이점 완벽 정리 (0) | 2025.05.29 |