LLM 평가 점수는 불안정한 테스트 스위트와 같다 — 그렇게 다루어야 한다
요약
LLM 평가는 비결정론적 요소로 인해 불안정한 테스트 스위트처럼 작동하므로, 이를 단순한 지표가 아닌 노이즈가 포함된 데이터로 다뤄야 합니다. 온도 설정 고정, 심사관 보정, 데이터셋 버전 관리 등을 통해 측정의 변동성을 통제하는 것이 핵심입니다.
핵심 포인트
- LLM 평가는 모델, 심사관, 데이터셋의 무작위성이 결합된 비결정론적 과정임
- 온도(temperature)를 0으로 설정하여 불필요한 샘플링 변동성을 최소화해야 함
- LLM-as-a-judge 사용 시 심사관 모델의 편향과 변동성을 지속적으로 보정해야 함
- 단일 점수보다는 실행 간 표준 편차와 데이터 분포를 함께 확인해야 함
당신의 평가 점수가 하룻밤 사이에 82점에서 79점으로 떨어졌습니다. 아무도 프롬프트를 바꾸지 않았고, 모델도 바꾸지 않았습니다. 당신이 다시 실행하자 84점이 나왔습니다. 그래서 배포를 진행했습니다. 왜냐하면 84점은 상승세였고, 스탠드업 미팅이 10분 뒤에 있었기 때문입니다.
그것은 평가가 아닙니다. 그것은 실험복을 입은 동전 던지기와 같습니다. 만약 단위 테스트(unit test)가 동일한 코드에서 통과하고, 실패했다가 다시 통과한다면, 당신은 그것을 불안정하다(flaky)고 부르거나 수정하거나 격리할 것입니다. 절대로 배포를 막는 기준(gate)으로 삼지 않을 겁니다. LLM 평가는 정확히 그러한 불안정한 테스트 스위트처럼 작동하며, 대부분의 팀들은 어쨌든 그 노이즈를 신호로 받아들입니다.
요약 — LLM 평가는 비결정론적 시스템(non-deterministic system)에 대한 테스트 스위트이며, 또 다른 비결정론적 시스템에 의해 점수가 매겨지고, 이 과정은 조용히 변화하는 데이터셋을 대상으로 합니다. 실제 실패 모드는 모든 불안정한 스위트가 가진 것들입니다: 통제되지 않는 시드(seeds), 표류하는 심사관(drifting judge), 유출되거나 변이되는 데이터셋(leaking or mutating dataset), 그리고 분산 없이 보고된 점수. 이 문제들을 지루한 방식으로 해결하세요 — 가능한 것은 고정하고, 심사관을 보정하며, 데이터셋을 동결하고 버전을 지정하고, 분포를 보고하고, 중첩(overlap)에 따라 게이팅을 설정하면, '모델 성능이 나빠졌다'는 말은 대부분 '측정이 노이즈가 많았다'로 돌아갑니다.
점수가 흔들리는 이유는 그 아래의 모든 것이 비결정적이기 때문이다
단일 평가 실행(eval run)에는 적어도 세 가지 독립적인 무작위 프로세스(random processes)가 쌓여 있습니다. 모델은 온도를 사용하여 토큰을 샘플링합니다. 심사관 — 만약 LLM-as-judge를 사용한다면 — 또한 같은 방식으로 자신의 판결을 샘플링합니다. 그리고 당신이 점수를 매기는 평가 데이터셋은 보통 작기 때문에, 몇 개의 항목만 바뀌어도 헤드라인 숫자가 여러 포인트만큼 요동칩니다.
세 가지 노이즈 소스를 쌓으면 스스로 움직이는 지표가 나옵니다. 실행 간 표준 편차(run-to-run standard deviation)가 4점인데, 3점의 변화를 회귀(regression)로 취급하는 것은 평가에서 프린트 문장(print statements)을 추가하여 레이스 컨디션(race condition)을 추적하려는 것과 같습니다. 당신은 변화에 반응하는 것이 아니라, 떨림(jitter)에 반응하고 있는 것입니다.
고정할 수 있는 시드는 고정하고; 할당된 예산으로 처리할 수 없는 것을 대비하라
모든 불안정한(flaky) 테스트에 대한 첫 번째 조치는 제거 가능한 무작위성(randomness)을 없애는 것입니다. 평가 점수 측정에서도 마찬가지입니다. 사실적 정확도, 형식 준수 여부, 루브릭 기반의 합격/불합격 여부를 확인하려면 모델을 temperature = 0으로 실행하고 설정할 수 있는 모든 샘플링 매개변수를 고정해야 합니다. 진정한 결정론(determinism)은 얻지 못할 것입니다 (커널, 배치 처리, 하드웨어는 여전히 로짓(logits)에 떨림을 주지만), 하지만 분산(variance)은 크게 줄일 수 있습니다.
반면에 창의성, 거부 행동, 견고성 등 실제 분포를 신경 써야 하는 경우에는 정반대로 의도적으로 수행해야 합니다. 즉, 일련의 시드(seeds)를 고정하고 각 항목을 이 모든 시드를 통해 실행하는 것입니다. 핵심은 무작위성이 통제되거나 측정되어야 한다는 것입니다. 통제되지 않은 상태로 남겨두고 그 평균값을 안정적인 것처럼 읽는 것은 불가능합니다.
LLM 평가자는 불안정한 의존성(flaky dependency)이므로 보정해야 한다
평가자 자체가 모델인 순간, 당신은 테스트 대상 시스템을 하나 더 추가하고 자체적인 테스트 없이 그 출력을 신뢰하기 시작한 것입니다. 평가자들은 모델 버전마다 표류하며, 재실행 시 자기모순에 빠지고, 위치 및 서술적 편향(position and verbosity biases)을 지니고 있습니다. 즉, 같은 답변이라도 A로 레이블링되었는지 B로 레이블링되었는지에 따라 점수가 다르게 매겨집니다.
평가자를 통제할 수 없는 다른 의존성처럼 취급하십시오. 골든 세트(golden set)를 기준으로 삼아야 합니다. 직접 레이블링한 몇십 개의 항목을 구성하고, 평가자가 이 인간 레이블과 얼마나 일치하는지 측정하며, 그 일치도를 시간이 지남에 따라 추적해야 합니다. 만약 평가자가 단지 70%의 확률로 인간과 동의한다면, 테스트 대상 모델이 말을 꺼내기도 전에 당신의 평가는 ±30%의 오차 막대(error bar)를 내장하고 있다는 의미입니다. 측정하기 전에 자(ruler)를 보정하십시오.
평가 세트를 소스 코드처럼 버전 관리해야 한다, 왜냐하면 그것은 그러하기 때문이다
여기에는 조용한 살인자가 있습니다: 누군가가 평가 세트를
평가 세트는 소스 코드처럼 버전 관리해야 한다, 왜냐하면 그것은 그러하기 때문이다
여기에는 조용한 살인자가 있습니다: 누군가가 평가 세트를
평가 데이터는 코드가 됩니다. 이를 버전 관리에 넣고, 변경 사항을 PR(Pull Request)에서 검토하며, 실행된 모든 결과에 해당 데이터셋의 해시를 표시해야 합니다. 다른 해시에 대해 실행된 두 점수를 비교할 때는 반드시 그렇게 말해야 합니다. 그리고 반대 방향인 누출(leakage)에도 대비해야 합니다. 이는 평가 항목이 학습 데이터나 퓨샷 예제(few-shot examples)로 흘러 들어가 모델이 정답지 자체를 본 탓에 점수가 올라가는 경우입니다. 오직 상승하는 숫자만이 종종 오염된 숫자일 수 있습니다.
포인트 점수 대신 분포를 보고하라
단 하나의 숫자, 즉
그리고 마지막으로 불안정한 테스트(flaky-test)를 처리하는 방법을 실행하세요: 격리입니다. 평가 결과가 너무 노이즈가 심해서 게이트 기준으로 삼을 수 없다면, 그것을 헤드라인 숫자에 평균 내어 실제 움직임이 숨겨지게 하지 마세요. 대신 감시 목록(watch list)으로 빼내고, 이를 다듬은 후, 분산(variance)이 통제될 때만 다시 게이팅에 승격시키세요. 노이즈가 심한 평가를 깨끗한 평가에 평균 내는 것이 그 노이즈를 상쇄하는 것은 아닙니다. 단지 당신이 실수로 신뢰하게 될 숫자로 세탁할 뿐입니다.
관점 전환 (The reframe)
움직인 평가 점수를 모델의 지능에 대한 판결처럼 취급하는 것을 멈추세요. 그것은 당신이 구축한 노이즈가 심한 파이프라인에서 나온 측정값일 뿐이며, 측정값에는 출력 여부와 관계없이 오차 막대(error bars)가 존재합니다. LLM 평가를 알 수 없게 느끼도록 만드는 거의 모든 것은 이미 소프트웨어 테스트가 해결한 분야입니다: 무작위성을 제어하고, 채점기(grader)를 보정하며, 고정 장치(fixtures) 버전을 관리하고, 분산을 보고하며, 신호에 게이팅을 적용하는 것입니다.
그렇게 하면, 대부분의 '모델이 퇴보했다'는 사건들은 '측정이 노이즈가 심했고 우리가 마침내 알아차렸다'로 해결됩니다. 당신의 모델은 아마 괜찮을 겁니다. 주변 테스트 스위트를 고치는 데 집중하세요.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기