LLM avec 29M paramètres sur microcontrôleur ESP32 : l'inférence locale sans Wi-Fi
Un chercheur a fait tourner un modèle linguistique de 28,9 millions de paramètres sur un ESP32-S3, le microcontrôleur qui coûte environ 8 dollars. Il génère du texte à environ 9,5 tokens par seconde, entièrement sur la puce, sans connexion à aucun serveur.
Le record précédent sur une puce de cette catégorie était 260 mille paramètres. Le bond, cent fois plus grand, vient d’une idée empruntée aux modèles Gemma de Google : la majorité des paramètres d’un LLM réside dans une table d’embedding que le modèle consulte, sans l’évaluer. Si tu la laisses dans la mémoire flash lente de la puce et que tu charges uniquement les quelques lignes nécessaires pour chaque token (environ 450 bytes), le modèle « volumineux » ne coûte presque rien en RAM.
Comme nous l’avons raconté le 20 juillet avec les LLM à 1 bit dans le navigateur, l’inférence locale descend progressivement la chaîne des appareils. Du Mac au navigateur, maintenant au microcontrôleur de 8 dollars sans Wi-Fi.
Pour ceux qui construisent sur matériel contraint ou font du bricolage hors ligne, le signal est clair : le seuil d’un agent fonctionnant sur l’appareil lui-même est en baisse. Ce modèle spécifique sait uniquement écrire de courtes histoires (entraîné sur TinyStories), il ne répond pas à des questions ni ne suit d’instructions. Mais l’architecture, l’astuce mémoire qui permet à un modèle cent fois plus volumineux de tenir sur une puce sans extension, c’est ce qui compte.
En détail
Le problème classique de l’inférence sur microcontrôleur est la RAM. L’ESP32-S3 dispose de 512KB de SRAM, la mémoire rapide où la puce fait ses calculs. Un modèle linguistique, même petit, doit normalement tenir entièrement dans cette mémoire pour être exécuté. 512KB suffisent pour environ 260 mille paramètres, et c’est là où s’était arrêté le record précédent sur ce type de matériel.
L’astuce provient des modèles Gemma 3n et Gemma 4 de Google, appelée Per-Layer Embeddings. Dans un LLM, la majorité des paramètres (dans ce cas 25 millions sur 28,9 au total) forme une table d’embedding : le vocabulaire que le modèle consulte pour transformer les mots en nombres et vice-versa. Le modèle lit cette table, mais ne l’utilise pas pour des calculs lourds. Tu peux donc la laisser dans la mémoire flash de la puce, lente mais spacieuse (16MB), et charger en SRAM uniquement les quelques lignes nécessaires pour le token actuel : environ 450 bytes par étape, six lignes de la table.
La partie qui fait le vrai traitement, le noyau de 3,9 millions de paramètres, reste en SRAM. La table de 25 millions vit en flash et est échantillonnée petit morceau par petit morceau. Le résultat est un modèle de 14,9MB à 4 bits qui génère du texte à 9,5 tokens par seconde, end-to-end, sur une puce qui consomme une fraction de watt.
Le modèle est entraîné sur TinyStories, un ensemble de données de courtes histoires simples conçu pour les minuscules modèles. Il écrit des phrases cohérentes du type « le chien court dans le parc », mais ne répond pas à des questions, ne suit pas d’instructions, ne connaît pas de faits. La limite ne vient pas de la mémoire, elle vient de la partie du modèle qui fait le raisonnement, et l’astuce mémoire ne la change pas. Le projet est honnête à ce sujet : l’intérêt porte sur l’architecture, pas sur ce que le modèle sait dire.
Qu’est-ce qui change pour le lecteur ? Jusqu’à hier, « inférence locale » signifiait un laptop, ou un navigateur avec WebGPU. Maintenant le seuil descend à une puce de 8 dollars avec 512KB de RAM et aucune connexion réseau. Pour ceux qui conçoivent des appareils embarqués, des capteurs avec un peu de logique, des interfaces vocales pour prototypes hors ligne, l’architecture démontre qu’un modèle linguistique peut tenir à l’intérieur de l’appareil lui-même. Pas de cloud, pas de latence réseau, pas de clé API.
Reste ouverte la question de la réplicabilité sur des tâches utiles. Le repo inclut le firmware, le câblage et les instructions de flashing, plus le code d’entraînement et de quantification en Python. Mais le passage de « écrit des histoires » à « suit des instructions » nécessite un modèle plus capable. Et un modèle plus capable nécessite plus de paramètres actifs en SRAM, ce qui ramène au goulot d’étranglement original. L’astuce de la mémoire élargit la table d’embedding, pas le cerveau.