Produit
Des choses qui ont coûté une journée à comprendre
Comptes rendus de défauts qui ne se sont pas annoncés : un chargeur qui plante au lieu d'échouer, une valeur par défaut inversée entre deux fichiers, et une frontière où un type erroné compile très bien des deux côtés.
Mis à jour 2026-09-12
Construire un moteur d'inférence, c'est lire beaucoup de code qui fonctionne et découvrir pourquoi il fonctionne. De temps en temps, on le découvre à la dure. Les comptes rendus qui suivent sont de cette seconde espèce.
Ils ont un point commun, et c'est aussi ce qui justifie de les écrire : aucun d'eux n'a produit de message d'erreur. Un défaut qui plante est corrigé en une heure. Un défaut qui renvoie une sortie plausible part en production et se fait trouver des semaines plus tard par quelqu'un qui avait simplement supposé que le modèle était médiocre.
Les notes ci-dessous parlent de MLX, des fichiers de configuration que les modèles publient, et de la frontière entre deux langages. Aucune n'est propre à Runlix : si vous écrivez quoi que ce soit qui charge des poids MLX, ou qui appelle du Rust depuis C#, vous les rencontrerez.
Pourquoi celles-ci et pas les autres
Les notes internes du moteur comptent quelques dizaines d'entrées, et elles n'ont pas toutes leur place sur une page publique. Deux règles tranchent.
Publié : ce qui appartient à la bibliothèque de quelqu'un d'autre. Comment MLX se comporte,
ce que mlx-lm présuppose, ce que le config.json d'un modèle peut contenir. Ce savoir n'est
pas à nous : c'est le prix d'avoir lu attentivement la bibliothèque d'un autre, et quelqu'un est
en train de le chercher en ce moment même parce qu'il bute sur le même mur.
Gardé : ce qui est à nous. La conception du cache paginé, la manière dont l'échantillonnage matérialise ses candidats, la décision de découper avant la projection finale. Ces choses-là ont demandé des mesures, et elles sont l'avantage du moteur, pas un fait général sur MLX.
Cette ligne n'est pas du secret pour le plaisir du secret. C'est que la première catégorie est un savoir dont les utilisateurs d'autrui ont besoin, et que la seconde est du travail.
À qui elles s'adressent
À trois sortes de lecteurs, et le premier paragraphe de chaque note vous dit laquelle vous êtes.
Si vous portez une architecture de modèle — depuis mlx-lm, ou depuis n'importe quelle
implémentation de référence vers n'importe quel langage — deux de ces notes décrivent exactement
les pièges que vous allez rencontrer, et la troisième parle de la frontière que vous construirez
pour appeler votre travail depuis une application.
Si vous utilisez MLX depuis C ou Rust plutôt que depuis Python, la note sur le chargeur vous épargnera une journée, et celle sur la frontière C décrit une classe de défauts qui empire tant que personne ne la cherche délibérément.
Si vous ne faites ni l'un ni l'autre, l'une d'elles vaut quand même la lecture : l'idée qu'un défaut renvoyant une valeur plausible coûte plus cher qu'un défaut qui plante n'a rien de propre aux moteurs d'inférence, et ce qui en découle non plus.
Ce qu'elles ne sont pas
Ce ne sont pas des tutoriels. Il n'y a ici aucun matériel pour débuter, et aucune n'explique ce qu'est un transformeur ni comment installer quoi que ce soit — ce matériel existe, il est bien écrit ailleurs, et le répéter n'ajouterait que des pages dont personne n'a besoin.
Ce ne sont pas non plus des notes de version. Rien ici n'annonce une fonctionnalité. Chacune est un défaut dont la recherche a duré assez longtemps pour que l'écrire paraisse moins cher que de laisser la personne suivante y perdre la même journée.
À quel rythme elles paraissent
Lentement, et c'est délibéré plutôt qu'une pénurie de matière.
Une note est mise en ligne quand le défaut est compris assez bien pour tenir en une phrase, et pas un jour avant. La moitié de la valeur de l'exercice tient dans cette contrainte : si le compte rendu a besoin de trois paragraphes de précautions pour décrire ce qui a mal tourné, l'enquête n'était pas finie, et la bonne réponse est d'aller la terminer plutôt que de publier les précautions.
Il n'y a donc pas de calendrier. Pour savoir quand l'une paraît, l'abonnement a une catégorie qui sert exactement à cela et à rien d'autre.
Comment tout cela est vérifié
Derrière chaque affirmation de ces notes, il y a un nombre ou une reproduction, et là où un nombre apparaît, il porte la date à laquelle il a été mesuré.
C'est une habitude que ce projet a apprise cher. Trois chiffres écrits à la main dans un document interne se sont révélés, une fois remesurés, être 33 au lieu de 32, 26 au lieu de 24, et 1294 au lieu de 605 — le dernier faux de plus du double. Un nombre dans un texte suivi n'a personne pour l'entretenir. Les nombres d'ici portent donc leur date, et si l'un d'eux a dérivé, c'est cette date qui vous prévient.
La frontière où les deux côtés compilent et où l'un des deux ment
À travers une ABI C, une fonction mal orthographiée n'est pas une erreur de compilation et une fonction mal typée n'est même pas visible par nm. Une déclaration 32 bits sur une valeur 64 bits a transformé 23347 Mo en 2,8 Go — plausible, et faux d'un facteur huit.
Mesuré 2026-09-11Le chargeur qui plante au lieu d'échouer
Charger des poids MLX sur le flux GPU ne lève aucune erreur. Cela renvoie un code non nul que vous n'avez probablement pas vérifié, puis la lecture des données tue le processus. Voici pourquoi, et quoi faire.
Mesuré 2026-09-06Une valeur par défaut inversée entre deux fichiers
Quand la configuration d'un modèle ne mentionne pas tie_word_embeddings, phi3 suppose false et llama suppose true. Copiez l'une ou l'autre et vous obtenez un modèle juste sur une famille et discrètement faux sur l'autre.
Mesuré 2026-09-06