Commit Graph

3 Commits

Author SHA1 Message Date
Richard Loyer 3775bbc37c chantier TTS CosyVoice3 + verdict R&D NPU
dist/cosyvoice/ : engine streaming chunk-causal (RTF 0.88, cache prompt block-causal,
  HiFT F16) + clonage vocal ECAPA + JNI + libs + exemple voix (damien.cvps)
dist/distill/ : pipeline distillation Reflow 2-NFE (train, export ONNX, eval)
dist/jni/ : CosyVoiceTtsEngine.kt + kazeia_cosyvoice_jni + maj engine/tts/speaker_encoder
dist/lib-cpu/ : libs ggml/llama CPU-only (contournement SELinux FastRPC untrusted_app)
dist/outetts/ : runner OuteTTS (écarté au profit de CosyVoice3)

R&D NPU (détail en mémoire) : QNN HTP exécute MAL le flow DiT de façon irréductible
hors-root (CPU-backend fidèle 0.74 vs HTP 0.14, même DLC ; chirurgie ONNX canonicalisée,
opt-level sans effet). Hexagon-MLIR open exécute GPT-2 correctement sur V79 -> QNN
backend coupable, pas le silicium. Ship = CPU RTF 0.88 ; bug-report Qualcomm = vrai levier.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 21:48:30 +02:00
Richard Loyer f4c6e1290c chantier B engine #3 : TTS lib audible + E2E in-app validé
Trois fixes pour que le pipeline engine TTS tourne dans l'app réelle :

- cp_inference: cp_keep_f16() retourne false par défaut. Garder les poids
  matmul CP en F16 faisait overflow les massive activations Qwen3 (>65504)
  -> NaN -> codes 0 -> audio inaudible. F32 = ref cp_runner bit-exact.
  KZTTS_CP_KEEP_F16=1 réactive l'ancien path (debug perf).
- tts_engine: arming EOS naturel gated derrière KZTTS_EOS_NATURAL (off par
  défaut). C'était un workaround de l'ère NaN qui tronquait la fin de phrase
  (frames 33/37). Depuis le fix F32 le talker se termine seul (cb0==codec_eos),
  frames 40/42. Masking + anti-repeat + hard-fallback conservés.
- kazeia_tts_jni: freopen stderr gated derrière KZTTS_STDERR_LOG (plus de
  redirection /sdcard par défaut en prod).
- build_kazeia_tts.sh: speaker_encoder.cpp + kazeia_mel.cpp ajoutés aux SRCS.

Validé E2E in-app : LLM lib (q35-lmq4 GGUF) + TTS lib coexistent sans
collision libllama, réponse FR audible jouée via AudioTrack 24kHz.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-03 22:37:47 +02:00
Richard Loyer 930f3c8c1f chantier B TTS #11: libkazeia_tts.so + Kotlin wrapper, JNI validé bout-en-bout
Refactor: tts_engine.{h,cpp} = API publique de l'engine TTS (load une fois,
synthesize N fois, free). État load-once dans struct TtsEngine (talker
model+ctx, CPState, Decoder, KzTextTokenizer, fixtures + embeds spéciaux
+ role_proj pré-calculé). KV cache talker reset via llama_memory_clear
au début de chaque synthesize -> appels indépendants.

tts_pipeline.cpp devient un thin CLI dessus (refonte sans changement de
sortie : WAV md5 identique au pré-refactor sur 'Bonjour je m'appelle Kazeia').

JNI bridge: kazeia_tts_jni.cpp expose 3 fonctions :
  Java_com_kazeia_tts_TtsJni_nativeLoad / Synthesize / Free
Signatures alignées avec TtsEngine.kt (companion loadLibrary 'kazeia_tts').
Build: build_kazeia_tts.sh -> b-jni/libkazeia_tts.so (~900 KB).

Test_engine_2calls (sans JNI) : 3 synth sur même instance, KV reset OK,
2 appels identiques -> WAV md5 identique, appel 3 différent -> codes
différents.

Test_jni_tts (harness JNI sans VM Java) : dlopen libkazeia_tts.so, JNIEnv
mock minimal (GetStringUTFChars/Release + NewIntArray/SetIntArrayRegion),
appels load + 2 synth + free. WAV md5 identiques aux runs directs. exit=0.

Empreinte tablette mesurée: ~3.5 GB par instance (talker f32 1.6 GB + CP
f16 mixte 250 MB + decoder 325 MB + vocab Qwen3 vocab_only 50 MB + fixtures
text_embed/tp_* 1.2 GB). Une instance par process.

RTF stable autour de 3.0 (CPU 6t), inchangé vs avant refonte.

Reste sur la liste initiale : tuning sampling (itératif à l'oreille).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 21:54:21 +02:00