본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 29. 17:14

LLM-as-a-Judge: 처음부터 직접 구축하고 인간과 비교 검증하기

요약

LLM의 출력을 평가하기 위해 LLM을 판사로 사용하는 'LLM-as-a-Judge' 방식의 한계와 직접 구축한 검증 과정을 다룹니다. LMSYS Chatbot Arena 데이터셋을 활용해 점수 불안정성, 낮은 해상도, 인간과의 낮은 일치율 등의 문제를 분석합니다.

핵심 포인트

  • LLM 판사는 점수 분포가 특정 구간에 쏠리는 해상도 부족 문제를 가짐
  • 동일 답변에 대해 점수가 변하는 불안정성 존재
  • 인간의 판단과 LLM 판사의 결정적 판단 일치율은 약 65% 수준
  • 위치 편향을 방지하기 위해 답변을 독립적으로 채점하는 방식 권장

Part 1에서 모델의 역할은 77개의 라벨 중 하나를 선택하는 것이었기에 == 연산자로 확인할 수 있었습니다. 하지만 대부분의 실제 LLM 출력은 그렇지 않습니다. 문단, 요약, 지원 답변 형태죠. 비교할 수 있는 라벨이 존재하지 않습니다.

그래서 사람들은 당연한 선택을 합니다. 바로 **LLM을 평가하기 위해 LLM을 사용하는 것(use an LLM to grade the LLM)**입니다. 질문과 답변을 보여주고, "이것이 얼마나 좋은지 1~10점으로 평가해줘"라고 요청한 뒤 그 숫자를 신뢰하는 방식입니다. 이는 놀라울 정도로 잘 작동합니다... 하지만 직접 찾아보지 않으면 알 수 없는 방식으로 작동하지 않는 순간이 옵니다.

저는 그 평가자(judge)를 처음부터 직접 구축했고, 실제 인간의 투표가 포함된 데이터셋을 통해 이를 검증했습니다. 바로 LMSYS Chatbot Arena 대화 데이터셋입니다 (제한이 없는 미러 사이트 agie-ai/lmsys-chatbot_arena_conversations를 통해 가져왔으므로, Kaggle에서 바로 실행 가능합니다). 각 행은 실제 사용자의 프롬프트, 두 개의 챗봇 답변, 그리고 어떤 답변이 더 나았는지에 대한 인간의 판결로 구성되어 있습니다.

평가자는 하나의 프롬프트와 정규 표현식(regex)입니다

JUDGE_RUBRIC = (
    'You are grading the quality of an answer to a question. '
    'Score from 1 (terrible) to 10 (excellent) based on correctness and helpfulness. '
...

그게 전부입니다. Qwen2.5-1.5B-Instruct가 하나의 답변을 읽고 숫자를 출력하는 것이죠. 노트북의 나머지 내용은 _그것을 맹목적으로 신뢰하지 않는 것_에 관한 것입니다. 루브릭(rubric, 평가 기준)이 의도적으로 단순하다는 점(

두 가지 문제가 있습니다. 첫째, 점수가 안정적이지 않습니다. 동일한 답변임에도 서로 다른 숫자가 나옵니다. 둘째, 더 심각한 문제는 '1~10점' 척도를 사용하는 판사(judge)가 항상 7점이나 8점만 내놓는다면, 이는 실제로 10점 척도를 사용하고 있는 것이 아니라는 점입니다. '좋음(good)'과 '훌륭함(great)'을 구분할 수 있는 해상도(resolution)가 거의 없는 것입니다. 따라서 두 개의 프롬프트(prompt)를 A/B 테스트할 때 한쪽이 7.6점, 다른 쪽이 7.9점을 받는다면, 그 격차는 소수점으로 포장된 노이즈(noise)에 불과합니다.

실패 사례 #2 — 인간과 일치하지 않음

각 쌍(pair)에 대해, 저는 답변 A와 답변 B를 독립적으로(judge가 두 답변을 동시에 보지 않도록 하여 위치 편향(position bias)을 완전히 방지함) 채점했습니다. 그 후 더 높은 점수를 받은 쪽을 judge의 선택으로 간주하고, 인간이 선택한 승자와 비교했습니다:

for p in pairs[:60]:
    s_a, _ = judge(p['question'], p['ans_a'])
    s_b, _ = judge(p['question'], p['ans_b'])
...

이 두 숫자를 함께 읽어보십시오:

  • 60개 중 20개가 무승부였습니다 — 전체 쌍의 3분의 1에서, 인간은 명확한 승자를 확인했음에도 불구하고 judge는 두 답변에 동일한 점수를 부여했습니다. (앞서 언급한 7~8점 구간을 기억하시나요? 모든 것이 7점 또는 8점으로 채점될 때, 많은 것들이 무승부가 됩니다.) 이는 실제 사람들이 볼 수 있는 차이를 인지하지 못한 것입니다.
  • 결정적인 판단에서의 일치율 65% — 동전 던지기보다는 낫지만, 확신을 가지고 내린 판단 중 3건 중 1건 이상에서 인간과 의견이 일치하지 않았습니다.

무승부를 오답으로 계산하면, judge가 모든 쌍 중 인간의 판단과 일치한 경우는 단 **26/60 = 43%**에 불과했습니다.

뼈아픈 증거 (The receipt that stung)

의견이 불일치한 사례들은 이것이 실패하는지를 알려줍니다. 제가 가장 좋아(혹은 인상 깊게 생각)하는 사례는 다음과 같습니다:

Q : 오늘은 며칠인가요?
  judge 점수 -> answer_a: 3, answer_b: 10  => judge는 model_b를 선택함
  하지만 인간은: model_a를 선호함

모델은 오늘이 며칠인지 전혀 모르고 있었기에, 확신에 찬 날짜 답변은 틀린 답이었습니다. 인간은 그 점을 잡아냈습니다. 하지만 judge는 확신에 찬 오답에는 10점을 주었고, 정직하게 확답을 피한 답변에는 3점을 주었습니다. judge는 정확성(correctness)을 채점한 것이 아니라, 확신도(confidence)를 채점하고 있었던 것입니다. (다른 사례들도 마찬가지였습니다. 1 대 2 또는 8 대 7의 '결정'들은 사실 무승부 주변에서 발생하는 노이즈에 불과했습니다.)

핵심 요점

이 노트북은 특정 _모델 (model)_에 대해 새로운 것을 밝혀내지는 않았습니다. 대신 점수를 매기는 주체인 **판사 (judge)**를 감사(audit)하였으며, 깔끔해 보이는 숫자 뒤에 숨겨진 두 가지 결함을 발견했습니다. 즉, 실행할 때마다 결과가 달라지는 자기 불일치 문제와, 사람의 판단과 일치하는 비율이 43%에 불과하다는 점입니다.

해결책은 "판사를 사용하지 마라"가 아닙니다. 핵심은 **평가자를 평가하는 것 (evaluate your evaluator)**입니다. 단일 숫자가 아닌 반복 측정을 통해 점수를 매기고 그 편차(spread)를 보고해야 하며, 아무도 라벨링하지 않은 데이터에 대해 판사를 신뢰하기 전에 반드시 인간의 라벨 (human labels)을 기준으로 보정(calibrate)해야 합니다.

다음 단계

Part 3: 잘못된 판사를 수정하는 두 가지 명확한 방법 — 더 큰 모델과 더 나은 루브릭 (rubric)을 다룹니다. 저는 동일한 인간의 투표 결과에 대해 네 가지 조합을 모두 실행하여, 각 레버가 실제로 얼마나 효과를 내는지 측정합니다. (더 저렴한 해결책이 예상보다 더 큰 역할을 합니다.)

📓 Kaggle에서 실행 가능한 전체 노트북: [https://www.kaggle.com/code/sumannath88/ep02-llm-as-a-judge]

PyTorch + Hugging Face Transformers로 제작되었습니다. 데이터: LMSYS Chatbot Arena (ungated mirror). 질문이나 수정 사항은 댓글로 환영합니다.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0