OpenAI Whisper 모델 파인튜닝 완벽 가이드: 한국어 음성인식 정확도 높이기

Whisper 모델이란?

OpenAI Whisper는 2022년 9월 공개된 범용 음성인식(ASR) 모델입니다. 68만 시간의 다국어 데이터로 사전 학습되어 뛰어난 성능을 자랑하지만, 특정 도메인이나 억양에 대해서는 파인튜닝이 필요할 수 있습니다.

Whisper의 주요 특징

특징 설명
다국어 지원 99개 언어 지원 (한국어 포함)
다양한 크기 tiny, base, small, medium, large (39M~1.5B 파라미터)
멀티태스크 음성인식, 번역, 언어 감지, VAD 동시 수행
강건성 배경 소음, 억양 변화에 강함

핵심 포인트: Whisper는 사전 학습된 범용 모델이지만, 특정 산업 용어(의료, 법률)나 지역 방언에 대해서는 파인튜닝으로 정확도를 크게 개선할 수 있습니다.

왜 파인튜닝이 필요한가?

사전 학습된 Whisper도 우수하지만, 다음과 같은 경우 파인튜닝이 필수입니다:

  • 도메인 특화 용어: 의료 진단명, 법률 용어, 기술 전문 용어
  • 지역 방언/억양: 사투리, 특정 연령층의 발음 패턴
  • 노이즈 환경: 공장, 콜센터 등 특수 환경 음성
  • 짧은 발화: 명령어 인식, 챗봇 응답 등

파인튜닝 전후 성능 비교 예시

데이터셋 베이스 Whisper CER 파인튜닝 후 CER 개선율
일반 한국어 8.2% 6.1% 25.6%
의료 상담 15.7% 9.3% 40.8%
사투리(경상도) 22.4% 11.8% 47.3%

CER = Character Error Rate (문자 오류율, 낮을수록 좋음)

파인튜닝 환경 준비

필수 라이브러리 설치

pip install torch torchvision torchaudio
pip install transformers datasets accelerate evaluate jiwer
pip install tensorboard

GPU 메모리 요구사항

모델 크기 파라미터 최소 VRAM 권장 배치 크기
tiny 39M 4GB 16
base 74M 6GB 12
small 244M 10GB 8
medium 769M 16GB 4
large-v3 1.5B 24GB+ 2

데이터 준비

데이터셋 포맷

Whisper 파인튜닝에는 오디오 파일 + 텍스트 전사(transcript) 쌍이 필요합니다.

from datasets import Dataset, Audio
import pandas as pd

# 데이터 구조 예시
data = {
    'audio': ['audio/sample1.wav', 'audio/sample2.wav'],
    'sentence': ['안녕하세요 반갑습니다', '오늘 날씨가 좋네요']
}

df = pd.DataFrame(data)
dataset = Dataset.from_pandas(df)

# 오디오 컬럼 타입 지정
dataset = dataset.cast_column('audio', Audio(sampling_rate=16000))

공개 한국어 데이터셋

  • KsponSpeech: AI Hub 한국어 대화 음성 (969시간)
  • Zeroth-Korean: 51.6시간 읽기 음성
  • AIHub 방송 콘텐츠: 뉴스, 드라마 (1000시간+)
  • 자체 수집 데이터: 최소 5~10시간 권장

실무 팁: 데이터가 적다면 Data Augmentation(속도 변화, 노이즈 추가, SpecAugment) 적용으로 다양성을 확보하세요.

파인튜닝 코드 예시

1. 모델 및 프로세서 로드

from transformers import WhisperProcessor, WhisperForConditionalGeneration

model_name = "openai/whisper-small"
processor = WhisperProcessor.from_pretrained(model_name, language="Korean", task="transcribe")
model = WhisperForConditionalGeneration.from_pretrained(model_name)

# 한국어로 언어 토큰 강제 설정
model.config.forced_decoder_ids = processor.get_decoder_prompt_ids(language="ko", task="transcribe")
model.config.suppress_tokens = []

2. 데이터 전처리

def prepare_dataset(batch):
    # 오디오를 16kHz로 리샘플링
    audio = batch["audio"]

    # 입력 피처 추출 (log-mel spectrogram)
    batch["input_features"] = processor.feature_extractor(
        audio["array"], 
        sampling_rate=audio["sampling_rate"]
    ).input_features[0]

    # 텍스트 토큰화
    batch["labels"] = processor.tokenizer(batch["sentence"]).input_ids

    return batch

# 데이터셋 전처리 적용
dataset = dataset.map(prepare_dataset, remove_columns=dataset.column_names)

3. 학습 설정 및 실행

from transformers import Seq2SeqTrainingArguments, Seq2SeqTrainer
import evaluate

# CER 메트릭 정의
cer_metric = evaluate.load("cer")

def compute_metrics(pred):
    pred_ids = pred.predictions
    label_ids = pred.label_ids

    # -100을 패딩으로 처리
    label_ids[label_ids == -100] = processor.tokenizer.pad_token_id

    pred_str = processor.tokenizer.batch_decode(pred_ids, skip_special_tokens=True)
    label_str = processor.tokenizer.batch_decode(label_ids, skip_special_tokens=True)

    cer = cer_metric.compute(predictions=pred_str, references=label_str)
    return {"cer": cer}

# 학습 인자 설정
training_args = Seq2SeqTrainingArguments(
    output_dir="./whisper-ko-finetuned",
    per_device_train_batch_size=8,
    gradient_accumulation_steps=2,  # 실질 배치 크기 = 16
    learning_rate=1e-5,
    warmup_steps=500,
    num_train_epochs=3,
    evaluation_strategy="steps",
    eval_steps=500,
    save_steps=1000,
    logging_steps=100,
    fp16=True,  # Mixed Precision 학습
    predict_with_generate=True,
    generation_max_length=225,
    report_to=["tensorboard"],
    load_best_model_at_end=True,
    metric_for_best_model="cer",
    greater_is_better=False,
)

# Trainer 초기화
trainer = Seq2SeqTrainer(
    model=model,
    args=training_args,
    train_dataset=dataset["train"],
    eval_dataset=dataset["test"],
    tokenizer=processor.feature_extractor,
    compute_metrics=compute_metrics,
)

# 학습 시작
trainer.train()

4. 모델 저장 및 추론

# 모델 저장
model.save_pretrained("./whisper-ko-final")
processor.save_pretrained("./whisper-ko-final")

# 추론 예시
import torch
from transformers import pipeline

pipe = pipeline(
    "automatic-speech-recognition",
    model="./whisper-ko-final",
    device=0 if torch.cuda.is_available() else -1
)

result = pipe("test_audio.wav")
print(result["text"])

파인튜닝 최적화 팁

LoRA를 활용한 효율적 학습

GPU 메모리가 부족하다면 PEFT(Parameter-Efficient Fine-Tuning) 기법인 LoRA를 사용하세요:

from peft import LoraConfig, get_peft_model

lora_config = LoraConfig(
    r=32,  # LoRA rank
    lora_alpha=64,
    target_modules=["q_proj", "v_proj"],  # Attention 레이어에만 적용
    lora_dropout=0.05,
    bias="none",
)

model = get_peft_model(model, lora_config)
model.print_trainable_parameters()
# 출력: trainable params: 3.4M || all params: 247M || trainable%: 1.38%

하이퍼파라미터 튜닝 가이드

파라미터 일반 데이터 소량 데이터 노이즈 많음
Learning Rate 1e-5 5e-6 1e-5
Batch Size 16 8 32
Epochs 3 5-10 3
Warmup Steps 500 200 1000
Weight Decay 0.01 0.001 0.01

실무 활용 사례

1. 콜센터 상담 내용 전사

  • 문제: 고객 상담 내용의 전문 용어(상품명, 약관) 인식 오류
  • 해결: 자체 수집한 10시간 상담 데이터로 파인튜닝
  • 결과: CER 18.3% → 9.1% (50% 개선)

2. 의료 진료 기록 자동화

  • 문제: 해부학 용어, 약품명 오인식
  • 해결: 의료 전사 데이터 + 용어 사전 기반 Data Augmentation
  • 결과: 전문 용어 정확도 92% 달성

3. 유튜브 자막 생성

  • 문제: 크리에이터 특유의 말투, 신조어 미인식
  • 해결: 채널별 10개 영상(약 2시간)으로 개인화 모델 학습
  • 결과: 수동 수정 시간 70% 단축

마무리

Whisper 모델 파인튜닝의 핵심 포인트를 정리하면:

  • 모델 선택: GPU 메모리에 따라 small~medium 추천 (LoRA 사용 시 large도 가능)
  • 데이터 품질: 전사 정확도가 98% 이상이어야 효과적 (잡음 데이터는 역효과)
  • 최소 데이터량: 도메인 특화는 5시간, 방언은 10시간 이상
  • 학습률: 1e-5에서 시작해 plateau 발생 시 절반으로 감소
  • 평가 지표: CER(문자 오류율) 또는 WER(단어 오류율) 추적

Whisper 파인튜닝은 범용 모델의 강점을 유지하면서도 특정 도메인에서 상용 ASR 수준의 성능을 달성할 수 있는 강력한 방법입니다. 초기 데이터 준비에 시간이 걸리더라도, 장기적으로는 인력 비용 절감서비스 품질 향상이라는 두 마리 토끼를 모두 잡을 수 있습니다.

이 글이 도움이 되셨나요? ☕

Buy me a coffee

코멘트

답글 남기기

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

TODAY 106 | TOTAL 106