kazeia/FROZEN.md

8.9 KiB
Raw Permalink Blame History

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

# 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)