본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 04. 10:16

도메인 특화 LLM 평가 세트 구축하기

요약

일반적인 벤치마크가 놓치는 도메인 특화 모델의 결함을 파악하기 위해 수동 평가 세트 구축의 필요성을 설명합니다. 실제 운영 환경의 에지 케이스를 포함한 고유한 평가 데이터셋이 모델의 신뢰성을 보장하는 핵심임을 강조합니다.

핵심 포인트

  • 일반 벤치마크는 특정 도메인의 세부 태스크를 측정하지 못함
  • 데이터 오염 문제를 해결하기 위해 비공개 홀드아웃 세트가 필수적임
  • CI/CD 과정에서 회귀 테스트를 위한 릴리스 게이트 역할 수행
  • 대표성 있는 에지 케이스를 포함한 수동 라벨링 데이터셋 구축 필요

도메인 특화 LLM 평가 세트 구축하기

귀하의 지원 팀은 지난 1년 동안 라벨링된 8,400개의 티켓(ticket)을 보유하고 있습니다. 귀하가 미세 조정(fine-tuned)한 분류기는 별도로 분리한 테스트 분할(test split)에서 91%의 성능을 기록했습니다. 제품을 출시합니다. 3주 후, 지원 팀장이 다가와 이렇게 말합니다: "부분 환불 시 환불 금액을 환각(hallucinate)하고, 고객이 캘리포니아에 있을 때마다 정책 인용을 틀리게 합니다." 91%는 실제였습니다. 하지만 그 91%는 잘못된 것을 측정하고 있었습니다. 귀하의 테스트 세트는 티켓 텍스트의 무작위 분할(random split)이었을 뿐, 모델이 실제로 고장 나는 케이스들의 샘플이 아니었습니다.

그것이 바로 수동으로 구축한 평가 세트(evaluation set)가 메워주는 간극입니다. MMLU나 HellaSwag와 같은 기성 벤치마크(benchmarks)는 귀하의 모델이 여전히 일반적인 추론을 할 수 있는지를 알려줍니다. 하지만 그것들은 귀하의 모델이 귀하의 데이터에서, 귀하의 에지 케이스(edge cases)에서, 지원 팀장이 사무실을 가로질러 걸어오게 만드는 바로 그 방식들로 고장 나는지는 알려주지 못합니다.

왜 직접 평가 세트를 구축해야 하는가?

팀이 운영 환경(production)에서 겪게 되는 순서대로 세 가지 이유를 나열하면 다음과 같습니다:

  1. 일반 벤치마크는 귀하의 태스크(task)를 측정하지 못합니다. MMLU에는 임신 3분기 낙태법에 관한 질문이 있지만, 고객이 본문에 "처리됨(processed)"이라는 단어를 사용했기 때문에 모델이 refund_pending 티켓을 refund_completed로 오분류하는지에 대해서는 아무것도 없습니다. 귀하의 태스크는 MMLU의 태스크가 아닙니다.
  2. 오염(Contamination)은 피하는 것이 아니라 해결하는 것입니다. 설령 벤치마크가 귀하의 도메인을 다룬다 하더라도, 모델이 사전 학습(pretraining) 과정에서 이를 보지 않았다고 확신할 수 없습니다. 비공개 홀드아웃 세트(private held-out set)만이 깨끗한 신호(signal)를 제공하는 유일한 세트입니다.
  3. 회귀(Regressions)를 근본 원인에서 포착할 수 있습니다. CI(지속적 통합)의 핵심은 실제로 출시할 대상에 대해 빠르게 실패(fail fast)하는 것입니다. MMLU에서 lm-eval-harness를 실행하는 것은 건전성 검사(sanity check)이지만, 모든 PR(Pull Request)마다 귀하의 400개 예시 평가를 실행하는 것은 릴리스 게이트(release gate)입니다.

표준적인 대안인 "스테이징(staging) 환경에서 그냥 눈으로 확인하자"는 방식은 실패율이 100%입니다. 단지 천천히 실패할 뿐입니다.

"좋은" 평가 세트란 실제로 무엇인가

도메인 특화 평가 세트(domain-specific eval set)는 자동화된 지표(automated metric)로 점수를 매기며, 정답(또는 허용 가능한) 출력과 쌍을 이루는 입력값들을 고정(frozen)하고 버전 관리(versioned)하며 수동으로 라벨링(hand-labeled)한 컬렉션입니다. 유용한 평가 세트와 단순한 전시용 결과물(vanity artifact)을 구분하는 다섯 가지 속성은 다음과 같습니다:

속성 (Property)의미 (What it means)"나쁜" 사례 (What "bad" looks like)
대표성 (Representative)까다로운 5%의 사례를 포함하여 사용자가 실제로 보내는 입력 분포(input distribution)를 포괄함모든 예시가 깔끔하고, 형식이 잘 갖춰져 있으며, 영어로만 되어 있음
.........

처음 세 가지는 커버리지(coverage)와 엄밀성(rigor)에 관한 것입니다. 네 번째는 스스로를 속이지 않는 것에 관한 것입니다. 다섯 번째는 CI(지속적 통합) 환경에서 평가를 실행할 수 있게 해주는 유일한 속성입니다.

엔드 투 엔드(end to end) 파이프라인

flowchart TD
    A[400–800개의 가공되지 않은<br/>실제 운영 입력 샘플링] --> B[개인정보(PII), 비밀번호,<br/>ID 비식별화]
    B --> C[루브릭(rubric)을 통한 주석 달기<br/>항목당 1–3명의 전문가 평가자]
...

모든 박스는 실제 명칭이 있는 단계입니다. 팀들이 가장 자주 건너뛰는 단계는 D이며, 절대 건너뛰어서는 안 되는 단계는 EF입니다. 만약 평가자들 간의 의견이 일치하지 않는다면, 당신의 "정답(ground truth)"는 그저 노이즈(noise)일 뿐이며, 평가는 우연히 그 노이즈에 과적합(overfit)된 모델에 보상을 주게 될 것입니다.

1단계 — 입력값 샘플링

가능하다면 실제 운영 트래픽(production traffic)에서 시작하십시오. 몇 가지 규칙은 다음과 같습니다:

  • 중요하게 생각하는 차원(dimension)에 따라 층화(Stratify)하십시오. 만약 고객 지원 팀장의 불만이 "캘리포니아 티켓"에 관한 것이라면, 세트 안에 캘리포니아 티켓이 4개가 아니라 최소 50개는 있어야 합니다. 층화 추출(Stratified sampling)은 이를 해결해주지만, 무작위 추출(random sampling)은 해결해주지 못합니다.
  • 의도적으로 롱테일(long tail)을 포함하십시오. 모델 추론(reasoning)의 30%를 차지하는 1%의 입력값들이 바로 평가 세트가 존재하는 이유입니다. 이를 "노이즈"라고 간주하여 필터링하지 마십시오.
  • 누구도 보기 전에 비식별화(De-identify)하십시오. 이름, 이메일, 주문 ID, 그리고 고객을 식별할 수 있는 모든 자유 형식 텍스트(free-text)를 교체하십시오. 이는 대부분의 관할 구역에서 법적 요구 사항이지, 스타일의 선택 문제가 아닙니다.

합리적인 시작 규모는 단일 작업 분류기(single-task classifier)의 경우 400개, 생성 작업(generation task)의 경우 200~300개, 실패 시 위험도가 높은 분야(의료, 법률, 금융 등)의 경우 800개 이상입니다. 이 숫자들은 마법의 숫자가 아닙니다. (a) 직접 수동 레이블링(hand-label)을 할 수 있는 비용 범위 내에 있고, (b) 정확도 70%에서 표준 오차(stderr)가 약 1~2포인트 정도이며, (c) 층화 슬라이싱(stratified slicing)을 수행했을 때 각 셀(cell)당 20개 이상의 항목을 확보할 수 있는 범위입니다.

2단계 — 루브릭(Rubric)을 통한 주석 달기

"내 평가 결과가 사용자들의 의견과 일치하지 않는다"는 문제의 가장 큰 원인은 한 엔지니어의 머릿속에만 존재하는 루브릭(rubric, 평가 기준)입니다. 이를 문서로 작성하십시오. 좋은 루브릭은 세 가지 섹션으로 구성됩니다:

  1. 레이블의 정의 (Definition of the label). 전문 용어 없이 한 문장으로 작성합니다. 예시: "고객이 환불을 약속받았으나 받지 못했다고 주장하거나, 잘못된 금액으로 환불 처리가 되었다고 주장하는 경우 이 티켓은 refund_dispute로 분류한다."
  2. 긍정적 사례 (Positive examples). 한 줄의 근거와 함께 모호하지 않은 사례 5~10개를 제시합니다. 이는 모두가 동의하는 "쉬운" 사례들입니다.
  3. 어려운 사례 및 결정적 기준 (Hard cases and tie-breakers). 선택된 레이블과 그 *이유(reasoning)*를 포함한 모호한 사례 5~10개를 제시합니다. 여기서 정책적 결정 사항을 인코딩합니다(예: "부분 환불 분쟁은 항상 refund_dispute로 분류하며, 절대 general_question으로 분류하지 않는다").

루브릭이 없는 400개 항목의 데이터 세트는 세 명의 평가자(rater)에 의해 세 가지 다른 방식으로 레이블링될 것이며, 코헨의 카파(Cohen's kappa) 계수가 그 사실을 알려줄 것입니다.

3단계 — 일치도 측정

이 부분은 수학이 위협적으로 보여서 사람들이 건너뛰는 단계입니다. 하지만 그렇지 않습니다. 중요한 두 가지 지표는 다음과 같습니다:

  • 코헨의 카파 (Cohen's kappa, κ) — 두 명의 평가자, 고정된 카테고리, 완전한 데이터에 사용합니다. 값의 의미: 0 = 우연에 의한 일치, 1 = 완벽한 일치, <0 = 우연보다 낮은 일치. 0.7 미만이라면 평가자가 문제가 아니라 루브릭이 문제입니다. 루브릭을 수정하고 다시 주석을 다십시오.
  • 크립펜도르프의 알파 (Krippendorff's alpha, α) — 평가자의 수에 제한이 없고, 모든 측정 수준(명목/서열/등간/비율)에서 사용 가능하며, 결측치를 허용합니다. 평가자가 3명 이상이거나 서열 레이블(예: "1 = 나쁨, 2 = 보통, 3 = 좋음, 4 = 매우 좋음")을 사용하는 경우에 사용하십시오.

두 지표 모두 Python에서 한 줄의 코드로 구현 가능합니다:

from sklearn.metrics import cohen_kappa_score
import krippendorff

...

경험 법칙(Rule of thumb): κ(카파) 또는 α(알파) ≥ 0.8이면 배포(ship), 0.7이면 반복 개선(keep iterating), <0.7이면 중단하고 루브릭(rubric) 수정. 카파 지수가 0.5라는 것은 평가자들이 나쁘다는 뜻이 아닙니다. 이는 평가자들이 레이블(label)의 의미에 대해 합의하지 못했다는 뜻이며, 결과적으로 모델 또한 합의하지 못할 것임을 의미합니다.

4단계 — CI에서 실행되는 스코어러(scorer) 작성하기

수동으로 구축한 평가(eval)의 목적은 제품을 망가뜨릴 수 있는 PR(Pull Request)을 차단하는 것입니다. 사람이 개입해야 하는(human in the loop) 스코어러는 이 목적에 어긋납니다. 선호도 순서에 따른 세 가지 스코어러 스타일은 다음과 같습니다:

스코어러적합한 용도장점단점
Exact match (완전 일치)분류(Classification), 구조화된 출력(structured output), 정규 표현식(regex) 추출 가능 답변저렴함, 결정론적(deterministic), 판사 편향(judge bias) 없음포맷팅에 취약함
...

대부분의 팀에게 정답은 구조화된 케이스를 위한 소규모의 완전 일치(exact-match) 채점기, 그리고 자유 형식(free-form) 케이스를 위한 LLM-as-judge를 결합하는 것입니다. 이때 판사(judge) 자체는 50개의 항목으로 구성된 검증 세트(validation set)에서 사람이 레이블링한 정답과 비교하여 점수를 매겨야 합니다. 만약 판사가 사람과 85% 이상의 일치율을 보인다면, 대규모로 사용하기에 안전합니다.

흔한 실수들

  • 모델 자신의 출력물로 주석 달기 (Annotating with the model's own outputs). "GPT-4가 이것들에 라벨을 달게 하고, 그 라벨로 다시 GPT-4를 평가하겠다"는 것은 폐쇄 루프 (closed loop)입니다. 당신의 평가 (eval)는 모델의 품질이 아니라, GPT-4가 자기 자신과 얼마나 일관성을 유지하는지를 측정하게 될 것입니다.
  • "쉬운 90%"의 함정. 만약 첫날 베이스라인 (baseline) 점수가 90%가 나온다면, 당신의 데이터 세트는 너무 쉬운 것입니다. 평가자들에게 당신이 중요하게 생각하는 실패 모드 (failure modes)에서 의도적으로 선택한 항목을 50개 더 추가하도록 하세요.
  • 시간에 고정된 데이터 세트 (Frozen-in-time sets). 프로덕션 (production) 환경의 분포는 변화합니다 (distribution shifts). 12개월 된 평가 세트는 아무것도 잡아내지 못하면서 신뢰 구간 (CI)만 녹색으로 표시하는 기계로 조용히 퇴화할 수 있습니다. 매 분기마다 항목의 10~20%를 다시 샘플링하세요.
  • 일치도 확인 생략하기. 제가 함께 일했던 한 팀은 600개의 항목으로 구성된 평가 세트를 출시했고, 모델에서 84%를 달성하자 승리를 선언했습니다. 하지만 라벨에 대한 코헨의 카파 (Cohen's kappa) 계수는 0.41이었습니다. 그 "84%"는 인간들끼리 서로 얼마나 일치하는지에 대한 상한선이었으며, 모델은 동전 던지기보다 겨우 나은 수준이었습니다.
  • "맞아 보인다"를 지표로 취급하기. 결정론적 스코어러 (deterministic scorer)가 없다면, 당신의 평가는 CI (지속적 통합)에서 실행될 수 없고, 실행 간에 비교할 수 없으며, PR (Pull Request)을 반려할 수도 없습니다. Slack에서 출력이 수용 가능한지 여부를 두고 논쟁하고 있는 자신을 발견하는 순간, 당신은 루브릭 (rubric) 문제를 겪고 있는 것입니다.

직접 구축하지 말아야 할 때

다음과 같은 경우에는 커스텀 평가 세트를 만드는 것이 잘못된 결정입니다:

  • 아직 베이스 모델 (Base model)을 선정하는 중일 때. 600개의 항목으로 구성된 세트를 만들기 전에, 상위 3~5개의 후보 모델을 HellaSwag, MMLU, 그리고 자체 데이터의 소규모 샘플(50개 항목)로 먼저 실행해 보세요. Llama-3.1-70B가 귀하의 작업에서 Phi-3-mini보다 높은 점수를 받을 것이라는 사실을 알기 위해 커스텀 평가 (Custom eval) 세트가 필요하지는 않습니다. 광범위한 스캔에는 lm-eval-harness를 사용하고, 한두 개의 최종 후보로 좁힌 후에 커스텀 세트를 구축하세요.
  • 실제 사용자 데이터에 접근할 수 없을 때. 합성 평가 세트 (Synthetic eval sets, 예시가 관찰된 것이 아니라 생성된 경우)는 모델이 자신이 생성한 데이터에 대해 얼마나 잘 수행하는지를 측정합니다. 이는 생성 품질 평가 (Generation quality eval)이지, 사용자 관련성 평가 (User-relevance eval)가 아닙니다. 일부 용도로는 유용할 수 있으나, 대부분의 경우에는 무용지물입니다.
  • 작업 내용이 너무 빠르게 변할 때. 제품 사양 (Product spec)이 매주 바뀐다면, 구축한 모든 평가는 한 달 안에 쓸모없게 됩니다. 작업이 안정될 때까지 기다리거나, 100개 항목 정도의 "방향성 (Directional)" 세트를 구축하고 곧 다시 작성될 것임을 받아들이세요.

요약 (TL;DR)

  • **도메인 특화 평가 세트 (Domain-specific eval set)**는 CI (지속적 통합)에서 자동으로 실행되는, 고정되고 버전이 관리되며 수동으로 라벨링된 입력값과 정답 (Ground-truth) 출력값의 집합입니다.
  • 400~800개 항목이 유용한 시작 범위입니다. 중요하게 생각하는 차원 (Dimension)에 따라 계층화 (Stratify)하고, 롱테일 (Long tail) 데이터를 의도적으로 포함하세요.
  • **평가자 간 일치도 (Inter-rater agreement)**를 Cohen's κ (평가자 2명) 또는 Krippendorff's α (평가자 다수, 서열 데이터)로 측정하세요. 0.8 이상일 때 배포하고, 0.7 이상일 때 반복 개선하며, 0.7 미만일 때는 루브릭 (Rubric)을 수정하세요.
  • 사람 없이 실행 가능한 채점자 (Scorer)를 선택하세요: 구조화된 작업에는 완전 일치 (Exact match), 바꾸어 말하기가 가능한 답변에는 임베딩 유사도 (Embedding similarity), 개방형 생성에는 LLM-as-judge (판단 도구로서의 LLM, 판단자를 검증하기 위한 별도의 검증 세트 포함)를 사용하세요.
  • 분포 변화 (Distribution shift)를 포착하기 위해 분기별로 항목의 10~20%를 재샘플링 (Re-sample)하세요. 그렇지 않으면 평가 세트는 귀하가 배포하는 제품을 조용히 측정하지 못하게 됩니다.
  • lm-eval-harness를 통해 후보 모델을 1~2개로 좁히기 전까지는 구축하지 마세요. 커스텀 평가는 릴리스 게이트 (Release gates)를 위한 것이지, 베이스 모델을 선정하기 위한 것이 아닙니다.

다음 포스트: 모든 PR (Pull Request)에서 실행되는 CI 파이프라인 (CI pipeline)에 평가 세트 (eval set)를 실제로 연결하는 방법 — GitHub Actions 설정, 모델 서빙 (model-serving) 측면, 그리고 "24GB GPU 없이 GitHub 러너 (GitHub runner)에서 7B 모델을 어떻게 실행할 것인가"라는 문제에 대해 다룹니다.

만약 도메인 평가 세트 (domain eval set)를 구축하셨고, 저희가 놓친 여러분만의 선호하는 점수 산정 기법(scoring trick)이 있다면 — 여러분이 애용하는 정규 표현식 (regex), 실제로 효과가 있는 판사 프롬프트 (judge prompt), 또는 프로덕션 데이터 (production data)를 활용한 샘플링 전략 (sampling strategy) 등 — 댓글을 남겨주세요. 다음 시리즈 포스트를 위해 다양한 패턴들을 수집하고 있습니다.

AI 자동 생성 콘텐츠

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

원문 바로가기
0

댓글

0