Skip to content
Published on

AI Papers: Test-Time Scaling 핵심 논문 정리 — 추론 예산으로 성능을 끌어올리는 방법

Authors
  • Name
    Twitter
AI Papers: Test-Time Scaling 핵심 논문 정리

1) Test-Time Scaling이 왜 중요한가

대형 모델 성능 향상은 보통 두 축으로 설명된다.

  1. Train-time scaling: 파라미터/데이터/학습 스텝을 늘린다.
  2. Test-time scaling: 추론 시점에 더 많은 계산을 사용한다.

Train-time scaling은 효과가 크지만, 비용·시간·인프라 제약이 매우 크다. 반대로 test-time scaling은 이미 학습된 모델을 활용하면서도 특정 문제에서 성능을 끌어올릴 수 있다. 특히 수학/코딩/멀티스텝 추론처럼 “정답 탐색”이 중요한 태스크에서 강력하다.

핵심 관점은 단순하다.

  • 같은 모델이라도 한 번의 샘플 대신 여러 후보를 만들고,
  • 그중 더 일관적이거나 검증 가능한 답을 선택하면,
  • 실제 정답률이 올라간다.

즉, TTS는 “모델 자체를 바꾸는 기술”이 아니라 추론 정책(inference policy) 을 최적화하는 기술이다.

2) 대표 방법 4가지

A. Best-of-N (다중 샘플링 + 선택)

가장 직관적인 방법이다.

  • temperature를 높여 N개 답을 생성
  • 간단한 스코어(길이/포맷/규칙/검증기 점수)로 최적 후보 선택

장점: 구현이 쉽다.
단점: 토큰 비용이 N배 가까이 증가한다.

B. Self-Consistency (표본 다수결)

Chain-of-Thought 계열에서 자주 쓰인다.

  • 여러 추론 경로를 생성
  • 최종 답이 가장 많이 합의되는 결과를 채택

수학 문제처럼 하나의 정답을 공유하는 태스크에서 효과가 좋다.

C. Search-based (Tree/Beam/MCTS)

중간 상태를 확장하며 탐색하는 방식이다.

  • 노드를 확장할지, 가지치기할지 결정
  • 제한된 budget에서 높은 가치 경로를 찾는다

코드 합성/계획 생성/복잡한 의사결정에서 유리하지만 구현 난이도가 높다.

D. Verifier/Reranker 결합

생성기(generator)와 검증기(verifier)를 분리한다.

  • 생성기는 다양한 후보를 만든다.
  • 검증기/리랭커가 사실성·정답성·근거성을 채점한다.

“생성 잘함”과 “판별 잘함”을 분리하면 안정성이 높아진다.

3) 논문 맥락에서 보는 TTS 흐름

TTS 자체가 단일 논문 한 편으로 귀결되기보다, 아래 흐름으로 발전했다.

  • Chain-of-Thought prompting
  • Self-Consistency decoding
  • Program-of-Thought / Tool-augmented reasoning
  • Verifier-guided decoding / Reranking
  • Search over thoughts / deliberate reasoning

실무에서는 이 중 한 가지를 고집하기보다 “문제 유형별 조합”이 일반적이다.

예:

  • 고객지원 FAQ: Best-of-2 + 간단한 policy check
  • 수학/논리 QA: Self-Consistency + 답안 정규화
  • 코드 생성: N개 생성 + 테스트 실행 + 테스트 통과 우선

4) 실무 적용 아키텍처

User Query
  -> Prompt Builder
  -> Candidate Generator (N samples)
  -> Verifier / Reranker
  -> Policy Filter (safety, format, citation)
  -> Final Answer

이 구조의 핵심은 “한 번 생성하고 끝”이 아니라 후보 집합을 관리하는 것이다.

5) 코드 예시: Best-of-N 기본 구현

from dataclasses import dataclass
from typing import List

@dataclass
class Candidate:
    text: str
    score: float


def score_answer(text: str) -> float:
    # 예시: 길이 패널티 + 금칙어 패널티 + 형식 점수
    penalty = 0.0
    if len(text) < 60:
        penalty += 0.3
    if "확실하지" in text:
        penalty += 0.1
    format_bonus = 0.2 if "##" in text or "- " in text else 0.0
    return max(0.0, 1.0 - penalty + format_bonus)


def select_best(candidates: List[str]) -> Candidate:
    scored = [Candidate(text=c, score=score_answer(c)) for c in candidates]
    return sorted(scored, key=lambda x: x.score, reverse=True)[0]

6) 코드 예시: Self-Consistency 집계

from collections import Counter
import re

def normalize_final_answer(text: str) -> str:
    # 마지막 답만 추출하는 단순 예시
    m = re.findall(r"정답[::]\s*(.+)", text)
    if m:
        return m[-1].strip()
    return text.strip().splitlines()[-1]


def majority_vote(samples: list[str]) -> tuple[str, int]:
    answers = [normalize_final_answer(s) for s in samples]
    c = Counter(answers)
    ans, cnt = c.most_common(1)[0]
    return ans, cnt

7) 코드 예시: 코드 생성에서 Test-based Rerank

import subprocess
import tempfile
from pathlib import Path


def run_pytest(code: str, tests: str) -> bool:
    with tempfile.TemporaryDirectory() as td:
        p = Path(td)
        (p / "solution.py").write_text(code)
        (p / "test_solution.py").write_text(tests)
        r = subprocess.run(["pytest", "-q"], cwd=td, capture_output=True, text=True)
        return r.returncode == 0


def pick_by_tests(candidates: list[str], tests: str) -> str:
    for c in candidates:
        if run_pytest(c, tests):
            return c
    return candidates[0]

8) 코드 예시: 추론 예산 제어

inference_policy:
  mode: best_of_n
  samples: 4
  temperature: 0.7
  max_tokens_per_sample: 512
  timeout_ms: 12000
  cost_budget_usd: 0.03
  fallback:
    on_timeout: 'single_pass'
    on_budget_exceeded: 'single_pass'

TTS에서 성능만 보면 비용이 폭증한다. 그래서 예산·시간 제한은 필수다.

9) 코드 예시: 운영 지표 수집

SELECT
  date_trunc('day', created_at) AS d,
  AVG(correct::int) AS accuracy,
  AVG(latency_ms) AS avg_latency,
  AVG(cost_usd) AS avg_cost,
  AVG(samples_used) AS avg_samples
FROM reasoning_eval_runs
WHERE created_at >= now() - interval '14 days'
GROUP BY 1
ORDER BY 1;

10) 언제 TTS를 써야 하고, 언제 피해야 하나

쓰는 게 좋은 경우

  • 정답 검증 루프가 있는 태스크(테스트/룰/체커)
  • 고정된 입력당 정확도 개선이 가치가 큰 태스크
  • 오답 비용이 높은 도메인

과도한 적용을 피할 경우

  • 응답 속도가 절대적으로 중요한 실시간 챗
  • 정답성이 아닌 창의성이 중요한 생성 작업
  • 후보 간 품질 차이가 작고 검증기가 약한 경우

11) 자주 하는 실수

  1. N만 늘리고 선택 정책이 빈약함
  2. 모델별 temperature 최적화 없이 고정값 사용
  3. 오프라인 점수만 보고 온라인 비용/지연을 무시
  4. 실패 시 fallback 경로가 없음
  5. verifier를 맹신하고 편향/오검출을 점검하지 않음

12) 도입 체크리스트

  • 태스크별 성공 정의(정확도/지연/비용) 합의
  • baseline(단일 샘플) 수치 확보
  • N, temperature, verifier 정책 실험표 작성
  • budget/timeout/fallback 정책 배포
  • A/B로 실제 사용자 지표 검증
  • 주기적 회귀 테스트 파이프라인 구성

13) 결론

Test-Time Scaling은 “모델을 바꾸지 않고 성능을 올리는” 현실적인 전략이다.
하지만 핵심은 N을 키우는 것이 아니라 선택·검증·예산 통제를 갖춘 추론 시스템 설계다.

실무 기준으로는 아래 순서를 추천한다.

  1. Best-of-2 또는 Self-Consistency부터 시작
  2. 검증기/리랭커를 붙여 후보 선택 품질 개선
  3. 예산·지연 제약을 정책으로 강제
  4. 온라인 A/B로 실제 효과 검증

이 흐름으로 가면 TTS는 단순 실험 트릭이 아니라 운영 가능한 성능 전략이 된다.

참고 자료

퀴즈 (8문항)
  1. Test-time scaling과 train-time scaling의 핵심 차이는?
    정답: ||학습이 아니라 추론 시점 계산 예산을 늘려 성능을 올린다||

  2. Self-Consistency가 특히 유리한 태스크는?
    정답: ||최종 정답 합의가 가능한 수학/논리 문제||

  3. Best-of-N의 가장 큰 비용 리스크는?
    정답: ||토큰 비용과 지연시간 증가||

  4. TTS에서 verifier의 역할은?
    정답: ||후보를 채점/선택해 최종 답의 신뢰도를 올린다||

  5. 코드 생성에서 가장 실전적인 rerank 신호는?
    정답: ||테스트 통과 여부||

  6. 운영에서 반드시 걸어야 할 제한 2가지는?
    정답: ||timeout과 cost budget||

  7. N만 키우면 항상 성능이 오를까?
    정답: ||아니다. 선택 정책이 약하면 비용만 늘 수 있다||

  8. TTS 도입 첫 단계 추천은?
    정답: ||Best-of-2 또는 Self-Consistency의 작은 실험부터 시작||