3.8 KiB
Kazeia-Engine
Moteur d'inférence LLM Snapdragon 8 Elite sans conversion .pte : charger
GGUF directement, NPU pour le prefill, CPU pour le decode. Mono-tablette,
local-first, sans root. Bench-driven : aucune décision sans chiffre reproductible.
Cibles & gabarits
- Qwen3-4B (dense, attn pleine) — tourne déjà sous ExecuTorch : decode 14-21 tok/s, TTFT 190 ms. Réf à approcher.
- Qwen3.5-4B (hybride DDDA×8 : 24 DeltaNet + 8 FullAttn, GDN, conv1d, SSM, head_dim 256, vocab 248k, tied embeds) — ExecuTorch ne sait pas l'exporter proprement. C'est lui qu'il faut bien faire tourner. Empreinte mémoire mini = priorité.
Verdict R&D (issu de briques + bench, ne PAS refaire l'erreur)
Sur SM8750, Qwen3.5-4B-Q4_0, decode M=1 = memory-bandwidth bound, pas compute. Mesures :
| Voie | Decode | Prefill | Statut |
|---|---|---|---|
llama.cpp CPU NEON (-dev none) |
16.5 tok/s | 75 | stable, ~67% BW |
| llama.cpp CPU+Hexagon auto | 16.5 | 159 | stable — prefill HMX |
| llama.cpp Hexagon-only | 3.6 | — | DSP seul = perdant decode |
| briques DSP-first custom | 5.3 | 26 | crash ~12min, abandonné |
| → Angle = NPU prefill / CPU decode, exactement ce que fait llama.cpp+chraac. Tout DSP-first sur decode plafonne (~5 tok/s) ; gros vocab + tied embeds bloque spec-dec. CPU NEON bat le HVX 3.4× sur Q6_K M=1. Bonus DDDA : 75% des couches O(1) → decode stable en long contexte. |
Base = llama.cpp upstream master (ne PAS forker chraac)
Upstream ggml-org/llama.cpp a le backend Hexagon officiel Qualcomm : libggml-hexagon (CPU) + HTP libggml-htp-v79.so (notre V79), sélection auto runtime, actif (avril 2026: Linux NPU, cumsum, argsort, op-batching). chraac = fork perso superseded. Decode CPU NEON mûr déjà là.
- ExecuTorch — référence à dépasser, pas dépendance.
briques-archive/+ mémoiresproject_briques_qwen35*— pièces : pièges V79 0x2e, q4x4x2/Q6_K valign, oracle ggml. À ne pas refaire DSP-first.- HW: i8mm+bf16+dotprod, PAS de SVE ; LPDDR5x ~77 GB/s, CPU ~25.
Le seul vrai trou = prefill GDN Qwen3.5 sur Hexagon
- Qwen3-4B prefill → HTP standard, flag de build, livré (159 tok/s). Qwen3.5 decode → CPU récurrent, livré. Qwen3.5 prefill: 8 FullAttn → HTP, 24 GDN → scan chunkwise, pas de kernel HTP (GDN fusionné = CUDA/Vulkan only). Decode toujours CPU pour les deux, verrouillé.
- ⚠
to_delete/llama.cppa déjàqwen3next+ggml_backend_hexagon_qwen35_compile: amorce GDN-HTP existante → BENCHER avant d'écrire un kernel. - Charge Kazeia: prefill 500-2000 tok/tour, CPU ~75 → 7-27s, HTP → 3-13s. Utile, pas vital.
Identité = faire tourner Qwen3.5-4B bien (tranché Richard, ambition haute)
Pas l'intégration minimale. Cible: Qwen3.5-4B near-ExecuTorch sur Pad3, mémoire mini, sans .pte. Decode=CPU verrouillé (16.5 tok/s, acquis). Bataille = prefill: pousser les 24 GDN sur HTP. Kernel GDN-HTP = sujet R&D, frontière kernel (aide assistant partielle: structure/debug, pas micro-optims bit-exactes).
- Rebuild upstream master + ggml-hexagon, valider htp-v79 + run 3.5-4B end-to-end CPU.
- Bencher
qwen35_compileHTP existant: 0%, partiel ou OK? décide écrire-vs-finir kernel. - Baseline prefill GDN CPU à battre. Mémoire <4 GB Q4_0/Q6_K-embeds. Itérer kernel si gap.
Source: /opt/Kazeia/to_delete/llama.cpp = upstream ggerganov + ggml-hexagon + htp + qwen35_compile, commit f0fe1058b. Backend Hexagon prod: libggml-hexagon (CPU) + libggml-htp-v79 (auto). Session HTP plafond 3.5GB → NDEV multi-device si >. NDK r27d, Hexagon SDK 6.5.0.0. Rebuild en cours.
Limite assistant
R&D LLM frontière (kernels HVX bit-exacts, quant) = aide partielle, je le dis au cas par cas.
GGUF/llama.cpp archivés vers /opt/Kazeia/to_delete. Git local: commits réguliers. — Richard & Damien.