Kazeia-engine/dist
Richard Loyer 4ad3b3716d chantier B STT #6 : 2 bugs critiques fixés grâce à l'A/B in-app du dev
L'A/B in-app du dev a révélé un bug grave que mon harness standalone ratait :
3/6 audios FR (elodie, richard, zelda) sortaient vides (0 tokens, EOT immédiat).

Investigation : reproduit en standalone (chaque audio dans son propre process)
- DONC PAS un bug d'enchaînement KV (mon code reset déjà self_k/v à chaque
  transcribe). Le dev avait une fausse piste qui m'a poussé à investiguer
  en profondeur côté algo decoder, ce qui a révélé les vraies causes.

Bug #1 : FFT zero-pad 512 vs DFT exact 400
- kazeia_mel utilisait next_pow2(N_FFT=400)=512 + FFT radix-2 zero-padded
- Conséquence : bins 0..200 du FFT 512 sont à fs/512=31.25 Hz/bin, alors
  que mel_filters.json est calibré pour fs/400=40 Hz/bin du DFT exact
- Spectre désaligné en fréquences -> mel cohérent sur voix graves (damien,
  jerome, sid) mais cassé sur voix avec hautes harmoniques (elodie,
  richard, zelda)
- Fix : DFT directe N=n_fft quand n_fft pas puissance de 2, FFT radix-2
  quand pow2 (TTS speaker encoder N_FFT=1024 reste rapide)
- Coût : mel 60 ms -> 220-320 ms (incontournable pour N_FFT=400)
- Fixe elodie après ce bug, mais richard/zelda restaient vides

Bug #2 : Pas de forced decoder prompt
- Sur audios borderline (énergie spectrale ambiguë), Whisper saute la
  prédiction de langue (top-1 step 0 = 50362 NOTIMESTAMPS direct au lieu
  de 50265 FR) et atteint EOT au step 1
- Trace step-0 logits richard : [50362:+25.1] [50265:+24.7] (0.4 diff)
- Solution standard HF whisper : forcer le prompt <SOT, |lang|, |task|>
  au lieu de laisser le modèle prédire les 3 tokens spéciaux
- IMPORTANT : NE PAS forcer <|notimestamps|> ; le decoder QAIRT pred
  timestamp_begin (50363) après <|transcribe|> et veut le mode timestamps.
  Forcer NOTIMESTAMPS cause un step 3 = EOT immédiat sur TOUS les audios.
- Fix : forced_prompt = [SOT, lang_tok, TRANSCRIBE_TOK], modèle décide
  timestamps vs notimestamps après. lang="auto" garde juste SOT.

Résultat après les 2 fixes : 6/6 audios FR transcrivent en texte cohérent
(damien/elodie/jerome/richard/sid/zelda).

Chiffres honnêtes (warm path, après fixes) :
- Mel : 220-320 ms (vs prod 189) — DFT plus coûteux mais correct
- Encoder : 60-86 ms (vs prod 125) — gain options QNN burst/v79/fp16
- Decoder/token : 12-13 ms (vs prod 23) — gain zero-copy + options QNN
- Total 21 tokens / 3s : ~620 ms (mesuré)
- Total estimé 22 tokens / 1.6s : ~546 ms (vs prod ~820, -33 %)

Les chiffres précédents (-45 %, mel 60 ms) étaient FAUX à cause du bug #1.
Le -33 % réel reste meilleur que prod mais l'écart s'est réduit.

A/B accuracy CER/WER vs WhisperHybridEngine reste à mesurer in-app par
le dev sur SES audios fixtures.

Modifs :
- kazeia_mel.cpp : ajout DFT directe pour n_fft non pow2
- stt_engine.cpp : forced decoder prompt + lang_to_token + flags KZSTT_QNN_*
  réglables runtime pour debug
- stt_cli.cpp : multi-audio sequence + KZSTT_DEBUG_STEPS pour trace logits

Crédit : sans le retour précis du dev sur les vides observés, ces bugs
étaient passé en checklist §9 et fait crash en prod.
2026-06-01 12:19:33 +02:00
..
decoder_patches chantier BigVGAN HMX Phase 2b: refactor sched-friendly + limite backend découverte 2026-05-29 14:05:35 +02:00
include chantier B STT #1 : S1 unification engine (mel partagé + skeleton stt + VAD C++) 2026-05-31 19:19:28 +02:00
jni chantier B STT #6 : 2 bugs critiques fixés grâce à l'A/B in-app du dev 2026-06-01 12:19:33 +02:00
lib chantier B STT #2 : S2 + S3 livrés (stt_engine ORT QNN + JNI + façade Kotlin + doc) 2026-05-31 22:15:58 +02:00
patches chantier B STT #5 : Action 1 dev — patch QNN options pour la prod gelée 2026-06-01 09:42:27 +02:00
scripts SE.1+SE.2+SE.3 partiel : speaker encoder pipeline POC bout-en-bout 2026-05-31 11:37:14 +02:00
CMakeLists.txt JNI bridge complet: generate() prefill+decode, build arm64 OK (libkazeia_engine.so 209K) 2026-05-24 21:58:00 +02:00
HANDOFF.md dist: audit intégrabilité HANDOFF — corrige passages périmés 2026-05-27 18:55:16 +02:00
INTEGRATION.md dist: bandeau HANDOFF source de vérité sur README/INTEGRATION (9B historique) 2026-05-26 23:34:15 +02:00
KAZEIA_ENGINE_OVERVIEW.md chantier B STT #2 : S2 + S3 livrés (stt_engine ORT QNN + JNI + façade Kotlin + doc) 2026-05-31 22:15:58 +02:00
MODELS.md dist: handoff intégration aligné décisions 26/05 (modèle q35-lmq4, perf, prompt) 2026-05-26 23:33:41 +02:00
PATCH_QNN_PROD.md chantier B STT #5 : Action 1 dev — patch QNN options pour la prod gelée 2026-06-01 09:42:27 +02:00
PERF.md dist: prefill HTP corrigé (SSM_CONV gate backend), JNI option C sans OPFILTER 2026-05-27 10:39:08 +02:00
PERF_ANALYSIS.md doc: PERF_ANALYSIS.md — diagnostic post-session, leviers triés ROI 2026-05-28 22:43:23 +02:00
PERF_CPU_OPTIMS.md doc: PERF_CPU_OPTIMS.md — bilan optims CPU, RTF 2.93->2.45 2026-05-29 17:30:54 +02:00
PERF_INFRA_TESTS.md tests infra HTP/HMX : verdict, le HTP n'est pas le bon outil pour TTS 2026-05-29 16:40:56 +02:00
PERF_VULKAN_TESTS.md Vulkan Adreno 830 testé : neutre au mieux, régresse au pire (commit aussi le code opt-in) 2026-05-29 22:28:16 +02:00
PITFALLS.md Doc complete: README+MODELS+PERF+PITFALLS, build nettoye 2026-05-24 21:59:56 +02:00
README.md dist: bandeau HANDOFF source de vérité sur README/INTEGRATION (9B historique) 2026-05-26 23:34:15 +02:00
STATUS.md dist: audit intégrabilité HANDOFF — corrige passages périmés 2026-05-27 18:55:16 +02:00
STT_INTEGRATION.md chantier B STT #6 : 2 bugs critiques fixés grâce à l'A/B in-app du dev 2026-06-01 12:19:33 +02:00
TTS.md Dist Kazeia-Engine: libs arm64+headers+JNI bridge+INTEGRATION/TTS doc; STT reste ORT 2026-05-24 21:55:01 +02:00
build_decoder_subproc.sh Decoder chraac en sous-process : -20% decoder, -9% pipeline, talker intact 2026-05-30 18:14:09 +02:00
build_ggml_vulkan.sh Vulkan Adreno 830 testé : neutre au mieux, régresse au pire (commit aussi le code opt-in) 2026-05-29 22:28:16 +02:00
build_kazeia_stt.sh chantier B STT #2 : S2 + S3 livrés (stt_engine ORT QNN + JNI + façade Kotlin + doc) 2026-05-31 22:15:58 +02:00
build_kazeia_tts.sh chantier B TTS #11: libkazeia_tts.so + Kotlin wrapper, JNI validé bout-en-bout 2026-05-28 21:54:21 +02:00
build_speaker_encoder.sh chantier B STT #1 : S1 unification engine (mel partagé + skeleton stt + VAD C++) 2026-05-31 19:19:28 +02:00
build_stt_cli.sh chantier B STT #2 : S2 + S3 livrés (stt_engine ORT QNN + JNI + façade Kotlin + doc) 2026-05-31 22:15:58 +02:00
build_stt_test.sh chantier B STT #1 : S1 unification engine (mel partagé + skeleton stt + VAD C++) 2026-05-31 19:19:28 +02:00
build_test_engine_2calls.sh chantier B TTS #11: libkazeia_tts.so + Kotlin wrapper, JNI validé bout-en-bout 2026-05-28 21:54:21 +02:00
build_test_tokenizer.sh chantier B TTS #10: tokenizer Qwen3 BPE via llama_tokenize, texte arbitraire 2026-05-28 21:21:53 +02:00
build_tts_pipeline.sh chantier B STT #1 : S1 unification engine (mel partagé + skeleton stt + VAD C++) 2026-05-31 19:19:28 +02:00
build_tts_pipeline_chraac.sh CH chraac-llama : -18% RTF (2.43 -> 2.04) via swap ggml source 2026-05-30 12:38:47 +02:00
llama-cli Dist Kazeia-Engine: libs arm64+headers+JNI bridge+INTEGRATION/TTS doc; STT reste ORT 2026-05-24 21:55:01 +02:00
package.sh dist: handoff intégration aligné décisions 26/05 (modèle q35-lmq4, perf, prompt) 2026-05-26 23:33:41 +02:00
system_fr.txt dist: handoff intégration aligné décisions 26/05 (modèle q35-lmq4, perf, prompt) 2026-05-26 23:33:41 +02:00
test_native Engine sur fork qualcomm: decode dense 15.5>pte, 3.5 ~11, KVq8+t4+fa+lm_head-Q4; prefill 93/285; RAG cross 24-28k 2026-05-26 15:53:14 +02:00

README.md

Source de vérité à jour = HANDOFF.md (26/05). Modèle tranché = q35-lmq4 (Qwen3.5-4B), 9B écarté. Les mentions de 9B/cascade ci-dessous sont historiques.

Kazeia-Engine — intégration kazeia-android

Moteur LLM (+ TTS) GGUF, sans .pte, fork llama.cpp upstream + backend Hexagon. Remplace ExecuTorch/Genie pour le LLM. STT reste ORT-QAIRT (inchangé). Prefill NPU / decode CPU. Modèle dense (Qwen3) plein NPU ; hybride (Qwen3.5 DDDA) GDN sur NPU corrigé.

0. Périmètre

Brique Avant Après
LLM Speaker/Thinker ExecuTorch .pte Kazeia-Engine GGUF
TTS Talker/CP ggml-cpu engine (Talker prefill HTP option.)
TTS Decoder libtts_decoder_ggml inchangé
STT Whisper ORT-QAIRT inchangé

1. Contenu du paquet

  • lib/ : libkazeia_engine.so (bridge JNI) + libllama.so + libggml{,-base,-cpu,-hexagon}.so + libggml-htp-v68/69/73/75/79/81.so (sélection auto = V79 sur Pad3). 168 MB.
  • jni/ : kazeia_engine_jni.cpp, EngineLlmEngine.kt. include/, CMakeLists.txt.
  • INTEGRATION.md (steps), TTS.md, MODELS.md, PERF.md, PITFALLS.md.

2. Build (5 étapes)

  1. lib/*.sokazeia-android/app/src/main/jniLibs/arm64-v8a/
  2. jni/kazeia_engine_jni.cppapp/src/main/jni/, include/*.h à côté
  3. EngineLlmEngine.ktcom/kazeia/llm/, System.loadLibrary("kazeia_engine")
  4. CMake: lib avec libllama+libggml+libggml-base, -march=armv8.6-a+dotprod+fp16+i8mm+bf16
  5. GGUF → external storage, paths via KazeiaApplication.LLM_DIR

3. Cascade — remplace LlmProcessor cascade

Thinker Guard-4B → 4 bullets ; Speaker 9B = SYS_KAZEIA+bullets. Mono-moteur, reset() entre tours. Prompts: voir RAPPORT_KAZEIA §8. --reasoning-budget 0 impératif (sinon ramble anglais) : EngineLlmEngine met thinking off. Mesuré: 9B>4B qualité, Speaker=9B.

→ MODELS.md (choix), PERF.md (chiffres), PITFALLS.md (params_fit, no tty, OOM 30B+), INTEGRATION.md (détail API). API: load/generate/reset/free.

VALIDÉ DEVICE 24/05

test_native (=logique generate bridge) sur Pad3: load 4B HTP+decode CPU+detok = OUT propre, exit0. Pipeline prefill-NPU/decode-CPU prouve end-to-end. dist/jni/test_native.cpp = harness reproductible. Bridge so: 4 symboles JNI + deps ok. Reste app: gradle+jniLibs+template chat.

v2 STATIC (collision libllama TTS resolue)

TTS Talker/CP linke vs son libllama.so -> conflit ABI. FIX: libkazeia_engine.so STATIC (llama+ggml+ggml-cpu+hexagon en .a, --whole-archive hexagon). NEEDED= libm/log/dl/c only, 42MB. Coexiste avec libllama TTS. Drop: libkazeia_engine.so + libggml-htp-v79.so. Valide device 4B HTP. Build: bstatic BUILD_SHARED_LIBS=OFF.

v3 utilisable: thinking-off bridge

generate(sys,usr,max): wrap ChatML + vide = stop reasoning, decode 4B 15tok/s ~5s/tour. test 4B: "Je suis desole..." 40s(load)+gen. signature 2-arg. cap maxTok 64. dist=libkazeia_engine.so static + htp-v79. #277 fix livre.

v4 USABLE: ngl0 CPU decode (vrai fix #277)

Hang in-app=0.21tok/s: ngl99 -> decode ping-pong NPU/GDN-CPU. FIX: n_gpu_layers=0 decode CPU pur 14tok/s. test 4B: reponse FR 4s/tour. dev avait raison: pas thinking. cap64 garde. Speaker=4B CPU ngl0. RAM 4.5G. dist=libkazeia_engine.so. utilisable, #277 debloque.