검증 가능한 도메인 — 수학과 코드

Training Verifiers to Solve Math Word Problems (Cobbe et al., OpenAI, arXiv 2021)

Evaluating Large Language Models Trained on Code (Chen et al., OpenAI, arXiv 2021)

Introduction

#7에서 본 MMLU 계열은 객관식이라 judge가 필요 없었다. 그런데도 완전히 깨끗하지는 않았다 — 정답 라벨 자체가 사람이 만든 것이라 오류·모호 문항이 섞여 있었고, MMLU-Redux 같은 후속 벤치가 그 오류를 다시 사람이 찾아내야 했다.

이번 글은 조작화(operationalization)를 한 단계 더 밀어붙인 도메인을 본다. 정답이 사람의 판단이 아니라 프로그램으로 검증되는 도메인, 즉 수학과 코드다. 여기서는 이렇게 묻는다 — “이 답이 맞는가”를 사람도 judge 모델도 아닌 컴파일러·유닛 테스트·기호 계산기가 판정하면 무슨 일이 일어나는가.

이 글의 논지는 세 줄로 요약된다.

  1. 채점이 프로그램이라는 것은 파라미터가 0개인 채점자를 쓴다는 뜻이다. 학습된 judge가 없으니 judge 편향이 없고, 사람 라벨러가 없으니 라벨 잡음도 없다. #12 ~ #14에서 다룬 문제 — 평가자마다 다른 “유창성” 정의, κ의 역설 — 가 원천적으로 발생하지 않는다.
  2. 그런데 “검증 가능”이라는 말 자체가 하나의 조작적 정의다. 그 정의를 실제로 구현하는 두 부품 — 테스트 스위트(무엇을 정답으로 인정할 것인가)와 답 추출 파서(모델 출력 어디서 최종 답을 뽑아낼 것인가) — 가 구성개념(construct)을 불완전하게 담으면, 그 불완전함이 아무 경고 없이 점수에 스며든다. 사람 judge는 이상한 채점 앞에서 최소한 “이거 좀 이상한데” 하는 감(judgment)이라도 있지만, 프로그램에는 그 감이 없다.
  3. 그래서 이 글은 세 개의 반례로 이 취약점을 구체적으로 보여준다. 통과했던 코드가 테스트를 강화하자 대거 떨어지는 사례, 정답 판정 파서가 동치 표현을 오답 처리하는 사례, 그리고 문항 수가 너무 적어 신뢰구간이 벤치마크 자체를 삼켜버리는 사례다.

수학 쪽에서는 GSM8K, MATH, AIME를, 코드 쪽에서는 HumanEval, MBPP, EvalPlus/HumanEval+, LiveCodeBench, SWE-bench(→ SWE-bench Verified)를 다룬다. 각 벤치는 이 시리즈의 공통 틀 — 구성개념 → 조작화 → 깨진 지점 → 후속 교정 — 으로 본다.

Background

검증 가능한 채점이란 무엇인가

검증 가능한 채점(verifiable grading)이란 점수를 다음과 같이 정의하는 것이다.

\[\text{score}(y, y^*) = f(y, y^*)\]
  • \(y\): 모델이 낸 출력.
  • \(y^*\): 정답 또는 정답을 판정할 수 있는 참조 자료(정답 숫자, 유닛 테스트 집합).
  • \(f\): 결정론적 프로그램이다. 학습된 가중치를 가진 judge 모델이 아니고, 사람 평가자도 아니다. 유닛 테스트를 실행하거나, 기호 계산으로 두 수식이 같은지 비교하거나, 문자열을 정규화한 뒤 비교하는 코드다.

이 정의가 주는 세 가지 장점이 있다.

  • 파라미터 0개: judge 모델처럼 별도로 학습·미세조정할 것이 없다. judge 자체가 가질 수 있는 위치 편향·장황함 편향(#19에서 다룰 문제)이 원천 차단된다.
  • 편향 없음: 같은 입력에 같은 프로그램을 돌리면 항상 같은 결과가 나온다. 사람 평가자 간 불일치(#13 κ 계열이 다루는 문제)가 존재하지 않는다.
  • 비용이 낮다: judge 모델 호출도, 사람 시급 지급도 없다. 유닛 테스트 실행은 CPU 몇 초면 끝난다.

그런데 이 장점에는 대가가 있다. \(f\) 라는 프로그램이 “정답인가”라는 구성개념을 완전히 조작화했다는 가정 위에 이 모든 이점이 서 있다. 그 가정이 틀리면 — 테스트가 허술하거나 파서가 형식에 취약하면 — 판정 오류가 조용히, 그리고 대규모로 발생한다. 비유하면 이렇다. 사람 채점관은 실수해도 “이상한데?”라는 자각이 남지만, 프로그램 채점관은 자기가 잘못 채점하고 있다는 사실 자체를 모른다. 채점관이 완벽한 것이 아니라, 채점관의 정의(스펙)가 완벽하다고 가정하는 것이다.

pass@k와 그 추정 — 왜 naive하게 세지 않는가

코드 생성 평가의 표준 지표는 pass@k다. 모델이 문제 하나당 \(k\) 개의 후보를 낼 수 있을 때, 그중 하나라도 모든 유닛 테스트를 통과하면 그 문제를 “풀었다”고 본다.

가장 단순한 방법은 문제당 정확히 \(k\) 개를 생성해 통과 여부를 세는 것이다. 하지만 이 방법은 분산이 크다 — 같은 모델이라도 어떤 \(k\) 개가 뽑히느냐에 따라 결과가 흔들리고, \(k\) 가 작을수록 문제 하나하나가 사실상 동전 던지기가 된다. Chen et al. (2021)은 대신 문제당 훨씬 많은 \(n\) 개(\(n \ge k\), 논문에서는 \(n=200\))를 생성해 두고, 그중 \(k\) 개만 뽑았다면 얼마나 자주 성공했을지를 조합론으로 정확히 계산하는 불편추정량(unbiased estimator)을 쓴다.

\[\text{pass@}k := \mathbb{E}_{\text{Problems}}\left[\, 1 - \frac{\binom{n-c}{k}}{\binom{n}{k}} \,\right]\]

기호를 풀면 이렇다.

  • \(n\): 문제 하나당 실제로 생성한 전체 샘플 수.
  • \(c\): 그 \(n\) 개 중 유닛 테스트를 전부 통과한(정답인) 샘플 수.
  • \(k\): 실제로 “몇 번 시도할 것인가”에 해당하는 값 — pass@1, pass@10처럼 보고하고 싶은 시도 횟수.
  • \(\binom{n}{k}\): \(n\) 개 중 \(k\) 개를 뽑는 전체 경우의 수.
  • \(\binom{n-c}{k}\): 오답 샘플(\(n-c\) 개) 중에서만 \(k\) 개를 뽑는 경우의 수 — 즉 \(k\) 번 다 오답을 뽑을 경우의 수.
  • \(1 - \dfrac{\binom{n-c}{k}}{\binom{n}{k}}\): “\(k\) 개를 뽑았을 때 전부 오답일 확률”을 1에서 빼면, “\(k\) 개 중 적어도 하나는 정답일 확률”이 나온다.

방향을 직접 확인해보자. \(k\) 가 커지면 (n, c 고정) \(\binom{n-c}{k}\) 는 작아지거나(뽑을 수 있는 조합이 줄어드니까), \(k > n-c\) 인 순간부터는 정확히 0이 된다(오답이 \(n-c\) 개뿐인데 \(k\) 개를 다 오답으로만 뽑을 수는 없으므로). 그러면 pass@k는 1로 수렴한다 — “더 많이 시도할수록 하나쯤은 맞힌다”는 직관과 일치한다. 같은 논리로 \(c\) 가 커지면(정답 비율이 높으면) 오답 후보군 \(n-c\) 가 작아지므로 \(\binom{n-c}{k}\) 가 작아지고, pass@k는 커진다 — 이 역시 맞는 방향이다.

이 추정량이 naive한 “k개만 뽑아서 세기”보다 나은 이유는 더 많은 정보(\(n\) 개 전체)를 실제로 쓰기 때문이다. k개만 뽑아 매번 다시 채점하면 매 시행이 독립적인 동전 던지기라 결과가 크게 흔들리지만, \(n \gg k\) 개를 미리 뽑아두고 조합론으로 “k개를 뽑았을 확률”을 정확히 계산하면 표본이 훨씬 크므로 추정량의 분산이 작아진다. 같은 데이터에서 더 안정적인 숫자를 뽑아내는, 통계적으로 더 효율적인 사용법인 셈이다.

토이 예제: n=5, c=2

문제 하나에 대해 샘플을 5개 생성했고(n=5), 그중 2개가 정답이었다고(c=2) 하자.

  • pass@1 \(= 1 - \dfrac{\binom{3}{1}}{\binom{5}{1}} = 1 - \dfrac{3}{5} = 0.4\). 이 값은 그냥 \(c/n = 2/5\) 와 같다 — \(k=1\) 일 때는 불편추정량이 표본비율과 일치하는 게 당연하다.
  • pass@2 \(= 1 - \dfrac{\binom{3}{2}}{\binom{5}{2}} = 1 - \dfrac{3}{10} = 0.7\).
  • pass@3 \(= 1 - \dfrac{\binom{3}{3}}{\binom{5}{3}} = 1 - \dfrac{1}{10} = 0.9\).
  • pass@5 \(= 1 - \dfrac{\binom{3}{5}}{\binom{5}{5}} = 1 - \dfrac{0}{1} = 1.0\). \(n=5\) 전부를 쓰면(\(k=n\)) 두 정답이 반드시 포함되니 100%가 되는 게 당연하다.

\(k\) 를 늘릴수록 pass@k가 단조 증가하는 것이 그대로 확인된다. 이 지표가 이 글에서 “코드” 쪽 채점의 기본 단위다. “수학” 쪽은 대부분 정답이 숫자·수식 하나이므로 \(k=1\) 의 이항 채점(맞았다/틀렸다)을 그대로 쓰는 경우가 많다.

Method

GSM8K — 초등 수준 문제에서 시작된 verifier

  • 구성개념: 초등학교 수준의 산술 추론 능력.
  • 조작화: Cobbe et al. (2021)은 총 8,792개 문항(학습 7,473 / 테스트 1,319)을 만들었다. 크라우드워커가 아니라 문제 작성자(problem writer)가 직접 작성해 언어적 다양성을 확보했다. 정답은 최종 숫자 하나이므로 exact match로 채점한다.
  • 이 논문의 진짜 기여는 데이터셋보다 verifier다. 파인튜닝만으로 정답률을 올리는 대신, 여러 후보 풀이를 생성한 뒤 “이 풀이가 맞았는가”를 판별하도록 별도로 학습한 verifier 모델로 순위를 매겨 최선의 풀이를 고른다. 이 verifier 방식을 쓰면 훨씬 작은 모델이 몇 배나 큰 파인튜닝 전용 모델과 맞먹는 정확도를 낸다는 것이 논문의 핵심 주장이고, verifier가 데이터를 늘릴수록 파인튜닝 단독보다 훨씬 잘 스케일한다는 점도 함께 보인다.
  • 이 지점이 이 시리즈의 다음 갈래를 예고한다. “정답이 프로그램으로 채점된다”는 조작화는 이후 강화학습의 reward 설계에 그대로 흘러 들어간다 — 규칙 기반 검증 가능 reward(RLVR)를 다룬 DeepSeek-R1의 원형이 여기 있다.
  • 깨진 지점: 초등 수준 산술이라 구성개념(“수학적 추론 능력”) 대비 난이도 천장이 너무 낮다. 최신 모델은 이 벤치에서 금방 포화(saturate)된다.
  • 후속 교정: 훨씬 어려운 MATH로 난이도를 올렸고, 최근에는 GSM8K 자체의 오염·과적합 여부를 문제를 변형해 재검증하는 GSM-Symbolic류 후속 연구가 등장했다.

MATH — 난이도는 올렸지만, 정답 판정이 새 문제가 됐다

  • 구성개념: 경시대회 수준의 수학 문제 해결 능력.
  • 조작화: Hendrycks et al. (2021)은 12,500개 문항(학습 7,500 / 테스트 5,000)을 만들었다. Prealgebra, Algebra, Number Theory, Counting & Probability, Geometry, Intermediate Algebra, Precalculus의 7개 과목5단계 난이도(Level 1이 가장 쉽고 Level 5가 가장 어려움)로 나눴다. 문항마다 단계별 풀이(step-by-step solution)까지 붙어 있어, 이 데이터는 이후 process reward 연구(Let’s Verify Step by Step 계열)의 기반이 된다.
  • 깨진 지점: 정답이 LaTeX 수식이라는 사실 자체가 문제다. \(\frac{1}{2}\), \(0.5\), \(1/2\)는 모두 같은 수를 가리키지만 문자열로는 셋 다 다르다. exact match를 쓰려면 정규화(normalization) 규칙이 필요한데, 그 규칙이 “수학적으로 같은가”라는 구성개념을 완전히 담지 못하면 맞는 답을 틀렸다고 채점한다. 실제로 EleutherAI의 lm-evaluation-harness 저장소에는 “Level 5 문항의 답 추출 로직이 지나치게 엄격할 수 있다(Answer extraction logic for Math Lvl 5 may be too strict)”는 이슈가 열려 있다 — 정확 매칭 채점이 실제 파이프라인에서 자주 뚫린다는 방증이다.
  • 후속 교정: 문자열 비교 대신 SymPy 같은 기호 계산 엔진으로 두 표현이 실제로 동치인지 판정하는 Math-Verify 같은 파서 도구가 표준으로 자리잡았다. 채점 신뢰도를 확보하기 위해 OpenAI가 사람 검수로 선별한 500문항 부분집합(MATH-500)도 실무에서 널리 쓰인다.

AIME — 문항이 너무 적어서 신뢰구간이 벤치마크를 삼킨다

  • 구성개념: 최상위 수준(고교 경시) 수학적 추론.
  • 조작화: 미국고교수학경시(AIME)는 매년 두 번(AIME I, AIME II) 치러지고 각 15문항, 연간 총 30문항이다. 답은 0~999 범위의 정수 하나이며 exact match로 채점한다. 학습 데이터 오염을 걱정할 필요가 적은 그 해에 새로 나온 대회 문제를 그대로 eval로 쓰는 방식이라, 2024년 이후 최신 모델 평가에서 “AIME 2024”, “AIME 2025”처럼 연도별로 지칭하며 널리 쓰인다.
  • 깨진 지점: 문항 수 30개는 통계적으로 지나치게 작다. 직접 계산해보면 감이 온다.
    • 문항 1개 차이 \(= \dfrac{1}{30} \approx 3.33\)%p.
    • 즉 두 모델의 점수차가 3%p라면, 그것은 정확히 문항 하나 차이일 수 있다.
    • 이항비율의 표준오차로 봐도 마찬가지다. \(p=0.5\), \(n=30\)일 때 \(\text{SE} = \sqrt{p(1-p)/n} = \sqrt{0.25/30} \approx 9.13\%\)이고, 95% 신뢰구간 반폭은 \(1.96 \times 9.13\% \approx 17.9\)%p에 달한다. 정확도 50%인 모델의 “진짜” 실력은 대략 32~68% 사이 어딘가라는 뜻이다.
    • 벤치마크 하나로 순위를 논하기엔 지나치게 넓은 구간이다. 이 계산을 이항비율 신뢰구간 이론으로 제대로 다루는 것이 #15의 역할이다.
  • 후속 교정: 여러 번 시행(run)한 뒤 평균과 표준오차를 함께 보고하는 방식(MathArena 같은 평가 플랫폼이 채택), 또는 여러 해의 AIME를 합쳐 표본 크기를 키우는 방식이 쓰인다.

HumanEval — 함수 하나, docstring 하나, 테스트 하나

  • 구성개념: 프로그램을 작성하는 능력(functional correctness).
  • 조작화: Chen et al. (2021)은 164개의 손으로 작성한 문제를 만들었다. 각 문제는 함수 시그니처와 docstring을 주고 함수 본문을 완성하게 한 뒤, 숨겨진(hidden) 유닛 테스트를 실행해 통과 여부로 채점한다 — 위 Background에서 정의한 pass@k 그대로다. 원 논문에서 Codex는 pass@1 28.8%, 문제당 100개 샘플을 뽑는 pass@100에서는 70.2%를 기록했다.
  • 깨진 지점: 문제당 테스트 케이스가 평균 몇 개 수준으로 적었다. edge case를 촘촘히 덮지 못했기 때문에, “그럴듯하지만 특정 입력에서는 틀리는” 코드도 통과할 여지가 있었다.
  • 후속 교정: 아래 EvalPlus/HumanEval+가 바로 이 문제를 겨냥한 벤치다.

MBPP — 더 쉬운 버전, 같은 설계

  • 구성개념·조작화: Austin et al. (2021)이 크라우드소싱으로 만든 974개의 초급 수준 파이썬 문제로, 문항마다 자동 검증용 테스트가 3개씩 딸려 있다. 설계 철학은 HumanEval과 동형(同型)이다 — 짧은 문제 설명을 주고 함수를 작성하게 한 뒤 유닛 테스트로 pass@k 채점을 한다. 다만 문제 난이도가 더 낮아 “입문자가 풀 수 있는 수준”을 겨냥한다.
  • 취약점과 교정 방향은 HumanEval과 완전히 같은 모양이라(테스트가 부실하면 오답이 통과) 아래 EvalPlus 절에서 MBPP+로 함께 다룬다.

EvalPlus / HumanEval+ — “정답”이라는 조작적 정의가 헐거웠던 교과서적 사례

  • 구성개념: HumanEval/MBPP와 동일하다 — 이 벤치는 새 구성개념을 제안한 게 아니라, 기존 조작화가 얼마나 부실했는지를 검증한 벤치다.
  • 조작화: Liu et al. (NeurIPS 2023, arXiv 2305.01210)은 HumanEval의 문제당 테스트 케이스를 80배로 늘려 HumanEval+를 만들었다(뒤집어 말하면 원래 테스트가 그 정도로 적었다는 뜻이다). 자동 테스트 생성기로 입력을 변형(mutation)해 edge case를 촘촘히 채웠고, 같은 방식으로 MBPP+도 만들었다.
  • 깨진 지점이자 발견: 강화된 테스트를 적용하자, 기존에 “정답”으로 채점됐던 코드가 대거 걸러졌다. GPT-4는 원본 HumanEval에서 pass@1 88.4%였지만 HumanEval+에서는 76.2%로 떨어졌다 — 12.2%p 하락이다. 26개 모델 전반을 놓고 보면 pass@k가 대체로 10~20%p대로 낮아졌고, 조건에 따라 최대 19.3~28.9%까지 낮아지는 경우도 보고됐다. 더 인상적인 결과는 순위 역전이다 — WizardCoder-CodeLlama와 Phind-CodeLlama는 원본 HumanEval에서 ChatGPT를 이기지 못했지만, HumanEval+에서는 ChatGPT를 이겼다. 즉 “어느 모델이 더 코드를 잘 짜는가”라는 순위 자체가 테스트 커버리지라는, 벤치마크의 눈에 보이지 않는 설계 선택에 의존하고 있었던 것이다.
  • 후속 교정: HumanEval+/MBPP+가 이후 코드 생성 평가의 표준 채점 스위트로 널리 채택됐다. 이 사례는 이 글 전체의 결론을 가장 선명하게 보여준다 — 규칙 기반 채점에서 “정답”의 조작적 정의는 테스트 스위트 그 자체이고, 테스트가 허술하면 타당도가 조용히, 그리고 대규모로 무너진다.

LiveCodeBench — 오염을 시점으로 회피한다

  • 구성개념: 코딩 능력. 다만 “이 능력이 진짜 일반화인가, 학습 데이터 암기인가”까지 함께 검증하고자 한다.
  • 조작화: Jain et al. (2024, arXiv 2403.07974)은 LeetCode·AtCoder·Codeforces 세 플랫폼에서 대회가 끝나는 대로 문제를 실시간으로 수집하고, 문제마다 정확한 공개일(publish date)을 함께 저장한다. 2023년 5월부터 누적을 시작해 500문항 이상으로 계속 자라는 living benchmark다. 평가할 때는 “이 모델의 학습 데이터 컷오프 이후에 나온 문제만” 골라 채점할 수 있다 — 정적 스냅샷 벤치마크로는 원천적으로 할 수 없는 일이다.
  • 깨진 지점(정확히는, 이 벤치가 다른 벤치들의 깨진 지점을 잡아낸 것): 논문은 DeepSeek-Instruct-33B가 자기 공개일(2023년 8월) 이전에 나온 LeetCode 문제에서는 pass@1이 약 60% 수준이다가, 공개일 이후 새로 나온 문제에서는 거의 0%로 떨어지는 것을 보였다 — 이전 문제의 정답이 학습 데이터에 이미 들어 있었다는 강한 정황이다. GPT-4o 역시 자기 학습 컷오프(2023년 11월) 부근에서 성능이 꺾이는 패턴이 보고됐다. “컷오프 이전 문제에서 높은 점수”는 실력이 아니라 암기일 수 있다는 것을, 정적 벤치마크는 원리적으로 보여줄 수 없다.
  • 후속 교정: 이 시점 기반 설계 자체가 후속 교정이다. “계속 새 문제를 공개일과 함께 쌓는다”는 방식으로, 정적 벤치마크가 못 하는 오염 회피를 구조적으로 해결했다. 오염 탐지의 통계적 방법론(교환가능성 검정 등) 일반론은 #20에서 다룬다.

SWE-bench → SWE-bench Verified — 검증 가능한 채점의 함정판

SWE-bench는 이미 이 블로그의 Red-Teaming 시리즈에서 에이전트가 실제 소프트웨어 이슈를 자율적으로 해결할 수 있는가라는 능력 축으로 다뤄진 적이 있다. 여기서는 같은 벤치를 “채점이 프로그램으로 완전히 자동화되어 있다”는 측정론적 각도에서만 짧게 본다 — 중복 서술이 아니다.

  • 구성개념: 실제 세계의 소프트웨어 엔지니어링 능력.
  • 조작화: Jimenez et al. (2023, arXiv 2310.06770)은 12개 인기 파이썬 저장소에서 실제 GitHub 이슈-PR 쌍 2,294개를 모았다. 모델이 패치를 생성하면, 그 저장소에 실제로 딸린 테스트 스위트(FAIL_TO_PASS/PASS_TO_PASS 테스트)를 그대로 실행해 통과 여부로 채점한다 — 사람 judge도, 학습된 RM도 필요 없다. 초기 최고 성능은 Claude 2의 1.96%였다.
  • 깨진 지점: 정작 문제는 “채점 방식”이 아니라 “문항 그 자체”에 있었다. OpenAI가 파이썬에 능숙한 개발자 93명을 동원해 무작위로 뽑은 1,699개 문항을 다시 심사했는데, 최종적으로 “문제 없음”으로 통과한 문항은 500개뿐이었다. 나머지 상당수는 유닛 테스트가 이슈 내용과 무관하게 지나치게 엄격하거나(정답이어도 사소한 이유로 테스트가 실패), 이슈 설명 자체가 무엇을 풀어야 하는지 불분명했다. 즉 채점 프로그램은 정확히 돌아갔는데도, 그 채점이 매겨지는 대상(문항) 자체의 타당도가 무너져 있었던 것이다.
  • 후속 교정: 그렇게 걸러낸 500개가 SWE-bench Verified다. “채점 함수는 결정론적이고 완벽했는데, 문제(스펙) 쪽이 나빴다”는 이 결론은, 아래 EvalPlus 사례와 정확히 같은 모양의 패턴이다 — 조작화의 실패는 채점 함수 하나가 아니라 파이프라인 전체(문항 + 테스트 + 파서)에서 일어날 수 있다.

Experiments

벤치마크 한눈에 보기

벤치 문항 수 채점 방식 알려진 취약점 후속 교정
GSM8K 8,792(학습 7,473 / 테스트 1,319) 숫자 정답 exact match 난이도 천장이 낮아 최신 모델은 포화 MATH로 난이도 상향, GSM-Symbolic류 재검증
MATH 12,500(학습 7,500 / 테스트 5,000), 5단계×7과목 LaTeX 답 정규화 후 exact match 동치 표현(분수·소수) 판정 실패 Math-Verify(SymPy 기반), MATH-500
AIME 연 30문항(AIME I·II 각 15) 정수(0~999) exact match 표본이 작아 CI가 극도로 넓음 다회 시행 평균 + SE 보고
HumanEval 164 유닛 테스트 실행, pass@k 문항당 테스트 부족 → 오답도 통과 EvalPlus/HumanEval+
MBPP 974(문항당 테스트 3개) 위와 동일 위와 동일 MBPP+
HumanEval+/MBPP+ 원 문항 동일, 테스트 80배 증량 강화된 유닛 테스트 (교정 그 자체) 표준 채점 스위트로 채택
LiveCodeBench 500문항 이상(2023.5~, 지속 수집) 시점 기반 수집 + 코드 실행 정적 벤치의 학습 데이터 오염 rolling 컷오프 평가
SWE-bench → Verified 2,294 → 500 실제 저장소 테스트 스위트 실행 원본 문항 다수가 모호·과도 엄격 사람 재검수로 Verified 부분집합

핵심 반례 1 — 통과했던 코드가 강화된 테스트에서 떨어진다

GPT-4는 원본 HumanEval에서 pass@1 88.4%를 기록했지만, 같은 문제에 EvalPlus가 만든 HumanEval+(테스트 80배 증량)를 적용하자 76.2%로 떨어졌다 — 12.2%p 하락이다. 이전에 “정답”으로 채점됐던 코드 중 상당수가, 사실은 강화된 테스트가 잡아낸 특정 입력에서 틀리는 코드였다는 뜻이다. 26개 모델 전반의 하락폭은 10~20%p대였고, 순위마저 뒤집혔다(WizardCoder-CodeLlama·Phind-CodeLlama가 원본에서는 못 이기던 ChatGPT를 HumanEval+에서는 이겼다). “통과 = 정답”이라는 등식이 테스트 커버리지에 의존하고 있었다는, 이 시리즈 전체에서 가장 선명한 반례다.

핵심 반례 2 — 취약점은 채점 함수가 아니라 파서다

규칙 기반 채점이 뚫리는 지점은 대개 “정답인가 아닌가를 비교하는 로직” 자체가 아니라, 모델의 자유 형식 텍스트에서 최종 답을 뽑아내는 전처리 단계, 즉 파서다. 두 방향 모두에서 실패가 일어난다.

  • 동치 표현을 오답으로 처리(위양성적 실패): MATH의 답은 \(\frac{1}{2}\), \(0.5\), \(1/2\)처럼 여러 형태로 쓸 수 있다. 문자열 정규화 규칙이 이 동치를 다 포괄하지 못하면, 수학적으로 맞는 답이 틀렸다고 채점된다. lm-evaluation-harness에 실제로 이런 이슈(“Level 5 답 추출 로직이 지나치게 엄격”)가 보고돼 있다는 사실이 이 문제가 이론이 아니라 실무에서 반복되는 현상임을 보여준다.
  • 파서가 엉뚱한 스팬을 뽑는 경우(형식 취약성): “답은 160분(2시간 40분)입니다”라는 출력에서 “마지막 숫자”를 답으로 뽑는 단순 규칙을 쓰면, 정답인 160이 아니라 부연 설명에 나온 40을 뽑아 오답 처리한다. \boxed{} 안의 내용만 뽑는 방식이 조금 더 안전하지만, 모델이 여러 후보를 나열하며 그중 하나만 \boxed{}로 감싸는 형식을 벗어나면 똑같은 문제가 재현된다. 반대 방향의 실패도 가능하다 — 채점 로직이 “정답 숫자가 출력 어딘가에 등장하는가”만 검사하는 느슨한 방식이라면, 추론 과정 중간에 우연히 정답과 같은 숫자가 스쳐 지나가기만 해도 최종 결론과 무관하게 통과 처리될 수 있다.

두 실패 모두 결론은 같다. 규칙 기반 채점의 진짜 취약점은 “무엇이 정답인가”를 정의하는 함수가 아니라, 자유 형식 텍스트를 그 함수의 입력 형식으로 바꾸는 파서다. 채점 함수는 결정론적이고 완벽할 수 있지만, 파서가 텍스트에서 잘못된 조각을 뽑아 건네주면 함수의 완벽함은 아무 의미가 없다.

핵심 반례 3 — 문항이 적으면 %p 차이가 통계적으로 무의미해진다

AIME처럼 연간 30문항뿐인 벤치마크에서는 “숫자 차이”와 “통계적으로 유의한 차이”가 전혀 다른 이야기다.

  • 문항 1개 \(= 1/30 \approx 3.33\)%p.
  • 두 모델의 정확도가 각각 60%(18/30)와 63.3%(19/30)라면, 그 차이는 정확히 문항 하나다.
  • \(n=30\), \(p=0.5\) 기준 95% 신뢰구간의 반폭은 대략 \(\pm 17.9\)%p — 이는 이후 #15에서 다룰 더 정교한 방법(Wilson 구간 등)을 쓰면 다소 좁아지지만, 여전히 문항 30개로는 두 자릿수 %p 차이가 아니면 신뢰구간이 겹칠 수 있다는 뜻이다.

즉 “모델 A가 모델 B보다 AIME에서 3%p 앞선다”는 헤드라인은, 통계적으로는 “둘이 문제 하나를 다르게 풀었을 수도, 우연히 그렇게 나왔을 수도 있다”는 말과 거의 구분되지 않는다.

통계 요약

기법 정의 언제 쓰나 이 글에서의 함정
pass@k 불편추정량 \(1 - \binom{n-c}{k}/\binom{n}{k}\) 코드 생성처럼 여러 샘플 중 하나라도 맞으면 성공인 과제 naive하게 k개만 뽑아 세면 분산이 커짐
이항비율 표준오차 \(\text{SE} = \sqrt{p(1-p)/n}\) 문항 수 \(n\) 이 작은 벤치(AIME 등)의 CI 어림 \(n=30\) 수준에서는 CI가 순위를 삼킬 만큼 넓다
1문항의 %p 환산 \(1/n \times 100\) 문항 수가 작아 “몇 %p 차이”의 실질 의미를 가늠할 때 AIME(n=30)에서 1문항 = 3.33%p

Conclusion

검증 가능한 도메인은 이 시리즈가 지금까지 본 것 중 평가의 이상적 경우에 가장 가깝다. 채점이 결정론적 프로그램이라 judge 편향도, 라벨러 간 불일치도, κ의 역설도 원천적으로 존재하지 않는다. 강화학습이 지금도 이 도메인부터 규칙 기반 verifiable reward를 쓰는 이유(DeepSeek-R1의 RLVR)가 바로 이 깨끗함이다.

그러나 “검증 가능”이라는 말은 테스트 스위트와 파서가 완전하다는 가정 위에서만 성립한다. 그 가정이 깨지는 순간 — 테스트가 허술하거나(HumanEval → EvalPlus), 정답 판정 규칙이 동치 표현을 놓치거나(MATH), 문항 자체가 애초에 모호하거나(SWE-bench → Verified) — #2가 다룬 구성타당도 실패가 형태만 바꿔 그대로 돌아온다. judge 편향 대신 테스트 커버리지 편향이, 라벨 노이즈 대신 파서 노이즈가 들어오는 것이다. 그리고 문항 수 자체가 적은 벤치(AIME)에서는 애초에 %p 단위의 비교가 통계적으로 무의미할 수 있다는 것도 함께 봤다.

다음 글(#9)은 정반대 극단으로 간다. 애초에 프로그램으로 채점할 수 없는 개방형 대화 — MT-Bench에서 Chatbot Arena까지 — 를 다루며, 여기서는 이번 글이 사라졌다고 말한 judge 편향과 라벨 잡음이 정면으로 되돌아온다.

참고 문헌


LLM 평가 체계 시리즈

이 글은 LLM 평가 체계 시리즈의 여덟 번째 글이다.

1부. 평가란 무엇인가

  1. 측정으로서의 평가 — 구성개념·조작화·타당도·신뢰도
  2. 벤치마크는 무엇을 재고 있나 — 벤치 445편 구성타당도 리뷰

2부. 무엇을 숫자로 만드나 — 평가 metric

  1. 척도와 허용 연산 — Likert 평균을 내도 되는가
  2. 분류 지표 — accuracy의 함정부터 PR-AUC까지
  3. 생성 지표와 그 타당도 — BLEU에서 COMET까지
  4. 객관식 평가는 왜 흔들리나 — 위치 편향과 포맷 민감도

3부. LLM 벤치마크 지형도

  1. 지식과 추론 — MMLU 계열의 흥망 — MMLU·GPQA·BBH·HELM
  2. (현재 글) 검증 가능한 도메인 — 수학과 코드 — GSM8K·MATH·HumanEval·SWE-bench
  3. 개방형 대화 — MT-Bench에서 Arena까지 — judge 기반 벤치의 등장
  4. 능력의 다른 축 — 지시따르기·긴 문맥·사실성
  5. 한국어 벤치마크 — 번역이 아니라 원산, 그리고 문화 타당도

4부. 사람이 읽는다 — 정성평가와 일치도

  1. 사람 평가 설계 — 루브릭·Likert·pairwise·BWS
  2. 우연을 빼다 — κ 계열 — Cohen·Fleiss·weighted·Krippendorff
  3. κ의 역설 — 일치율 90%인데 κ가 0.21

5부. 차이는 진짜인가 — 정량평가의 통계

  1. 점수는 추정치다 — 이항비율 신뢰구간과 Wald의 실패
  2. 차이는 유의한가 — paired bootstrap·순열검정·McNemar
  3. 몇 개를 재야 하나 — 검정력·표본크기·다중비교
  4. LLM eval의 통계 실무 — 클러스터 SE·IQM·분산 분해

6부. 신뢰할 수 있는 평가 체계

  1. judge를 통계로 다루기 — 편향·Bradley-Terry·PPI
  2. 오염·재현성·효율 — 오염 검정·harness·IRT
  3. 안전 평가의 통계와 체계 설계 — 희귀사건·calibration·체크리스트

본 시리즈는 21편으로 구성된다.




Enjoy Reading This Article?

Here are some more articles you might like to read next:

  • 안전 평가의 통계와 체계 설계 — 희귀사건과 calibration, 스물한 편의 마지막 체크리스트
  • 오염·재현성·효율 — 이 점수는 무엇을 재고 있나
  • judge를 통계로 다루기 — 편향, Bradley-Terry, PPI
  • LLM eval의 통계 실무 — 클러스터 SE, 분산 분해, IQM
  • 몇 개를 재야 하나 — 검정력, 표본크기, 다중비교