kazeia/FROZEN.md

235 lines
8.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Kazeia — Stack production figée
**Date du gel : 2026-05-02**
Ce document définit la stack **autorisée** de Kazeia. Tout composant non listé
ici doit être considéré comme **non autorisé** et ne doit pas être réintroduit
sans validation explicite + mise à jour de ce contrat.
---
## Emplacement des modèles (MAJ 2026-05-18 — chantier installeur Phase 0)
Les chemins `/data/local/tmp/kazeia/models/` et `/data/local/tmp/kazeia-et/`
cités ci-dessous restent **valides sur les tablettes de dev** (modèles poussés
par `adb push`). Ils sont désormais **résolus au runtime par `KazeiaPaths`** :
- si la racine `/data/local/tmp` existe et est non vide → elle prime (dev) ;
- sinon → stockage externe app `getExternalFilesDir("kazeia")/{models,llm}`,
rempli par l'installeur (modèles téléchargés depuis le Nextcloud).
Aucun composant n'est ajouté ni retiré — seul l'emplacement de chargement
devient dynamique. `KazeiaApplication.MODELS_DIR` / `.LLM_DIR` sont les points
d'accès uniques. Cf `project_kazeia_installer_updates`.
---
## STT — Speech-to-Text
### Composant figé
`com.kazeia.stt.WhisperHybridEngine` (542 lignes) — chemin **NPU only**
- Encoder + Decoder Qualcomm AI Hub HfWhisper KV-cache (Whisper-Small 12L/12H)
- Modèles tablette : `/data/local/tmp/kazeia/models/whisper-small-sm8750/`
(fingerprints MD5 dans `/opt/Kazeia/kazeia-stt-perf-validated/models/README.md`)
- Backend : ONNX Runtime QNN HTP V79 (Snapdragon 8 Elite)
- Performance validée : RTF 0.5 (audio 1.6 s → 825 ms)
- Override `<|translate|>``<|transcribe|>` actif (force transcription FR)
- Auto-détection layers/heads via `enc.outputInfo["k_cache_cross_0"]`
### Mel extractor figé
`com.kazeia.stt.MelExtractor` + `kazeia-android/app/src/main/jni/mel_extractor.cpp`
- HuggingFace-compatible WhisperFeatureExtractor en C++ pur
- 80 mels × 3000 frames, FFT 400, hop 160
### Wrapper v2 figé
`com.kazeia.v2.SttStage` — thin wrapper sur `WhisperHybridEngine`
### ❌ Interdit
- Pas de fallback CPU (`WhisperSttEngine`, `WhisperJni`, `whisper.cpp`) — supprimés
- Pas de fallback Android stock (`AndroidSttEngine`) — supprimé
- Pas d'autres backends (`WhisperLiteRtEngine`, `WhisperNpuSttEngine`) — supprimés
- Pas de Qwen3-ASR (1.7B GGUF cassé, 0.6B qualité FR insuffisante)
- Pas de `libwhisper.so` dans jniLibs — supprimé
---
## VAD — Voice Activity Detection
### Composant figé
**Détection RMS-énergie inline** :
- v1 : `KazeiaService.startContinuousListening()` — frame 1600 samples (100 ms),
threshold RMS=150, ≥ 300 ms speech, ≥ 800 ms silence end
- v2 : `com.kazeia.v2.VadStage` — réimplémentation propre du même algorithme
### ❌ Interdit
- Pas de Silero VAD (`SileroVadEngine.kt` + `silero_vad.onnx` — supprimés)
- Pas de `AudioCaptureManager.kt` — supprimé
- Pas de `core.VadEngine` interface — supprimée
- Cf `feedback_kazeia_vad_rms.md` : Silero plafonne à 5e-4 sur ce mic
---
## LLM — Large Language Model
### Composants figés v1 (legacy `KazeiaService`)
`com.kazeia.llm.ExecuTorchLlmEngine` (in-process)
- Modèle : `hybrid_llama_qnn.pte` symlink → `hybrid_llama_qnn_4b.pte` sur tablette
- Tokenizer : `tokenizer.json`
- Backend : ExecuTorch + QNN HTP NPU (in-process via PyTorch ExecuTorch JNI)
- Path : `/data/local/tmp/kazeia-et/`
### Composants figés v2 (`KazeiaServiceV2`)
`com.kazeia.v2.LlmCascadeStage` (mode mono-Speaker — temporaire RAM-budget)
- Spawn 1× `qnn_llama_runner --daemon_mode` via `ExecutorchDaemon`
- Modèle : `hybrid_llama_qnn_4b.pte` + `tokenizer.json`
- System prompt : SYS_SPEAKER (psychologue bienveillant, 1-2 phrases FR concises)
- Le code Thinker/cascade est conservé en commentaire pour restauration future
### ❌ Interdit
- Pas de `LlamaCppLlmEngine` (purgé 2026-04-29)
- Pas de `KazeiaLlmJni` (purgé 2026-04-29)
- Pas de Genie SDK (bug GQA Qwen3)
- Pas de cascade Thinker+Speaker SIMULTANÉE en cohabitation TTS (RAM OOM, cf
cleanup 2026-05-02)
- Pas de `LLM_BACKEND` constante / `_currentLlmModel` UI selector
### Restauration cascade complète : conditionné
À envisager **uniquement après** :
- Task #240 (libllama.so contre chraac-llama récent) → -30 % RAM/perf Talker+CP
- OU partage `.ptd` entre 2× 4B → -2.4 GB RAM
- OU phased loading opportuniste (cf `feedback_kazeia_vad_rms.md` non, l'analyse
RAM dans la conversation 2026-05-02)
- En attendant, mono-Speaker reste figé
---
## TTS — Text-to-Speech
### Composant figé
`com.kazeia.tts.Qwen3TtsEngine` — voie **ggml-cpu Talker + ggml-cpu CP + ggml C++ Decoder**
- Talker : `TtsTalkerCpuJni` linké contre `libllama.so` (in jniLibs)
- Modèle préféré : `talker_f32.gguf` (1.78 GB, fp32, élimine drift fp16)
- Fallback : `talker_f16.gguf`
- CP : `TtsCpCpuJni` linké contre `libllama.so`
- Modèle préféré : `cp_f32.gguf` (316 MB)
- Fallback : `cp_f16.gguf`
- Decoder : `libtts_decoder_ggml.so` static-linked contre **chraac-llama** ggml
(build : `kazeia-tts-decoder-ggml/build-android-static-chraac/`)
- GGUF : `qwen3tts_decoder.gguf` (340 MB)
- **RTF 0.96 mesuré 2026-05-02** (cf `kazeia-tts-perf-validated/`)
- Tokenizer texte : `Qwen3BpeTokenizer` (BPE byte-level Qwen2/Qwen3)
- Voice cloning : Damien (prefix 9 × 1024 + suffix 2 × 1024)
### API figée
- `synthesizeAndPlay(text, language)` — pour invocations one-shot
- `startStreamingSession()` / `enqueueSentence(text)` / `endStreamingSession()`
pour streaming sentence-par-sentence (utilisé dans v2.TtsStage)
### Wrapper v2 figé
`com.kazeia.v2.TtsStage` — wrapper streaming-session sur `Qwen3TtsEngine`
### ❌ Interdit dans le chemin de chargement
- Pas de chemin `cp_kv_v2 ONNX` (ligne 630-658 de Qwen3TtsEngine, gated sur
`!useCpuPath` 2026-05-02)
- Pas de `cp_et_runner` TCP (sub-process root, gated 2026-05-02)
- Pas de `talker_kv_cpu` ONNX fp32 (gated sur `!useCpuPath`)
- Pas de Hexagon talker / CP (`hexStartRunner`, `useHexagonTalker`) — pas dans
flux production
- Pas de `phrase_embeds.bin` cache (bypassed 2026-05-02 — provoquait dégénération)
### ❌ Interdit moteurs alternatifs
- Pas de `AndroidTtsEngine` — supprimé
- Pas de `ChatterboxTtsEngine` — supprimé
---
## Audio playback
### Composant figé
`com.kazeia.audio.AudioPlaybackManager` (54 lignes)
L'AudioTrack interne au streaming session du `Qwen3TtsEngine` (avec keepAlive
watchdog ColorOS) reste également figé.
---
## Build / Backends
### ggml — sources autorisées
| Composant | Source ggml autorisée | Build dir |
|---|---|---|
| **TTS Decoder** | `chraac-llama` (branch `dev-refactoring`, commit `897501a`) | `build-android-static-chraac` |
| TTS Talker (lib) | jniLibs `libggml-cpu.so` (`llama-upstream`, à migrer Task #240) | `kazeia-android/.../jniLibs/arm64-v8a` |
| TTS CP (lib) | idem | idem |
| STT | n/a (ONNX Runtime, pas ggml) | n/a |
**Critique** : ne JAMAIS pointer le décodeur TTS vers `whisper.cpp/ggml` ou
`llama-upstream/ggml` — sinon RTF passe à 1.4-1.5 (mesuré, cf
`kazeia-tts-perf-validated/docs/MEASUREMENTS.md`).
### Compile flags figés
```cmake
# TTS decoder (libtts_decoder_ggml.so)
-O3 -march=armv8.6-a+dotprod+fp16+i8mm+bf16 -fopenmp -static-openmp
GGML_CPU_ARM_ARCH=armv8.6-a+dotprod+fp16+i8mm+bf16
GGML_OPENMP=ON
BUILD_SHARED_LIBS=OFF
```
---
## Fichiers de référence persistants
- `/opt/Kazeia/kazeia-stt-perf-validated/` — doc + MD5 modèles STT/VAD
- `/opt/Kazeia/kazeia-tts-perf-validated/` — doc + libs `.a` + bench CLI
reproductible TTS (RTF<1)
- `/opt/Kazeia/chraac-llama/` fork ggml indispensable pour le décodeur TTS
- `/opt/Kazeia/kazeia-tts-decoder-ggml/build-android-static-chraac/` build
statique pointé par l'app
---
## Comment dégeler / modifier ce contrat
**Procédure obligatoire** avant de réintroduire un composant supprimé OU de
remplacer un composant figé :
1. Mesurer la perf du composant cible **vs** la voie figée (sur la même phrase
de test, même tablette, même gouverneur DVFS)
2. Démontrer que la nouvelle voie est strictement meilleure (perf, RAM ou
maintenabilité) avec des chiffres reproductibles
3. Mettre à jour ce `FROZEN.md` avec le nouveau composant + les chiffres
4. Mettre à jour `MEMORY.md` index + memory file pertinent
5. Documenter le commit/build SHA exact dans `kazeia-{stt,tts}-perf-validated/`
6. Conserver l'ancien composant comme `*.archive.kt` UN trimestre avant
suppression définitive (filet de sécurité rollback)
Sans ce processus, **ne pas modifier la stack figée**.
---
## Métriques de référence (2026-05-02)
| Domaine | Métrique | Valeur figée | Comment |
|---|---|---:|---|
| STT | Load total | 750-1035 ms | NPU encoder + decoder + mel filters |
| STT | RTF (audio 1.6 s) | **0.51** | mel + encoder + decoder NPU |
| VAD | Trigger end-of-speech | 800 ms après dernier audio > seuil | hardcoded |
| LLM | Mono-Speaker forward | ~22 tok/s | qnn_llama_runner subprocess |
| TTS Decoder | RTF (audio 4.48 s) | **0.96** | ggml C++ chraac-llama, standalone |
| TTS Pipeline complet | RTF | ~2.87 | bottleneck CP (Task #240 pending) |