13 분 소요

아홉번째 실습 9으로 LLM 평가 및 벤치마킹을 해 보자! LLM 평가는 이 분야에서 가장 어려운 문제 중 하나로 사람마다 “좋다”의 기준이 다르다. 자동화된 지표는 의미를 놓치기 때문에 전체 벤치마크를 실행하면 모델 하나당 수백 달러가 들 수 있다. 평가를 신뢰할 수 없다면 이후 수행하는 모든 최적화는 기준 없이 진행되는 작업이 된다.

이 실습은 가장 단순한 지표에서 현대적인 평가 방식까지 단계적으로 다룬다.

  • Perplexity: 고전적이지만 여전히 유용한 언어 모델 지표로 GPU에서 계산한다.
  • BLEU / ROUGE: 기계 번역 및 요약 시대에 사용된 n-gram overlap 지표이다. 구체적인 예제를 통해 LLM 출력에서 왜 실패하는지 확인한다.
  • Side-by-side model comparison: 크기가 다른 두 모델에서 출력을 생성하고 정성적으로 비교한다.
  • LLM-as-a-Judge: 현대적인 평가 패턴으로, 핵심 패턴을 구현하고 단순(naive)한 LLM 판정을 신뢰하기 어렵게 만드는 position bias를 감지한다.

참고로 n-gram 오버랩 지표는 모델이 만든 문장과 정답 문장이 얼마나 같은 단어 조각을 공유하는지를 세는 평가 방식이다. 또한 순서 편향(position bias)는 LLM이 두 답변을 비교 평가할 때 내용의 품질보다 답변이 놓인 위치에 영향을 받는 편향을 말한다.

추천 논문

  • Zheng et al. 2023 - Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena. LLM-as-judge를 신뢰 가능한 평가 방법으로 정립한 대표 논문이다. GPT-4가 인간 선호도와 80% 이상 일치하며 이는 인간끼리의 일치율과 비슷한 수준임을 보인다. 또한 세 가지 주요 편향(position, verbosity, self-enhancement)과 완화 방법을 정리한다. 실시간 리더보드인 Chatbot Arena(lmarena.ai)는 이 연구의 실용적 결과물이다.
  • HuggingFace — Perplexity of fixed-length models. 현대 트랜스포머(transformer)에서 perplexity를 올바르게 계산하는 표준 참고 자료이다. stride, context window, model.eval()이 중요한 이유를 설명한다. 참고로 퍼플렉서티(Perplexity)는 LLM이 다음 단어를 얼마나 덜 헷갈리고 예측하는지를 나타내는 지표다. 보통 낮을수록 예측 성능이 좋다.

비교 모델

  • gpt2 (124M params, 2019): 작지만 날카로운 기준선(baseline)이다.
  • gpt2-medium (355M params, 2019): 같은 시대의 모델이며 약 3배 크다.

두 모델은 8GB VRAM에 함께 무리 없이 올라가며 약 5개 프롬프트만으로도 품질에 대한 모델 크기 효과(size effect)를 확인할 수 있다.


실험 1 - Perplexity: branching factor 직관

Perplexity는 cross-entropy loss의 지수값이다. 이 값은 다음 질문에 답한다. “모델이 각 토큰을 예측할 때 평균적으로 몇 개의 동일 확률 후보 중에서 선택하고 있는가?” 구체적인 수치는 다음과 같다. - Perplexity 2 → 모델이 사실상 동전 던지기 수준으로 선택한다. 매우 확신이 높은 상태이다.

  • Perplexity 50 → 약 50개 단어 중에서 선택한다. 자연어 텍스트에 대한 괜찮은 소형 언어 모델(LM)에서 흔한 수준이다.
  • Perplexity 10,000 → 약 10K 단어(vocabulary) 전체에서 거의 무작위로 선택하는 상태이다. 품질이 매우 낮은 모델이다.

Perplexity는 상대적 지표이다. 서로 다른 tokenizer 간 perplexity를 비교하는 것은 의미가 없다. 단어(vocabulary) 크기가 다르면 스케일(scale)이 달라지기 때문이다. 그러나 동일한 tokenizer와 동일 corpus에서는 값이 낮을수록 좋다.

LLM 시대에는 perplexity의 위상이 다소 낮아졌다. perplexity는 reasoning, factuality, instruction-following을 포착하지 못한다. 그래도 사전훈련(pretraining) 중 가장 먼저 정상성 검증(sanity check)할 지표로 여전히 유용하다. 갑작스러운 perplexity spike는 보통 데이터 파이프라인(data pipeline)이 깨졌다는 신호이다.

  • 브랜칭 팩터(branching factor): 언어 모델이 다음 토큰을 예측할 때 평균적으로 몇 개의 후보 토큰 중에서 고르는 것처럼 보이는가를 직관적으로 표현한 용어이다.
  • 정상정 검증(sanity check): 벤치마킹 전에 결과가 정상 범위에 있는지 간단히 확인한다.

흔한 실수: model.eval() 누락

학습 모드(training mode) 상태의 모델에서 perplexity를 계산하면 드롭 레이어(dropout layer)가 활성화되어 순방향(forward pass) 중 활성화값(activation)이 무작위로 0이 된다. 이 경우 측정된 perplexity는 실제보다 높게 나오며, 더 나쁘게는 비결정적이 된다. 같은 데이터에서 실행할 때마다 perplexity가 달라진다면 거의 항상 이 문제가 원인이다.

할 일: gpt2를 로드하고 CUDA로 이동한 뒤 eval mode로 설정한다. 짧은 평가 텍스트에 대해 표준 exp(mean(loss)) 공식을 사용해 perplexity를 계산하고 scalar 값을 ppl에 할당한다.

import torch
from transformers import AutoTokenizer, AutoModelForCausalLM

# 평가를 위해 GPT-2 모델과 토크나이저를 로드하고 GPU로 이동
device = torch.device('cuda')
tok = AutoTokenizer.from_pretrained('gpt2')
model = AutoModelForCausalLM.from_pretrained('gpt2').to(device)
model.eval()  # ← 중요: dropout을 비활성화하므로 perplexity 계산 결과가 재현 가능해진다.

# 평가에 사용할 약 350토큰 길이의 영어 지문
eval_text = (
    "The quick brown fox jumps over the lazy dog. Machine learning models "
    "have become remarkably capable in recent years. Fine-tuning on "
    "domain-specific data often produces better results than prompting alone."
)

# 평가 텍스트를 토큰화하고 GPU로 이동
ids = tok(eval_text, return_tensors='pt').input_ids.to(device)
with torch.no_grad():
    out = model(ids, labels=ids)
    ppl = torch.exp(out.loss).item()

# perplexity 결과 출력
print(f'GPT-2 perplexity on our eval text: {ppl:.2f}')
print(f'Interpretation: the model behaves as if it had to pick between ~{ppl:.0f} equally-likely next tokens per step.')
/usr/local/lib/python3.11/dist-packages/torch/cuda/__init__.py:65: FutureWarning: The pynvml package is deprecated. Please install nvidia-ml-py instead. If you did not install pynvml directly, please report this to the maintainers of the package that installed pynvml for you.
  import pynvml  # type: ignore[import]

`loss_type=None` was set in the config but it is unrecognized. Using the default loss: `ForCausalLMLoss`.

GPT-2 perplexity on our eval text: 89.87
Interpretation: the model behaves as if it had to pick between ~90 equally-likely next tokens per step.

실험 2 - BLEU & ROUGE: 측정하는 것과 놓치는 것

BLEU(Papineni et al. 2002)와 ROUGE(Lin 2004)는 각각 기계 번역과 요약 시대에 사용된 n-gram 오버랩(overlap) 지표이다. 이 지표들은 다음을 묻는다. candidate output의 n-gram 중 참조값(reference)에 등장하는 것은 얼마나 되는가?

LLM 이전의 좁은 task(스페인어→영어 번역, 뉴스 요약 등)를 수행하는 시스템에서는 이 지표들이 인간 평가와 꽤 잘 상관된다. 비용이 낮고, reference 기반이며 완전히 결정적이다.

현대 LLM 출력에서 문제가 되는 이유는 다음과 같다.

  • 의미 이해가 없다. "The guard watched the gate""The watchman observed the gate"는 같은 의미이지만, n-gram으로는 "The""the gate" 정도만 공유한다. BLEU는 이를 거의 0점에 가깝게 평가한다.
  • 단일 reference bias가 있다. LLM은 다양하면서도 유효한 출력을 생성한다. overlap 지표를 사용하려면 가능한 모든 패러패이즈(paraphrase, 의미는 같지만 표현 방식이 다른 문장)를 레퍼런스(reference, 모델의 출력을 비교·평가하기 위해 미리 준비한 정답 문장 또는 기준 문장)로 열거해야 하는데 이는 현실적으로 불가능하다.
  • 쉽게 게이밍된다. 모델은 실제로 답변하지 않고 reference n-gram을 반복하는 방식으로 BLEU를 최적화할 수 있다.
  • reference에 의존한다. chat, coding, reasoning 같은 자유 형식(open-ended generation, 정답이 하나로 정해지지 않은 질문에 대해 다양한 형태의 답변을 생성하는 방식)에서는 reference 자체가 없는 경우가 많다.

BLEU보다 나은 지표를 만들기 위한 분야도 형성되어 있다. BERTScore, COMET, BLEURT 같은 지표는 학습된 임베딩(learned embedding)을 사용해 의미 유사도(semantic similarity)를 측정한다. 그러나 chat 시대에는 이들조차 대부분 LLM-as-judge 방식으로 대체되고 있다(실험 4 참조).

학습된 임베딩(learned embedding)은 모델 학습 과정에서 데이터로부터 직접 학습된 임베딩 벡터를 말한다. 또한 의미 유사도란 두 문장이 표현은 달라도 의미가 얼마나 가까운지를 나타내는 지표이다.

유명한 BLEU 실패 예제

두 쌍(pair)에 대해 BLEU를 계산한다.

Pair Reference Candidate Expected BLEU Semantic match?
A The guard watched the gate The guard watched the gate ~1.0 Same
B The guard watched the gate The watchman observed the gate near 0 Also the same!

두 후보(candidate)는 같은 의미이다. 그러나 BLEU는 이를 크게 다르게 평가한다.

import evaluate

# BLEU 및 ROUGE 평가 지표 로드
bleu = evaluate.load('bleu')
rouge = evaluate.load('rouge')

# Pair A — 완전 일치
ref = ['The guard watched the gate.']
cand = ['The guard watched the gate.']

# BLEU 및 ROUGE 점수 계산
bleu_score = bleu.compute(predictions=cand, references=[ref])['bleu']
rouge_scores = rouge.compute(predictions=cand, references=ref)

# 평가 결과 출력
print(f'PAIR A (exact match)')
print(f'  BLEU:    {bleu_score:.3f}')
print(f'  ROUGE-L: {rouge_scores["rougeL"]:.3f}')
PAIR A (exact match)
  BLEU:    1.000
  ROUGE-L: 1.000
# Pair B — 의미는 동일하지만 단어 선택은 다른 경우
ref_b = ['The guard watched the gate.']
cand_b = ['The watchman observed the gate.']
synonym_bleu = bleu.compute(predictions=cand_b, references=[ref_b])['bleu']
synonym_rouge = rouge.compute(predictions=cand_b, references=ref_b)

# 평가 결과 출력
print(f'PAIR B (synonym substitution, same meaning)')
print(f'  BLEU:    {synonym_bleu:.3f}   <-- notice the huge drop!')
print(f'  ROUGE-L: {synonym_rouge["rougeL"]:.3f}')
print()
print(f'This is why BLEU/ROUGE are poor metrics for LLMs — they cannot reward semantic equivalence.')
PAIR B (synonym substitution, same meaning)
  BLEU:    0.000   <-- notice the huge drop!
  ROUGE-L: 0.600

This is why BLEU/ROUGE are poor metrics for LLMs — they cannot reward semantic equivalence.

실험 3 - Side-by-side 모델 압축 (GPT-2 대 GPT-2 Medium)

지표는 비교할 때만 유용하다. gpt2(124M)와 gpt2-medium(355M) 두 모델을 같은 프롬프트에서 생성해 보고 모델 크기 효과(size effect)를 직접 확인한다. 참고로 모델 크기 효과는 같은 프롬프트를 넣었을 때 모델 파라미터 수가 커지면 출력 품질이나 생성 특성이 어떻게 달라지는지를 확인한다는 의미다.

이는 실제 평가 작업과 동일한 구조이다. 고정된 프롬프트 집합(prompt set)에 대해 모델 A와 모델 B를 실행하고, 출력을 저장한 뒤 집계(aggregate)된 결과에 지표를 적용한다. 스케일(scale)이 커질 때 달라지는 것은 프롬프트 집합(prompt set) 크기(수백 개 → 수만 개)와 evaluator 유형(자동 지표 → LLM judge → human)이다.

할 일: generations{prompt: {model_name: generated_text}} 형태로 채운다. 결과 재현성을 위해 deterministic generation(do_sample=False)을 사용한다.

# 프롬프트 생성 
prompts = [
    'The key insight behind gradient descent is',
    'The most common reason a machine learning model overfits is',
    'A transformer differs from a recurrent neural network because',
]

# 모델 비교를 위해 GPT-2와 GPT-2 Medium을 로드
models_to_compare = {
    'gpt2': None,
    'gpt2-medium': None,
}

# 두 모델을 모두 로드한다. 두 모델을 동시에 메모리에 올려도 전체 VRAM 사용량은 약 1.4GB 수준이다.
for name in models_to_compare:
    tok_i = AutoTokenizer.from_pretrained(name)
    mdl_i = AutoModelForCausalLM.from_pretrained(name).to(device)
    mdl_i.eval()
    if tok_i.pad_token is None:
        tok_i.pad_token = tok_i.eos_token
    models_to_compare[name] = (tok_i, mdl_i)

# 모델 로드 완료 메시지 출력
print(f'Loaded: {list(models_to_compare)}')
Loaded: ['gpt2', 'gpt2-medium']
# 프롬프트별로 각 모델의 출력을 생성하고 저장
generations = {}
for p in prompts:
    generations[p] = {}
    for name, (tok_i, mdl_i) in models_to_compare.items():
        ids = tok_i(p, return_tensors='pt').input_ids.to(device)
        with torch.no_grad():
            out = mdl_i.generate(ids, max_new_tokens=40, do_sample=False, pad_token_id=tok_i.eos_token_id)
        text = tok_i.decode(out[0], skip_special_tokens=True)
        generations[p][name] = text

# 생성된 텍스트 출력
for p, per_model in generations.items():
    print(f'PROMPT: {p}')
    for name, text in per_model.items():
        print(f'  [{name}] {text}')
    print()
The attention mask is not set and cannot be inferred from input because pad token is same as eos token. As a consequence, you may observe unexpected behavior. Please pass your input's `attention_mask` to obtain reliable results.

PROMPT: The key insight behind gradient descent is
  [gpt2] The key insight behind gradient descent is that it is a very simple process. The gradient is a series of steps, each step being a gradient of the gradient of the gradient of the gradient of the gradient of the gradient of the gradient of
  [gpt2-medium] The key insight behind gradient descent is that it is a method of finding the shortest path between two points. The algorithm is based on the idea that the shortest path between two points is the shortest path between two points.

The algorithm

PROMPT: The most common reason a machine learning model overfits is
  [gpt2] The most common reason a machine learning model overfits is that it is too complex to be used in a real-world situation.

The problem is that the model is too complex to be used in a real-world situation.

The model
  [gpt2-medium] The most common reason a machine learning model overfits is because it is trained on a large number of data points. This is a common problem in machine learning, and it is often the reason why models overfit.

In this article, we will

PROMPT: A transformer differs from a recurrent neural network because
  [gpt2] A transformer differs from a recurrent neural network because it is a neural network that is able to learn from the input and learn from the output.

The first step in the process is to create a neural network that learns from the input and learns
  [gpt2-medium] A transformer differs from a recurrent neural network because it is a network that learns to process a set of inputs. The input to a recurrent neural network is a set of inputs that are fed into it. The output of a recurrent neural network is a

실험 4 - LLM-as-a-Judge: 현대적 패턴과 주의점

자유 형식 생성(open-ended generation)에서 2023년에 부상한 핵심 평가 기법은 다음과 같다. 강한 LLM을 사용해 다른 LLM의 출력을 평가한다. MT-Bench paper는 GPT-4가 인간 선호와 80% 이상 일치함을 보였으며 이는 인간끼리의 일치율과 사실상 비슷한 수준이다.

패턴은 다음과 같다.

  • 고정된 프롬프트 집합(prompt set)에 대해 모델 A와 모델 B의 후보 출력(candidate output)을 수집한다.
  • judge LLM(이상적으로는 두 후보보다 강한 모델)에 다음과 같이 질문한다. *“이 prompt에 대해 어느 응답이 더 나은가 - A인가 B인가
    • 그리고 이유는 무엇인가?”*
  • 프롬프트 전체에 대해 집계(aggregate)하여 승률(win rate)를 계산한다.

운영 프로덕션 환경에서는 LMSYS의 Chatbot Arena 리더보드, AlpacaEval, 그리고 새로운 chat model에 대한 모든 진지한 A/B test가 이 방식에 기반한다.

반드시 알아야 할 세 가지 편향

Zheng et al. 2023에서 제시한 편향은 다음과 같다.

  • 순서 편향(Position bias) : judge가 먼저 나온 응답(response)을 선호하거나, 때로는 마지막 응답을 선호하는 경향이다. 완화 방법은 두 순서 배치(ordering)을 모두 평가하고 판정 결과(verdict)가 일관될 때만 승률값(win)으로 계산하는 것이다.
  • 판정 편향(Verbosity bias) : judge가 실제로 더 좋지 않아도 더 긴 응답을 선호하는 경향이다. 완화 방법은 judge에게 길이를 무시하라고 명시하거나 채점 기준표(rubric)에서 감점(penalize)하는 것이다.
  • 자기 선호 편향(Self-enhancement bias) : judge가 자기 모델 패밀리(model family)의 출력을 선호하는 경향이다. 완화 방법은 후보자(candidate)와 다른 패밀리의 judge를 사용하는 것이다.

여기서는 순서 편향 감지(position bias detection) 패턴을 구체적으로 구현한다.

# LLM-as-a-Judge 프롬프팅 패턴을 모방하는 규칙 기반 judge이다.
# 운영 환경에서는 이를 실제 LLM 호출(GPT-4, Claude, Llama-3-70B 등)로 대체한다.
# 이때 동일한 프롬프트 템플릿을 사용한다. 편향 감지 패턴은 동일하다.

JUDGE_PROMPT_TEMPLATE = """You are an impartial judge. Given a prompt and two responses (A and B), pick the better response based on:
- Correctness of information
- Coherence and fluency
- Relevance to the prompt

Ignore response length. Output exactly one of: 'A', 'B', or 'TIE'.

PROMPT: {prompt}

RESPONSE A: {a}

RESPONSE B: {b}

Your verdict (A/B/TIE):"""


def rule_based_judge(prompt, a, b):
    """LLM 호출을 대신하는 규칙 기반 judge이다. 프롬프트와 관련된 고유 내용 단어가 더 많은 응답을 선호한다.
    실제 환경에서는 client.chat.completions.create(...) 같은 LLM 호출로 대체한다."""
    import string
    def score(text, prompt):
        # 문장부호를 제거하고 소문자로 변환한 뒤 단어 단위로 분리함.
        prompt_words = set(prompt.lower().translate(str.maketrans('', '', string.punctuation)).split())
        text_words = [w for w in text.lower().translate(str.maketrans('', '', string.punctuation)).split() if w not in prompt_words]
        # 프롬프트를 그대로 반복하는 경우는 감점하고 고유한 내용 단어가 많을수록 점수를 높인다.
        return len(set(text_words))
    # 응답 A와 응답 B의 점수를 계산한다.
    sa, sb = score(a, prompt), score(b, prompt)

    # 점수 차이가 작으면 동점으로 판정한다.
    if abs(sa - sb) < 2:
        return 'TIE'
    return 'A' if sa > sb else 'B' # 점수가 더 높은 응답을 선택한다.

# 프롬프트가 템플릿에 채워졌다고 가정하라! 실제 LLM 호출에서는 이 내용을 그대로 전송한다.
example_filled = JUDGE_PROMPT_TEMPLATE.format(
    prompt=prompts[0],
    a=generations[prompts[0]]['gpt2'],
    b=generations[prompts[0]]['gpt2-medium'],
)

print('Example filled prompt (first ~500 chars):')
print(example_filled[:500] + '...')
Example filled prompt (first ~500 chars):
You are an impartial judge. Given a prompt and two responses (A and B), pick the better response based on:
- Correctness of information
- Coherence and fluency
- Relevance to the prompt

Ignore response length. Output exactly one of: 'A', 'B', or 'TIE'.

PROMPT: The key insight behind gradient descent is

RESPONSE A: The key insight behind gradient descent is that it is a very simple process. The gradient is a series of steps, each step being a gradient of the gradient of the gradient of the gra...
# 순서(position) 편향을 감지하기 위해 A/B 순서를 바꾸어 judge를 두 번 실행한다.
judge_verdicts = []
for p in prompts:
    a_text = generations[p]['gpt2']
    b_text = generations[p]['gpt2-medium']
    verdict_ab = rule_based_judge(p, a_text, b_text)       # gpt2 as A
    verdict_ba = rule_based_judge(p, b_text, a_text)       # gpt2 as B (swapped)
  
    # A/B 순서를 바꿔 얻은 판정 결과를 원래 모델 이름 기준으로 변환하여 일관되게 비교함
    name_ab = {'A': 'gpt2', 'B': 'gpt2-medium', 'TIE': 'TIE'}[verdict_ab]
    name_ba = {'A': 'gpt2-medium', 'B': 'gpt2', 'TIE': 'TIE'}[verdict_ba]

    # 판정 결과를 저장함 
    judge_verdicts.append({
        'prompt': p,
        'gpt2_as_A': name_ab,
        'gpt2_as_B': name_ba,
        'consistent': name_ab == name_ba,
    })

# A/B 순서 교체로 승자가 달라진(swapped, A와 B를 순서로 바꾸는 것) 프롬프트가 하나라도 있으면 순서 편향으로 본다.
position_bias_detected = any(not v['consistent'] for v in judge_verdicts)

import pandas as pd
df = pd.DataFrame(judge_verdicts)
print(df.to_string(index=False))
print()
print(f'Position bias detected: {position_bias_detected}')
if position_bias_detected:
    print('  -> Some verdicts flipped when we swapped A/B. In production, discard those comparisons or require agreement across orderings.')
                                                       prompt   gpt2_as_A   gpt2_as_B  consistent
                   The key insight behind gradient descent is gpt2-medium gpt2-medium        True
  The most common reason a machine learning model overfits is gpt2-medium gpt2-medium        True
A transformer differs from a recurrent neural network because         TIE         TIE        True

Position bias detected: False

학습 정리

  • Perplexity는 학습(training) 중 기본 동작 검증(smoke test)로 여전히 유용하지만, reasoning이나 factuality는 포착하지 못한다. 측정 전에는 항상 model.eval()을 호출해야 한다. 참고로 기본 동작 검증은 전체 테스트를 깊게 돌리기 전에 시스템이 일단 망가지지 않고 최소한 정상적으로 실행되는지 빠르게 확인하는 테스트를 말한다.
  • BLEU/ROUGE는 좁은 태스크(narrow task)에서는 인간 평가와 상관될 수 있지만, 의미적 동등성(semantic equivalence)를 보상하지 못하므로 LLM에서는 쉽게 깨진다. 이들은 하나의 신호로만 사용해야 하며 유일한 지표로 사용해서는 안 된다. 참고로 좁은 태스크란 평가 기준이 비교적 명확하고, 정답 표현이 크게 다양하지 않은 작업으로 기계 번역, 문서 요약, 정보 추출, 짧은 QA 등이 있다. 반대로 LLM의 일반 답변, 추론, 코딩 설명, 에세이 생성처럼 정답 표현이 다양하고 평가 기준이 복합적인 작업은 좁은 태스크가 아니다. 또한, 의미적 동등성(semantic equivalence)은 표현은 다르지만 의미가 같은 상태를 말한다.
  • Side-by-side generation은 모든 LLM A/B 테스트의 기반이다. 먼저 고정된 프롬프트 집합(prompt set)에서 출력을 수집한 뒤 지표를 적용한다.
  • LLM-as-judge는 정답이 정해져 있지 않은 생성 작업(open-ended generation)의 현대적 표준이다. 그러나 간단(naive)하게 사용하면 position bias, verbosity bias, self-enhancement bias에 취약하다. 항상 두 순서(ordering)으로 판정하고, 가능하면 후보자(candidate)와 다른 모델 패밀리(model family)의 judge를 사용한다.

참고 자료

  • Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena - 대표적인 LLM-judge 논문이다. eval pipeline을 만든다면 섹션 3과 4를 읽는 것이 좋다.
  • HuggingFace's lm-evaluation-harness - EleutherAI의 사실상 표준 벤치마크 러너(benchmark runner)이고 수백 개 task와 pluggable metric을 제공한다.
  • HELM (Holistic Evaluation of Language Models) - Stanford의 대규모 벤치마크이다. accuracy, calibration, robustness, fairness, bias, toxicity, efficiency를 포괄한다.
  • BERTScore paper - BLEU의 시맨틱 문제에 대한 임베딩 기반 접근이다.
  • Chatbot Arena (LMSYS) - 약 100개 LLM에 대한 실시간 블라인드 쌍대 비교 투표(live blind pairwise voting) 환경이다. 인간 선호(human preference) 기준의 골드 스탠더드(gold standard)로 볼 수 있다. 참고로 실시간 블라인드 쌍대 비교 투표는 사용자가 두 모델의 답변을 모델 이름을 모르는 상태에서 나란히 보고 더 좋은 답변에 투표하는 평가 방식이다.

댓글남기기