Fonctionne avec Qwen3.8-Flash-Next sur des RTX 3090 grâce au chargement délégué des tenseurs de llama.cpp
Pourquoi un modèle épars de 88 Go et de 180 milliards de paramètres peut fonctionner sur des GPU grand public, et comment des options comme -ot, -ncmoe et mmap de llama.cpp le répartissent sur la VRAM, la RAM et NVMe.
Qwen3.8-Flash-Next est un modèle ouvert comptant approximativement 180 milliards de paramètres, dont les fichiers quantifiés totalisent 88 GB, pourtant certaines personnes affirment pouvoir le faire fonctionner sur une seule carte RTX 3090 disposant de 24 GB de VRAM. En théorie, cela représente une différence d’un ordre de grandeur. Il fonctionne grâce à l’architecture du modèle, et non en raison d’une quantification particulièrement efficace ou d’une GPU exceptionnellement puissante : de grandes parties du modèle n’ont jamais besoin d’être stockées sur la carte graphique. Cet article explique les quatre choix de conception qui rendent cela possible, puis présente des configurations complètes pour llama.cpp, tant sur un système avec trois GPU que sur une machine avec une seule GPU, en indiquant la fonction de chaque flag important ainsi que le débit réellement attendu.
Pourquoi Flash-Next vaut la peine d’être exécuté localement
Alibaba a lancé Flash-Next en août. Au moment de la rédaction de ce texte, ses résultats publiés le placent en tête de Qwen3.8-27B, DeepSeek V4 Flash (0731) et, sur plusieurs benchmarks d’agence, Opus 4.6, tout en activant seulement 6 milliards de paramètres par token. Les classements des benchmarks changent rapidement, il convient donc de vérifier les évaluations actuelles avant de considérer ces comparaisons comme définitives. Ce qui reste plus stable, c’est la structure du modèle, car c’est cette structure qui détermine quel matériel peut le faire fonctionner.
Quatre choix architecturaux qui déplacent le travail hors du GPU
Flash-Next combine quatre idées. Chacune d’elles déplace une partie du travail coûteux depuis un matériel cher vers un matériel moins cher, ou l’élimine complètement.
Mélange ultra-spars d’experts
Le modèle compte 48 couches, et chaque couche contient 512 sous-réseaux d’experts. Chaque token ne passe que par 11 d’entre eux : 10 sélectionnés par un routeur qui examine le token et choisit les spécialistes les plus adaptés, ainsi qu’un expert partagé que chaque token utilise sans passer par un routage. En d’autres termes, environ 2 % des experts effectuent le travail pour un donné token.
Une image utile est celle d’un hôpital disposant de 512 spécialistes en service et d’un médecin généraliste toujours présent. Chaque patient reçoit dix consultations adaptées à ses symptômes, tandis que les 501 autres spécialistes ne sont pas impliqués. La notion clé pour l’inférence locale est que « en service » signifie simplement « accessible ». Un spécialiste n’a pas besoin d’être exécuté sur une GPU pour être disponible.
L’expert partagé existe parce que les architectures basées uniquement sur le routage ont tendance à perdre les connaissances générales nécessaires à chaque token. En plaçant ces connaissances dans un expert généraliste toujours actif, les experts spécialisés peuvent se concentrer davantage sur leur domaine. La plupart des architectures MoE actuelles en incluent un, et ses paramètres font partie du total de 6 milliards de paramètres actifs.
Gated DeltaNet plus Qwen Sparse Attention
Un transformateur standard conserve une entrée clé/valeur pour chaque token qu’il a traité. Ce cache KV croît linéairement avec la longueur du contexte et devient énorme pour des textes très longs. Flash-Next évite largement ce problème. Trois sur quatre couches utilisent Gated DeltaNet, qui compresse l’historique en un état de taille fixe. La couche restante dans chaque groupe utilise Qwen Sparse Attention, qui lit à partir d’un budget fixe de 512 blocs, 2 048 tokens, que le contexte contienne 32 K ou un million de tokens.
L’effet pratique est spectaculaire : avec un contexte de 178 K, le cache KV dans les configurations présentées ci-dessous occupe environ 6 Go, tandis qu’un modèle dense comparable nécessiterait près d’une dizaine de fois plus de mémoire. C’est la raison pour laquelle une carte de 24 Go peut tout simplement gérer une longue conversation.
Un flux résiduel multi-lignes contrôlé par des portes
Les transformateurs classiques acheminent tout via un seul flux résiduel, du premier au dernier niveau, et dans les réseaux profonds, les caractéristiques initiales ont tendance à s’atténuer au fil du parcours. Flash-Next élargit ce chemin en quatre voies parallèles, des portes apprises contrôlant ce qui entre et sort de chaque voie. Lors de l’entraînement, l’une des voies s’est spécialisée en un canal à long rayon d’action permettant de transmettre les informations initiales profondément dans le réseau. Il s’agit d’un petit changement architectural qui augmente les capacités sans coût significatif.
Une table d’incorporation d’n-grammes
Le quatrième élément est un tableau de 51 milliards de paramètres, plus que le reste du modèle combiné, qui ne réalise aucune multiplication matricielle. Il s’agit d’une structure de recherche, et c’est la raison principale pour laquelle une seule carte graphique gaming est suffisante.
Le tableau des n-grammes : une connaissance qui ne nécessite pas de GPU
Dans un modèle linguistique normal, chaque token est mappé sur une ID et le modèle cherche cette ID dans un tableau d’incorporation : une ligne par token. Une ligne représentant un seul token contient très peu d’informations sur le contexte. Pour une phrase telle que « Dostoïevski a écrit Les Frères », l’incorporation de « le » ne dit rien sur les Karamazov ; le modèle doit inférer la suite à l’aide de ses couches coûteuses, et il doit le faire à chaque fois que ce schéma apparaît.
Flash-Next ajoute une deuxième table dont les lignes sont identifiées par des phrases courtes plutôt que par des tokens individuels. Conceptuellement, les entrées ressemblent au schéma suivant : une phrase hachée à gauche et le type d’indication que son vecteur appris encode à droite.
Drawer "born on october" → hint: 1985, Honolulu, singer
Drawer "dostoevsky brothers" → hint: Karamazov, novel, 1880
Drawer "def main(" → hint: python entry point
Lors de la lecture, le modèle hache les quelques tokens les plus récents, récupère la ligne correspondante et obtient ainsi une indication précalculée pratiquement gratuitement. Personne n’a rédigé ces lignes manuellement. Au cours de l’entraînement, chaque fois qu’une phrase était suivie d’une certaine continuation, sa ligne était légèrement ajustée dans cette direction, de sorte qu’après des trillions de tokens, chaque ligne représente approximativement ce qui vient généralement ensuite. La table contient environ 20 millions d’entrées de bigrammes et de trigrammes, et son output est injecté une seule fois, tôt, au niveau 2. Il s’agit en fait de mémorisation de formulations courantes, or une grande partie du texte réel est constituée de telles formulations.
La différence entre les deux types de connaissances dans le modèle est ce qui rend possible la répartition sur le matériel. La comparaison ci-dessous en résume l’essentiel.
| | Neural network | N-gram table |
|------------------|-------------------------|-------------------------|
| Work per token | Matrix math (expensive) | Drawer lookup (no math) |
| Needs the GPU? | Yes, every millisecond | No — CPU can fetch it |
| Lives in | VRAM | RAM. Even SSD. |
La propriété déterminante est que la ligne à récupérer ne dépend que du texte d’entrée, et non de tout état caché au sein du réseau. Dès que une requête est tokenisée, la CPU sait exactement quelles lignes seront nécessaires, ce qui lui permet de les précharger tandis que la GPU est encore occupée avec des couches antérieures.
Cela permet de répartir le modèle dans la hiérarchie mémoire en fonction des forces de chaque niveau :
- VRAM (rapide, coûteuse) : les environ 6 milliards de paramètres effectivement calculés pour chaque token.
- RAM système (modérée, bon marché) : les poids des experts inactifs et le tableau de n-grammes de 29 Go.
- Stockage NVMe (lent, le moins cher) : les données en surcharge, chargées dynamiquement lorsqu’elles sont utilisées.
La GPU cesse d’être l’endroit où tout le modèle est stocké pour devenir celui où se déroulent les calculs en temps réel.
Une configuration à trois GPU pour un usage quotidien
Prenons un serveur composé de trois cartes RTX 3090 (72 GB de VRAM au total), de 48 GB de mémoire système DDR4 et d’un disque NVMe PCIe Gen3 contenant les poids du modèle. Rien dans cette configuration n’est de niveau station de travail ; il s’agit du type d’appareil que de nombreux développeurs assemblent à partir de cartes graphiques plus anciennes destinées aux jeux.
Le fichier de modèle utilisé ici est la version UD-IQ4_XS provenant du répertoire GGUF d’unsloth pour ce modèle sur Hugging Face, soit environ 88 GB répartis en trois fichiers : près de 59 GB pour les poids principaux du modèle et 29 GB pour la table des n-grammes. La prise en charge de cette architecture est récente, il faut donc télécharger la dernière version du code llama.cpp et le recompiler avant de l’essayer.
La commande ci-dessous lance llama-server sur trois des GPU de la machine. La plupart des paramètres sont courants (hôte, port, paramètres d’échantillonnage, tailles de lot, longueur du contexte) ; il convient donc d’prêter attention aux paramètres de décharge, aux paramètres de division et au mode de chargement, qui sont abordés juste après.
CUDA_VISIBLE_DEVICES=0,2,3 CUDA_SCALE_LAUNCH_QUEUES=4x llama-server \
-m /mnt/data_2t/ai_models_all/llm_hf_models/unsloth/Qwen3.8-Flash-Next-GGUF/Qwen3.8-Flash-Next-UD-IQ4_XS-00001-of-00003.gguf \
--alias Qwen3.8-Flash-Next \
--jinja \
--metrics \
--host 0.0.0.0 \
-ngl 99 \
--batch-size 4096 \
--ubatch-size 512 \
--flash-attn on \
--temp 1.0 --top-p 0.95 --top-k 20 --min-p 0.0 --repeat-penalty 1.0 \
--split-mode layer \
--tensor-split 0.9,0.95,1.0 \
--fit off \
--main-gpu 0 \
--ctx-size 178000 \
--parallel 1 \
--image-min-tokens 1024 \
--reasoning-format none \
--timeout 1200 \
--ctx-checkpoints 8 \
--port 8082 \
--load-mode mmap \
--cache-type-k q8_0 --cache-type-v q8_0 \
-ot '^per_layer_token_embd\.weight$=CPU' \
--reasoning-effort low \
-t 14
Fixation de la table des n-grammes en RAM système
La directive -ot '^per_layer_token_embd\.weight$=CPU' indique à llama.cpp que tout tenseur dont le nom correspond à cette expression régulière doit être stocké en mémoire CPU plutôt qu’en VRAM. Le tableau de n-grammes est conservé sous le nom de tenseur per_layer_token_embd.weight ; ainsi, cette seule ligne permet d’éviter que les 29 GB correspondants soient stockés dans les GPU. Lorsqu’un token nécessite une ligne, le CPU la récupère et transmet le résultat, ce qui correspond exactement au mécanisme de préchargement décrit précédemment. Les symboles ^ et $ sont importants : ils garantissent que le motif ne s’applique qu’à ce tenseur et n’affecte pas par erreur d’autres poids.
Permettre au système d’exploitation de gérer le stockage via mmap
--load-mode mmap mape en mémoire le fichier du modèle au lieu de le lire d’abord dans la RAM. Le système d’exploitation conserve ensuite les pages fréquemment consultées dans le cache de pages disponible et laisse les pages peu utilisées sur le SSD. Avec 48 GB de RAM et une table de 29 GB, c’est un bon équilibre : le noyau décide quelles données doivent rester en mémoire. Sur une machine disposant de beaucoup de mémoire, comme 128 GB, il est plus judicieux de choisir none, car tout le fichier est lu une seule fois et il n’y a plus de pannes de page par la suite.
Distribution des couches sur plusieurs cartes
--split-mode layer combiné à --tensor-split 0.9,0.95,1.0 divise le réseau principal de 59 GB en groupes contigus de couches, un groupe par GPU, avec des proportions légèrement inégales afin que la première carte dispose d’espace supplémentaire pour ses fonctions additionnelles en tant que --main-gpu. -ngl 99 place les 48 couches sur les GPU, soit environ 20 GB par carte. Le cache KV, quantifié en q8_0 grâce à --cache-type-k et --cache-type-v, est stocké à côté des poids et couvre 178 K de tokens en environ 6 GB.
Rendement mesuré sur trois cartes
Les valeurs indiquées ci-dessous correspondent à ce setup.
Decode: 30-50 tokens/second
Prefill: 400-700 tokens/second
Context: 178,000 tokens
Cela est plus rapide que la vitesse de lecture d’un modèle de classe proche des modèles de pointe, sur des cartes grand public utilisées dans un boîtier de taille moyenne.
Configuration avec un seul GPU et ses limites
Une carte 3090 suffit si vous répondez à une condition : au moins 64 Go de RAM système. La table d’n-grammes ainsi que les experts déplacés ont besoin d’un espace de stockage, et la mémoire système constitue généralement la mise à niveau la moins coûteuse pour une machine d’IA locale.
La commande utilise le même fichier GGUF. Les différences notables sont le nouveau flag -ncmoe, une seule carte GPU visible, --load-mode none au lieu de mmap, ainsi que moins de threads CPU.
CUDA_VISIBLE_DEVICES=0 llama-server \
-m /mnt/data_2t_3/ai_models_all/unsloth/Qwen3.8-Flash-Next-GGUF/Qwen3.8-Flash-Next-UD-IQ4_XS-00001-of-00003.gguf \
--alias Qwen3.8-Flash-Next \
--jinja \
--metrics \
--host 0.0.0.0 \
-ngl 99 \
-ncmoe 38 \
--batch-size 4096 \
--ubatch-size 1024 \
--flash-attn on \
--temp 1.0 --top-p 0.95 --top-k 20 --min-p 0.0 --repeat-penalty 1.0 \
--ctx-size 178000 \
--parallel 1 \
--image-min-tokens 1024 \
--reasoning-format none \
--timeout 1200 \
--ctx-checkpoints 8 \
--port 8083 \
--load-mode none \
-ot '^per_layer_token_embd\.weight$=CPU' \
--reasoning-effort low \
-t 8
Quel est le rôle de -ncmoe 38 ?
-ncmoe 38 conserve les poids des experts des 38 premières couches en RAM CPU, tandis que les 10 dernières couches conservent leurs experts en VRAM. Cela représente environ 43 Go de poids d’expert en mémoire système. Les composants d’attention et partagés de chaque couche continuent cependant de fonctionner sur la GPU grâce à -ngl 99.
Le stockage important en RAM reste réalisable grâce à la faible densité des données. Chaque token active 10 des 512 experts par couche, ce qui signifie qu’il n’affecte au total que environ 1,3 Go des poids des experts. Les experts stockés en RAM sont calculés sur le CPU où ils se trouvent, sans être copiés vers la GPU, tandis que ceux en VRAM s’exécutent nativement sur la carte graphique. Le CPU étant bien plus lent qu’une 3090, cela entraîne un véritable retard, mais cet impact dépend du fait que chaque token affecte environ 2 % des poids, et non de tout le contenu stocké.
Puisque beaucoup de données sont conservées en RAM, l’option --load-mode none lit le fichier entièrement au démarrage plutôt que de compter sur des erreurs de page, ce qui explique également pourquoi une capacité minimale de 64 Go est nécessaire.
Ajustements pour d’autres cartes
La même commande fonctionne sur une RTX 4090 ou 5090 ; seuls les paramètres -ncmoe doivent être ajustés en fonction de la VRAM disponible. Les points de départ recommandés sont indiqués ci-dessous.
| GPU | VRAM | Suggested -ncmoe | Experts in RAM |
|------------|------|------------------|----------------|
| RTX 3090 | 24GB | 38 | ~43GB |
| RTX 4090 | 24GB | 38 | ~43GB |
| RTX 5090 | 32GB | 28-30 | ~32GB |
Chaque fois que vous diminuez la valeur de -ncmoe, les experts d’une couche, soit environ 1,1 Go, sont ramenés sur la GPU. Une fois le modèle chargé, vérifiez l’outil nvidia-smi et veillez à laisser environ 500 Mo de VRAM libres ; faire fonctionner la carte avec sa mémoire complètement pleine entraîne des erreurs de manque de mémoire lorsque le contexte s’agrandit.
Fixer des attentes réalistes
Avec une seule carte 3090, la décodage se fait à **15 à 20 tokens par seconde**. Cela est utilisable, mais juste : suffisamment rapide pour suivre le texte, trop lent cependant pour que les génération longues soient fluides, car une partie du calcul a réellement lieu sur le CPU dans la RAM système. En tant que démonstration de concept, ou pour tirer parti d’une machine que vous possédez déjà, faire fonctionner un modèle de 180 milliards de paramètres à une vitesse de lecture sur une seule carte gaming est remarquable.
Pour un assistant disponible toute la journée pour le codage et les tâches quotidiennes, trois ou quatre cartes 3090 sont nécessaires pour assurer une expérience confortable. L’écart entre environ 18 et 40 tokens par seconde marque la différence entre une démonstration et un outil quotidien. Si vous préférez explorer des modèles Qwen plus petits localement pour le codage agent, la démarche expliquée dans la création d’un jeu local avec Qwen3.8-27B montre une configuration plus légère.
Prédiction multi-token : la prochaine amélioration de vitesse à suivre
Flash-Next est équipé d’une tête de prédiction multi-token (MTP) entraînée, un petit module supplémentaire qui propose plusieurs tokens à venir en même temps afin que le modèle principal puisse les vérifier en parallèle. Il s’agit d’une décodage spéculatif avec une composante de brouillon entraînée du début à la fin pour ce modèle précis. Sur vLLM, on a constaté qu’il permet des accélérations de décodage d’environ 2,5 fois sur des prompts réels.
Lors de la rédaction de ce texte, llama.cpp prend en charge l’architecture Flash-Next elle-même, mais sa version préliminaire de MTP ne couvre pas encore ce modèle. Une prise en charge existe pour les modèles similaires, donc le changement devrait être modeste ; cependant, vérifiez les notes de version actuelles de llama.cpp avant d’en supposer la disponibilité. Une fois ce support intégré, les performances de 30 à 50 tokens par seconde obtenues avec une configuration à trois GPU pourraient raisonnablement monter à environ 60 à 100 tokens par seconde sur le même matériel, uniquement grâce à une mise à jour logicielle. Considérez cela comme une estimation tant que vous n’aurez pas pu mesurer les performances réelles.
Points clés
- Flash-Next convient aux ordinateurs grand public en raison de sa conception, et non par la force brute : un MoE ultra-spars, un état d’attention de taille fixe ainsi qu’une table d’n-grammes à lecture seule permettent tous de réduire la quantité de données nécessaires en VRAM.
-ot avec une expression régulière stricte permet de l’y placer.-ncmoe est la valeur principale pour les configurations à une seule GPU : réduisez-la jusqu’à ce que la VRAM soit presque pleine, en laissant une petite marge de sécurité.mmap lorsque la RAM est limitée et que vous souhaitez que le système d’exploitation gère l’emplacement mémoire ; choisissez none lorsque la RAM est abondante et que vous voulez une latence prévisible après le chargement.