LLM 추론에서 비결정성을 극복하는 방법
(thinkingmachines.ai)- LLM(대형 언어 모델) 추론에서는 동일한 입력과 조건에도 결과가 다르게 나오는 비결정성(nondeterminism) 문제가 발생함
- 기존에는 동시성(concurrency) 과 부동소수점(floating-point) 연산의 비결합성(non-associativity) 이 비결정성의 주요 원인으로 간주되어 왔음
- 실제 결정적인 원인은 배치 크기(batch size) 변화에 따른 커널(연산 코드) 내부의 계산 순서 변화에서 비롯됨
- 커널 내 모든 연산이 배치 불변성(batch invariance) 을 갖도록 구현하면 완전한 재현성(reproducibility) 보장 가능함
- 데이터 병렬 연산, split reduction, 고정 크기 split 전략 등으로 주요 연산(RMSNorm, matmul, attention)에 대해 배치 불변 커널 제작이 가능함
서론 및 문제 개요
- 과학적 진보의 핵심 요소인 재현성(reproducibility) 이 LLM(대형 언어 모델) 추론에서는 잘 지켜지지 않음
- 같은 질문을 ChatGPT에 여러 번 해도 서로 다른 답변이 생성되는 경우 자주 발생함
- 이는 LLM에서 결과를 샘플링(sampling) 하는 과정이 확률 분포에 기반한 확률적 선택이기 때문임
- 그러나, temperature를 0으로 설정해도 실제로는 LLM API가 반드시 결정적이지 않음(즉, 같은 입력에 대해 결과가 항상 같지 않음)
- 오픈소스 추론 라이브러리(vLLM, SGLang 등)와 자가 하드웨어에서 실행해도 비결정성 문제 존재
기존 가설과 한계
- 널리 알려진 가설: 동시성 + 부동소수점의 비결합성 때문에 비결정성 발생
- GPU에서의 부동소수점 연산은 연산 순서와 스레드 종료 순서에 따라 미세하게 결과 달라짐
- 그러나, 실제로는 동일 데이터에 같은 방식으로 행렬곱을 반복해도 항상 동일한(bw=bitwise equal) 결과 얻어짐
- 진짜 원인을 파악하려면 더 깊은 분석 필요
LLM 추론의 비결정성 원인 심층 분석
부동소수점 비결합성의 본질
- 부동소수점 연산은 (a+b)+c ≠ a+(b+c) 관계를 가짐
- 서로 다른 크기(exponent)를 가진 값들 연산 시 정밀도 손실, 정보 소실, 연산 순서에 따라 결과 달라짐
- 연산 순서가 달라질 수 있으므로, 여러 번의 합계를 랜덤하게 수행하면 다양한 결과(실험적으로도 확인) 가 도출됨
커널의 연산 순서 변화와 동시성
- 일반적으로 비결정성의 주 원인으로 원자적 덧셈(atomic add) 등에서의 동시성 문제 지적
- 하지만, LLM 추론에서 사용하는 대부분의 커널(특히 forward pass)은 원자적 덧셈 없이도 동작함
- 사전 적절한 병렬 전략, split(reduction) 등으로 동일 연산 순서를 확보할 수 있음
사실상 핵심 원인: "배치 불변성(batch invariance)" 결여
- 개별 커널은 입력이 동일하면 항상 같은 결과를 반환(run-to-run deterministic)
- 하지만, 여러 사용자의 동시 요청(batch size)이 비결정적으로 바뀌기 때문에 각 요청에 대해 실질적으로는 결과가 일정하지 않음
- 배치 크기에 따라 내부적으로 연산을 분할하거나 합치는 순서가 달라져서 비결정성 발생
- 즉, 서버 부하와 병렬도(배치 사이즈)가 비결정적이었다는 점이 핵심 원인임
배치 불변 커널 설계와 핵심 연산 사례
RMSNorm
- 데이터 병렬화(data-parallel) 전략 적용: 각 배치 요소를 독립적으로 하나의 코어가 처리
- 배치 크기가 크면 충분한 병렬성 유지, 즉 병렬 전략이 일정하여 배치 불변성이 확보됨
- 배치 크기가 매우 작을 때는 split reduction 등 대안 전략을 쓰나, 이 경우엔 일부 배치 불변성 희생됨
행렬곱(matmul)
- 타일(tile)별로 병렬화하여 데이터 병렬 전략 활용
- 텐서코어 사용 최적화를 위해서는 2D 타일로 분할해야 하며, 매우 작은 배치에서는 split-K 같은 특별 전략 필요
- split-K 전략을 쓸 때 배치 불변성 깨질 수 있음
- 성능 일부를 희생하더라도, 동일 커널 구성을 강제하여 일정한(reproducible) 연산 순서 확보 가능
어텐션(attention)
- FlashAttention2 등에서 쿼리 방향 병렬화, Key/Value 동시 reduction 전략으로 배치 불변성 확보
- 배치 크기, 시퀀스 분할(chunked prefill, prefix caching 등)에 따라 reduction 순서가 달라지면 불변성 깨짐
- split-KV(FlashDecoding) 등 split-reduction 전략에서는 split 크기를 고정(fixed split-size) 하여 연산 순서를 동일하게 유지
- 내부 동작상 key/value 캐시와 신규 토큰을 별도 처리하지 않고, 모든 연산에서 키/값 레이아웃을 일관적으로 유지해야 함
구현
- vLLM과 torch.Library를 활용해 batch-invariant 커널을 적용한 결정적 추론 데모 제공
- 관련 연산 대체 kernel은 GitHub 레포(thinking-machines-lab/batch-invariant-ops)에서 열람 가능
실험 및 성능
비결정성 측정 실험
- Qwen/Qwen3-235B-A22B-Instruct-2507 모델로 temperature 0 조건에서 동일 프롬프트(“Tell me about Richard Feynman”) 1000회 생성
- 80가지 서로 다른 완성이 생성(동일 프롬프트이지만 비결정성 존재)
- 처음 102개 토큰까지는 동일, 103번째 토큰에서 첫 분기 발생(“Queens, New York” vs “New York City”)
- 배치 불변 커널 사용 시 1000번 모두 동일 결과, 완전 재현성 확보
성능 평가
- GPU 1대, Qwen-3-8B 구동, 각각 90~110 길이의 시퀀스 1000개 요청
- vLLM 기본: 26초
- 비최적화 deterministic vLLM: 55초
- 개선된 attention 커널 적용: 42초
- 최적화가 부족하지만 실용 가능한 성능 수준 유지
On-policy RL에서의 가치
- 기존에는 training과 inference 간 미세한 숫자 차이로 인해 on-policy RL이 정확히 구현되지 않음
- 결정적 추론이 가능해지면, 샘플링과 트레이닝 모두 bitwise identical하게 만들어 진정한 on-policy RL 구현 가능
- KL-divergence, reward 등 주요 metric에서 완전히 일치하는 결과 확인
결론
- LLM 추론 시스템에서 비결정성과 수치 오차를 무시하기 쉽지만, 이 문제의 근본 원인(배치 불변성 결여) 을 파악하고 개선하면 완전한 재현성 및 결정성을 얻을 수 있음
- 본 연구는 LLM 추론의 비결정성 문제 해결 방안을 밝혀 개발자들이 자체 시스템 내에서 완전한 재현성을 확보할 수 있게 도움
인용 정보
- 본 연구를 인용할 때는 다음 정보를 사용
He, Horace and Thinking Machines Lab, "Defeating Nondeterminism in LLM Inference",
Thinking Machines Lab: Connectionism, Sep 2025.
또는
@article{he2025nondeterminism,
author = {Horace He and Thinking Machines Lab},
title = {Defeating Nondeterminism in LLM Inference},
journal = {Thinking Machines Lab: Connectionism},
year = {2025},
note = {https://thinkingmachines.ai/blog/…},
doi = {10.64434/tml.20250910}
}
Hacker News 의견
-
"이론적인" 비결정성을 완전히 닫힌 개별 입력-출력 쌍에서 해결하더라도 실제 두 가지 비결정성 문제, 즉 동일한 입력이 이전 맥락에 따라 다른 결과를 낸다는 문제와 약간 변형된 입력이 올바르게 변형된 결과를 내지 못하는 문제가 남아 있음. 이런 문제가 해결되지 않는 한, 닫힌 시스템에서의 비결정성은 사실 조회 테이블로도 충분한 상황을 제외하면 그다지 도움이 안 됨. 테스트하지 않은 입력에 대해 "정확한" 단위 테스트나 평가 세트로 무슨 증명을 하기는 어려움
-
"정확히 같은 입력인데도 다른 이전 맥락에 따라 결과가 달라지는" 상황은 사실 존재하지 않음. 이전 맥락 자체가 입력임. 만약 어떤 입력 프롬프트에서 항상 같은 결과가 나온다면, 맥락은 무시되고 있다고 볼 수 있음. 즉, 세션 내 상태와 무관하게 항상 비어있는 맥락에서 시작한다는 것과 같음. 몇몇 사람들이 원하는 것은,
- 의미가 같은 다양한 프롬프트 문장(예: "What is the capital of France"와 "What is France's capital")이 똑같은 답변을 내야 한다는 요구임
- 이전 맥락이 질문에 아무 상호작용을 하지 않을 때는 결과에 영향을 미치지 않았으면 좋겠다는 요구임. 예를 들면, 프롬프트 "what is 2 + 2"에 항상 같은 답변이 나와야 하고, 맥락에서 2 + 2 = 5라고 지정하지 않는 한 변하지 않아야 한다는 것임. 이런 요구는 LLM이라는 존재에 대해 오해하고 있다는 걸 보여줌
-
'이전 맥락'이 다른 결과를 만든다는 게 왜 문제임? 만약 맥락이 결과에 영향을 주지 않는다면, 맥락을 그냥 버려도 됨. 그런 동작을 굳이 원하는 이유가 뭐임? 실제로 도구라면 내 의도나 모드 전환(예, vim에서 insert 모드 전환 후 동작 변경)에 따라 다르게 반응하길 기대함. 지능 역시 그런 식으로 동작하길 바람. 맥락을 무시하는 게 오히려 극단적인 확증 편향에 더 가깝게 느껴짐
-
버그를 재현할 때 굉장히 유용함
-
"별 도움이 안 된다"고 말하는 지점까진 동의했었음. 아마 "문제를 완전히 해결해주진 않는다"는 의미로 말한 것 같음
-
-
확률적 시스템에서 왜 결정성에 그렇게 신경을 쓰는지 궁금함. 사용자의 입장에선 "How do I X?"라는 입력에 언제나 똑같은 결정론적 답을 내놓는다 한들, "how do i x?", "how do I x", "how do I X??" 등 의미가 같은 입력에 서로 전혀 다른 결과가 나온다면 별 의미 없는 일이 됨. LLM에서 진짜 필요한 건 의미적으로 같은 입력이면 항상 의미적으로 같은 출력을 보장하는 능력임. 이건 우리가 보통 알고리즘에서 말하는 결정성과는 완전히 다른 개념임
-
모든 LLM 기반 애플리케이션이 사용자가 즉흥적으로 채팅하는 인터페이스만 갖는 건 아님. 도구 호출을 평가 목적으로 10번 연속 하는 경우라든가, DSPy Optimizer 같은 도구링크로 프롬프트를 계속 테스트하는 경우처럼, 토큰 수준 입력까지 전적으로 내가 통제할 수 있다면 예측 불가성을 줄이는 게 중요함. 이런 환경에선, 토큰 레벨에서의 변동성을 제거해 입력 자체의 모호함만 제거할 수 있다면 시스템의 행동을 훨씬 신뢰할 수 있는 트리, 그래프 구조로 매핑할 수 있음
-
당신 말이 틀리진 않지만, 그렇다고 해서 이 정도의 결정성이 쓸모없다는 건 아님. 만약 똑같은 입력 토큰을 넣어도 항상 결과가 다르면, 동료들과 결과를 재현하며 공유하거나 LLM이 아주 드물고 예측 곤란한 출력을 내는 상황을 테스트(예, red teaming)하기 어려움
-
LLM 출력에 스테가노그래피로 정보를 심는 프로젝트를 하고 있음: innocuous 모델의 상위 10개 토큰 정도만 추출해서 사용하고, 주로 CPU 기반 8B 모델에서 테스트하기 때문에, 하드웨어 영향으로 토큰 순서가 달라질 걱정은 크지 않지만, 미세한 정밀도 손실로 선택지가 바뀌지 않도록 eventually guard 조건도 만들어 둘 생각임
-
AI 플랫폼 고객에게 매우 유용할 수 있음. 프롬프트를 temperature 0으로 여러 번 돌려서 결과가 항상 같은지 확인해서, AI 제공업체가 PRO 모델을 싼 다른 모델로 몰래 바꿔치기하고 있는지 검증할 수 있음
-
"버그" 재현 목적에선 반드시 필요함. 동일한 입력 스트링을 넣을 때 똑같이 잘못되거나 특이한 출력을 매번 재현할 수 있다면 디버깅이 훨씬 쉬워짐. 결과가 100번에 한 번씩 달라지면 훨씬 어려워짐
-
-
(JAX/XLA 작업 경험) 이건 꽤 잘 알려진 내용임. 나 역시 여러 번 이런 현상(배치 단위 변동성)에 부딪혔고 아래 이슈에서 설명을 들음: penzai issue #82, jax issue comment
- 이 내용이 최상위 댓글이 되어야 한다고 생각함
-
때로 비결정성의 원인은 구현의 세부사항임. 예를 들어, GPT-2 소스코드에선 GUI에서 temperature를 0으로 지정해도 실제론 0이 아닌 "epsilon"(아주 작은 수) 값이 들어감. 이는 division by zero(제로 나누기) 오류를 방지하기 위함이라 납득할 만함. 비결정성은 많은 애플리케이션에서 "쓸모없음"임. LDA 토픽 모델에서도 오래된 문제임. 특히 법률, 금융, 규제 분야에서는 결정론적이지 않은 방법을 쓰는 것이 불법일 수도 있음. 아니면 원치 않는(모든 화면 기록을 보관하여 나중에 무슨 일이 있었는지 하나하나 복구 가능하게 유지해야 하는) 추가 의무가 생길 수 있음
-
"다른 이와 함께 Thinking Machines에서 작업" 이야기가 나옴. 예전에 MIT AI Lab 앞에서 빨간 LED 큐브가 빛나던 그 기계를 직접 보던 시절이 그립다는 생각을 듦. Richard Feynman이 정말 멋진 일을 했고, 관련 글도 있음 Feynman and the Connection Machine. 미국에서 “THINKING MACHINES” 상표권은 Hillis가 아니라 그가 창업한 회사에 등록되었고 1998–1999년에 말소됨. 회사는 1994년에 파산했으며 자산은 Sun Microsystems(이후 Oracle) 등으로 넘어갔음. Amira Murati가 세운 Thinking Machines Lab Inc.가 2025년에 새로 “THINKING MACHINES” 상표 출원을 진행 중임
- 매번 저 회사 이름 볼 때마다 이 혼동을 하게 됨
-
최근 높은 퀄리티의 블로그 스타일 연구 토론이 정말 반가움. Anthropic이 이 문화를 이끌고 있고 점점 확산되는 추세라 기대가 큼. 과거 RL 연구 시기엔 OpenAI도 이런 방식이었음
-
자연어 자체가 모호함을 지님. 모호해야만 함. 여기서 시도하는 '원을 네모로 만들고 왜 그래야 하는지 설명해보려는' 접근 방식은 잘못됐다고 생각함. 이런 논의는 결국 언어나 랜덤성의 본질을 더 잘 받아들이고, QKV projection matrix 같은 미니 문법 하위 패턴 그 이상에서 언어를 해석하게 되는 토론으로 발전할 것임
- 맞는 말임. 다만 결정성은 모호함이 아님. 결정성이란 "정확히 이 입력에 정확히 이 출력을 보장해야 함"임. 같은 모델에 같은 질문을 하면 무조건 같은 답변이 나와야 한다고 기대함. 물론 문장만 살짝 바꾼 질문이라면 다소 다른 답변이 나오는 걸 충분히 이해함
-
회사 이름이 여전히 마음에 들지 않음. 왜 이런 작명이 반복되는지 의문임. 전설적인 조직의 성격이 신생 벤처에도 스며들길 바라는 맥락인지 모르겠음. 다음 스타트업 이름을 PARC로 정한다고 네 트워킹 혁신이 자동으로 이어질 일은 없지 않나 생각함
-
1994년에 사라진 “Thinking Machines” 회사 얘기하는 거 맞음? 좀 찾아봐야 알 수 있었고, 생각보다 유명하지 않아서 그런 의도는 아닌 듯. 그냥 멋지고 직관적인 이름이라고 생각함
-
이름 짓기만으로 마케팅이 공짜로 따라오니, 상표 제도의 탄생 이유와 같음
-
-
정말 흥미로운 내용임. 잘 모르는 사람들을 위해 말하면, 이 회사는 이전 OpenAI CTO Mira Murati가 시작한 곳임