patdev commited on
Commit
801b252
·
verified ·
1 Parent(s): 14e1364

banc 4 modeles sur Ada : Kimi-Linear devant, variantes A4B/A9B/A12B, speculation contre-intuitive

Browse files
reports/2026-08-23-banc-a12b-multisession.md ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Qwen3.8-MoE-27B-A12B : banc multi-session, TurboQuant et n-gram (23/08/2026)
2
+
3
+ Mesures sur RTX 6000 Ada (sm89), vLLM 0.27.1, checkpoint
4
+ `patdev/Qwen3.8-MoE-27B-A12B-W4A16` (INT4 groupwise, noyau Marlin WNA16 MoE), contexte 32 k,
5
+ `gpu-memory-utilization 0.90`. Prompt : génération d'une fonction Python avec docstring et test.
6
+
7
+ ## Ce que ONNX et TensorRT ne peuvent pas faire ici
8
+
9
+ La demande initiale était « A12B en ONNX GenAI et en TensorRT, avec plusieurs sessions ».
10
+ Trois vérifications l'ont écartée avant tout essai :
11
+
12
+ | | verdict | preuve |
13
+ |---|---|---|
14
+ | A12B en ONNX GenAI | **impossible** | le constructeur d'ORT GenAI ne connaît pas `Qwen3_5MoeForCausalLM` (sa liste s'arrête à `Qwen3ForCausalLM`, `PhiMoEForCausalLM`, `GptOssForCausalLM`) ; l'attention linéaire hybride n'est exportable par aucun outil disponible |
15
+ | A12B en TensorRT-LLM | **impossible sur Ada** | `NotImplementedError: WFP4A16 MoE is unsupported on SM89` — noyau réservé à sm90 |
16
+ | plusieurs sessions en ONNX GenAI | **impossible par conception** | l'API `Generator` (`append_tokens`, `generate_next_token`, `is_done`) n'a aucun moyen d'ajouter ou retirer une requête en cours ; les 163 tok/s mesurés sont un plafond mono-session |
17
+
18
+ Le MXFP4 produit pour TRT-LLM n'est pas non plus servable par vLLM : `_is_mxfp4()` route vers
19
+ `CompressedTensorsW4A4Mxfp4`, donc du **W4A4** (activations 4 bits), alors que le checkpoint est
20
+ weight-only (`input_activations: null`). Même classe de piège de mappage que celui trouvé dans
21
+ TRT-LLM. D'où le choix du **W4A16 groupwise**, qui passe par le noyau Marlin éprouvé.
22
+
23
+ ## Montée en charge
24
+
25
+ | concurrence | agrégé j/s | par flux | latence |
26
+ |---|---:|---:|---:|
27
+ | 1 | 45,7 | 45,7 | 4,4 s |
28
+ | 4 | 151,4 | 37,8 | 5,3 s |
29
+ | 8 | 294,9 | 36,9 | 5,4 s |
30
+ | 16 | 529,0 | 33,1 | 6,0 s |
31
+ | **32** | **875,5** | 27,4 | 7,3 s |
32
+
33
+ **×19,2 entre 1 et 32 sessions**, pour seulement 40 % de perte par flux : le batching continu
34
+ travaille très bien sur ce modèle.
35
+
36
+ ### L'écart avec Ornith se resserre sous charge
37
+
38
+ | | solo | 32 sessions |
39
+ |---|---:|---:|
40
+ | Ornith-1.5-35B-A3B (≈3 B actifs) | 134,1 | 1 380 |
41
+ | A12B (12,80 B actifs) | 45,7 | 875,5 |
42
+ | **rapport** | **2,9×** | **1,58×** |
43
+
44
+ En solo, l'A12B paie plein tarif ses 4,3× de paramètres actifs. À 32 sessions, l'écart tombe à
45
+ 1,58× : le régime devient limité par le calcul partagé entre requêtes, et le surcoût par jeton
46
+ se dilue. **Pour un usage multi-agents, le supplément de qualité coûte bien moins cher qu'en
47
+ solo.**
48
+
49
+ ## TurboQuant : recommandable ici, contrairement à Ornith
50
+
51
+ | | bf16 KV | TurboQuant `k3v4_nc` | écart |
52
+ |---|---:|---:|---|
53
+ | cache KV | 232 288 jetons | **733 499** | **×3,16** |
54
+ | solo | 45,7 | 45,3 | −0,9 % |
55
+ | 8 sessions | 294,9 | 289,2 | −1,9 % |
56
+ | 32 sessions | 875,5 | 839,7 | −4,1 % |
57
+
58
+ **Le contexte triple pour ~4 % de débit à forte charge.** C'est l'inverse du résultat sur Ornith
59
+ (15,0 contre 26,4 j/s le 22/08), et la raison est structurelle : l'A12B a **16 couches
60
+ d'attention pleine** dont le cache est volumineux, alors qu'Ornith est presque entièrement en
61
+ attention linéaire, dont les états sont de **taille fixe** et ne gagnent rien à être quantifiés.
62
+
63
+ À retenir comme règle : **TurboQuant paie proportionnellement à la part d'attention pleine du
64
+ modèle.**
65
+
66
+ ## Spéculation n-gram : ×2,8, mais uniquement sur du code
67
+
68
+ | | bf16 | n-gram (k=3, lookup 4) | écart |
69
+ |---|---:|---:|---|
70
+ | solo | 45,7 | **129,2** | **+183 %** |
71
+ | 8 sessions | 294,9 | **637,8** | **+116 %** |
72
+ | latence solo | 4,4 s | **1,5 s** | −66 % |
73
+
74
+ Elle amène l'A12B **au niveau d'Ornith en solo** (129,2 contre 134,1) alors qu'il active 4,3× plus
75
+ de paramètres, et sans aucun poids supplémentaire.
76
+
77
+ **Réserve majeure, à ne pas perdre de vue** : le prompt du banc demande d'écrire une fonction
78
+ Python avec docstring et test unitaire, c'est-à-dire le **cas le plus favorable** à la
79
+ spéculation n-gram, qui recopie des motifs répétés. Les mesures du 22/08 donnaient **+86 % en
80
+ édition de code mais −43 % en prose**. Ce ×2,8 est un plafond de génération de code, pas une
81
+ accélération générale : **activer pour du codage, désactiver pour de la rédaction.**
82
+
83
+ ## Contexte long : mesure dominée par le préremplissage
84
+
85
+ | ~8 k de contexte | agrégé | par flux | latence |
86
+ |---|---:|---:|---:|
87
+ | 1 session | 26,2 | 26,2 | 7,6 s |
88
+ | 8 sessions | 49,3 | 6,2 | 32,2 s |
89
+
90
+ Ces chiffres ne mesurent **pas le décodage** : 8 000 jetons à ingérer pour 200 générés, donc le
91
+ préremplissage domine. Ils disent surtout que le cache KV de l'A12B (232 288 jetons en bf16) est
92
+ **4,1× plus petit** que celui d'Ornith (958 169) — d'où l'intérêt de TurboQuant sur ce modèle.
93
+
94
+ ## Pourquoi aucun brouillon Kimi ne nous servira
95
+
96
+ Deux dépôts ont été proposés : `Inferact/Kimi-K3-DSpark` et `modal-labs/Kimi-K3-DFlash`. Tous deux
97
+ déclarent `base_model: moonshotai/Kimi-K3` et sont inutilisables ici.
98
+
99
+ Un brouillon de spéculation propose des jetons que la cible **vérifie** : il doit donc partager son
100
+ vocabulaire exact, sa géométrie et sa disposition de cache.
101
+
102
+ | | Kimi-K3-DSpark | notre A12B |
103
+ |---|---:|---:|
104
+ | `hidden_size` | 7 168 | 5 120 |
105
+ | `vocab_size` | 163 840 | 248 320 |
106
+ | attention | MLA (latent de 576) | linéaire hybride + GQA |
107
+
108
+ Les identifiants de jetons ne désignent même pas les mêmes mots. Et le chiffre phare de DSpark —
109
+ 464 tok/s — est obtenu sur **4× GB300 en tensor-parallel 16**, sans rapport avec une carte à
110
+ 0,84 $/h. Kimi-K3 lui-même pèse 1 561 Go, hors de portée des 49 Go de VRAM.
111
+
112
+ C'est précisément pourquoi la spéculation **n-gram** est le bon levier ici : elle ne demande aucun
113
+ poids et fonctionne sur n'importe quel modèle.
114
+
115
+ ## Pièges rencontrés
116
+
117
+ - **`ninja` est une dépendance cachée** des modèles à attention linéaire : leurs noyaux se
118
+ compilent à la volée. Sans lui dans le `PATH` du sous-processus, `EngineCore` meurt sur un
119
+ `RuntimeError: Engine core initialization failed` qui masque le vrai
120
+ `FileNotFoundError: 'ninja'` quinze lignes plus haut. Ornith y échappait, ses noyaux étant en
121
+ cache. `torch.compile` allait au bout (78 s) avant l'échec, ce qui faisait croire à tort à un
122
+ problème de modèle.
123
+ - **Écrire un `.sh` avec Python sous Windows** produit des CRLF que bash refuse
124
+ (`syntax error near unexpected token $'{\r'`). Utiliser `newline="\n"`, ou `tr -d "\r"` à
125
+ l'arrivée, et valider par `bash -n`.
reports/2026-08-23-banc-quatre-modeles-ada.md ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Quatre familles de modèles sur RTX 6000 Ada : le débit suit l'activation (23/08/2026)
2
+
3
+ Toutes les mesures sur la même carte (RTX 6000 Ada, sm89), vLLM 0.27.1, `--max-num-seqs 64`,
4
+ `gpu-memory-utilization 0.92`, prompts identiques (génération de code, et prose pour comparaison).
5
+
6
+ ## Le tableau d'ensemble
7
+
8
+ | modèle | actifs/jeton | solo | 8 sessions | 32 sessions | cache KV | démarrage |
9
+ |---|---:|---:|---:|---:|---:|---:|
10
+ | **Kimi-Linear-48B A3B** | 3,48 B | **152,2** | **772,8** | **1 609,8** | 866 531 | **70 s** |
11
+ | Ornith-1.5-35B-A3B *(servi actuellement)* | ~3 B | 134,1 | — | 1 380 | 958 169 | ~140 s |
12
+ | Kimi-Linear A4B (top-11) | 4,04 B | 143,7 | 618,2 | 1 286,5 | 1 743 985 | 60 s |
13
+ | Kimi-Linear A9B (top-38) | 9,00 B | 95,9 | 463,5 | 1 245,4 | 1 616 554 | 70 s |
14
+ | Kimi-Linear A12B (top-54) | 11,95 B | 80,7 | 481,2 | 1 183,5 | 1 545 557 | 60 s |
15
+ | Qwen3.8-MoE-27B-A12B *(fabriqué cette nuit)* | 12,80 B | 45,7 | 294,9 | 875,5 | 232 288 | 130 s |
16
+ | Qwen3.8-27B dense FP8 | 27 B | 21,0 | 184,8 | 598,0 | 197 361 | 220 s |
17
+
18
+ ## Trois régularités, et une règle qui s'est révélée fausse
19
+
20
+ ### 1. Le débit solo suit inversement les paramètres actifs
21
+
22
+ 3 B → 134-152 tok/s, 12 B → 45-81, 27 B → 21. La relation n'est pas strictement proportionnelle :
23
+ **Kimi-Linear A12B fait 80,7 contre 45,7 pour notre Qwen3.8-A12B, à activation quasi identique**
24
+ (11,95 contre 12,80 B). L'écart de 77 % vient de l'architecture : socle de 1,83 B et attention
25
+ presque toute linéaire chez Kimi, contre 9,78 B de socle et 16 couches d'attention pleine chez
26
+ Qwen3.8.
27
+
28
+ ### 2. Plus un modèle active de paramètres, mieux il monte en charge
29
+
30
+ | modèle | solo → 32 sessions |
31
+ |---|---:|
32
+ | Ornith (3 B) | ×10,3 |
33
+ | Qwen3.8-A12B (12,8 B) | ×19,2 |
34
+ | Qwen3.8-27B dense (27 B) | ×28,5 |
35
+
36
+ Mécanisme : un modèle à faible activation est borné par la bande passante mémoire et laisse les
37
+ unités de calcul oisives ; les requêtes concurrentes viennent les remplir. Un dense, déjà saturé
38
+ en calcul, avait le plus de marge relative à récupérer. Il finit néanmoins **2,3× derrière
39
+ Ornith** à 32 sessions.
40
+
41
+ ### 3. Le coût d'un expert supplémentaire est sous-proportionnel en solo
42
+
43
+ Sur Kimi-Linear, mêmes poids, seul `num_experts_per_token` change :
44
+
45
+ | top-k | actifs | solo | coût par rapport à top-8 |
46
+ |---|---:|---:|---|
47
+ | 8 | 3,48 B | 152,2 | — |
48
+ | 11 | 4,04 B | 143,7 | +16 % d'activation pour −5,6 % de débit |
49
+ | 38 | 9,00 B | 95,9 | ×2,6 d'activation pour −37 % |
50
+ | 54 | 11,95 B | 80,7 | ×3,4 d'activation pour −47 % |
51
+
52
+ **En session unique, monter le nombre d'experts actifs est presque gratuit** — le bon levier pour
53
+ gagner en qualité quand on code seul. À 32 sessions, chaque expert se paie plein tarif.
54
+
55
+ Anomalie intéressante : **l'A12B bat l'A9B en multi-session** (481 contre 464 à 8 sessions) tout en
56
+ activant 33 % de paramètres en plus. Au-delà d'un certain nombre d'experts actifs, le noyau MoE
57
+ groupe mieux ses calculs. Conséquence pratique : **pour de la qualité en multi-agents, préférer
58
+ l'A12B à l'A9B — le débit est équivalent.**
59
+
60
+ ### 4. La règle « la spéculation ne paie que sur les MoE » est FAUSSE
61
+
62
+ Énoncée puis démentie par la mesure suivante :
63
+
64
+ | modèle | effet du n-gram |
65
+ |---|---|
66
+ | Qwen3.8-MoE-A12B | **+183 %** solo |
67
+ | Qwen3.8-27B dense | +11 % solo, **−9 %** à 8 sessions |
68
+ | **Kimi-Linear-48B A3B (un MoE)** | **−77 %** solo, −78 % à 8, −62 % à 32 |
69
+
70
+ Kimi-Linear est un MoE à 256 experts et perd les trois quarts de son débit. L'explication tient à
71
+ l'**attention linéaire** : chaque jeton met à jour un état récurrent, et rejeter un brouillon
72
+ impose de **restaurer cet état** — bien plus coûteux qu'un retour en arrière dans un cache KV
73
+ classique. La spéculation est structurellement mal adaptée aux modèles à état.
74
+
75
+ **Réserve sur le +183 % de notre A12B** : son routeur n'a pas été réentraîné après la
76
+ re-partition (moyenne des lignes fusionnées). Un routeur mal calibré produit des sorties
77
+ répétitives, que le n-gram prédit presque parfaitement — ce gain pourrait donc mesurer une
78
+ dégénérescence plutôt qu'une accélération. Le banc ne contrôlait pas la qualité du texte : lacune
79
+ de méthode, corrigée par un contrôle de répétitivité (proportion de 4-grammes distincts).
80
+
81
+ ## Les modèles Kimi : ce qui existe vraiment
82
+
83
+ | dépôt | verdict |
84
+ |---|---|
85
+ | `moonshotai/Kimi-K3` (1 561 Go) | inhébergeable : 49 Go de VRAM, 200 Go de disque |
86
+ | `ubicloud/Kimi-K3-Pruned-35B` / `-65B` | **leurres** : 2 et 3 couches sur 93, maquettes de pipeline |
87
+ | `lovedheart/Kimi-K3-Lite` (1 561 Go) | socle de 21,29 B — A4B/A9B/A12B tous impossibles |
88
+ | `Inferact/Kimi-K3-DSpark`, `modal-labs/Kimi-K3-DFlash` | brouillons de spéculation **pour K3 uniquement** |
89
+ | **`cyankiwi/Kimi-Linear-48B-A3B-Instruct-AWQ-4bit`** | **30,5 Go, réel, complet — le meilleur du banc** |
90
+
91
+ Un brouillon de spéculation doit partager le vocabulaire exact, la géométrie et la disposition de
92
+ cache de sa cible. Kimi-K3-DSpark (vocab 163 840, dimension 7 168, MLA) ne peut rien proposer à
93
+ Qwen3.8 (vocab 248 320, dimension 5 120) : les identifiants de jetons ne désignent même pas les
94
+ mêmes mots. Et son chiffre phare — 464 tok/s — est obtenu sur **4× GB300 en tensor-parallel 16**.
95
+
96
+ ## Fabriquer les variantes Kimi : une ligne de configuration
97
+
98
+ Contrairement à Qwen3.8, où le socle de 9,78 B rend A4B et A9B arithmétiquement impossibles, le
99
+ socle de Kimi-Linear ne fait que **1,83 B** :
100
+
101
+ | composant | taille |
102
+ |---|---:|
103
+ | experts routés (256) | 47,110 B |
104
+ | attention pleine | 0,994 B |
105
+ | embeddings (163 840 × 2 304) | 0,755 B |
106
+ | expert partagé | 0,184 B |
107
+ | normes + routeur | 0,079 B |
108
+ | **socle** | **1,828 B** |
109
+ | **par expert** | **0,184 B** |
110
+
111
+ D'où : actifs = 1,828 + 0,184 + k × 0,184. Les trois cibles s'obtiennent en changeant
112
+ `num_experts_per_token` (11, 38, 54 sur 256), poids partagés par liens durs — les quatre
113
+ configurations occupent 30 Go au total.
114
+
115
+ ## Pièges rencontrés
116
+
117
+ - **`max_num_seqs` est plafonné par le cache Mamba, pas par la VRAM.** Sur un hybride,
118
+ chaque séquence en décodage réserve un bloc d'état :
119
+ `ValueError: max_num_seqs (256) exceeds available Mamba cache blocks (251)`. Cela empêche la
120
+ capture des graphes CUDA, dont on sait qu'elle vaut un facteur 6. Borner explicitement.
121
+ - **`ninja` est une dépendance cachée** des modèles à attention linéaire : leurs noyaux se
122
+ compilent à la volée. Sans lui dans le `PATH`, `EngineCore` meurt sur un message qui masque le
123
+ vrai `FileNotFoundError` quinze lignes plus haut.
124
+ - **Le tokeniseur de Kimi-Linear** importe `bytes_to_unicode` depuis
125
+ `transformers.models.gpt2.tokenization_gpt2`, d'où la fonction a disparu ; elle vit désormais
126
+ dans `transformers.convert_slow_tokenizer`. Corrigé avec repli sur l'ancien chemin.
127
+ - **Écrire un `.sh` avec Python sous Windows** produit des CRLF que bash refuse. Utiliser
128
+ `newline="\n"` et valider par `bash -n`.
129
+
130
+ ## Ce que cela implique
131
+
132
+ **Le modèle servi aujourd'hui n'est pas le meilleur disponible.** Ornith était le choix par défaut
133
+ depuis plusieurs sessions ; Kimi-Linear-48B-A3B fait mieux sur tous les axes mesurés — +13 % en
134
+ solo, +17 % à 32 sessions, latence de 1,3 s, démarrage deux fois plus rapide — pour un contexte à
135
+ peine inférieur (866 k contre 958 k). Il offre en prime un réglage qualité/vitesse par simple
136
+ ligne de configuration.
137
+
138
+ Réserve honnête : **ce banc mesure le débit, pas la qualité des réponses.** Kimi-Linear est de la
139
+ génération Kimi 2, et aucune évaluation comparative de qualité n'a été faite ici.
reports/README.md CHANGED
@@ -14,6 +14,8 @@ en a conclu, pour ne pas le refaire.
14
  | 2026-08-23 | `2026-08-23-l4-graphes-cuda-et-multi-modeles.md` | L4 : 12,4 → 75,7 tok/s en activant les graphes CUDA (×6) ; rendement par Go/s vs notre TP=2 ; Kimi-K3 / Qwen3.8 déjà servis par le bootstrap ; TRT-LLM impasse confirmée |
15
  | 2026-08-23 | `2026-08-23-tensorrt-et-onnx-mesures.md` | TRT-LLM **impasse fermée** (INT4 et FP8, sur L40S et sur Ada) ; graphe ONNX réparé et fonctionnel (126,9 tok/s L40S) ; baseline L4 corrigée 13→76 ; MTP à 29 % d’acceptation même en FP8 |
16
  | 2026-08-23 | `2026-08-23-mxfp4-deblocage-trtllm-et-familles-moe.md` | **TRT-LLM : le noyau MoE 4 bits est reserve a sm90** — aucun chemin MoE quantifie sur Ada (2 correctifs Python ecrits, valables sur Hopper) ; l'EP TensorRT existe bien dans onnxruntime-gpu 1.29 ; **ONNX GenAI 163,2 tok/s sur Ada, devant vLLM** ; planchers reels Qwen3.8 (10,79 B) et Kimi K3 (21,29 B) : A4B et A9B impossibles |
17
-
 
 
18
  Convention : `AAAA-MM-JJ-sujet.md`, français, sources en URL, « non trouvé » explicite, et une
19
  section finale « ce que nous en avons fait » quand c'est appliqué.
 
14
  | 2026-08-23 | `2026-08-23-l4-graphes-cuda-et-multi-modeles.md` | L4 : 12,4 → 75,7 tok/s en activant les graphes CUDA (×6) ; rendement par Go/s vs notre TP=2 ; Kimi-K3 / Qwen3.8 déjà servis par le bootstrap ; TRT-LLM impasse confirmée |
15
  | 2026-08-23 | `2026-08-23-tensorrt-et-onnx-mesures.md` | TRT-LLM **impasse fermée** (INT4 et FP8, sur L40S et sur Ada) ; graphe ONNX réparé et fonctionnel (126,9 tok/s L40S) ; baseline L4 corrigée 13→76 ; MTP à 29 % d’acceptation même en FP8 |
16
  | 2026-08-23 | `2026-08-23-mxfp4-deblocage-trtllm-et-familles-moe.md` | **TRT-LLM : le noyau MoE 4 bits est reserve a sm90** — aucun chemin MoE quantifie sur Ada (2 correctifs Python ecrits, valables sur Hopper) ; l'EP TensorRT existe bien dans onnxruntime-gpu 1.29 ; **ONNX GenAI 163,2 tok/s sur Ada, devant vLLM** ; planchers reels Qwen3.8 (10,79 B) et Kimi K3 (21,29 B) : A4B et A9B impossibles |
17
+
18
+ | 2026-08-23 | `2026-08-23-banc-quatre-modeles-ada.md` | **Kimi-Linear-48B bat Ornith sur tous les axes** (152 solo, 1 610 a 32) ; le debit suit l'activation ; variantes A4B/A9B/A12B par une ligne de config ; la regle « la speculation ne paie que sur les MoE » demontree FAUSSE (-77 % sur Kimi) |
19
+
20
  Convention : `AAAA-MM-JJ-sujet.md`, français, sources en URL, « non trouvé » explicite, et une
21
  section finale « ce que nous en avons fait » quand c'est appliqué.