Exécution d'un LLM de 28,9 millions de paramètres sur un microcontrôleur ESP32-S3 à 8 $
Découvrez comment les plongements par couche des modèles Gemma de Google permettent à un modèle de langage de 28,9 millions de paramètres de fonctionner entièrement sur une puce ESP32-S3 à 8 $, générant du texte à 9,5 tokens par seconde.
Le problème : les LLM ne tiennent pas sur les microcontrôleurs
Les microcontrôleurs disposent de très peu de mémoire rapide. L'ESP32-S3, une puce populaire coûtant environ 8 $, ne vous offre que 512 Ko de SRAM. Normalement, l'intégralité du modèle doit être chargée dans cette mémoire rapide pour effectuer l'inférence, ce qui limite sévèrement la taille du modèle. L'état de l'art précédent sur une puce similaire n'était que de 260 000 paramètres.
La percée : les plongements par couche
L'idée clé provient des modèles Gemma 3n et Gemma 4 de Google : les plongements par couche (PLE). La plupart des paramètres d'un modèle de langage se trouvent dans la table de plongements — une grande table de correspondance qui associe les tokens à des vecteurs. Le modèle lit dans cette table mais n'effectue pas de calculs dessus. Vous pouvez donc laisser cette table de 25 millions de lignes dans la mémoire flash lente et ne récupérer que les quelques lignes (environ 450 octets) nécessaires à chaque token. La petite partie qui effectue le calcul réel reste dans la SRAM rapide.
Cela signifie que le grand modèle ne coûte presque rien à exécuter — vous ne chargez jamais la majeure partie. Il reste simplement dans la flash et est échantillonné petit à petit.
Les chiffres
| Métrique | Valeur |
|---|---|
| Paramètres | 28,9M stockés (25M dans la table de correspondance flash) |
| Puce | ESP32-S3 (~8 $) avec 512 Ko SRAM, 8 Mo PSRAM, 16 Mo flash |
| Vitesse | ~9,5 tok/s de bout en bout (9,7 tok/s en pur calcul) |
| Connectivité | Aucune — tout s'exécute sur l'appareil |
| Taille du modèle | 14,9 Mo en 4 bits |
Disposition de la mémoire
L'astuce fonctionne grâce à une hiérarchie mémoire soigneusement conçue :
- SRAM (rapide, minuscule) : Le noyau "pensant" — utilisé à chaque token
- PSRAM (moyenne) : La tête de sortie et la mémoire de travail
- FLASH (énorme, lente) : La table de 25M de paramètres — environ 6 lignes lues par token (~450 octets)
Ce qu'il fait (et ne fait pas)
Le modèle a été entraîné sur TinyStories (Ronen Eldan et Yuanzhi Li, Microsoft Research), donc il écrit des histoires courtes et simples et les maintient généralement cohérentes. Il ne répondra pas aux questions, ne suivra pas d'instructions, n'écrira pas de code ni ne connaîtra de faits. Cette limitation provient de la petite partie de raisonnement du modèle — l'astuce mémoire ne change pas ce qu'un modèle de 28,9 millions de paramètres peut dire.
L'exécuter vous-même
Le firmware complet, les schémas de câblage et les étapes de flash sont dans firmware/esp32_llm/README.md. Le code d'entraînement, d'ablation et de quantification se trouve dans src/ et experiments/. La méthode complète, les ablations et les mesures sur puce sont documentées dans RESULTS.md.
Crédits
- TinyStories : Le jeu de données — des histoires synthétiques courtes suffisamment simples pour que les petits modèles apprennent une écriture cohérente (arXiv:2305.07759)
- Plongements par couche : La conception de Google issue des modèles Gemma, permettant de grands modèles sur de petites puces
- llama2.c : Le travail d'Andrej Karpathy qui a inspiré l'idée que l'on peut entraîner un minuscule modèle de langage et l'exécuter en C pur
L'historique désordonné
Le dépôt préserve intentionnellement l'historique désordonné, y compris un bug dans la comptabilité des paramètres qui a gonflé les premiers chiffres, et le résultat corrigé. L'historique des commits et RESULTS.md montrent où les chiffres ont bougé et pourquoi.
Ce projet démontre qu'avec la bonne architecture, même un microcontrôleur à 8 $ peut exécuter un modèle de langage étonnamment capable — ouvrant des possibilités pour des applications IA véritablement en périphérie.