Como superar a não determinismo na inferência de LLMs
(thinkingmachines.ai)- Na inferência de LLMs (grandes modelos de linguagem), ocorre o problema de não determinismo (nondeterminism), em que resultados diferentes podem surgir mesmo com a mesma entrada e as mesmas condições
- Até agora, concorrência (concurrency) e a não associatividade (non-associativity) das operações de ponto flutuante (floating-point) vinham sendo consideradas as principais causas do não determinismo
- Na prática, a verdadeira causa determinante vem da mudança na ordem de cálculo dentro do kernel (código de operação) conforme a variação do tamanho do batch (batch size)
- Se todas as operações dentro do kernel forem implementadas com invariância a batch (batch invariance), é possível garantir reprodutibilidade (reproducibility) completa
- Com operações paralelas por dados, split reduction e estratégia de split de tamanho fixo, é possível criar kernels invariantes a batch para operações principais como RMSNorm, matmul e attention
Introdução e visão geral do problema
- A reprodutibilidade (reproducibility), elemento central do progresso científico, não tem sido bem preservada na inferência de LLMs (grandes modelos de linguagem)
- Mesmo fazendo a mesma pergunta ao ChatGPT várias vezes, é comum que sejam geradas respostas diferentes
- Isso acontece porque o processo de sampling de resultados em LLMs é uma escolha probabilística baseada em uma distribuição de probabilidade
- Porém, mesmo com a temperature ajustada para 0, na prática a API de LLM não é necessariamente determinística (ou seja, não retorna sempre o mesmo resultado para a mesma entrada)
- O problema de não determinismo também existe ao rodar em bibliotecas open source de inferência, como vLLM e SGLang, e em hardware próprio
Hipóteses anteriores e limitações
- Hipótese amplamente conhecida: o não determinismo ocorre por causa de concorrência + não associatividade de ponto flutuante
- Em operações de ponto flutuante na GPU, o resultado pode variar sutilmente conforme a ordem das operações e a ordem de término das threads
- Porém, na prática, mesmo repetindo a mesma multiplicação de matrizes sobre os mesmos dados e da mesma forma, sempre se obtém exatamente o mesmo resultado (bw=bitwise equal)
- Para identificar a causa real, é necessária uma análise mais profunda
Análise aprofundada das causas do não determinismo na inferência de LLMs
A essência da não associatividade de ponto flutuante
- Operações de ponto flutuante obedecem à relação (a+b)+c ≠ a+(b+c)
- Ao operar valores com magnitudes diferentes (exponent), há perda de precisão, perda de informação e o resultado muda conforme a ordem das operações
- Como a ordem das operações pode mudar, se várias somas forem executadas aleatoriamente, surgem resultados variados (confirmado também experimentalmente)
Mudança na ordem das operações do kernel e concorrência
- Em geral, problemas de concorrência em operações como atomic add são apontados como causa principal do não determinismo
- Porém, a maioria dos kernels usados na inferência de LLMs (especialmente no forward pass) funciona mesmo sem atomic add
- Com estratégia de paralelização adequada e split (reduction), é possível garantir a mesma ordem de operações
A causa central de fato: ausência de "invariância a batch (batch invariance)"
- Cada kernel individualmente sempre retorna o mesmo resultado se a entrada for a mesma (run-to-run deterministic)
- Porém, como as requisições simultâneas de vários usuários (batch size) mudam de forma não determinística, na prática o resultado não é estável para cada requisição
- Conforme o tamanho do batch, a ordem de dividir ou combinar operações internamente muda, causando não determinismo
- Ou seja, a causa central era o fato de que a carga do servidor e o paralelismo (tamanho do batch) eram não determinísticos
Projeto de kernels invariantes a batch e casos das operações principais
RMSNorm
- Aplicação de estratégia data-parallel: cada elemento do batch é processado de forma independente por um único core
- Quando o tamanho do batch é grande, mantém-se paralelismo suficiente; assim, a estratégia de paralelização permanece constante e a invariância a batch é preservada
- Quando o tamanho do batch é muito pequeno, usam-se estratégias alternativas como split reduction, mas nesse caso parte da invariância a batch é sacrificada
Multiplicação de matrizes (matmul)
- Usa-se estratégia data-parallel com paralelização por tile
- Para otimizar o uso de Tensor Cores, é preciso dividir em tiles 2D, e em batches muito pequenos são necessárias estratégias especiais como split-K
- Ao usar a estratégia split-K, a invariância a batch pode ser quebrada
- Mesmo com alguma perda de desempenho, é possível garantir uma ordem de operações constante e reproduzível ao forçar a mesma configuração de kernel
Attention
- Em FlashAttention2 e afins, a paralelização na direção de query e a redução simultânea de Key/Value garantem a invariância a batch
- Se a ordem de reduction mudar conforme o tamanho do batch ou a divisão da sequência (chunked prefill, prefix caching etc.), a invariância é quebrada
- Em estratégias de split-reduction como split-KV (FlashDecoding), é possível manter a mesma ordem de operações fixando o tamanho do split (fixed split-size)
- Internamente, não se deve tratar separadamente o cache de key/value e os novos tokens; é preciso manter um layout consistente de keys/values em todas as operações
Implementação
- Foi disponibilizada uma demo de inferência determinística com aplicação de kernels batch-invariant usando vLLM e torch.Library
- Os kernels de substituição para essas operações podem ser vistos no repositório GitHub (thinking-machines-lab/batch-invariant-ops)
Experimentos e desempenho
Experimento de medição de não determinismo
- Com o modelo Qwen/Qwen3-235B-A22B-Instruct-2507, em condição de temperature 0, foi feita a geração 1000 vezes com o mesmo prompt (“Tell me about Richard Feynman”)
- Foram geradas 80 finalizações diferentes (mesmo prompt, mas com não determinismo)
- Até os 102 primeiros tokens, o resultado era igual; a primeira divergência ocorreu no token 103 (“Queens, New York” vs “New York City”)
- Ao usar kernels invariantes a batch, os 1000 resultados foram idênticos, garantindo reprodutibilidade completa
Avaliação de desempenho
- Com 1 GPU rodando Qwen-3-8B, foram feitas 1000 requisições de sequências com comprimento entre 90 e 110
- vLLM padrão: 26 segundos
- vLLM determinístico não otimizado: 55 segundos
- Com kernel de attention melhorado: 42 segundos
- Embora ainda faltem otimizações, o desempenho permanece em um nível prático de uso
Valor para On-policy RL
- Antes, por pequenas diferenças numéricas entre training e inference, on-policy RL não podia ser implementado com precisão
- Com inferência determinística, torna-se possível fazer sampling e training bitwise identical, permitindo uma implementação real de on-policy RL
- Foi confirmada correspondência completa dos resultados em métricas principais como KL-divergence e reward
Conclusão
- Em sistemas de inferência de LLMs, é fácil ignorar o não determinismo e os erros numéricos, mas ao identificar e corrigir a causa raiz (falta de invariância a batch), é possível obter reprodutibilidade e determinismo completos
- Este estudo mostra um caminho para resolver o problema de não determinismo na inferência de LLMs e ajuda desenvolvedores a garantir reprodutibilidade total em seus próprios sistemas
Informações de citação
- Ao citar este estudo, use as informações abaixo
He, Horace and Thinking Machines Lab, "Defeating Nondeterminism in LLM Inference",
Thinking Machines Lab: Connectionism, Sep 2025.
ou
@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}
}
1 comentários
Comentários do Hacker News
Mesmo que a não determinismo “teórica” seja completamente eliminada em pares individuais e fechados de entrada e saída, ainda restam dois problemas reais de não determinismo: o mesmo input produzir resultados diferentes dependendo do contexto anterior, e inputs levemente modificados não produzirem resultados corretamente modificados. Enquanto esses problemas não forem resolvidos, o não determinismo em sistemas fechados não ajuda muito, exceto em situações em que uma tabela de consulta já seria suficiente. É difícil provar qualquer coisa com testes unitários “precisos” ou conjuntos de avaliação para inputs que não foram testados
A situação de “o resultado mudar dependendo de um contexto anterior diferente mesmo com exatamente o mesmo input” na verdade não existe. O próprio contexto anterior faz parte do input. Se um certo prompt de entrada sempre produz o mesmo resultado, então pode-se considerar que o contexto está sendo ignorado. Ou seja, é o mesmo que sempre começar com um contexto vazio, independentemente do estado da sessão. O que algumas pessoas querem é:
Por que seria um problema o fato de que “o contexto anterior” produz resultados diferentes? Se o contexto não afeta o resultado, então basta descartá-lo. Por que querer esse comportamento à força? Na prática, se for uma ferramenta, espero que ela responda de forma diferente conforme minha intenção ou troca de modo (por exemplo, mudar para o modo insert no vim e então o comportamento mudar). Também espero que a inteligência funcione assim. Ignorar contexto parece mais próximo de um viés de confirmação extremo
É muito útil para reproduzir bugs
Eu concordava até a parte de dizer que “não ajuda muito”. Acho que provavelmente queria dizer “não resolve completamente o problema”
Fico curioso sobre por que existe tanta preocupação com determinismo em um sistema probabilístico. Do ponto de vista do usuário, mesmo que para o input "How do I X?" a resposta fosse sempre a mesma e determinística, isso não significaria muito se inputs com o mesmo significado como "how do i x?", "how do I x" e "how do I X??" gerassem resultados completamente diferentes entre si. O que realmente precisamos em LLMs é a capacidade de garantir que inputs semanticamente iguais sempre produzam outputs semanticamente iguais. Isso é um conceito totalmente diferente do que normalmente chamamos de determinismo em algoritmos
Nem toda aplicação baseada em LLM tem só uma interface de chat em que o usuário escreve de forma improvisada. Em casos como executar chamadas de ferramenta 10 vezes seguidas para fins de avaliação, ou testar prompts continuamente com ferramentas como o DSPy Optimizer link, reduzir a imprevisibilidade importa quando eu tenho controle total até sobre os tokens de entrada. Nesses ambientes, se for possível eliminar a variabilidade no nível do token e deixar apenas a ambiguidade do próprio input, então fica muito mais viável mapear o comportamento do sistema em estruturas confiáveis de árvore ou grafo
O que você diz não está errado, mas isso não significa que esse nível de determinismo seja inútil. Se até com exatamente os mesmos tokens de entrada o resultado sempre mudar, fica difícil reproduzir e compartilhar resultados com colegas ou testar situações em que o LLM produz saídas muito raras e imprevisíveis (por exemplo, red teaming)
Estou trabalhando em um projeto de esteganografia para embutir informação em saídas de LLM: innocuous. Extraio e uso só algo como os 10 principais tokens do modelo e, como testo principalmente em modelos 8B baseados em CPU, não me preocupo tanto com a ordem dos tokens mudar por causa do hardware, mas pretendo eventualmente criar também condições de proteção para evitar que pequenas perdas de precisão mudem as opções escolhidas
Isso pode ser muito útil para clientes de plataformas de AI. Dá para rodar um prompt várias vezes com temperature 0 e verificar se o resultado é sempre igual, validando se o provedor de AI não está trocando escondido um modelo PRO por outro mais barato
Para reproduzir “bugs”, isso é indispensável. Se for possível reproduzir sempre a mesma saída errada ou estranha ao inserir a mesma string de input, o debugging fica muito mais fácil. Se o resultado mudar uma vez a cada 100 execuções, fica muito mais difícil
(Experiência trabalhando com JAX/XLA) Isso é algo bastante conhecido. Eu mesmo já esbarrei várias vezes nesse fenômeno (variabilidade por batch) e recebi explicações nas issues abaixo: penzai issue #82, comentário na issue do jax
Às vezes a causa do não determinismo está em detalhes de implementação. Por exemplo, no código-fonte do GPT-2, mesmo se você definir temperature como 0 na GUI, na prática entra um valor "epsilon" diferente de zero (um número muito pequeno). Isso é compreensível, porque evita erro de divisão por zero. O não determinismo é “inútil” em muitas aplicações. Também é um problema antigo em modelos de tópico LDA. Em áreas como jurídico, finanças e regulação, usar métodos não determinísticos pode até ser ilegal. Ou então pode gerar obrigações extras indesejadas, como ter de manter gravações completas de todas as telas para depois conseguir reconstruir exatamente o que aconteceu
Surgiu a história de “trabalhar com outra pessoa na Thinking Machines”. Isso me deu saudade da época em que eu via pessoalmente aquela máquina com cubos vermelhos de LED brilhando em frente ao MIT AI Lab. Richard Feynman fez coisas realmente incríveis, e há um texto sobre isso: Feynman and the Connection Machine. Nos EUA, a marca registrada “THINKING MACHINES” não foi registrada por Hillis, mas pela empresa que ele fundou, e foi cancelada em 1998–1999. A empresa faliu em 1994, e seus ativos foram parar em empresas como a Sun Microsystems (depois Oracle). A Thinking Machines Lab Inc., fundada por Amira Murati, está agora em processo de registrar novamente a marca “THINKING MACHINES” em 2025
É muito bom ver recentemente discussões de pesquisa em estilo de blog com alta qualidade. A Anthropic está puxando essa cultura, e tenho esperança porque isso vem se espalhando cada vez mais. No passado, na época das pesquisas em RL, a OpenAI também era assim
A própria linguagem natural tem ambiguidade. E precisa ter. Acho equivocada essa tentativa de “transformar um círculo em quadrado e explicar por que isso deveria acontecer”. Discussões como essa vão acabar evoluindo para conversas sobre aceitar melhor a natureza da linguagem e da aleatoriedade, e interpretar linguagem para além de subpadrões gramaticais mínimos como matrizes de projeção QKV
Ainda não gosto do nome da empresa. Fico me perguntando por que esse tipo de nomeação continua acontecendo. Talvez seja na esperança de que o caráter de uma organização lendária se transfira para uma nova startup. Mas não é como se dar o nome PARC para a próxima startup fosse fazer a inovação em redes aparecer automaticamente
Você está falando da empresa “Thinking Machines” que acabou em 1994? Tive de pesquisar para descobrir, e como ela não é tão famosa quanto eu imaginava, acho que essa não deve ser a intenção. Só acho que é um nome legal e intuitivo
Só de escolher o nome, o marketing já vem de graça, que é justamente o motivo de existência do sistema de marcas registradas
Conteúdo realmente interessante. Para quem não sabe, esta é a empresa criada pela ex-CTO da OpenAI, Mira Murati