RAPPORT §7: piste kernel GDN fermee — GDN-compute != goulot prefill (fork ql)

A/B pp512 mesure: serial f32=89.5 (vrai baseline) = fp16 89.65 = WY chunkwise 89.6.
3 schemas calcul GDN (0.5x/1x/2.5x flops) -> pp512 plat => l'arithmetique GDN ne
limite pas le prefill sur le fork ql (GDN-HTP). Mur ailleurs (denses/FFN/attn/op-batch).
Corrige premisse "GDN=ancre" (ancien tree GDN-CPU) et le baseline fantome "98".
Aucune optim kernel GDN (chunkwise/HMX/fp16) ne bouge le prefill.

ql -> 50e250d: fp16 serial validate (oracle 28/28, env KZ_F16 defaut OFF), WY chunkwise
conserve inutilise, HMX-per-tete NO-GO. Pousser pp512 = profiler ops non-GDN HTP.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Richard Loyer 2026-05-26 21:46:05 +02:00
parent dd29169672
commit a7c0e96793
2 changed files with 14 additions and 3 deletions

View File

@ -26,7 +26,18 @@ briques (stack NPU+lm_head CPU) : 2B 13, 4B 7, 9B 2.1 tok/s. **2B briques 13/2.5
## 6. Intégration #277 (dev) — débloquée, 2 fixes ## 6. Intégration #277 (dev) — débloquée, 2 fixes
hang in-app = thinking non bridé + 1 thread. FIX : signature `generate(sys,usr,maxTok)`, ChatML+`<think></think>`, ngl0 + n_threads=8 → 14 tok/s. Bridge STATIC (0 NEEDED libllama, coexiste TTS). dist `/opt/Kazeia-engine/dist/` : libkazeia_engine.so + htp-v79.so + EngineLlmEngine.kt + docs. hang in-app = thinking non bridé + 1 thread. FIX : signature `generate(sys,usr,maxTok)`, ChatML+`<think></think>`, ngl0 + n_threads=8 → 14 tok/s. Bridge STATIC (0 NEEDED libllama, coexiste TTS). dist `/opt/Kazeia-engine/dist/` : libkazeia_engine.so + htp-v79.so + EngineLlmEngine.kt + docs.
## 7. R&D pousser prefill = HVX chunkwise GDN ## 7. R&D pousser prefill GDN — PISTE FERMÉE (26/05, mesuré)
55→100 crédible mais HMX accumule fp16 (pas bit-exact). Voie HVX qf32, 3-5 sem. lm_head NPU = mort (CPU 31ms < HVX 104). Fork qualcomm/llama.cpp cloné (`ql/`) avec IQ4_NL HVX test bench IQ4_NL = à finir (quantize on-device). Conclusion dure : **le calcul GDN n'est pas le goulot du prefill sur le fork ql**. A/B sur la même commande llama-bench (Qwen3.5-4B-Q4_0, pp512, ngl99/t8/b512, gate scalaire S_v=128) :
| Schéma GDN (HTP) | flops GDN | pp512 |
|---|---:|---:|
| serial f32 (vrai baseline) | 1× | **89.5** |
| serial fp16 (HVX 64-lane) | ~0.5× ALU | 89.65 |
| WY chunkwise | ~2.5× | 89.6 |
Trois schémas de calcul (0,5× / 1× / 2,5× flops) → pp512 **plat**. Si l'arithmétique GDN limitait, le 2,5× s'effondrerait et le 0,5× grimperait. Donc le mur prefill (~89,5) est **ailleurs** : matmuls denses / FFN MoE / attention / conv / overhead op-batch. Ça corrige la vieille prémisse « GDN = l'ancre » (vraie sur l'ancien tree GDN-CPU série, **fausse** sur le fork GDN-HTP). Le « 98 » d'avant était un fantôme de mesure ; vrai baseline = 89,5.
Corollaire : **aucune optim du kernel GDN** (chunkwise, HMX, fp16) ne peut bouger le prefill. HMX-per-tête en plus = NO-GO (matmuls 32×128 latency-bound ~12 µs, 28 têtes × 24 couches sérialisées sur le moteur HMX unique). Pour réellement pousser pp512 il faut profiler/attaquer les ops **non-GDN** sur HTP — autre chantier, et prefill = « utile pas vital ».
Artefacts (branche `ql` gdn-chunkwise-wy) : kernel fp16 serial validé (oracle 28/28, `hvx_vec_mpyacc_f32_f16`, état fp16 paddé-64, aucune dérive à 256 tok — le gate exp(g<0) borne), gardé derrière env `KZ_F16` (défaut OFF = baseline f32 inchangé) ; kernel WY chunkwise conservé inutilisé comme base d'un éventuel batch-têtes. `GGML_HEXAGON_OPFILTER` existe sur ce fork ; profiler `GGML_HEXAGON_PROFILE` masqué par llama-bench (sortie DEBUG).
## 8. À FAIRE : quantize 4B IQ4_NL on-device + bench, brancher JNI, valider qualité FR. STT reste ORT-QAIRT. Détail commits : `git log`. ## 8. À FAIRE : quantize 4B IQ4_NL on-device + bench, brancher JNI, valider qualité FR. STT reste ORT-QAIRT. Détail commits : `git log`.

2
ql

@ -1 +1 @@
Subproject commit 35c9b1f39ebe5a7bb83986d64415a079218be78d Subproject commit 50e250d7bce09f3cf312c1f4eb97f62f17ce1acd