Exécution d'un LLM de 2,78 billions de paramètres sur un seul CPU avec 8 Go de RAM

Découvrez comment un modèle Kimi K3 de 2,78 billions de paramètres fonctionne sur un seul CPU avec seulement 8,24 Go de RAM, en utilisant du C99 portable et un streaming mémoire astucieux.

Le monde de l'IA est obsédé par l'échelle, mais que diriez-vous de pouvoir exécuter un modèle de 2,78 billions de paramètres sur une machine que vous possédez déjà ? C'est exactement ce que le projet kimi-k3-in-c réalise : un modèle Kimi K3 de 2,78T paramètres fonctionnant en inférence sur un seul CPU, en utilisant seulement 8,24 Go de RAM, sans GPU, sans BLAS et sans framework. Tout le moteur est un binaire C99 de 176 Ko qui diffuse le modèle depuis le disque, rendant possible l'exécution d'une IA de pointe sur du matériel qui n'a rien de pointe.

Ce n'est pas un jouet ou une approximation fortement quantifiée. La sortie est identique octet par octet, que vous l'exécutiez sur un ordinateur portable avec 8 Go de RAM ou sur une station de travail avec 224 Go. La seule différence est la vitesse : 32,69 secondes par jeton dans le cas le plus lent, 19,21 secondes par jeton dans le plus rapide. Le projet atteint cela grâce à une combinaison d'ingénierie intelligente, d'une compréhension approfondie de l'architecture du modèle et d'une volonté de remettre en question les hypothèses conventionnelles sur ce qui est nécessaire pour l'inférence de LLM.

Le problème : un modèle qui ne tient pas en mémoire

Kimi K3 est un modèle de mélange d'experts (MoE) avec 2,78 billions de paramètres, fourni sous forme de point de contrôle de 1,56 To. Aucune machine grand public ne peut contenir cela en mémoire. L'approche naïve — tout charger en RAM — nécessiterait 5,56 To en précision bfloat16. Ce n'est pas seulement peu pratique ; c'est impossible pour quiconque sans centre de données.

L'idée clé est que les modèles MoE n'ont pas besoin que tous leurs paramètres soient actifs en même temps. Pour un jeton donné, seuls 16 des 896 experts par couche se déclenchent. Cela représente environ 104 milliards de paramètres actifs sur 2,78 billions — seulement 3,7 %. Le reste peut rester sur le disque, tant qu'il est accessible en cas de besoin.

Les quatre réductions

Le projet atteint son empreinte mémoire grâce à quatre réductions clés :

  1. Experts MXFP4 : Les experts routés sont fournis dans un format à virgule flottante 4 bits, ne prenant que 0,53125 octet par poids au lieu de 2 octets pour bfloat16. Cela réduit à lui seul les poids des experts de 5,45 To à 1,447 To.
  2. Attention KDA : L'attention Delta de Kimi utilise un état récurrent de taille fixe qui ne croît pas avec la longueur du contexte. Cela signifie que 69 des 93 couches ont une empreinte mémoire constante, quelle que soit la quantité de texte que vous leur fournissez.
  3. Attention MLA : L'attention latente multi-têtes met en cache un seul latent de 576 dimensions par position au lieu de 96 têtes de clé/valeur séparées, réduisant le cache KV de 53 fois.
  4. Streaming du tronc : Les couches denses (le « tronc ») sont diffusées depuis le disque couche par couche, en utilisant un préfixe épinglé et un seul tampon en anneau. Cela transforme l'exigence de mémoire d'un plancher fixe en un cadran que vous pouvez ajuster.

Comment cela fonctionne : l'architecture

Le moteur est écrit en C99 portable, sans dépendances externes autres que libm et OpenMP. La base de code est remarquablement petite : six fichiers C compilés en un seul binaire de 176 Ko. Cela est possible car le projet évite tout frais général de framework et implémente chaque noyau à partir de zéro.

Lecture du point de contrôle

Le point de contrôle de 1,56 To se compose de 96 fichiers safetensors. Le moteur lit les en-têtes JSON pour construire un index de tous les 497 220 tenseurs, puis ne lit que les octets nécessaires à la demande. Cela se fait avec des lectures O_DIRECT, contournant entièrement le cache de pages, ce que le projet a trouvé plus rapide que les lectures tamponnées sur leur matériel de test.

Le cache d'experts

Les experts routés sont chargés dans un cache LRU avec une taille configurable. Cependant, le projet a découvert un résultat surprenant : le cache d'experts est presque inutile à petite taille. En raison de l'entraînement d'équilibrage quantile du modèle, l'utilisation des experts est aplatie sur l'ensemble du pool, donc il n'y a pas de sous-ensemble chaud que le cache puisse exploiter. Le cache ne commence à aider qu'au-dessus d'environ 36 Go d'arène.

Le streaming du tronc

Le tronc dense (108,81 Go) est lu couche par couche. Le moteur épingle autant de couches que le budget le permet et diffuse le reste à travers un seul tampon en anneau. Comme le moteur parcourt les couches dans un ordre fixe, un préfixe épinglé atteint un taux de succès déterministe de N/93, ce qui est bien meilleur qu'un cache LRU ne le ferait sur un balayage cyclique.

Validation : prouver que c'est correct

Le projet ne prétend pas seulement fonctionner ; il le prouve grâce à une échelle de validation rigoureuse :

  • Tests sans poids : Un modèle oracle de 13 couches avec le même graphe de tenseurs que le modèle réel, vérifié par rapport à une référence PyTorch. Les trois chemins d'exécution (forçage par l'enseignant, décodage glouton, décodage incrémental) produisent des identifiants de jetons identiques.
  • Conformité des couches : Les 93 couches du modèle complet sont vérifiées par rapport à une référence PyTorch, avec une erreur maximale de 0,00x le budget d'arrondi.
  • Parité des logits : Les logits du moteur C correspondent à la référence torch élément par élément sur la sortie complète de 163 840 vocabulaire, avec une différence maximale de 7,87e-6.
  • Échelle de mémoire : Douze budgets mémoire différents, de 8 Go à 224 Go, produisent tous des identifiants de jetons identiques octet par octet.

Performances : à quoi s'attendre

Sur un seul CPU (AMD EPYC 7763, 124 cœurs), le moteur atteint :

  • 8 Go de RAM : 32,69 s/jeton
  • 32 Go de RAM : 31,44 s/jeton
  • 64 Go de RAM : 28,60 s/jeton
  • 128 Go de RAM : 29,40 s/jeton (notez le bruit)
  • 224 Go de RAM : 19,21 s/jeton

Les performances sont fortement liées aux E/S. Entre 41 % et 61 % du temps réel est passé à attendre le disque. Cela signifie que le périphérique de stockage compte plus que le CPU. Un disque NVMe rapide est essentiel pour de bonnes performances.

Pour commencer

Pour exécuter cela vous-même, vous aurez besoin de :

  • Linux x86-64 avec AVX2 et FMA
  • Au moins 8 Go de RAM
  • Environ 1,7 To d'espace disque libre
  • GCC ≥ 9 ou Clang ≥ 10
  • Python 3.9+ (pour les outils de téléchargement et d'empaquetage)

Clonez le dépôt, compilez avec make -j, et exécutez make test pour vérifier que le moteur fonctionne avant de télécharger le point de contrôle de 1,56 To. Ensuite, téléchargez le modèle, empaquetez le tronc, et exécutez :

./bin/k3 ~/k3model --trunk ~/k3trunk --preset laptop \
  --tok ~/k3model --prompt "La capitale de la France est" --gen 8 --incremental

Conclusion

Le projet kimi-k3-in-c est une leçon magistrale d'ingénierie système. Il démontre qu'avec la bonne approche, même les plus grands modèles d'IA peuvent être rendus accessibles au matériel ordinaire. Les points clés à retenir :

  • La mémoire est un cadran, pas un plancher : En diffusant le tronc, vous pouvez échanger la vitesse contre l'utilisation de la mémoire.
  • Comprenez votre modèle : Les choix d'architecture (KDA, MLA, MXFP4) sont exploités au maximum.
  • Mesurez tout : La méthodologie de validation et de mesure rigoureuse du projet garantit que chaque affirmation est étayée par des données.

Ce n'est pas seulement une curiosité technique ; c'est un plan pour rendre l'IA plus accessible. Si vous avez déjà voulu exécuter un modèle de mille milliards de paramètres sur votre propre machine, ce projet montre que c'est possible — et c'est open source.

Source

FareedKhan-dev/kimi-k3-in-c : Un Kimi K3 de 2,78 billions de paramètres exécutant l'inférence sur un seul CPU avec 8,24 Go de RAM. C99 portable : pas de BLAS, pas de framework, pas de GPU.