Kazeia-engine/dist/HANDOFF.md

55 lines
3.4 KiB
Markdown

# Kazeia-Engine — handoff intégration (MAJ 26/05/2026)
Point d'entrée unique. Remplace le LLM ExecuTorch/Genie par llama.cpp (fork ql) + Hexagon.
GGUF, pas de `.pte`. STT reste ORT-QAIRT (inchangé).
## Décisions figées cette session
- **Modèle Speaker = Qwen3.5-4B en variante `q35-lmq4.gguf`** (embeds en Q4 au lieu du Q6_K
par défaut → 2.38 GB, decode +5%, qualité ≈ Q4_0 mesurée). Choisi sur l'éval qualité
(`../eval/VERDICT.md`) : gagne le SAFETY (cite 3114/15) et la majorité du SUPPORT vs le dense.
- **9B écarté** (decode ~4-5 t/s réel, trop lent ; pas de gain qualité justifiant). Cascade
éventuelle = Guard-4B (thinker) + 4B (speaker), pas 9B.
- **Kernel GDN = chantier clos** : son calcul n'est PAS le goulot (cf RAPPORT_RD §7). Ne pas
y retoucher pour la perf. Decode au plafond BW CPU (~25 GB/s).
## État du bridge JNI (`jni/kazeia_engine_jni.cpp`) — ce qui est CÂBLÉ
Config déjà correcte et alignée :
- `n_threads=4`, `flash_attn=ENABLED`, `n_batch=512`, sampler **greedy**.
- Thinking OFF déterministe (ChatML + `<think></think>` vide injecté) → pas de ramble.
- API : `load(path,nCtx) → generate(h,sys,usr,maxTok) → reset(h) / free(h)`.
- **`n_gpu_layers = 0` → tout CPU** (pas de HTP). Choix après le ping-pong ngl99 (decode 0.2 t/s).
## ⚠ Les 2 décisions ouvertes (à toi, sur batterie pleine)
1. **Prefill : CPU-only vs HTP.** Le JNI est CPU-only → prefill ~18-19 t/s (sain). Le HTP fait
89.5 t/s mais n'est PAS câblé (le ping-pong vient du mono-contexte ngl99 qui renvoie le
decode sur NPU). Pour des tours psy courts, CPU suffit (prompt ~100-300 tok → 5-15 s). Pour
du RAG/long, il faudra un vrai split (prefill HTP → bascule decode CPU), non trivial en
mono-contexte llama.cpp. **Garder CPU-only tant que les prompts restent courts.**
2. **KV `q8_0` : à revérifier.** Le JNI met `type_k/v=q8_0`. Mesure (batterie faible, throttle)
a montré decode q8_0=6.6 vs KV-f16=10.8 plus tôt → le déquant KV pourrait coûter plus que
le gain BW à court contexte (même effet que la quant poids sous-Q4). **A/B f16 vs q8_0 sur
batterie pleine ; si f16 gagne, repasse `type_k/v=GGML_TYPE_F16`.** (q8_0 ne sert que la RAM
KV en long contexte.)
## Perf (chiffres sains — la tablette throttlait à 11% ce soir, à reconfirmer)
| | prefill | decode | RAM |
|---|--:|--:|--:|
| q35-lmq4 (JNI CPU-only) | ~18-19 (CPU) | **~10.8** (t4+fa, KV f16) | 2.4 GB |
| capacité HTP (si câblé) | 89.5 | — | +~3.3 ION |
## Système (prompt) — `system_fr.txt` fourni
Inclut les garde-fous (3114, pas de prescription) + 2 correctifs issus de l'éval :
tutoiement constant, et « ne présume pas du pire, fais préciser » (le modèle lisait
« le départ de ma fille » comme un décès). À passer tel quel en `sys` de `generate()`.
## Paquet à intégrer
- `lib/*.so``app/src/main/jniLibs/arm64-v8a/` (libkazeia_engine.so **statique** + ggml/htp ;
htp-v79 = celui de cette session, fp16 derrière env `KZ_F16` OFF par défaut = comportement inchangé).
- `jni/kazeia_engine_jni.cpp` + `jni/EngineLlmEngine.kt` + `include/` → projet app.
- `q35-lmq4.gguf` → external storage (2.38 GB, hors git ; le pousser ou le reproduire, cf MODELS.md).
- `./package.sh` réassemble `lib/` depuis le build `ql/b` + recopie le prompt.
## Détails
INTEGRATION.md (build/CMake), MODELS.md (modèle + recette), PERF.md (mesures+leviers morts),
PITFALLS.md (pièges vécus), STATUS.md (limites). Verdict qualité : `../eval/VERDICT.md`.