같은 모델인데 왜 성능이 변할까

🏷️ 정보 LLM

어제는 잘 풀던 문제를 오늘은 같은 모델이 헤맨다. 같은 프롬프트를 두 번 보냈는데 답이 다르다. 많은 사람이 이걸 "모델이 또 조용히 바뀌었나"로 의심합니다.

그런데 모델 가중치는 그대로일 때가 대부분입니다. 바뀐 건 모델이 아니라, 그 모델을 돌리는 추론 인프라입니다. 같은 이름 뒤에서 서버 부하, 배치 크기, 캐시 상태, 라우팅이 요청마다 다르게 돌아갑니다. 우리가 "성능"이라 부르는 건 모델 단독의 실력이 아니라, 그 순간의 모델 더하기 인프라 더하기 부하의 합작품입니다.

이 글은 그 합작의 메커니즘을 짚습니다. 출처는 모두 1차 자료입니다.

같은 질문, 다른 답

temperature=0은 이론상 가장 결정적인 설정입니다. 매번 확률이 가장 높은 토큰만 고르니 같은 입력에는 같은 출력이 나와야 합니다. 그런데 Thinking Machines Lab이 한 모델(Qwen3-235B)을 이 설정으로 1000번 돌렸더니 결과는 이랬습니다.

항목

설정

temperature=0 (greedy)

실행 횟수

1000회

고유한 출력 개수

80개

최빈 출력 등장 횟수

78회

같은 질문에 80가지 다른 답이 나온 겁니다. 범인은 난수가 아니라 배치 크기였습니다.

추론 서버는 여러 사용자의 요청을 한 묶음(배치)으로 묶어 GPU에 던집니다. 트래픽이 많으면 배치가 커지고, 적으면 작아집니다. 문제는 GPU 커널 상당수가 비배치불변(non-batch-invariant)이라는 점입니다. 배치 크기가 바뀌면 행렬 곱이나 정규화 안에서 부동소수점 값을 더하는 순서가 바뀝니다.

부동소수점 덧셈은 결합법칙이 성립하지 않습니다. (a + b) + ca + (b + c)의 마지막 비트가 다를 수 있습니다. 이 미세한 차이가 두 후보 토큰의 확률이 거의 같을 때 argmax를 뒤집고, 한 번 갈라진 토큰은 다음 토큰을 또 가르며 답 전체를 발산시킵니다.

연쇄는 이렇게 정리됩니다.

서버 부하 변동
  → 배치 크기 변동
    → 비배치불변 커널에서 부동소수점 합산 순서 변화
      → 토큰 확률 미세 변화
        → argmax 뒤집힘
          → 출력 전체 발산

Thinking Machines Lab은 이 배치 크기 변동을 "거의 모든 LLM 추론 엔드포인트가 비결정적인 주된 이유"로 지목했습니다. 사용자 관점에서 서버 부하는 통제 불가능하고 사실상 비결정적입니다. 즉 내가 새벽에 쓰느냐 피크 시간에 쓰느냐만으로도 출력이 흔들릴 수 있습니다. 같은 곳에서 독립 확인한 SGLang 팀은 reduction 커널을 배치불변 구현으로 교체해 1000회 모두 동일 출력을 얻었습니다.

가중치는 그대로인데 품질이 떨어진 사건

이건 이론이 아니라 실제로 터진 적이 있습니다. 2025년 9월 17일, Anthropic은 세 건의 추론 버그에 대한 포스트모템을 공개했습니다.

그중 하나가 TPU/XLA 환경의 approximate top-k 오컴파일이었습니다. 특정 배치 크기와 모델 구성에서만 완전히 잘못된 결과를 반환하던 버그입니다. 핵심은 모델 가중치가 한 글자도 바뀌지 않았다는 점입니다. 같은 모델이 인프라 레벨 버그 하나로 품질이 떨어졌습니다.

한 가지 짚을 것은, 이 버그가 무작위가 아니었다는 점입니다. Anthropic은 앞뒤 연산 구성에 따라 결정적으로 잘못된 값이 나왔다고 밝혔습니다. 사용자들이 그 시기 "모델이 멍청해졌다"고 느낀 체감의 상당 부분이, 가중치 변경 없는 이런 인프라 사고일 수 있다는 뜻입니다.

인프라만 바꿔도 품질이 흔들린다는 건 학계에서도 측정됐습니다. NeurIPS 2025 연구(arXiv:2506.09501)는 GPU 개수와 종류, 평가 배치 크기만 바꿨을 때 같은 모델에서 나타난 변동을 정리했습니다.

조건

변동 폭

디코딩 방식

greedy (temperature=0 고정)

정확도 변동

최대 9%p

응답 길이 변동

최대 9,000 토큰

기저 원인

부동소수점 비결합성

프롬프트도 같고 디코딩도 greedy인데, 배포 환경만 달라도 정확도가 9%포인트, 답변 길이가 9,000토큰까지 벌어졌습니다.

속도가 들쑥날쑥한 이유

품질만이 아니라 속도도 같은 모델에서 크게 흔들립니다. 이건 추론이 성격이 정반대인 두 단계로 나뉘기 때문입니다.

요청마다 어느 단계가 지배적이냐가 다르니, 같은 모델이 요청마다 실질적으로 다른 속도로 응답합니다. 여기에 캐시 상태가 더해집니다. 직전에 비슷한 요청이 있어 KV 캐시가 따뜻한지 차가운지에 따라 첫 토큰까지 걸리는 시간(TTFT)이 갈립니다.

캐시 상태

첫 응답 시간(TTFT)

웜 (직전 prefix 재사용)

약 0.6초

콜드 (처음부터 계산)

약 4.3초

같은 모델, 같은 요청인데 타이밍만으로 7배 차이가 납니다.

여기서 반직관적인 함정이 하나 나옵니다. 프롬프트를 짧게 다듬어 "최적화"했더니 오히려 느려지는 경우입니다. 캐싱은 보통 일정 길이(예: 1024토큰) 이상에서만, 정확한 prefix가 일치할 때만 켜집니다. 프롬프트를 줄여 그 문턱 밑으로 내려가거나 prefix를 바꿔버리면 캐싱이 통째로 꺼집니다. 입력 토큰을 절반으로 줄여도 지연 자체는 몇 퍼센트밖에 안 줄지만, 캐싱이 꺼지면 그 손해가 훨씬 큽니다.

병렬화와 라우팅도 지연을 바꾼다

큰 모델은 여러 GPU에 쪼개 올립니다. 이 분산 방식 자체가 지연에 들어갑니다.

여기에 서빙 스택 구현 자체도 변수입니다. 스케줄링이나 텐서 전후처리 같은 CPU측 오버헤드가 빠른 가속기에서는 종단 지연의 절반 이상을 차지할 수 있습니다. 같은 모델, 같은 워크로드인데 어떤 추론 엔진을 쓰느냐로 속도가 갈립니다.

결론

같은 모델 이름은 같은 경험을 보장하지 않습니다. 정리하면 출력을 흔드는 축은 이렇습니다.

흔드는 것

사용자가 통제 가능?

서버 부하 → 배치 크기

출력 내용(같은 질문에 다른 답)

불가

인프라 버그

품질(가중치 변경 없이 저하)

불가

GPU 구성·배치

정확도·응답 길이

불가

KV 캐시 웜/콜드

속도(TTFT)

부분적

병렬화·라우팅·서빙 스택

지연

불가

대부분 모델 바깥, 사용자 통제 밖에 있습니다.

그래서 실무 결론은 단순합니다. 한 번 잘 나왔다고 "이 모델 좋다", 한 번 망쳤다고 "이 모델 별로다"로 단정하지 않는 것입니다. 모델을 평가하려면 여러 번, 다른 시간대에, 로그를 남기며 봐야 합니다. 재현성이 중요한 작업이라면 배치불변 커널을 켠 결정적 추론 모드를 제공하는지 확인하는 것이 다음 질문입니다. 우리가 한 번의 응답에서 보는 건 모델의 실력이 아니라, 그 순간 모델과 인프라와 부하가 함께 만들어낸 한 장면일 뿐입니다.


참고한 1차 출처: Thinking Machines Lab, "Defeating Nondeterminism in LLM Inference"(2025-09) Anthropic, "A postmortem of three recent issues"(2025-09-17) / NeurIPS 2025, arXiv:2506.09501 / Meta Engineering, "Scaling LLM inference"(2025-10).