Skip to content

필사 모드: 추론 강도는 모델 선택이 아니라 요청 단위 배포 파라미터입니다

한국어
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.

같은 모델인데 점수가 세 개 실려 있습니다

새 모델이 나와서 벤치마크 결과를 확인하러 갑니다. 그런데 점수가 하나가 아닙니다. 세 개입니다. 어느 숫자를 슬랙에 올려야 할까요.

이 상황은 이제 예외가 아니라 기본값에 가깝습니다. 추론 강도를 조절할 수 있는 모델이 늘면서, 모델 하나가 점 하나가 아니라 곡선 하나로 발표되기 시작했습니다. 그리고 이 변화는 발표 형식의 변화가 아니라 배포 설계의 변화입니다.

예전에는 모델을 고르는 것이 결정의 끝이었습니다. 어떤 모델을 쓸지 정하고 나면 성능과 비용이 함께 정해졌습니다. 지금은 모델을 고른 뒤에도 결정이 하나 남아 있고, 그 결정이 성능과 비용을 양쪽으로 크게 흔듭니다. 이걸 설정 파일에 상수로 박아 두면 그 흔들림을 전부 포기하는 셈입니다.

ARC 결과 페이지가 실제로 알려 주는 것

ARC Prize의 DeepSeek V4 Flash 0731 결과 페이지를 보겠습니다. 2026년 7월 31일에 공개된 모델이고, 추론 강도 세 단계가 각각 측정되어 있습니다.

추론 강도ARC-AGI-1ARC-AGI-2
Max89.0%61.4%
High87.0%56.0%
Low84.0%46.0%

비용은 최대 강도 기준으로만 표기되어 있습니다. ARC-AGI-1 준비공개 평가에서 과제당 0.02달러, ARC-AGI-2에서 과제당 0.04달러입니다.

강도가 사 주는 것은 과제 난이도에 따라 세 배 차이 납니다

이 표에서 바로 계산되는 것이 하나 있습니다. 강도를 최저에서 최대로 올렸을 때의 이득입니다.

ARC-AGI-1에서는 84.0에서 89.0으로 5.0퍼센트포인트가 오릅니다. ARC-AGI-2에서는 46.0에서 61.4로 15.4퍼센트포인트가 오릅니다. 같은 다이얼을 같은 만큼 돌렸는데 어려운 쪽에서 세 배 넘게 벌었습니다.

방향을 뒤집어 읽으면 더 실용적입니다. 쉬운 과제에서 최대 강도를 쓰는 것은 대체로 낭비입니다. ARC-AGI-1에서 최저 강도는 최대 강도의 94퍼센트 수준을 이미 내고 있습니다. 반대로 어려운 과제에서 최저 강도로 돌리는 것은 성능을 크게 버리는 선택입니다.

그래서 "이 모델을 어떤 강도로 쓸 것인가"라는 질문은 애초에 잘못된 형태입니다. 강도는 모델의 속성이 아니라 과제의 속성에 맞춰 정할 값입니다.

요청 단위로 정한다는 것의 의미

실무에서 이 결론은 설정 파일 한 줄이 아니라 라우팅 로직이 됩니다. 들어온 요청마다 난이도를 추정하고 강도를 고릅니다.

난이도 추정이 완벽할 필요는 없습니다. 대부분의 서비스에서는 아주 거친 신호로도 충분합니다. 입력 길이, 요구된 단계 수, 과거 같은 유형에서의 실패율, 사용자가 명시한 긴급도 같은 것들입니다.

다만 이 추정을 한 번에 맞히려 들면 곧 한계에 부딪힙니다. 난이도를 예측하는 분류기를 붙이는 순간 그 분류기 자체가 유지 대상이 되고, 분포가 바뀔 때마다 다시 학습해야 합니다. 더 튼튼한 방법은 추정하지 않고 틀렸을 때 올리는 것입니다. 예측 대신 관측을 쓰는 쪽이 거의 언제나 더 오래 갑니다.

사다리는 검증자가 있을 때만 성립합니다

"""단계 상향 사다리: 싸게 먼저 시도하고, 틀린 게 확인되면 올린다."""
from typing import Callable, Sequence

LADDER = ("low", "high", "max")


def solve_with_escalation(
    task,
    run: Callable[[object, str], object],       # (task, effort) -> answer
    verify: Callable[[object, object], bool],   # (task, answer) -> 통과 여부
    ladder: Sequence[str] = LADDER,
):
    """검증자가 통과시킬 때까지 강도를 올린다. 사용한 강도를 함께 반환한다."""
    attempts = []
    for effort in ladder:
        answer = run(task, effort)
        ok = verify(task, answer)
        attempts.append((effort, ok))
        if ok:
            return answer, effort, attempts
    return answer, ladder[-1], attempts   # 끝까지 실패하면 최종 시도를 돌려준다


def expected_cost(p_pass_by_effort: dict, unit_cost: dict, ladder=LADDER) -> float:
    """사다리의 기대 비용. 낮은 단계 통과율이 높을수록 평균이 내려간다."""
    total, reach = 0.0, 1.0
    for effort in ladder:
        total += reach * unit_cost[effort]
        reach *= 1 - p_pass_by_effort[effort]
    return total


p = {"low": 0.80, "high": 0.60, "max": 0.50}     # 각 단계에 도달했을 때의 통과율
cost = {"low": 0.004, "high": 0.010, "max": 0.020}
print(round(expected_cost(p, cost), 5))          # 최대 강도만 쓰는 경우와 비교해 볼 것

이 구조의 전제는 verify입니다. 검증이 불가능하면 사다리는 성립하지 않고, 남는 선택지는 처음부터 높은 강도로 돌리는 것뿐입니다. 그래서 강도 최적화를 하고 싶다면 먼저 물어야 할 질문은 "강도를 어떻게 고를까"가 아니라 틀렸다는 걸 싸게 알아낼 방법이 있는가입니다.

한 가지 더 주의할 점은 지연 시간입니다. 사다리는 평균 비용을 낮추지만 최악의 경우 지연을 늘립니다. 세 단계를 다 밟은 요청은 한 번에 최대 강도로 돌린 요청보다 늦게 끝납니다. 그래서 사용자가 기다리는 동기 경로에서는 사다리를 두 단계로 줄이거나, 낮은 단계를 먼저 스트리밍으로 보여 주고 상향 결과로 교체하는 식의 설계가 필요합니다. 배치 작업이라면 이 고민은 하지 않아도 됩니다.

검증자를 만들 수 없을 때의 대체 신호

완전한 검증자가 없어도 부분적인 신호는 대개 만들 수 있습니다.

코드 생성이라면 컴파일과 테스트 실행이 그대로 검증자입니다. 구조화된 출력이라면 스키마 검증과 참조 무결성 검사가 상당 부분을 잡습니다. 검색 기반 답변이라면 인용된 문장이 원문에 실제로 존재하는지를 문자열 대조로 확인할 수 있습니다.

이런 것조차 없는 자유 서술 과제라면 신호를 결과가 아니라 과정에서 찾습니다. 같은 입력을 낮은 강도로 두 번 돌려 답이 서로 크게 다르면, 그 요청은 이 모델에게 어려운 요청일 가능성이 높습니다. 두 번 돌리는 비용이 한 단계 올리는 비용보다 싼 구간에서는 이 방법이 실용적입니다.

여기서 답이 다르다는 판정을 다시 모델에게 맡기면 비용 이점이 사라집니다. 문장 임베딩의 코사인 거리나, 답에서 추출한 핵심 숫자와 고유명사의 집합 비교처럼 값싼 대조로 충분한 경우가 많습니다. 검증자는 정확할 필요가 없고 싸면서 한쪽으로만 틀리면 됩니다. 놓치는 실패가 있어도 되지만, 맞은 답을 틀렸다고 판정하는 일은 드물어야 사다리가 낭비 없이 돕니다.

이 페이지에서 확인할 수 없는 것

정직하게 짚어 둘 부분이 있습니다. 앞의 표에는 강도별 점수가 세 줄 있지만, 비용은 최대 강도 기준 한 줄만 있습니다. 낮은 강도의 과제당 비용은 이 페이지에서 확인되지 않습니다.

그래서 비용당 한계 정확도를 이 데이터만으로 완전히 계산할 수는 없습니다. 위 코드의 단가는 구조를 보여 주기 위한 예시일 뿐이고, 실제 값은 각자 자기 트래픽에서 재야 합니다. 그리고 이건 이 페이지의 결함이라기보다 지금 업계 전반의 발표 관행입니다. 강도별 점수는 늘어났는데 강도별 비용은 아직 같이 나오지 않습니다.

측정은 어렵지 않습니다. 자기 평가셋 100건을 세 강도로 각각 돌리고, 정확도와 실제 청구 토큰을 함께 기록하면 곡선이 나옵니다. 이 실험은 반나절이면 끝나고, 이후 모든 강도 결정의 근거가 됩니다.

한 가지 더 유의할 것은 벤치마크의 난이도 분포와 우리 트래픽의 난이도 분포가 다르다는 점입니다. ARC 과제는 의도적으로 어렵게 설계된 문제 모음이고, 실제 서비스 트래픽은 대체로 쉬운 요청이 압도적으로 많은 긴 꼬리 분포입니다. 그래서 위 표에서 얻을 교훈은 "우리도 최대 강도를 써야 한다"가 아니라, 난이도 구간마다 다이얼의 값어치가 다르다는 사실 자체입니다.

배포 파라미터로 다루려면 남겨야 할 것들

마지막은 기록입니다. 강도를 요청 단위로 정하기 시작하면, 강도를 로그에 남기지 않는 순간 모든 지표가 해석 불가능해집니다.

최소한 이 네 가지를 응답과 함께 저장합니다. 실제 사용된 강도, 사다리에서 시도한 횟수, 각 시도의 검증 결과, 그리고 총 소비 토큰입니다. 여기에 요청을 어느 난이도 구간으로 분류했는지까지 남기면 나중에 라우팅 규칙을 데이터로 조정할 수 있습니다. 이게 있으면 나중에 "지난주 대비 정확도가 올랐는데 비용도 올랐다"는 상황에서 원인을 즉시 분리할 수 있습니다. 없으면 모델 탓인지 라우팅 탓인지 트래픽 구성 변화 탓인지 영원히 알 수 없습니다.

처음의 질문으로 돌아가면, 슬랙에 올려야 할 숫자는 셋 중 하나가 아닙니다. 세 개를 다 올리고 우리 과제가 어느 쪽에 가까운지를 같이 적는 것이 맞습니다.

참고 자료

현재 단락 (1/62)

새 모델이 나와서 벤치마크 결과를 확인하러 갑니다. 그런데 점수가 하나가 아닙니다. 세 개입니다. 어느 숫자를 슬랙에 올려야 할까요.

작성 글자: 0원문 글자: 4,011작성 단락: 0/62