KsponSpeech + Whisper Fine-tuning

TL;DR: 62만개 KsponSpeech 데이터를 H100 GPU로 전처리하고, Whisper Large-v3를 Fine-tuning해서 한국어 STT 모델을 성공적으로 구축했습니다. 27분 학습으로 “빠짝하고” 같은 한국어를 정확히 인식하는 모델 완성! 🚀

🎯 프로젝트 개요

목표: 처음부터 끝까지 한국어 음성인식(STT) 모델 구축
데이터: KsponSpeech 데이터셋 (한국어 음성 + 전사 텍스트)
방법: Whisper Large-v3 모델을 한국어로 Fine-tuning
하드웨어: NVIDIA H100 80GB HBM3

📊 최종 성과

항목결과
전처리 데이터621,681개 샘플 (965시간)
학습 시간27분 54초 (500 steps)
최종 Loss0.177
테스트 결과“빠짝하고” → “두 달 빠짝하고 b n” ✅
GPU 활용률4.779 samples/second

🛠️ 전체 플로우

1단계: 데이터 준비 및 전처리

# KsponSpeech 5개 ZIP 파일 압축 해제
unzip "KsponSpeech_*.zip"

# 총 622,545개 파일 확인
find . -name "*.pcm" | wc -l  # 오디오 파일
find . -name "*.txt" | wc -l  # 전사 텍스트

주요 도전과제들:

  • 인코딩 문제: 텍스트가 EUC-KR로 인코딩되어 깨져보임
  • 파일 형식: PCM raw audio → WAV 변환 필요
  • 대용량 처리: 62만개 파일을 메모리 효율적으로 처리

해결 방법:

# 다양한 인코딩 시도로 안전한 텍스트 로딩
encodings = ['euc-kr', 'cp949', 'utf-8', 'latin-1']
for encoding in encodings:
    try:
        with open(txt_path, 'r', encoding=encoding) as f:
            text = f.read().strip()
        if any('\u3131' <= char <= '\uD79D' for char in text):  # 한글 체크
            return clean_text(text)
    except:
        continue

2단계: 대용량 데이터 전처리

kspon_preprocess.py 핵심 기능:

  • ✅ PCM → WAV 변환 (16kHz, 16-bit)
  • ✅ EUC-KR → UTF-8 텍스트 정제
  • ✅ 노이즈 태그 제거 (noise), *침묵*
  • ✅ 길이 필터링 (0.5초~30초)
  • ✅ Train/Validation/Test 분할 (8:1:1)

처리 결과:

총 샘플 수: 621,681개
총 시간: 964.7시간
Train: 497,344개 (770시간)
Validation: 62,168개 (97시간)  
Test: 62,169개 (97시간)

3단계: Whisper Fine-tuning의 도전

첫 번째 시행착오들:

  1. 메모리 부족: 50만개 데이터 한번에 처리하다가 Killed
  2. 라이브러리 충돌: msgpack 버전 호환성 문제
  3. 전처리 에러: 멀티프로세싱에서 오디오 디코딩 실패

해결 과정:

# 샘플 데이터로 축소 (50만개 → 1천개)
train_sample = random.sample(train_data, 1000)
validation_sample = random.sample(val_data, 200)
test_sample = random.sample(test_data, 200)

4단계: 성공한 Fine-tuning 설정

whisper_final_fixed.py 핵심 설정:

training_args = TrainingArguments(
    output_dir="./whisper-korean-fixed",
    per_device_train_batch_size=4,        # 메모리 절약
    per_device_eval_batch_size=2,
    gradient_accumulation_steps=4,        # 효과적 배치 크기 유지
    learning_rate=1e-5,
    max_steps=500,                        # 빠른 테스트
    bf16=True,                           # H100 최적화
    dataloader_num_workers=1,            # 안정성
    eval_strategy="no",                  # 학습만 집중
)

학습 과정:

Step 100: Loss 0.45 → Step 300: Loss 0.12 → Step 500: Loss 0.018
최종 Loss: 0.177 (매우 좋은 수렴!)

5단계: 모델 테스트 및 검증

test_whisper.py로 성능 확인:

# 테스트 결과
Expected: "빠짝 하고"
Got:      "두 달 빠짝하고 b n"

# 분석
✅ 핵심 단어 "빠짝하고" 정확 인식
❌ 앞뒤로 약간의 hallucination
→ 1,000개 샘플 치고는 훌륭한 성능!

💡 핵심 노하우 및 팁

1. 메모리 최적화 전략

# 🚫 이렇게 하지 마세요
datasets = dataset.map(preprocess, num_proc=4)  # 메모리 폭발

# ✅ 이렇게 하세요  
datasets = dataset.map(preprocess, num_proc=1)   # 안전한 단일 프로세스
datasets = datasets.filter(lambda x: x is not None)  # 에러 데이터 제거

2. 인코딩 문제 해결

# 여러 인코딩을 순차적으로 시도
encodings = ['euc-kr', 'cp949', 'utf-8', 'latin-1']
# 최후의 수단: errors='ignore'로 안전하게 처리

3. H100 GPU 활용 최적화

# BF16 혼합정밀도로 메모리 절약 + 성능 향상
bf16=True
gradient_checkpointing=True
per_device_train_batch_size=4  # 메모리에 맞게 조정

4. 데이터 크기 조절 전략

Phase 1: 전체 데이터 전처리 (62만개)
Phase 2: 샘플링으로 학습 (1천개)  
Phase 3: 점진적 확장 (1만개 → 10만개 → 전체)

🔧 재현 가능한 코드 구조

project/
├── kspon_preprocess.py      # 데이터 전처리 (1시간 16분)
├── whisper_final_fixed.py   # 모델 학습 (27분)
├── test_whisper.py          # 성능 테스트
├── kspon_processed/         # 전처리된 데이터
│   ├── train.json          # 497,344개
│   ├── validation.json     # 62,168개  
│   └── test.json          # 62,169개
└── whisper-korean-fixed/   # 학습된 모델 (6GB)

📈 성능 분석 및 개선 방향

현재 성능

  • 정확도: 핵심 단어 인식 성공
  • 속도: H100에서 빠른 추론
  • 한계: 작은 데이터로 인한 hallucination

개선 방안

  1. 데이터 확장: 1천개 → 10만개 → 전체 50만개
  2. 학습 시간 증가: 500 steps → 5,000 steps
  3. 하이퍼파라미터 튜닝: Learning rate, Batch size 최적화
  4. 후처리: Beam search, Length penalty 조정

🎉 결론

62만개 한국어 음성 데이터를 H100 GPU로 효율적으로 처리하고, 27분만에 실용적인 한국어 STT 모델을 구축했습니다.

핵심 성공 요인:

  • 🔧 체계적인 전처리: 인코딩, 형식 변환, 정제
  • 🧠 Transfer Learning: Whisper 사전학습 모델 활용
  • 하드웨어 최적화: H100 + BF16 + 메모리 관리
  • 🎯 점진적 접근: 작은 샘플부터 시작해서 안정성 확보

이 프로젝트를 통해 대용량 음성 데이터 처리부터 최신 Transformer 모델 Fine-tuning까지 실제 MLOps 파이프라인을 구축할 수 있었습니다.

📚 참고 자료


코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다