- TurboFieldfare exécute Gemma 4 26B-A4B avec environ 2 Go de mémoire, sans charger l’ensemble du modèle de 14,3 Go en mémoire, ce qui permet l’inférence locale même sur les Mac Apple Silicon dotés de 8 Go de RAM
- Il ne garde en résidence qu’un cœur partagé de 1,35 Go et le cache KV en FP16, puis streame depuis le SSD, à chaque token, les poids des experts MoE nécessaires ; un cache LFU à 16 emplacements et des
preadparallèles limitent les E/S - Gemma 4 26B-A4B active environ 3,88B de paramètres par token ; la vitesse de décodage mesurée est de 5,1 à 6,3 tok/s sur un MacBook Air M2 8 Go, et de 31 à 35 tok/s sur un M5 Pro 24 Go
- Il s’agit d’un runtime dédié, implémenté en Swift 6.2 et Metal 4, qui fournit une app Mac native, une CLI, un outil d’installation et un serveur expérimental compatible OpenAI sur un même répertoire de modèle
.gturbo - Le périmètre actuel se limite à l’inférence texte uniquement sur les Mac Apple Silicon sous macOS 26 ou ultérieur avec au moins 8 Go de RAM ; les images, l’audio, la vidéo, ainsi que l’authentification serveur distante et TLS ne sont pas pris en charge
Une architecture d’exécution qui réduit la mémoire
- TurboFieldfare ne charge pas entièrement en mémoire le modèle instruction-tuned Gemma 4 26B-A4B
- Le cœur partagé de 1,35 Go et le cache KV en FP16 restent en mémoire
- Seuls les routed experts nécessaires à chaque token sont lus depuis le SSD vers des buffers visibles par Metal
- Le modèle texte seul installé fait environ 14,3 Go, mais les poids et le cache KV 4K utilisent environ 2 Go de mémoire
- Le modèle active environ 3,88B de paramètres par token sur un total de 26B paramètres
- Les poids utilisent une quantification MLX affine 4 bits par groupes de 64 ; le router est en 8 bits, les experts partagés et routés en 4 bits
- Ce n’est pas une configuration qui encapsule MLX ou llama.cpp, mais un runtime dédié Swift·Metal conçu pour Gemma 4 26B-A4B
Processus de génération de tokens
- Dans chaque couche Transformer, Metal calcule l’attention et le router avec les poids résidents
- Le CPU compare les 8 meilleurs ID d’experts choisis par le router avec un cache LFU de 16 emplacements par couche
- Les cache misses sont comblés par un nombre limité d’appels
preadparallèles - Pendant les lectures SSD, Metal calcule la branche shared-expert résidente
- Une fois la lecture terminée, la sortie shared et la sortie routed sont combinées
- Les cache misses sont comblés par un nombre limité d’appels
- Le prefill du prompt utilise des chunks allant jusqu’à 128 tokens afin qu’un expert déjà chargé puisse traiter plusieurs lignes
- Lors de la phase de génération, la boucle des routed layers est répétée token par token
- Le cache KV utilise un stockage circulaire limité pour 25 couches à sliding window, et un stockage linéaire pour 5 couches en full attention
- L’attention de décodage repose sur une méthode exact split-K/V qui sépare les chemins K et V normalisés
Installation et format du modèle
- Au premier lancement, sélectionner Download télécharge environ 15 Go depuis une révision Hugging Face fixe via des requêtes par plages
- L’installateur ne crée pas l’intégralité du checkpoint original dans un fichier temporaire ni en mémoire
- Il récupère les plages d’octets nécessaires et les reconditionne directement au format
.gturbo - Comme il ne prépare pas séparément l’ensemble des shards ou tensors, l’usage de mémoire temporaire reste limité
- L’installation finalisée doit passer la validation du manifeste et des hash de fichiers avant de pouvoir être utilisée
- Il récupère les plages d’octets nécessaires et les reconditionne directement au format
- Une fois l’installation terminée, le modèle occupe environ 14,3 Go de stockage, et le processus d’installation lui-même ne charge pas le modèle en mémoire
- Le runtime n’accepte qu’un répertoire
.gturbocomplet contenant lemanifest.jsonfinal - Il prend en charge la reprise des téléchargements interrompus, la suppression des états de téléchargement partiels et la vérification d’installation sans charger le modèle
Environnement d’exécution et performances
- L’environnement requis est un Mac Apple Silicon, macOS 26, Metal 4, Xcode 26 et Swift 6.2 ou ultérieur
- Le package est réservé à arm64 ; les anciennes versions de macOS et de Metal ne sont pas prises en charge
- La cible de validation est le MacBook Air M2 8 Go, avec suffisamment d’espace de stockage libre pour installer le modèle et une connexion Internet pour le téléchargement initial
- Les performances de décodage mesurées sont les suivantes
- MacBook Air M2 8 Go : 5,1 à 6,3 tok/s
- M5 Pro 24 Go : 31 à 35 tok/s
- Le débit varie selon la longueur du prompt, la longueur de génération, l’état du cache de pages et le matériel ; ces mesures constituent donc des points de référence, pas des plafonds de performance
- Avant d’exécuter le modèle, il faut fermer les apps très consommatrices de mémoire et vérifier la mémoire disponible avec
memory_pressure -Q - L’app, le decode service, la CLI, le serveur, les tests ou d’autres processus de modèles locaux ne doivent être exécutés qu’un à la fois
Produits fournis et modes d’utilisation
- Le package Swift fournit six produits
TurboFieldfare: bibliothèque Swift incluant le runtime et les kernels MetalTurboFieldfareMac: app Mac native pour l’installation et la générationTurboFieldfareDecodeService: processus local jetable, propriétaire du modèle et de Metal, utilisé par l’app MacTurboFieldfareCLI: chat instruction en ligne de commande et raw completionTurboFieldfareServer: serveur Chat Completions compatible OpenAI sur loopbackTurboFieldfareRepack: outil d’installation en streaming et de vérification d’installation
- Dans l’app Mac, après avoir téléchargé le modèle, sélectionner Load Model, puis saisir un prompt pour générer du texte
- La barre d’état permet de suivre la progression, la vitesse de décodage et l’usage mémoire
- Il est possible d’ajuster le sampling, la longueur de contexte, les emplacements du cache d’experts et les options du runtime
- Le chat instruction de la CLI accepte un tableau de messages JSON et le convertit au même format que l’app Mac
- La valeur par défaut de la limite de réponse
--max-newest de 1 024 tokens - L’app Mac peut générer jusqu’à remplir la fenêtre de contexte choisie
- La valeur par défaut de la limite de réponse
--promptsert à la raw completion, sans appliquer de format de chat, et aux comparaisons reproductibles- Le texte généré est envoyé sur la sortie standard, les statistiques temporelles sur l’erreur standard, et
--quietpermet de désactiver la sortie des statistiques
Prompts et périmètre pris en charge
- L’app Mac traite l’entrée comme une instruction et applique automatiquement le format de chat de Gemma
- Les réglages de sampling par défaut sont temperature
0.2, Top-K64et Top-P0.95- Régler temperature sur
0utilise une sortie greedy déterministe - Le modèle peut se répéter ou répondre de façon incorrecte ; les résultats importants doivent donc être vérifiés
- Régler temperature sur
- L’app et la CLI prennent en charge les messages utilisateur·modèle et une system guidance optionnelle, mais n’exposent ni n’exécutent d’outils
- Les entrées et sorties du modèle sont actuellement limitées au texte ; les images, l’audio et la vidéo ne sont pas pris en charge
- La CLI propose
--max-context,--temperature,--top-k,--top-p,--repetition-penalty,--seedet des chaînes--stoprépétables
Serveur local compatible OpenAI
- Le serveur expérimental s’exécute sur
127.0.0.1:8080/v1et prend en charge Chat Completions, le streaming, les déclarations d’outils de fonction et la réutilisation d’un prompt à préfixe unique - Le serveur renvoie les tool calls produits par le modèle, mais l’approbation et l’exécution de tous les appels d’outils relèvent du client
- Comme il n’y a ni authentification distante ni TLS, le serveur doit rester limité au loopback
- L’app Mac, la CLI et le serveur utilisent le même répertoire
.gturbo, mais un seul produit propriétaire du modèle doit être exécuté à la fois
Périmètre d’implémentation et journal d’expérimentation
- Les kernels Metal personnalisés gèrent le GEMV quantifié, l’attention, le MoE, la normalisation, RoPE, le sampling et les fusions de production
- Le runtime implémente le streaming des routed experts depuis le SSD, un cache d’experts limité, le prefill d’un prompt unique par chunks et la génération token par token
- 103 résultats de mesure couvrant les kernels, le caching, les E/S, le prefill et le décodage sont conservés dans le journal d’expérimentation
- La documentation d’expérimentation inclut les optimisations qui ont eu un fort impact, les idées qui ont échoué et les résultats initiaux infirmés après une validation plus poussée
- Les travaux à venir portent sur le développement d’apps iPhone·iPad, les mesures de vitesse et de mémoire pour l’inférence mobile, ainsi que les benchmarks sur Mac mini M4 16 Go et d’autres Mac Apple Silicon 8 Go
Licence et conditions du modèle
- Le code source et la documentation sont distribués sous Apache License 2.0
- Les poids du modèle ne sont pas inclus dans le dépôt ; l’installateur les télécharge séparément depuis un checkpoint Hugging Face fixe
- Les conditions de distribution d’origine continuent de s’appliquer aux poids
- TurboFieldfare est un projet de recherche indépendant, non affilié à Google et non sponsorisé ni approuvé par Google
1 commentaires
Avis sur Hacker News
Je me suis toujours demandé pourquoi on devait à chaque fois charger tout le modèle en mémoire, comme s’il fallait même savoir qui est le roi Charles. À mon avis, les techniques pour découper de gros fichiers et les lire efficacement avec peu de mémoire existent déjà.
Dans l’IA de pointe, on a l’impression qu’on excelle à fabriquer des modèles, mais qu’on laisse les problèmes de passage à l’échelle et de praticité aux équipes infra. Si moins de 10 % des connaissances sont réellement utilisées, un simple fine-tuning et de l’optimisation pourraient sans doute faire baisser fortement les coûts
Les LLM denses offrent généralement de meilleures performances, mais si on externalise les couches vers du stockage externe, ils deviennent bien plus lents que les MoE
De nos jours, quand on télécharge un projet d’origine inconnue, il faut lancer soi-même ce type d’audit de sécurité. En demandant d’ignorer les instructions d’agent du dépôt et les fichiers Markdown, puis d’inspecter le code Swift/Metal, les scripts de build, la config CI et les dépendances, le résultat a été qu’aucun malware, backdoor, vol d’identifiants ou endpoint réseau caché n’a été trouvé, mais que des risques de compilation, de supply chain et d’exécution subsistent.
Si quelqu’un a un meilleur prompt, je veux bien le voir, et le coût de l’exécution avec Cursor Composer 2.5 était inférieur à 0,20 dollar
Sur un MacBook Air M1 sous macOS 15, ça compile si on supprime les deux lignes suivantes ou si on les entoure avec
if #available(macOS 26.0, *):opts.languageVersion = .version4_0D’après les commentaires, on perd l’effet qui rend l’attention 11,24 fois plus rapide et accélère le préremplissage de 2,4 fois, mais on obtient quand même 5 à 6 tokens par seconde sur un Air M1 à GPU 8 cœurs
L’amélioration de préremplissage x2,4 ne fonctionne que sur la famille de GPU apple10, et de mémoire le M1 est en apple7
Je me demande comment ce projet se compare à un
mmapclassique. Dans llama.cpp aussi, on peut exécuter le modèle 26B avec 2 Go de RAM si on activemmapet qu’on désactive le repacking.La différence clé semble être que les lectures SSD sont synchronisées avec l’inférence pour minimiser la latence, alors que le système d’exploitation n’a pas conscience de ce contexte d’exécution
mmap. Sur un M2 8 Go, lire un expert de 3,36 Mo à froid prenait 10 ms avecmmap, contre 2,8 ms avecpread, et la simulation complète tournait respectivement à 0,50 token/s et 4 tokens/s.Avec
mmap, l’OS lit de manière réactive quand le modèle touche les pages, donc il ne sait pas quel expert a été sélectionné ni à quel moment il peut chevaucher les lectures avec le travail GPU. Les poids communs utilisent encoremmappar simplicité, et llama.cpp peut sans doute aussi tourner sous les 2 Go, mais probablement plus lentementLa phrase « les résultats mesurés sont une référence, pas une limite supérieure de performance » ressemble à une formulation typique de Claude
Si l’auteur a seulement utilisé un LLM pour lisser la formulation sans ajouter de contenu inutile, ça ne me dérange pas. Si le texte lui-même est un produit généré sans intérêt, il suffit de le noter négativement
Obtenir 12 tokens par seconde et une réponse presque immédiate sur un Mac Studio M1 Max équipé d’un SSD plus rapide, c’est impressionnant. Cela montre qu’il est possible d’exécuter de gros modèles directement depuis le SSD plutôt que depuis la mémoire
On voit beaucoup de moteurs de streaming SSD en ce moment, mais rares sont ceux qui tentent des fonctions plus avancées. Les principaux modèles disposent de têtes MTP pour le décodage spéculatif, donc on pourrait les utiliser pour précharger les poids experts sur le SSD.
Si les poids sont prêts avant que le GPU n’en ait besoin, on peut fortement réduire le coût des défauts de cache VRAM ; et si cela s’avère efficace, les futurs modèles pourraient avoir une tête dédiée au préchargement des experts, pensée dès l’entraînement
Avec les tokens brouillons produits par le MTP, on peut prédire jusqu’aux experts de la première couche, mais pour connaître ceux de la 10e couche, il faut exécuter les couches 1 à 9 et charger d’abord leurs experts. Il faudrait donc, au lieu d’un générateur du token suivant, un mécanisme entraîné pour prédire d’un coup l’activation des experts de toutes les couches
Un projet pour exécuter DiffusionGemma est lui aussi presque prêt, et les deux projets pourraient très bien se compléter. Sur un M3 36 Go, on atteint environ 20 tokens par seconde, et il y a de fortes chances qu’ils puissent aussi réutiliser mutuellement des kernels plus rapides.
Le code actuel est sur https://github.com/mmastrac/diffgemma, mais ce n’est pas encore dans un état diffusable
Je serais curieux d’avoir ton avis là-dessus
Je me demande pourquoi il y a un si grand écart entre 5 à 6 tokens par seconde sur un MacBook Air M2 8GB et 31 à 35 tokens par seconde sur un MacBook Pro M5. Il ne semble pas que la différence de performances du SSD soit à ce point énorme, mais je m’attendais à ce que le SSD soit ici le goulot d’étranglement dominant
https://www.tomshardware.com/laptops/macbooks/m5-macbook-pro...
Si l’on ne peut utiliser qu’un total de 2GB, cache système compris, la vitesse d’inférence pourrait être plus faible
pread. Même si le processus reste sous les 2GB, un Mac M5 peut en mettre une partie en cache, et le matériel lui-même est bien plus rapideLa lecture par token était de 83ms sur le M2 et de 12ms sur le M5 Pro, tandis que le temps total était respectivement de 163ms et 30ms. Cela vient à la fois d’une lecture plus rapide et d’un traitement GPU plus rapide
À l’avenir, j’espère qu’avec des systèmes dotés de 30 à 60GB de mémoire et d’un SSD très rapide, ce type de technique permettra aussi d’exécuter des modèles géants
https://github.com/danveloper/flash-moe
https://github.com/JustVugg/colibri
On peut utiliser https://github.com/antirez/ds4 ou https://github.com/steadfastgaze/MoEspresso, que j’ai développé moi-même. Comme il faut lire depuis le SSD les experts nécessaires au token suivant qui ne sont pas en mémoire, la vitesse est limitée par la lecture du SSD, et plus la mémoire est grande, plus l’inférence est rapide