[Metrics] Perplexity

Soeon Park·2025년 7월 5일
post-thumbnail

Perplexity(혼란도)란?

언어 모델의 예측 성능을 수치화하는 지표로, 모델이 주어진 문장을 얼마나 “잘 예측하는지”를 나타냄

  • 값이 낮을수록 모델이 문장을 더 잘 예측한다는 의미
  • 확률론적으로는 “평균 지수화된 음의 로그우도”로 정의되며,
  • 직관적으로는 “모델이 매 토큰마다 선택해야 할 후보지의 개수(분기수)”를 의미합니다.

1. 정의 및 수식

문장 W=w1,w2,,wNW = w_1, w_2, \dots, w_N에 대한 perplexity(PPL(W))perplexity ( \mathrm{PPL}(W) )는 다음과 같다:

PPL(W)=exp(1Ni=1NlogP(wiw<i))\mathrm{PPL}(W) = \exp\Bigl(-\frac{1}{N} \sum_{i=1}^{N} \log P(w_i \mid w_{<i})\Bigr)

이때,

  • (N)(N): 전체 토큰 수
  • (P(wiw<i))(P(w_i \mid w_{<i})): 언어 모델이 토큰 (wi)(w_i)를 앞선 문맥 (w<i)(w_{<i})로부터 예측한 확률
  • 음의 로그우도(Negative Log-Likelihood)를 평균 낸 후, 지수화(exp)한 형태

2. 수식 유도

1. Cross-Entropy

H(W)=1Ni=1NlogP(wiw<i)H(W) = -\frac{1}{N} \sum_{i=1}^{N} \log P(w_i \mid w_{<i})

2. Perplexity

PPL(W)=exp(H(W))=exp(1Ni=1NlogP(wiw<i))\mathrm{PPL}(W) = \exp\bigl(H(W)\bigr) = \exp\Bigl(-\tfrac{1}{N}\sum_{i=1}^N \log P(w_i\mid w_{<i})\Bigr)

3. 해석

  • 지수화된 교차엔트로피이므로,
    PPL=b\mathrm{PPL} = b
    라면 모델은 매 토큰마다 평균 (b)개의 후보 중에서 정답을 골라내는 셈입니다.

    e.g., Perplexity가 10이면, 매 단어마다 모델이 약 10가지 후보 중 하나를 맞추는 성능임


4. 한국어 적용 시 유의사항

  • 한국어 전용 토크나이저 & 모델 사용
    • 형태소 기반이나 SentencePiece 토크나이저로 사전 처리된 모델 필요
    • 예: skt/kogpt2-base-v2, beomi/KcELECTRA-base
  • 절대값 vs. 상대값
    • 서로 다른 토크나이저·모델 간 절대 perplexity 비교는 부적절
    • 같은 모델 내에서 AI 생성 문장 vs. 인간 문장 비교용으로 사용

5. Perplexity Gap

두 언어 모델 간 차이를 피처로 활용할 때는 다음과 같이 정의한다:

ΔPPL=PPLsimpleLM(W)    PPLgptLM(W)\Delta \mathrm{PPL} = \mathrm{PPL}_{\text{simpleLM}}(W) \;-\; \mathrm{PPL}_{\text{gptLM}}(W)
  • GPT 계열 대형 모델에 친화적인 텍스트는 (PPLgptLM)(\mathrm{PPL}_{\text{gptLM}})이 낮아짐
  • 단순 LM 대비 격차인 (ΔPPL)(\Delta \mathrm{PPL})가 크게 나타나는 경향을 이용

6. 계산 예시 (Python)

import torch
from transformers import AutoTokenizer, AutoModelForCausalLM

model_name = "skt/kogpt2-base-v2"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model     = AutoModelForCausalLM.from_pretrained(model_name).eval().to("cuda")

def perplexity(text: str) -> float:
    enc = tokenizer(text, return_tensors="pt").to("cuda")
    with torch.no_grad():
        output = model(**enc, labels=enc.input_ids)
        loss = output.loss  # 평균 NLL
    return torch.exp(loss).item()

text = "공부가 너무너무 하기싫은데 해야지 어쩌겠어!"
print("Perplexity:", perplexity(text))

라면 모델은 매 토큰마다 평균 (b)개의 후보 중에서 정답을 골라내는 셈!

  • 예: Perplexity가 10이면, 매 단어마다 모델이 약 10가지 후보 중 하나를 맞추는 성능.

7. 결론

  • Perplexity는 언어 모델의 토큰별 예측 난도를 측정하는 평가 지표
  • 지표가 낮을 수록 더욱 유창하다는 뜻
  • 각 언어에 맞게 전용 모델로 임베딩 후 진행해야 됨
  • 대개 Perplexity Gap을 Custom Style Metric Feature로 결합하면 분류 성능이 향상

그럼.. 이만....

profile
베풀기 위해 더 많이 공부하고 성장하기 ᓚᘏᗢ: 공부 정리용

0개의 댓글