LLM 평가의 핵심 개념, 주요 벤치마크(MMLU, HumanEval, MT-Bench), 자동 평가(LLM-as-Judge), RAG 평가(RAGAS), 자체 평가 체계 구축, A/B 테스트 전략을 체계적으로 정리합니다.
Data Dynamics2026年4月16日13 min read
This post is not yet translated. The original Korean version is shown below.
LLM의 성능을 객관적으로 측정하고 비교하는 것은 모델 선택, Fine-Tuning 효과 검증, 프로덕션 품질 관리의 핵심입니다. 이 글에서는 LLM 평가의 기본 개념부터 자체 평가 체계 구축까지 체계적으로 다룹니다.
1. LLM 평가가 중요한 이유
평가가 필요한 상황
상황
평가 목적
평가 방법
모델 선택
GPT-4 vs Claude vs LLaMA 비교
벤치마크, 도메인 태스크 평가
Fine-Tuning
학습 전후 성능 비교
태스크별 정확도, 형식 준수율
RAG 파이프라인
검색+생성 품질 측정
RAGAS, Recall@K
프롬프트 최적화
프롬프트 변형 간 비교
A/B 테스트, LLM-as-Judge
프로덕션 모니터링
서비스 품질 지속 관리
사용자 피드백, 자동 평가
평가의 어려움
비결정성: 같은 입력에 다른 출력 (Temperature > 0)
주관성: "좋은 답변"의 기준이 모호
다차원: 정확도, 유창성, 유용성, 안전성 등 다양한 축
도메인 의존: 범용 벤치마크와 실제 성능 괴리
2. 주요 벤치마크
범용 벤치마크
벤치마크
평가 대상
형식
문제 수
특징
MMLU
범용 지식
4지선다
15,908
57개 주제, 가장 널리 사용
MMLU-Pro
범용 지식 (고난도)
10지선다
12,032
MMLU 업그레이드, CoT 필요
HellaSwag
상식 추론
4지선다
10,042
상황 후속 문장 선택
ARC-Challenge
과학 추론
4지선다
1,172
초등~중등 과학 문제
Winogrande
상식
2지선다
1,267
대명사 지시 대상 판별
TruthfulQA
사실성
생성형
817
할루시네이션 평가
GSM8K
수학
생성형
1,319
초등 수학 문제
MATH
수학 (고난도)
생성형
5,000
경시대회 수준 수학
코드 벤치마크
벤치마크
평가 대상
언어
문제 수
HumanEval
함수 생성
Python
164
HumanEval+
강화된 테스트
Python
164
MBPP
기본 프로그래밍
Python
500
SWE-bench
실제 이슈 해결
다중
2,294
LiveCodeBench
실시간 코딩
다중
지속 갱신
대화/지시 벤치마크
벤치마크
평가 대상
평가 방식
MT-Bench
멀티턴 대화
GPT-4가 1~10점 채점
AlpacaEval
지시 따르기
GPT-4 승률 비교
Chatbot Arena
실사용자 선호도
ELO 레이팅 (블라인드)
IFEval
지시 따르기 정확도
형식 준수 정확도
MTEB (Massive Text Embedding Benchmark)
임베딩 모델의 종합 평가:
태스크
설명
평가 지표
Retrieval
검색 관련도
nDCG@10
Classification
텍스트 분류
Accuracy
Clustering
텍스트 클러스터링
V-measure
STS (Semantic Similarity)
의미 유사도
Spearman 상관
Reranking
재순위화
MAP
3. 자동 평가: LLM-as-Judge
개념
강력한 LLM(GPT-4, Claude)을 평가자(Judge)로 활용하여 다른 모델의 응답 품질을 자동으로 채점합니다.
import anthropicclient = anthropic.Anthropic()def llm_judge(question: str, response: str, criteria: list) -> dict: """LLM을 평가자로 활용""" eval_prompt = f"""다음 응답을 평가하세요.## 질문{question}## 응답{response}## 평가 기준 (각 1~5점){chr(10).join(f"- {c}" for c in criteria)}## 채점 규칙- 1점: 매우 부족- 2점: 부족- 3점: 보통- 4점: 우수- 5점: 매우 우수JSON 형식으로 반환:{{"scores": {{"기준명": 점수}}, "average": 평균, "reasoning": "평가 근거", "improvements": "개선 사항"}}""" result = client.messages.create( model="claude-sonnet-4-6", max_tokens=1024, temperature=0.0, messages=[{"role": "user", "content": eval_prompt}] ) return json.loads(result.content[0].text)# 사용scores = llm_judge( question="Kafka에서 컨슈머 랙이 증가하는 원인은?", response="...(평가 대상 응답)...", criteria=["정확성", "완전성", "실용성", "코드 예시 품질"])
Pairwise 비교
두 응답을 비교하여 어느 것이 더 나은지 판별합니다.
def pairwise_compare(question: str, response_a: str, response_b: str) -> str: """두 응답 중 더 나은 것을 선택""" prompt = f"""두 응답을 비교하여 더 나은 것을 선택하세요.질문: {question}응답 A: {response_a}응답 B: {response_b}더 나은 응답을 선택하고 이유를 설명하세요.반환 형식: {{"winner": "A" 또는 "B" 또는 "tie", "reason": "이유"}}""" result = client.messages.create( model="claude-sonnet-4-6", max_tokens=512, temperature=0.0, messages=[{"role": "user", "content": prompt}] ) return json.loads(result.content[0].text)
LLM-as-Judge의 한계와 보완
한계
설명
보완 방법
위치 편향
첫 번째 응답을 선호하는 경향
순서를 바꿔 2회 평가
장문 편향
긴 응답을 높게 평가하는 경향
"간결함" 기준 추가
자기 편향
같은 모델의 응답을 선호
다른 모델로 평가
지시 편향
평가 기준 순서에 민감
기준 순서 랜덤화
4. RAG 평가: RAGAS
RAGAS 프레임워크
RAG 시스템의 검색 품질과 생성 품질을 자동으로 평가합니다.
from ragas import evaluatefrom ragas.metrics import ( faithfulness, answer_relevancy, context_precision, context_recall, context_utilization)from datasets import Dataset# 평가 데이터 구성eval_data = { "question": [ "Spark에서 셔플 파티션을 조정하는 방법은?", "Kafka 컨슈머 그룹의 리밸런싱이란?" ], "answer": [ "spark.sql.shuffle.partitions 설정을 변경합니다...", "컨슈머 그룹 내에서 파티션 할당을 재조정하는 과정입니다..." ], "contexts": [ ["Spark 셔플 파티션은 spark.sql.shuffle.partitions로 설정..."], ["Kafka 리밸런싱은 컨슈머 그룹의 멤버 변경 시 발생..."] ], "ground_truth": [ "spark.sql.shuffle.partitions 설정으로 셔플 파티션 수를 조정합니다.", "리밸런싱은 컨슈머 그룹 내 파티션 재할당 과정입니다." ]}dataset = Dataset.from_dict(eval_data)results = evaluate( dataset, metrics=[faithfulness, answer_relevancy, context_precision, context_recall])print(results)# {'faithfulness': 0.92, 'answer_relevancy': 0.88, # 'context_precision': 0.85, 'context_recall': 0.90}
RAGAS 지표 해석
지표
의미
낮으면
개선 방향
Faithfulness
응답이 컨텍스트에 근거하는가
할루시네이션
프롬프트에 "컨텍스트만 사용" 강조
Answer Relevancy
응답이 질문에 적절한가
엉뚱한 답변
프롬프트 개선, 검색 품질 향상
Context Precision
검색 결과가 관련성 있는가
노이즈 문서
리랭킹 추가, 메타데이터 필터
Context Recall
필요한 정보를 다 찾았는가
정보 누락
K값 증가, 하이브리드 검색
5. 자체 평가 체계 구축
평가 데이터셋 설계
# 평가 데이터셋 구조eval_dataset = [ { "id": "eval-001", "category": "troubleshooting", "difficulty": "medium", "question": "Spark executor OOM 에러가 발생합니다. 원인과 해결 방법은?", "reference_answer": "executor.memory를 늘리거나, 파티션 수를 증가시키거나...", "required_elements": ["executor.memory", "파티션", "데이터 스큐"], "evaluation_criteria": { "accuracy": "기술적으로 정확한 원인 분석", "completeness": "주요 원인 3가지 이상 포함", "actionability": "구체적 설정값 또는 코드 포함", "format": "구조화된 형식 (번호 목록 등)" } }]
자동 평가 파이프라인
class EvaluationPipeline: def __init__(self, judge_model: str = "claude-sonnet-4-6"): self.judge = anthropic.Anthropic() self.judge_model = judge_model self.results = [] def evaluate_batch(self, model_fn, eval_dataset: list) -> dict: """배치 평가 실행""" for item in eval_dataset: # 1. 모델 응답 생성 response = model_fn(item["question"]) # 2. 자동 지표 평가 auto_scores = self.auto_evaluate(item, response) # 3. LLM-as-Judge 평가 judge_scores = self.judge_evaluate(item, response) self.results.append({ "id": item["id"], "category": item["category"], "auto_scores": auto_scores, "judge_scores": judge_scores, "response": response }) return self.aggregate_results() def auto_evaluate(self, item: dict, response: str) -> dict: """규칙 기반 자동 평가""" scores = {} # 필수 요소 포함 여부 required = item.get("required_elements", []) found = sum(1 for e in required if e.lower() in response.lower()) scores["element_coverage"] = found / max(len(required), 1) # 응답 길이 적정성 word_count = len(response.split()) scores["length_appropriate"] = 1.0 if 50 < word_count < 500 else 0.5 return scores def aggregate_results(self) -> dict: """결과 집계""" categories = {} for r in self.results: cat = r["category"] if cat not in categories: categories[cat] = [] categories[cat].append(r["judge_scores"]["average"]) return { "overall_average": sum(r["judge_scores"]["average"] for r in self.results) / len(self.results), "by_category": {k: sum(v)/len(v) for k, v in categories.items()}, "total_evaluated": len(self.results) }
6. A/B 테스트와 프로덕션 평가
온라인 A/B 테스트
import randomfrom datetime import datetimeclass ABTestManager: def __init__(self): self.experiments = {} def create_experiment(self, name: str, variants: dict, traffic_split: dict): """A/B 테스트 실험 생성""" self.experiments[name] = { "variants": variants, # {"A": model_a, "B": model_b} "traffic_split": traffic_split, # {"A": 0.5, "B": 0.5} "results": {"A": [], "B": []}, "created_at": datetime.now() } def get_variant(self, experiment_name: str, user_id: str) -> str: """사용자별 일관된 변형 할당""" # 사용자 ID 기반 결정적 할당 (같은 사용자는 항상 같은 변형) hash_val = hash(f"{experiment_name}:{user_id}") % 100 exp = self.experiments[experiment_name] cumulative = 0 for variant, ratio in exp["traffic_split"].items(): cumulative += ratio * 100 if hash_val < cumulative: return variant return list(exp["variants"].keys())[-1] def record_feedback(self, experiment_name: str, variant: str, score: float): """사용자 피드백 기록""" self.experiments[experiment_name]["results"][variant].append(score) def get_statistics(self, experiment_name: str) -> dict: """통계적 유의성 분석""" exp = self.experiments[experiment_name] stats = {} for variant, scores in exp["results"].items(): if scores: stats[variant] = { "mean": sum(scores) / len(scores), "count": len(scores), "positive_rate": sum(1 for s in scores if s > 0) / len(scores) } return stats
프로덕션 모니터링 지표
지표
설명
수집 방법
목표
사용자 만족도
좋아요/싫어요 비율
피드백 버튼
> 80% 긍정
태스크 완료율
사용자가 원하는 결과를 얻었는지
후속 질문 분석
> 70%
응답 지연시간
TTFT, 전체 응답 시간
서버 메트릭
P95 < 3초
할루시네이션율
사실과 다른 응답 비율
자동 검증 + 사람 평가
< 5%
거부율
안전성 가드레일에 의한 차단
로그 분석
적정 수준 유지
비용
토큰당 비용, 일일 비용
API 과금
예산 내
참고: LLM 평가는 "한 번에 완벽하게"가 아닌 "지속적으로 개선"하는 프로세스입니다. 프로덕션 데이터에서 실패 사례를 수집하고 평가 데이터셋에 추가하는 피드백 루프를 구축하세요.
References
Hendrycks, D. et al. (2021). "Measuring Massive Multitask Language Understanding (MMLU)." ICLR
Chen, M. et al. (2021). "Evaluating Large Language Models Trained on Code (HumanEval)." arXiv
Zheng, L. et al. (2023). "Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena." NeurIPS
Es, S. et al. (2024). "RAGAS: Automated Evaluation of Retrieval Augmented Generation." EACL
Muennighoff, N. et al. (2023). "MTEB: Massive Text Embedding Benchmark." EACL