2 points par GN⁺ 2025-09-12 | 1 commentaires | Partager sur WhatsApp
  • En inférence de LLM (grands modèles de langage), un problème de non-déterminisme (nondeterminism) apparaît : même avec une entrée et des conditions identiques, les résultats peuvent différer
  • Jusqu’ici, la concurrence (concurrency) et la non-associativité des opérations en virgule flottante (floating-point) étaient considérées comme les principales causes du non-déterminisme
  • En réalité, la cause déterminante est le changement de taille de batch (batch size), qui modifie l’ordre des calculs à l’intérieur des kernels (code de calcul)
  • Si toutes les opérations d’un kernel sont implémentées de façon à garantir l’invariance au batch (batch invariance), il devient possible d’assurer une reproductibilité (reproducibility) complète
  • Grâce à des techniques comme les opérations parallèles sur les données, le split reduction et les stratégies de split à taille fixe, il est possible de construire des kernels invariants au batch pour les principales opérations (RMSNorm, matmul, attention)

Introduction et vue d’ensemble du problème

  • La reproductibilité (reproducibility), élément central du progrès scientifique, est mal assurée dans l’inférence des LLM (grands modèles de langage)
  • En posant plusieurs fois la même question à ChatGPT, on obtient souvent des réponses différentes
  • Cela vient du fait que, dans les LLM, le processus de sampling repose sur une sélection probabiliste fondée sur une distribution de probabilités
  • Cependant, même en réglant le temperature à 0, une API de LLM n’est pas nécessairement déterministe en pratique (autrement dit, la même entrée ne produit pas toujours exactement le même résultat)
  • Le problème de non-déterminisme existe aussi avec des bibliothèques d’inférence open source (vLLM, SGLang, etc.) et sur du matériel exploité en propre

Hypothèses classiques et leurs limites

  • Hypothèse largement admise : le non-déterminisme vient de la concurrence + la non-associativité des flottants
    • Sur GPU, les opérations en virgule flottante peuvent produire des résultats légèrement différents selon l’ordre des opérations et l’ordre de terminaison des threads
  • Mais en pratique, répéter exactement la même multiplication de matrices sur les mêmes données produit toujours un résultat identique (bw=bitwise equal)
  • Il faut donc une analyse plus approfondie pour identifier la vraie cause

Analyse approfondie des causes du non-déterminisme en inférence LLM

Nature de la non-associativité des flottants

  • Les opérations en virgule flottante vérifient la relation (a+b)+c ≠ a+(b+c)
  • Lors d’opérations entre des valeurs de tailles différentes (exponent), il peut y avoir perte de précision et perte d’information, ce qui fait que le résultat varie selon l’ordre des calculs
  • Comme l’ordre des opérations peut changer, exécuter plusieurs additions dans des ordres aléatoires conduit à des résultats variés (confirmés expérimentalement)

Variation de l’ordre des calculs dans les kernels et concurrence

  • En général, on désigne souvent les problèmes de concurrence, comme l’addition atomique (atomic add), comme principale cause du non-déterminisme
  • Mais la plupart des kernels utilisés en inférence LLM (en particulier lors du forward pass) fonctionnent sans addition atomique
  • Avec une stratégie de parallélisation appropriée, un split (reduction), etc., il est possible de garantir le même ordre d’opérations

La cause centrale en pratique : l’absence d’« invariance au batch (batch invariance) »

  • Chaque kernel pris individuellement renvoie toujours le même résultat à entrée identique (run-to-run deterministic)
  • Mais comme les requêtes simultanées de plusieurs utilisateurs (batch size) varient de manière non déterministe, le résultat n’est pas stable en pratique pour chaque requête
  • Selon la taille du batch, l’ordre interne de découpage ou de fusion des calculs change, ce qui introduit du non-déterminisme
  • Autrement dit, la vraie cause est le fait que la charge serveur et le niveau de parallélisme (taille du batch) étaient non déterministes

Conception de kernels invariants au batch et cas des opérations clés

RMSNorm

  • Application d’une stratégie de parallélisation orientée données (data-parallel) : chaque élément du batch est traité indépendamment par un cœur
  • Si la taille du batch est grande, le parallélisme reste suffisant, donc la stratégie parallèle reste constante et l’invariance au batch est assurée
  • Quand la taille du batch est très petite, on utilise des stratégies alternatives comme le split reduction, mais cela peut alors sacrifier une partie de l’invariance au batch

Multiplication de matrices (matmul)

  • Utilisation d’une stratégie de parallélisation par tile pour exploiter le parallélisme des données
  • Pour optimiser l’usage des Tensor Cores, il faut découper en tiles 2D, et pour des batches très petits, des stratégies spéciales comme split-K sont nécessaires
  • L’usage de split-K peut rompre l’invariance au batch
  • Même si cela coûte une partie des performances, il est possible de forcer une configuration de kernel identique afin de garantir un ordre d’exécution constant (reproducible)

Attention

  • Avec FlashAttention2, etc., l’invariance au batch peut être assurée grâce à une parallélisation dans la direction des requêtes (query) et à une stratégie de reduction simultanée sur Key/Value
  • Si l’ordre de reduction change selon la taille du batch ou le découpage de séquence (chunked prefill, prefix caching, etc.), l’invariance est rompue
  • Dans les stratégies de split-reduction comme split-KV (FlashDecoding), il faut fixer la taille de split (fixed split-size) pour conserver le même ordre de calcul
  • En interne, il faut aussi éviter de traiter séparément le cache key/value et les nouveaux tokens, et conserver une disposition cohérente des clés/valeurs dans toutes les opérations

Implémentation

  • Une démo d’inférence déterministe appliquant des kernels invariants au batch est fournie à l’aide de vLLM et de torch.Library
  • Les kernels de remplacement pour les opérations concernées sont disponibles dans le dépôt GitHub (thinking-machines-lab/batch-invariant-ops)

Expériences et performances

Expérience de mesure du non-déterminisme

  • Avec le modèle Qwen/Qwen3-235B-A22B-Instruct-2507, génération 1000 fois du même prompt (« Tell me about Richard Feynman ») avec temperature 0
  • 80 complétions différentes sont générées (preuve de non-déterminisme malgré un prompt identique)
  • Les 102 premiers tokens sont identiques ; la première bifurcation apparaît au 103e token (« Queens, New York » vs « New York City »)
  • Avec les kernels invariants au batch, les 1000 exécutions produisent exactement le même résultat, assurant une reproductibilité complète

Évaluation des performances

  • Sur 1 GPU, exécution de Qwen-3-8B avec 1000 requêtes de séquences de longueur 90 à 110
    • vLLM standard : 26 secondes
    • vLLM déterministe non optimisé : 55 secondes
    • avec kernel d’attention amélioré : 42 secondes
  • L’optimisation reste incomplète, mais le niveau de performance reste exploitable en pratique

Intérêt pour le RL on-policy

  • Jusqu’ici, de légères différences numériques entre entraînement et inférence empêchaient une mise en œuvre exacte du RL on-policy
  • Avec une inférence déterministe, il devient possible de rendre l’échantillonnage et l’entraînement bitwise identical, ce qui permet une véritable implémentation du RL on-policy
  • Les métriques clés comme la KL-divergence et la reward montrent des résultats parfaitement identiques

Conclusion

  • Dans les systèmes d’inférence LLM, il est facile de négliger le non-déterminisme et les erreurs numériques, mais en identifiant et en corrigeant leur cause fondamentale (l’absence d’invariance au batch), on peut obtenir une reproductibilité et un déterminisme complets
  • Cette étude met en lumière une méthode pour résoudre le problème du non-déterminisme en inférence LLM et aide les développeurs à garantir une reproductibilité totale dans leurs propres systèmes

Informations de citation

  • Pour citer cette étude, utilisez les informations suivantes
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 commentaires

 
GN⁺ 2025-09-12
Réactions sur Hacker News
  • Même si l’on résout la non-déterminisme « théorique » pour des paires entrée-sortie individuelles totalement fermées, il reste en pratique deux problèmes de non-déterminisme : le fait qu’une même entrée puisse produire un résultat différent selon le contexte précédent, et le fait qu’une entrée légèrement modifiée ne produise pas un résultat correctement modifié. Tant que ces problèmes ne sont pas résolus, le non-déterminisme dans un système fermé n’aide pas beaucoup, sauf dans des situations où une simple table de correspondance suffirait de toute façon. Il est difficile de prouver quoi que ce soit avec des tests unitaires « exacts » ou des jeux d’évaluation pour des entrées non testées

    • La situation où « exactement la même entrée donne un résultat différent selon un contexte antérieur différent » n’existe pas vraiment. Le contexte précédent fait lui-même partie de l’entrée. Si une invite donnée produit toujours le même résultat, on peut considérer que le contexte est ignoré. Autrement dit, c’est comme si l’on repartait toujours d’un contexte vide, indépendamment de l’état de la session. Ce que certaines personnes veulent, c’est :

      • que différentes formulations d’une même phrase, de sens équivalent (par ex. "What is the capital of France" et "What is France's capital"), donnent exactement la même réponse
      • que le contexte précédent n’influe pas sur le résultat lorsqu’il n’interagit pas du tout avec la question. Par exemple, l’invite "what is 2 + 2" devrait toujours donner la même réponse, et ne pas changer à moins que le contexte n’ait explicitement défini 2 + 2 = 5. Ces exigences montrent une incompréhension de ce qu’est un LLM
    • Pourquoi est-ce un problème que le « contexte précédent » produise un résultat différent ? Si le contexte n’influence pas le résultat, on peut simplement le jeter. Pourquoi vouloir ce comportement à tout prix ? Pour un véritable outil, on s’attend justement à ce qu’il réagisse différemment selon mon intention ou un changement de mode (par ex., dans vim, le comportement change après passage en mode insertion). J’aimerais aussi que l’intelligence fonctionne ainsi. Ignorer le contexte ressemble plutôt à une forme extrême de biais de confirmation

    • C’est extrêmement utile pour reproduire un bug

    • J’étais d’accord jusqu’au moment où il a été dit que cela « n’aide pas beaucoup ». J’imagine que cela voulait plutôt dire « ne résout pas complètement le problème »

  • Je me demande pourquoi on accorde autant d’importance au déterminisme dans un système probabiliste. Du point de vue de l’utilisateur, même si l’entrée "How do I X?" reçoit toujours exactement la même réponse déterministe, cela n’a pas beaucoup de valeur si des entrées de même sens comme "how do i x?", "how do I x", "how do I X??" produisent des résultats totalement différents. Ce qu’il faut vraiment pour les LLM, c’est la capacité à garantir qu’une entrée sémantiquement équivalente produise toujours une sortie sémantiquement équivalente. C’est un concept totalement différent du déterminisme au sens habituel des algorithmes

    • Toutes les applications basées sur des LLM ne se limitent pas à une interface de chat improvisée par l’utilisateur. Si j’exécute dix fois de suite des appels d’outils à des fins d’évaluation, ou si je teste continuellement des invites avec un outil comme le DSPy Optimizer lien, et que je contrôle totalement l’entrée jusqu’au niveau des tokens, alors il est important de réduire l’imprévisibilité. Dans ce type d’environnement, si l’on peut éliminer la variabilité au niveau du token pour ne garder que l’ambiguïté propre à l’entrée, on peut cartographier le comportement du système dans des structures en arbre ou en graphe bien plus fiables

    • Ce que vous dites n’est pas faux, mais cela ne veut pas dire que ce niveau de déterminisme est inutile. Si le résultat change à chaque fois même avec exactement les mêmes tokens en entrée, il devient difficile de partager et reproduire les résultats avec des collègues, ou de tester des cas où le LLM produit des sorties très rares et imprévisibles (par ex. en red teaming)

    • Je travaille sur un projet qui insère des informations par stéganographie dans la sortie d’un LLM : innocuous. J’utilise seulement les dix premiers tokens environ du modèle, et comme je teste surtout sur des modèles 8B sur CPU, je m’inquiète peu d’un changement d’ordre des tokens dû au matériel, mais je pense quand même ajouter à terme des conditions de garde pour éviter qu’une légère perte de précision ne modifie le choix

    • Cela peut être très utile pour les clients de plateformes IA. On peut exécuter plusieurs fois la même invite avec temperature 0 et vérifier si le résultat est toujours identique, afin de détecter si un fournisseur IA remplace discrètement un modèle PRO par un autre modèle moins cher

    • C’est indispensable pour reproduire un « bug ». Si l’on peut reproduire à chaque fois exactement la même sortie erronée ou étrange avec la même chaîne d’entrée, le débogage devient bien plus simple. Si le résultat ne diffère qu’une fois sur cent, c’est beaucoup plus difficile

  • (Expérience de travail avec JAX/XLA) C’est quelque chose d’assez connu. J’ai moi aussi rencontré plusieurs fois ce phénomène (variabilité au niveau du batch), et on me l’a expliqué dans les issues suivantes : penzai issue #82, commentaire sur une issue jax

    • Je pense que ce devrait être le commentaire le mieux classé
  • Parfois, la cause de la non-déterminisme vient des détails d’implémentation. Par exemple, dans le code source de GPT-2, même si l’on fixe temperature à 0 dans l’interface, une valeur "epsilon" (très petite, mais non nulle) est en réalité utilisée. C’est compréhensible, car cela évite une erreur de division par zéro. Le non-déterminisme est « inutile » dans beaucoup d’applications. C’est aussi un vieux problème dans les modèles de topics LDA. En particulier dans les domaines juridique, financier ou réglementé, il peut même être illégal d’utiliser des méthodes non déterministes. Ou alors cela peut créer des obligations supplémentaires indésirables (comme devoir conserver tous les enregistrements d’écran afin de pouvoir reconstituer plus tard, point par point, ce qui s’est passé)

  • Il est question de « travailler avec d’autres chez Thinking Machines ». Cela me rappelle l’époque où l’on voyait directement la machine aux cubes LED rouges briller devant le MIT AI Lab. Richard Feynman a fait un travail vraiment remarquable, et il existe aussi ce texte : Feynman and the Connection Machine. Aux États-Unis, la marque « THINKING MACHINES » n’était pas déposée par Hillis, mais par la société qu’il avait fondée, et elle a été radiée en 1998–1999. L’entreprise a fait faillite en 1994, et ses actifs ont été repris notamment par Sun Microsystems (puis Oracle). Thinking Machines Lab Inc., fondée par Amira Murati, a lancé en 2025 une nouvelle demande de dépôt de la marque « THINKING MACHINES »

    • Chaque fois que je vois le nom de cette société, je fais cette confusion
  • Je suis vraiment content de voir récemment des discussions de recherche au format billet de blog de si bonne qualité. Anthropic porte cette culture, et j’espère beaucoup de sa diffusion croissante. À l’époque de la recherche en RL, OpenAI fonctionnait aussi de cette manière

  • Le langage naturel est intrinsèquement ambigu. Il doit l’être. Je pense que cette tentative de « transformer un cercle en carré puis d’expliquer pourquoi il devrait l’être » est une mauvaise approche. Ce type de discussion finira par évoluer vers une meilleure acceptation de la nature du langage et du hasard, et vers une interprétation du langage qui dépasse des sous-motifs mini-grammaticaux comme la matrice de projection QKV

    • C’est vrai. Cela dit, le déterminisme n’est pas l’ambiguïté. Le déterminisme signifie « pour exactement cette entrée, il faut garantir exactement cette sortie ». Si je pose la même question au même modèle, je m’attends à obtenir exactement la même réponse à chaque fois. Bien sûr, si je reformule légèrement la phrase, je comprends tout à fait que la réponse puisse être un peu différente
  • Je n’aime toujours pas le nom de l’entreprise. Je me demande pourquoi ce genre de dénomination se répète. Peut-être est-ce l’idée que la nature d’une organisation légendaire puisse déteindre sur une jeune startup. Mais j’ai du mal à croire que baptiser la prochaine startup PARC transmette automatiquement une quelconque innovation en réseau

    • Vous parlez bien de l’entreprise « Thinking Machines » disparue en 1994 ? J’ai dû faire quelques recherches pour le savoir, et elle n’est pas aussi connue qu’on pourrait le penser, donc je ne crois pas que ce soit l’intention. Je trouve simplement que c’est un nom cool et intuitif

    • Il suffit de choisir un nom pour bénéficier gratuitement du marketing qui va avec ; c’est d’ailleurs la raison d’être du système des marques

  • Sujet vraiment intéressant. Pour ceux qui ne le savent pas, cette entreprise a été lancée par Mira Murati, ancienne CTO d’OpenAI