Commit Graph

9 Commits

Author SHA1 Message Date
Kazeia Team ecda7b5715 chore(stt): retrait du backend STT "lib" (non utilisé/non validé)
Le backend STT "lib" (KazeiaSttAdapter → com.kazeia.stt.SttEngine → libkazeia_stt)
n'était jamais le défaut (sttEngine="prod"=Whisper) et restait non validé
(transcriptions vides/drift, A/B non mergé). Retiré :
- KazeiaService : dispatch STT simplifié → WhisperHybridEngine seul.
- archivés : KazeiaSttAdapter.kt, stt/SttEngine.kt, BenchQnnHarness.kt + libkazeia_stt.so
  (/opt/Kazeia/archive/2026-06-18_cosyvoice-bascule/stt-lib/).
- KazeiaApplication : trigger bench_qnn retiré.
- ConfigStore.sttEngine documenté vestigial.
- manifest jniLibs re-figé (18→17).
Gardés : WhisperHybridEngine (NPU, gelé), MelExtractor (mel_extractor), core.SttEngine.
Build vert.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 10:56:58 +02:00
Kazeia Team 66e81f0668 refactor(tts): bascule CosyVoice = seul TTS + purge legacy (≈322 Mo libs)
Bascule définitive vers CosyVoice (clonage vocal 9 langues, CPU-only) :
- ConfigStore défaut ttsEngine = "cosyvoice" ; KazeiaService dispatch CosyVoice
  uniquement ; chemins TTS-B/streaming Qwen3 retirés (CosyVoice = batch
  speakText qui streame en interne) ; KazeiaPipeline.speakText simplifié.

Purge du superseded (archivé /opt/Kazeia/archive/2026-06-18_cosyvoice-bascule/) :
- Kotlin tts/ : Qwen3TtsEngine, KazeiaTtsEngine, TtsEngine(lib), TtsPipeline,
  Qwen3TtsGgmlDecoder, TtsTalkerCpuJni, TtsCpCpuJni, NeonOps, BenchTtsHarness,
  Qwen3BpeTokenizer. (Gardés : CosyVoiceTtsEngine, SentenceStreamer, core.TtsEngine.)
- v2/ (rewrite abandonné) + entrées manifest ChatActivityV2/KazeiaServiceV2.
- Handlers d'intents dev Qwen3 (run_pipeline/stream_*/full_pipeline/decode_codes).
- jniLibs (-322 Mo) : libexecutorch_jni(185M), libexecutorch, libtts_pipeline(51M),
  libQnnGpu*(3), libkazeia_tts, libfbjni, libllama-common(74M).
- CMake : neon_ops/tts_talker_cpu/tts_cp_cpu/tts_decoder_ggml + ggml/llama IMPORTED
  (gardé : mel_extractor pour STT).
- Gradle : executorch.jar + fbjni + soloader.
- Manifest jniLibs re-figé (27→18 libs).

Survivants prod : LLM GGUF (kazeia_engine+llama+ggml) + LLM .pte (kazeia_pte+QnnHtp)
+ STT (kazeia_stt+ORT+mel_extractor) + TTS (cosyvoice). Build debug+release vert.

Bump 0.2.2 / versionCode 14.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 09:07:41 +02:00
Kazeia Team d1baacd096 refonte(llm): Phase 3 — archivage code mort (Genie + EngineLlmAdapter)
Après analyse de dépendances : l'essentiel d'ExecuTorch/QNN est VIVANT via le
TTS Qwen3TtsEngine "prod" (org.pytorch.executorch.Module → libexecutorch.so,
+ libQnnGpu.so backend Adreno, + QnnHtp). NE PAS archiver (stack TTS figée).

Réellement mort (refonte LLM) → archivé dans
/opt/Kazeia/archive/2026-06-17_refonte-engine/ :
- EngineLlmAdapter.kt (ancien adaptateur GGUF, remplacé par UnifiedLlmAdapter ;
  références restantes = commentaires uniquement)
- GenieJni.kt + genie_jni.cpp + libGenie.so (backend Genie mort ; libgenie_jni.so
  n'était même plus shipé → GenieJni ne pouvait plus se charger)
- cible CMake genie_jni retirée ; manifest jniLibs re-figé (27 libs, -libGenie)

Aussi : ConfigStore.llmEngine documenté comme VESTIGIAL (le dispatch passe par
UnifiedLlmAdapter magic-byte depuis la refonte ; modèle choisi par speaker.modelId).

Build release vert ; LLM device non-régressé (GGUF 18 / qwen3-4b .pte 18.6 /
guard4b .pte 21 tok/s) ; aucune lib genie dans l'APK.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 23:28:14 +02:00
Kazeia Team 0a72654093 refonte(llm): moteur LLM unifié GGUF + .pte NPU (UnifiedLlmAdapter)
Remplace la couche LLM par la dernière version de kazeia-engine
(cf dist/LLM_INTEGRATION.md). Chargement par magic-byte :
- GGUF ("GGUF"@0)  -> EngineLlmEngine (libllama CPU i8mm, session cache-préfixe KV)
- .pte  ("ET12"@4) -> PteLlmEngine (ExecuTorch+QNN, NPU V79, sans root)

- LlmLoader.kt copié de l'engine + fix encode DJL (encode(p,false,false))
- UnifiedLlmAdapter : pont com.kazeia.core.LlmEngine, generateWithSystem par tour
- ModelRegistry : 5 modèles (Qwen3.5-4B GGUF défaut + 4 .pte en sous-dossiers)
- KazeiaService recâblé ; DEFAULT_SYSTEM_PROMPT -> ConfigStore.DEFAULT_SPEAKER_PROMPT
- DJL tokenizer arm64 Android : tokenizers + tokenizer-native alignés 0.33.0
  (natif libdjl_tokenizer.so dans l'AAR ; natifs desktop exclus, -23 Mo APK)
- jniLibs : +libkazeia_pte.so, +libQnnHtpNetRunExtensions.so,
  libqnn_executorch_backend.so -> QAIRT 2.42 ; manifest re-figé (28 libs)
- fichiers morts archivés (ExecuTorchLlmEngine, GenieLlmEngine)

Phase 1 (#287) : build debug green. Phase 2 = validation device.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 22:47:32 +02:00
Kazeia Team 3b58fcb467 feat(tts): CosyVoice rapide (hiftf16, RTF 0.88 + cache) + guard init — v0.1.10
Nouveau jeu CosyVoice livré par l'engine (mêmes 5 symboles JNI, façade inchangée,
toujours auto-contenu) : 2 .so swappés (libkazeia_cosyvoice + libcosyvoice ;
libomp/libc++_shared identiques). Modèle cv3_distilled_30k_hiftf16.gguf (953 Mo)
remplace cv3_distilled_30k.gguf — MODEL mis à jour dans l'adaptateur.

Validé device : charge OK, synthèse OK, cache de voix entre appels →
1er son tour 1 ~10,6s → tour 2 ~6,7s (-37%). (RTF dev annoncé 0.88 ; sur cette
tablette thermiquement saturée on mesure ~1,1-1,7 — à revérifier device froid.)

Bonus robustesse : guard `if (!::voiceCommands.isInitialized) return false` dans
handleVoiceCommand — une entrée arrivée avant la fin de l'init du service ne
crashe plus (UninitializedPropertyAccessException, vu en test en tirant un intent
trop tôt).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 23:50:42 +02:00
Kazeia Team b822974b99 fix(llm): sessionReset natif corrigé (archi hybride) — reset de borne propre — v0.1.8
Bug : sessionReset()+sessionAsk() renvoyait VIDE. Cause = q35-lmq4 est l'archi
hybride Qwen3.5 (DeltaNet/SSM) ; llama_memory_seq_rm d'un suffixe « Returns false
if a partial sequence cannot be removed » (l'état récurrent ne se rembobine pas
partiellement). Le code ignorait ce retour → KV incohérent → tour suivant vide.

Fix natif (kazeia-engine dist/jni/kazeia_engine_jni.cpp, .so rebuildé CPU-only,
drop-in) : sessionReset teste le retour de seq_rm ; s'il échoue (récurrent/
hybride) → reset COMPLET (llama_memory_clear + re-prefill du system mémorisé) +
llama_sampler_reset. sessionStart mémorise désormais les tokens system.

App : EngineLlmAdapter.resetSession() rebascule sur le session.reset() natif
(au lieu du contournement newSession). Validé device : après reset, le tour
n'est plus vide ET la mémoire est effacée (ne connaît plus le prénom),
prefill ~285ms, decode ~17 tok/s, tours suivants OK.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 11:26:00 +02:00
Kazeia Team 8d548b1ca6 feat(llm): session cache-préfixe KV + streaming + mémoire conv. — v0.1.7
Intègre les 3 APIs livrées par l'engine (libkazeia_engine.so drop-in, façade
EngineLlmEngine.kt : generateStream / newSession / LlmSession / GenStats).

EngineLlmAdapter : crée une LlmSession au load (system prefillé 1×), et chaque
generate() fait session.ask() en STREAMING (onToken câblé au pipeline existant).
Le system n'est plus re-prefillé à chaque tour.

Mesuré device (q35-lmq4, t=6, v0.1.7) :
- tour : 2991→~1100 ms (prefill 2700→~300 ms, system caché). Decode réel
  17 tok/s (le « 3,2 » était l'artefact prefill-inclus ; tps vient maintenant
  de getLastStats, débit décode).
- streaming callback OK sous vraie JVM (le seul point que le dev n'avait pas
  pu tester) — aucun crash.
- mémoire conversationnelle (bonus) : rappelle « Richard » sur 3 tours.

Confidentialité : la mémoire est vidée aux bornes de conversation —
EngineLlmAdapter.resetSession() (recrée la session) appelé sur CLEAR_CHAT et
sur changement de profil actif (onProfileStoreChanged). Validé : après switch
de profil, le LLM ne connaît plus le prénom.

⚠ Bug natif à corriger côté engine : sessionReset()+sessionAsk() renvoie vide
(n_past non restauré à n_sys après seq_rm). Contourné en recréant la session
(newSession). Le mode mémoire (ask→ask sans reset) est, lui, OK.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 11:12:11 +02:00
Kazeia Team cca38ef50f feat(tts): intégrer libs CosyVoice3 auto-contenues + validation device — v0.1.4
Blocage libggml levé côté engine : nouvelles libs auto-contenues (ggml statique
+ visibilité hidden dans libcosyvoice.so, 0 symbole ggml_ exporté). 3 .so ajoutés
à jniLibs/arm64-v8a/ (libkazeia_cosyvoice, libcosyvoice ~20 Mo, libc++_shared ;
libomp déjà présent identique). Manifest régénéré (26 libs).

Validé on-device (release v0.1.4, SM8750) :
- chargement libkazeia_cosyvoice.so OK, modèle cv3_distilled_30k.gguf chargé en
  997 ms, voix 'damien' chargée, aucune collision libggml ni crash.
- nativeSynthesize (le marshalling JNI String→FloatArray, seul point non testé
  par le dev) CONFIRMÉ : phrase FR → 214080 samples 24 kHz (8.92 s), RTF ≈ 1.0.
  Audio sain (RMS 2303, pic 19741, 51% non-silence), voix clonée audible.

jniLibs gitignorés (whitelist) : seul le manifest est versionné. Tarball
build-artifacts à régénérer pour les machines tierces (suivi).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 21:31:42 +02:00
Kazeia Team 9c6f4e8838 build: reproductibilité des jniLibs — manifest sha256 + script + garde release
Les 23 .so de app/src/main/jniLibs/ (474 Mo, 5 chaînes de build : kazeia-engine,
ExecuTorch, QNN SDK 2.42, Genie, TTS pipeline) sont des artefacts gitignorés
posés à la main — « ça ne buildait que sur cette machine ». On ne les versionne
pas (l'historique gonflerait de ~500 Mo par update engine) ; on versionne leur
DÉFINITION :

- scripts/jnilibs.MANIFEST.sha256 : état attendu (sha256 + provenances).
- scripts/jnilibs.sh : verify (CI/Gradle) | sync-engine (rafraîchit le
  sous-ensemble kazeia-engine depuis /opt/Kazeia-engine/dist) | update-manifest
  (re-fige, à committer) | export/import (tarball pour autre machine).
- Garde Gradle : preReleaseBuild dépend de verifyJniLibs → un build RELEASE avec
  des libs manquantes/modifiées/non déclarées ÉCHOUE. Debug reste libre.

Validé : release passe avec libs conformes ; échoue sur lib altérée (MODIFIÉ
libomp.so) ; verify OK après restauration. Ménage au passage : 3 .bak morts
(~293 Mo) sortis de jniLibs vers _jnilibs_backup_baks/.

Nouvelle machine : git clone + ./scripts/jnilibs.sh import <tarball> (export
déposé sur box.kazeia.com privé) → build garanti conforme.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 09:31:00 +02:00