Temperature=0이 결정론적(Deterministic)임을 의미하지는 않습니다. 배치 크기(Batch Size)가 결정합니다.
요약
Temperature=0 설정이 항상 결정론적인 결과를 보장하지 않는 이유를 설명합니다. GPU 추론 시 배치 크기 변화에 따른 부동 소수점 연산 순서의 차이가 미세한 로짓 변화를 일으켜 결과가 달라질 수 있음을 다룹니다.
핵심 포인트
- Temperature=0은 샘플링 단계만 결정론적으로 만듦
- GPU의 부동 소수점 연산은 결합 법칙이 성립하지 않음
- 배치 크기 변화가 리덕션 순서를 바꿔 미세한 오차 유발
- 상위 후보 토큰 간 확률이 근접할 경우 결과가 완전히 달라짐
문제점
제가 함께 일했던 한 팀은 모델을 temperature=0으로 호출하고, 그 출력을 골든 컴플리션(golden completion)과 비교(diff)하는 평가 스위트(eval suite)를 보유하고 있었습니다. 이들은 탐욕적 디코딩(greedy decoding)을 사용하면 동일한 입력에 대해 동일한 출력이 나온다는 이론, 즉 회귀(regression)를 포착하기에 완벽하다는 이론을 바탕으로 이를 운영했습니다. 대부분의 경우 잘 작동했습니다. 하지만 일주일에 몇 번씩, 몇 달 동안 통과해 왔던 컴플리션이 코드 변경도, 프롬프트 변경도, 모델 버전 업데이트도 없었는데 갑자기 "실패"로 나타나며 차이가 발생했습니다. 그들은 자신들의 테스트 하네스(harness)에 레이스 컨디션(race condition)이 있다고 확신하며 실제 엔지니어링 시간을 허비했습니다.
하지만 그렇지 않았습니다. 모델은 원래 해야 할 일을 정확히 수행하고 있었습니다. temperature=0이 무엇을 보장하는지에 대한 그들의 가정이 바로 버그였습니다.
발생하는 이유
temperature=0은 정확히 한 가지, 즉 샘플링(sampling) 단계만을 결정론적(deterministic)으로 만듭니다. 확률 분포에서 추출하는 대신, 모델은 항상 가장 높은 확률의 토큰을 선택합니다 — 이것이 탐욕적 디코딩 (greedy decoding)입니다. 그것이 전부입니다. 그것이 보장하는 전부입니다.
이는 해당 확률을 생성하는 순전파(forward pass)가 결정론적인지에 대해서는 아무것도 말해주지 않으며, 실제 GPU 추론(inference) 서버에서는 대개 결정론적이지 않습니다. 행렬 곱셈(Matmuls), 어텐션(attention), 그리고 정규화 레이어(normalization layers)는 모두 방대한 양의 부동 소수점(floating-point) 값을 합산하는 과정을 포함합니다. 부동 소수점 덧셈은 결합 법칙(associative)이 성립하지 않습니다 — 반올림 오차(rounding error)를 다루게 되면 (a + b) + c는 a + (b + c)와 다른 결과를 생성할 수 있으며, 모델 규모에서는 리덕션(reduction)당 수천 개의 항을 합산하게 됩니다. 이러한 합산이 일어나는 순서는 커널의 리덕션 전략(reduction strategy)에 의해 결정되며, 이는 GPU 전체에 작업이 어떻게 스케줄링되는지에 따라 달라집니다.
실제로 불안정성(flakiness)을 유발하는 부분은 바로 여기입니다. 추론 서버(inference servers)는 GPU 활용률(utilization)을 높게 유지하기 위해 동시 요청들을 하나로 묶어 배치(batch)로 처리합니다. 실시간 부하(load)에 따라 귀하의 요청과 함께 배치에 포함되는 정확한 요청 집합이 호출할 때마다 달라지며, 이는 커널(kernel)이 인지하는 배치 크기(batch size)와 형태(shape)를 변화시킵니다. 이는 다시 리덕션 순서(reduction order)를 변화시키고, 결과적으로 출력 로짓(logits)의 미세한 반올림 오차(rounding error)를 변화시킵니다. 보통 이는 눈에 보이지 않습니다. 로짓의 소수점 6번째 자리 차이는 어떤 토큰이 가장 높은 확률을 가질지에 영향을 주지 않기 때문입니다. 하지만 상위 두 후보 토큰의 확률이 매우 근접해 있을 때, 그 노이즈는 가끔 argmax를 뒤집기에 충분합니다. 생성(completion) 초기에 뒤집힌 토큰 하나는 이후의 시퀀스 전체를 완전히 다른 결과로 연쇄적으로 변화시키는데, 그 뒤의 모든 것이 이제는 다른 접두사(prefix)를 조건(conditioned)으로 하기 때문입니다.
귀하의 요청은 변하지 않았습니다. 모델도 변하지 않았습니다. 정확히 그 밀리초(millisecond)에 귀하와 GPU를 공유하던 다른 사람들의 요청 배치가 변했을 뿐이며, 그것만으로도 충분했습니다.
이에 대한 대처 방법
-
temperature=0을 비트 단위로 동일한(bit-identical) 출력을 보장하는 약속으로 취급하지 마십시오. 이는 오직 샘플링(sampling) 단계에 대한 약속일 뿐입니다. 순전파(Forward-pass) 결정론(determinism)은 이와 별개의, 훨씬 더 구현하기 어려운 속성입니다. -
규정 준수, 보안 민감 감사, 또는 미묘한 회귀(regression) 디버깅을 위해 진정으로 비트 단위의 동일한 재현성(reproducibility)이 필요하다면, 배치 불변 커널(batch-invariant kernels)이 필요하다는 점을 알아두어야 합니다. 즉, 행렬 곱셈(matmul), 어텐션(attention), 정규화(normalization)를 위한 리덕션(reduction) 구현이 배치 구성과 관계없이 동일한 결과를 생성하도록 작성되어야 합니다. 이는 추론(inference) 연구의 활발한 분야이며, 이를 보장하는 초기 구현체들은 실제 처리량(throughput) 비용이 발생하는 것으로 나타났습니다. 최신 최적화 버전들은 이 오버헤드를 약 60%에서 34% 정도로 줄였습니다. 결정론(determinism)은 구매할 수 있는 속성이지만, 공짜는 아닙니다.
-
일상적인 평가(eval) 및 회귀 테스트(regression suites)를 위해서는 정확한 일치(exact match) 대신 허용 오차(tolerance)를 고려하여 설계하십시오. 의미론적 동등성(semantic equivalence)을 비교하거나, 각 케이스를 N번 실행하여 분포 내에서의 안정성을 확인하거나, 모델의 상위 2개 토큰 확률이 근접한 경우(top-2 token probabilities were close)를
-
temperature=0은 결정론적인 토큰 선택 (항상 argmax)을 보장하지만, 결정론적인 순전파 (forward pass)를 보장하지는 않습니다. -
부동 소수점 덧셈 (Floating-point addition)은 결합 법칙 (associative)이 성립하지 않습니다. GPU 리덕션 커널 (reduction kernels)은 배치 구성 (batch composition)에 따라 달라지는 순서로 합산합니다.
-
배치 구성은 다른 동시 요청 (concurrent requests)으로 인한 실시간 서버 부하에 따라 변하며, 이것이 동일한 호출이 때때로 다른 완성본 (completions)을 생성할 수 있는 이유입니다.
-
배치 불변 커널 (batch-invariant kernels)을 사용하면 비트 단위로 동일한 결정론적 결과 (Bit-identical determinism)를 달성할 수 있지만, 현재로서는 무시할 수 없는 상당한 처리량 (throughput) 비용이 발생합니다.
-
바이트 단위의 재현성 (byte-for-byte reproducibility)을 가정하는 대신, 토큰 수준의 변동성 (token-level variance)을 허용하는 평가 (evals)를 구축하십시오.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기