📊

AI 모델 평가 입문 — 내 모델이 잘하는지 어떻게 아나?

정확도, BLEU, CER, SDR — 태스크마다 다른 평가 지표와 \"왜 이걸 쓰는지\"

왜 평가가 필요한가

파인튜닝을 했다. trainer.train()이 끝났다. 근데 내 모델이 진짜 잘하는지 어떻게 아나?

"돌려보니까 괜찮아 보이는데?"는 평가가 아니다. 숫자로 측정해야 한다.

핵심 개념: 정답이 있는 테스트 데이터

훈련 데이터: 모델이 학습하는 데 사용 (시험 공부 자료)
테스트 데이터: 모델을 평가하는 데 사용 (시험 문제)

시험 공부 자료(훈련 데이터)로 시험을 보면 당연히 100점이다. 의미 없다. 모델이 처음 보는 데이터로 평가해야 진짜 실력을 알 수 있다.

IMDB 데이터셋이 train 25,000개 + test 25,000개로 나뉜 이유가 이것이다.

from datasets import load_dataset
dataset = load_dataset("imdb")
# dataset["train"] → 25,000개 (훈련용, 모델이 봄)
# dataset["test"]  → 25,000개 (평가용, 모델이 안 봄)

태스크별 평가 지표

1. 분류 (감정 분석, 이미지 분류 등) — 정확도(Accuracy)

가장 직관적. 맞은 개수 / 전체 개수.

from evaluate import load

accuracy = load("accuracy")

predictions = [1, 0, 1, 1, 0]  # 모델 예측
references  = [1, 0, 0, 1, 0]  # 정답

result = accuracy.compute(predictions=predictions, references=references)
print(result)
# → {'accuracy': 0.8}  (5개 중 4개 맞음 = 80%)

Precision / Recall / F1 — 정확도만으로 부족할 때:

100개 중 긍정 95개, 부정 5개인 데이터에서 "전부 긍정"이라고 찍으면 정확도 95%다. 근데 부정을 하나도 못 찾았다. 이럴 때 F1이 필요.

f1 = load("f1")
result = f1.compute(predictions=predictions, references=references, average="binary")
print(result)  # → {'f1': 0.8}

지표 뭘 측정 공식
Accuracy 전체 중 맞은 비율 맞은 수 / 전체
Precision "긍정"이라고 한 것 중 진짜 긍정 TP / (TP+FP)
Recall 진짜 긍정 중 찾아낸 비율 TP / (TP+FN)
F1 Precision과 Recall의 조화 평균 2×P×R / (P+R)

2. 텍스트 생성 (번역, 요약 등) — BLEU / ROUGE

생성된 텍스트가 정답과 얼마나 겹치는지 측정.

bleu = load("bleu")

predictions = ["The cat sat on the mat"]
references  = [["The cat is on the mat"]]  # 정답 (여러 개 가능)

result = bleu.compute(predictions=predictions, references=references)
print(f"BLEU: {result['bleu']:.2f}")
# → BLEU: 0.61  (61% 겹침)

지표 용도 측정 방식
BLEU 번역 n-gram 겹침 (1~4단어 조합이 얼마나 같은지)
ROUGE 요약 정답의 n-gram이 생성에 얼마나 포함되었는지
BERTScore 범용 BERT 임베딩으로 의미적 유사도 (단어 겹침이 아닌 의미)

BLEU 0.0 = 완전 다름, 1.0 = 완전 동일. 실전에서 0.3~0.5면 양호.

3. OCR — CER / WER

글자/단어 단위 오류율. 낮을수록 좋다.

cer = load("cer")

predictions = ["賃料は月額150,000円とする"]
references  = ["賃料は月額150,000円とする"]

result = cer.compute(predictions=predictions, references=references)
print(f"CER: {result:.2%}")
# → CER: 0.00% (완벽 일치)

# 오류가 있는 경우
predictions_bad = ["賃料は月額150,000円とすろ"]  # る → ろ
result_bad = cer.compute(predictions=predictions_bad, references=references)
print(f"CER: {result_bad:.2%}")
# → CER: 5.88% (17글자 중 1글자 틀림)

지표 단위 계산
CER (Character Error Rate) 글자 (삽입+삭제+대체) / 정답 글자수
WER (Word Error Rate) 단어 (삽입+삭제+대체) / 정답 단어수

CER 0% = 완벽. 실전에서 1~5%면 좋은 수준.

4. 음원 분리 — SDR

분리된 소리가 원본과 얼마나 가까운지. 높을수록 좋다.

# pip install mir_eval
import mir_eval
import numpy as np

reference = np.random.randn(44100)   # 원본 보컬 (1초)
estimated = reference + 0.1 * np.random.randn(44100)  # 분리된 보컬 (약간 노이즈)

sdr, sir, sar, _ = mir_eval.separation.bss_eval_sources(
    reference[np.newaxis, :], estimated[np.newaxis, :]
)
print(f"SDR: {sdr[0]:.1f} dB")
# → SDR: 20.0 dB (높을수록 좋음)

지표 뭘 측정 좋은 수준
SDR (Signal-to-Distortion Ratio) 전체 왜곡 10+ dB
SIR (Signal-to-Interference Ratio) 다른 소스 섞임 15+ dB
SAR (Signal-to-Artifacts Ratio) 인공적 잡음 10+ dB

5. 음성 인식 (STT) — WER

OCR의 WER과 동일. 인식된 텍스트와 정답 텍스트의 단어 오류율.

wer = load("wer")
result = wer.compute(
    predictions=["hello how are you"],
    references=["hello how old are you"]
)
print(f"WER: {result:.2%}")
# → WER: 20.00% (5단어 중 1단어 차이)

전체 지표 한눈에

태스크 지표 방향 코드
분류 Accuracy 높을수록 ↑ load("accuracy")
분류 F1 높을수록 ↑ load("f1")
번역 BLEU 높을수록 ↑ load("bleu")
요약 ROUGE 높을수록 ↑ load("rouge")
OCR CER 낮을수록 ↓ load("cer")
OCR WER 낮을수록 ↓ load("wer")
STT WER 낮을수록 ↓ load("wer")
음원 분리 SDR 높을수록 ↑ mir_eval
의미 유사도 BERTScore 높을수록 ↑ load("bertscore")

전부 pip install evaluate하면 load("지표명")으로 쓸 수 있다.

파인튜닝 + 평가 = 세트

# 감정 분석 파인튜닝에 평가 추가
from evaluate import load
import numpy as np

accuracy = load("accuracy")

def compute_metrics(eval_pred):
    predictions, labels = eval_pred
    predictions = np.argmax(predictions, axis=1)
    return accuracy.compute(predictions=predictions, references=labels)

trainer = Trainer(
    model=model,
    train_dataset=dataset["train"],
    eval_dataset=dataset["test"],     # ← 테스트 데이터
    compute_metrics=compute_metrics,   # ← 평가 함수
    args=TrainingArguments(
        output_dir="./results",
        eval_strategy="epoch",         # ← 매 에폭마다 평가
    )
)
trainer.train()
# 훈련 중 출력:
# Epoch 1: accuracy=0.82
# Epoch 2: accuracy=0.87
# Epoch 3: accuracy=0.89  ← 에폭마다 정확도가 올라가는 걸 볼 수 있다

compute_metrics를 Trainer에 넘기면 훈련 중에 자동으로 평가해준다. 에폭마다 "지금 내 모델이 몇 점인지" 숫자가 나온다.

평가 없이 파인튜닝하면?

과적합(overfitting)을 모른다. 훈련 데이터에서는 99%인데 실제 데이터에서는 50%일 수 있다. 시험 문제를 미리 봤으니 시험은 100점이지만, 실전에서는 못 푸는 것과 같다.

평가는 선택이 아니다. 파인튜닝의 필수 파트다.

핵심 개념

1

pip install evaluate — HuggingFace 평가 라이브러리 설치

2

metric = load(\"accuracy\") — 태스크에 맞는 지표 로드

3

metric.compute(predictions, references) — 예측과 정답 비교 → 숫자 1개

4

Trainer에 compute_metrics 추가 — 훈련 중 매 에폭마다 자동 평가

사용 사례

파인튜닝 품질 확인 — 에폭마다 정확도/CER/BLEU를 추적해서 과적합 방지 모델 비교 — 같은 테스트 데이터로 여러 모델의 점수를 비교 배포 판단 — \"CER 3% 이하면 프로덕션 투입\" 같은 기준 설정