Commit Graph

32 Commits

Author SHA1 Message Date
Richard Loyer 9ef5e11b53 chantier B TTS #6: P3.4+P3.5 = pipeline complet 100% tablette bout-en-bout
tts_pipeline.cpp : binaire unique qui orchestre TOUT en un seul process :
  input_ids + x_vector (fixtures)
    -> text_projection + lookups + spéciaux (P3.2) -> prefill_embeds [T, 1024]
    -> Talker engine (libllama, M-RoPE IMROPE, Patch 1+2) -> logits + hidden
    -> sampling top_k+temp sur CB0 (le greedy pur tombe dans un attracteur :
       cb0 répété -> decoder produit du silence. temp=0.9 top_k=50 = défauts
       Python, débloquent l'attracteur)
    -> CP runner (cp_inference, recompute bit-exact) -> CB1..15
    -> sum 16 codecs + tts_pad -> next embed (orchestration ggml-side, bit-exact)
    -> codes [N, 16] -> decoder ggml (libqwen3tts-decoder rebuilt vs ql/ggml,
       evite conflit double-ggml) -> WAV PCM 24kHz

Sortie : Bonjour je m'appelle Kazeia, 32 frames -> 2.56s audio audible
(rms=0.040, range [-0.26, 0.29]). 100% tablette : pas de Python, pas de root,
pas de QNN. Stack unifiee ggml.

Bench tablette CPU 6 threads (sweet spot, 8 = contention scheduler) :
  load total       :  1.12 s  (talker f32 + cp + decoder + fixtures)
  Talker prefill   :  0.10 s
  Loop (N=32)      :  8.57 s   talker_decode=1.01 cp=7.55 (talker 31ms/step, cp 236ms/step)
  Decoder          :  5.32 s   (RTF dec 2.00)
  TOTAL            : 14.00 s pour 2.67s audio -> RTF 5.25

Gros leviers perf restants pour RTF<1 (P3.5 itératif, dehors session) :
- KV cache CP : 15 passes/step recompute O(L^2) -> incremental O(L). Estimation
  gain x5-8 sur CP. Tentative cette session = abandonnee (risque casser bit-exact).
- Decoder ggml : histo chraac 0.96 prouve realisable, faut tuner.
- Threads big cores via taskset (Pad3 SD8Elite 8 cores big, scheduler ne route
  pas tjrs au mieux).

Q8_0 CP teste -> perd la precision (76% codes match vs 100% f16) ; sampling et
CP en f16 reste necessaire (confirme observation rapport TTS avril : modeles RVQ
incompatibles avec quantization).

Decoder ggml rebuilte au passage avec ggml engine : kazeia-tts-decoder-ggml/
build-android-engine/ -> libqwen3tts-decoder.a sans conflit symboles. Patch
mineur build-time, pas de modif source decoder.

P3.4 (libkazeia_tts.so JNI assemblage Kotlin) : reporte en session future, le
code de tts_pipeline.cpp est l'implementation reference a wrapper en JNI.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 15:25:00 +02:00
Richard Loyer 746bbe77cd chantier B TTS #5: P3.3 = vrai CP runner intégré (bit-exact)
cp_inference.h/cpp : extrait de cp_runner.cpp standalone (kazeia-tts-decoder-ggml/),
adapté en module réutilisable. Architecture identique (qwen3 5L, GQA 16/8, head_dim
128, RoPE NEOX theta=1e6, q/k-norm AVANT RoPE, recompute T<=16 sans KV cache).
API : cp_load() + cp_predict(hidden[1024], cb0_emb[1024]) -> int32[15] = CB1..CB15.

cp_validate.cpp : reproduit sur tablette les conditions du standalone cp_runner
-> 495/495 codes match (33/33 frames parfaits) vs cp.generate(do_sample=False)
greedy golden, sur les 33 frames du dump 'Bonjour' historique. CP intégré =
bit-exact au standalone, qui est lui-même bit-exact à PyTorch.

tts_orchestrate.cpp mis à jour : si cp_f16.gguf/cp_heads/cp_codec_embs présents
dans <dump_dir>, le CP est ENABLED et remplace le teacher-forcing CB1..15.
Hidden state Talker capturé via llama_get_embeddings_ith(ctx,-1) après chaque
decode_embeds (pas besoin de re-instrumenter le forward Talker).

Mesure sur 'Bonjour je m'appelle Kazeia' (N=26 frames, audio 2.17s) tablette CPU 4t :
  Talker prefill (T=19) : 0.124 s
  Loop (N=26 steps)     : 7.705 s   talker_decode=0.763, cp=6.942
    per-step talker     : 29.3 ms
    per-step CP (15 pass): 267.0 ms
  Total Talker+CP       : 7.829 s -> RTF talker+cp = 3.61

Le CP est le nouveau goulot (267ms × 15 passes/step). Levier P3.5 = KV cache CP
(recompute -> incremental), threads 8, ou Q8_0 du CP.

CB0 match golden = 3/26 = trajectoire stochastique Python diverge rapidement vs
notre greedy ; PAS un bug CP (cp_validate prouve la conformité bit-exact).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 15:11:07 +02:00
Richard Loyer 7a998dec6b chantier B TTS #4: P3.1+P3.2 = x_vector + prefill_embeds depuis input_ids (bit-exact)
P3.1 - x_vector Damien dumpe offline : tts.model.extract_speaker_embedding(damien_15s_24k.wav)
-> f32[1024] = 4 KB. Embed dans l'app comme ressource. Pas de port du speaker
encoder Python (8.9M params), voix fixe = pre-calcul trivial.

P3.2 - reproduction C++ de la construction Python des talker_input_embeds.
Reference modeling_qwen3_tts.py:2124-2233 (mode x_vector_only + non_streaming).
Sequence prefill (19 positions pour 'Bonjour je m'appelle Kazeia', 8 tokens texte):
  0..2  : text_projection(text_embed[input_ids[:3]])                  role <im_start>assistant\n
  3..7  : tts_pad + tok_embd[think/think_bos/lang_fr/think_eos/x_vec]  5 positions codec prefix
  8     : tts_bos + tok_embd[codec_pad]                                 1 position
  9..N+8: text_projection(text_embed[input_ids[3:-5]]) + tok_embd[codec_pad]   text body
  N+9   : tts_eos + tok_embd[codec_pad]
  N+10  : tts_pad + tok_embd[codec_bos]
ou tts_*_embed = text_projection(text_embed[tts_bos/eos/pad_token_id]).chunk(3).

Composants : text_embed [151936, 2048] f32 (1.21 GB, a quantiser en P3.5),
text_projection ResizeMLP(2048->2048->1024, SiLU, bias=True), tok_embd talker
[3072, 1024], x_vector [1024], constants (special token ids).

Validation host (g++ -O2) sur phrase 'Bonjour je m'appelle Kazeia' :
  mean_rmse = 3.2e-8, max_abs = 1.8e-6 sur les 19 positions vs prefill_embeds
  capture du dump Python -> noise pure du f32 (eps ~1.2e-7).
Construction bit-exact.

Reste pour usage texte arbitraire : tokenizer BPE Qwen3 en C++ (llama_vocab
supporte cela en standard, a brancher en P3.4 quand on assemble la lib finale).
Pour l'instant input_ids dumpes depuis Python pour 1 phrase fixe = suffisant
pour P3.3 (integration CP) et P3.4 (assemblage).

Fixtures /opt/Kazeia/tts_talker_dump/ : text_embed.bin, tp_fc1_w/b.bin,
tp_fc2_w/b.bin, damien_xvector.bin, input_ids_full.bin, manifest_text.txt.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 15:05:23 +02:00
Richard Loyer 2e0b145b51 chantier B TTS #3: orchestration ggml-side bit-exact + WAV E2E sur tablette
Le binaire dist/jni/tts_orchestrate.cpp boucle :
  prefill talker (talker_f32.gguf via engine) -> greedy CB0 depuis logits engine
  -> CB1..15 teacher-forces depuis codes_golden (CP non encore integre, mais
     deja valide bit-exact standalone)
  -> next_embed = talker.tok_embd[CB0] + sum_i cp_codec_embs[i-1, CB(i)] + tts_pad
  -> talker.decodeEmbed(next_embed) -> repeat
  -> dump codes_engine [N=26, 16] sur disque

Resultats end-to-end ('Bonjour je m'appelle Kazeia', N=26 frames, ~2.08s audio) :
  pipeline ggml-side sur tablette (talker engine + decoder existant) :
  - codes engine vs codes Python : 7/26 frames divergent (CB0 only) = sampling
    stochastique Python (subtalker_dosample temp=0.9) vs greedy engine. Attendu.
  - next_embed engine vs step_inputs_py: rmse=0 cos=1.000 a chaque step ou
    CB0 matche -> orchestration sum+pad strictement bit-exact.
  - WAV decoder tablet sur codes_golden vs PY_REF : cos=0.999999, rmse=3.9e-5
    (juste du noise int16 quantization, bit-exact pratique).
  - WAV decoder tablet sur codes_engine vs PY_REF : cos=0.999200, rmse=3.8e-3
    -> divergence audio uniquement du sampling, son audible et coherent.
  - WAV tablet vs host (memes codes) : cos=1.000000 -> decoder ggml deterministe.

Le seul ecart restant (cos=0.9992 engine vs PY_REF) est purement strategique
(sampling vs greedy), pas implementation. Engine ggml-side prouve fonctionnel.

Reste pour P3 finition (sessions suivantes) :
- Integrer le vrai CP runner (cp_runner.cpp) -> remplace teacher-forcing CB1..15
- Speaker Encoder x-vector (8.9M params) OU pre-calcul offline
- BPE tokenizer Qwen3-TTS + text_projection -> production prefill_embeds depuis texte FR
- Assemblage final en JNI (libkazeia_tts ?) utilisable depuis l'app Kotlin

Dump tools: /opt/Kazeia/tts_talker_dump/dump_talker.py (step I/O + logits)
            /opt/Kazeia/tts_talker_dump/dump_talker2.py (pad/bos/eos/codes/tables)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 14:25:18 +02:00
Richard Loyer 12df0d0ba3 chantier B TTS #2: fix M-RoPE positions en embeds-mode + validation bit-exact
Bug subtil dans llm_graph_input_pos::set_input (llama-graph.cpp:121-123) : pour
M-RoPE (n_pos_per_embd=4), la conversion 1D->4D des positions n'est faite QUE
pour ubatch.token. En embeds-mode (ubatch.embd != nullptr), la branche else fait
un memcpy raw de ubatch.pos avec taille T*4, lisant T*3 entiers out-of-bounds
au-dela du buffer T-only que j'allouais. -> positions garbage -> sortie cassee
(cos=-0.02 vs Python avant fix, soit pire qu'aleatoire).

Fix cote JNI (chantier P1) : detecte rope_type via llama_model_rope_type et
alloue T*4 positions quand MROPE/IMROPE, en remplissant les 3 premiers axes
avec la position et le 4eme avec 0 (text-only) -- exactement ce que le framework
fait pour les tokens. Memoire : decode_embd_batch dans kazeia_engine_jni.cpp.

Smoke test bit-exact Python vs engine (test_talker_replay.cpp, teacher-forced) :
- 19 positions prefill + 26 steps decode sur talker_f32.gguf (Bonjour je m'appelle Kazeia)
- hidden : mean_cos=1.000000, mean_rmse=2.9e-3
- logits : mean_cos=1.000000, mean_rmse=1.8e-3
- argmax engine == argmax Python sur les 26 steps (info only -- la divergence
  RMSE residuelle est du f32 noise, ordre de sommation).

Le port Talker engine est valide bit-exact (precision f32) sur tablette CPU.
Reste P3 etape 3 : orchestration finale (BPE tokenizer + x-vector encoder +
cablage CP runner + decoder ggml) en mode standalone.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 13:54:03 +02:00
Richard Loyer 50814f3bca chantier B TTS #1: API JNI embeds-only + M-RoPE qwen3 dense
Premières 2 pieces du chantier B (porter le Talker Qwen3-TTS sur l'engine
pour TTS standalone tablette, sans dépendre du pipeline Python).

P1 - API embeds-only dans le JNI (dist/jni/kazeia_engine_jni.cpp)
Le Talker a vocab=3072 codes audio (pas de BPE), entrée = embeds
pré-mélangés (text+x-vector au prefill, sum 16 codecs + tts_pad au decode),
sortie = logits[3072] + hidden[1024] (pour le Code Predictor).
Solution: pas un appel monolithique, 5 primitives qui laissent l'orchestration
côté caller:
  - nEmbd(h), nVocab(h) - dimensionnement des buffers Kotlin
  - resetEmbeds(h)       - KV clear + pos=0
  - prefillEmbeds(h, embds[T*n_embd], T, outHidden[n_embd])
  - decodeEmbed(h, embd[n_embd], outLogits[vocab], outHidden[n_embd])
Implementation: llama_set_embeddings(ctx, true), llama_batch.embd au lieu
de .token, logits=1 sur la derniere position seulement (economie KV).
KEngine porte un compteur pos_embd interne. Kotlin wrapper miroir dans
dist/jni/EngineLlmEngine.kt.

P2 - M-RoPE qwen3 dense (sous-module ql, commit c1609a1)
Pointeur sous-module avance pour embarquer le support.

Validation device: dist/jni/test_talker.cpp charge talker_f32.gguf, lance
llama_decode embeds-only T=4 prefill puis 1 step, recupere hidden+logits
sans crash. Log device: print_info rope_type=8, mrope sections=[24,20,20,0],
prefill OK / step OK. argmax stable (entree bidon, juste smoke).

Libs rebuiltes: dist/lib/libllama.so + libkazeia_engine.so + libggml-base.so.
Reste P3 = cablage Talker->CP->Decoder cote orchestration.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 13:37:17 +02:00
Richard Loyer 97180b29a6 dist: audit intégrabilité HANDOFF — corrige passages périmés
- libkazeia_engine.so = SHARED (pas statique) -> shipper tout lib/ ensemble (ABI #277)
- KV f16 déjà rebuildé dans le .so livré (la note 'rebuild/q8_0' était stale)
- OPFILTER obsolète (fix SSM_CONV dans backend) -> libellés B/C + tableau nettoyés
- note instrumentation OPLOG/DUMP dormante dans libggml-hexagon.so (zéro-coût)
Paquet vérifié: 5 symboles JNI, source f16+routing arch conformes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 18:55:16 +02:00
Richard Loyer 464d4e69c0 chantier dense-HMX: avancement #2 (replay) — root = fault HMX non-déterministe, instrumentation DSP requise (bloquée sans root). Tools committés.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 14:35:14 +02:00
Richard Loyer 224b375a10 chantier dense-HMX: avancement — ni magnitude, ni NaN, ni shape pure (value/context-spécifique)
3 hypothèses éliminées par mesure: overflow fp16 (act=9.8), NaN/Inf inputs (0), shape pure (isolation
synthétique k=4096 ne crashe pas). Op fautive = o_proj MUL_MAT q4_0 k=4096 après FLASH_ATTN_EXT.
Prochaines étapes révisées (dump-and-replay value-vs-context, instrumentation DSP log-vers-buffer).
OPLOG mis à jour (nan/inf) dans dist/lib. ql -> commit OPLOG.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 14:09:52 +02:00
Richard Loyer 5aa4457567 chantier: instrumentation crash dense-HTP-HMX + .pte retiré (engine seul runtime)
CHANTIER_HMX_DENSE.md: analyse + outils pour le crash matmul HMX dense. Finding: PAS un overflow
fp16 (activation du matmul fautif = 9.8) — c'est un bug de tiling/buffer HMX pour k=4096 (o_proj
après FLASH_ATTN_EXT). Localisé via OPLOG CPU-side (FARF DSP bloqué sans root). Étapes + repro documentés.

HANDOFF: .pte retiré -> engine seul runtime LLM. Dense=HVX (40) sur l'engine; HMX (295)=ce chantier.
dist/lib refreshé (libggml-hexagon.so avec OPLOG dormant, htp-v79 propre). ql -> 7d4cade.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 13:29:32 +02:00
Richard Loyer 0407ac8b71 dist: ROOT CAUSE crash dense-HTP = matmul HMX (fp16) ; fix = HVX pour le dense
Analyse complète (méthode SSM_CONV) du crash dense-HTP:
- bench HTP synthétique (pp512, +tg8) = OK ; cli/engine texte réel crashe 0x2e > ~14 tokens.
- OPFILTER bisect: SOFT_MAX/ROPE/RMS_NORM/GET_ROWS/CPY/CONT/ADD n'arrêtent PAS le crash ; MUL_MAT->CPU OUI.
- GGML_HEXAGON_USE_HMX=0 (matmul HVX) supprime le crash, =1 le reproduit. => le matmul HMX (fp16 tile)
  faute sur les activations réelles du dense (massive activations Qwen3 > plage fp16 ; bench synthétique
  ne déclenche pas l'overflow). Analogue du SSM_CONV pour la 3.5, mais ici c'est le matmul HMX coeur.

Câblage: lecture general.architecture dans le GGUF AVANT init backend -> hybride (qwen35/qwen3next):
HMX on + option C (préservé) ; dense: USE_HMX=0 + HTP contexte-unique (HVX, ~40 prefill =3x CPU, decode ~11,
stable). Repli CPU si pas de HTP. Validé test_jni_native: dense (HVX HTP) + 3.5 (option C) cohérents.
TODO backend: matmul HMX robuste aux activations hors plage fp16.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 12:42:15 +02:00
Richard Loyer c166391f49 dist: routage par structure (is_hybrid) — 3.5->option C, dense->CPU robuste
Détection au load via llama_model_is_hybrid/is_recurrent (structure, pas string d'archi):
- hybride GDN (qwen3.5/qwen3next) -> option C (prefill HTP/decode CPU), préservé+validé.
- dense (qwen3, etc.) / pas de HTP -> CPU pur (universel, robuste).
Charge l'instance CPU d'abord (détection + universel), n'ajoute l'instance HTP que pour l'hybride.

Diagnostic dense-HTP: le prefill dense sur HTP CRASHE (dspqueue_read 0x2e) sur prompt réaliste
(reproduit aussi en llama-cli -dev HTP0 -fa 1; le "ça marche" antérieur = prompt minuscule sans fa,
cas chanceux). Bug backend HTP attention dense multi-token, non corrigé. Dense a un .pte (451) de
toute façon -> dense=CPU robuste. Validé test_jni_native: dense (CPU) + 3.5 (option C) cohérents.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 12:30:43 +02:00
Richard Loyer eeffbc350f dist: JNI générique (auto-détecte archi) — tout LLM, sans dégrader la 3.5
Le JNI lit general.architecture: qwen35/qwen3next -> option C (prefill HTP/decode CPU, préservé
et revalidé cohérent+mémoire). Tout le reste (qwen3 dense, etc.) -> CPU pur (universel, jamais de
crash). Dense Qwen3-4B validé via le moteur (CPU, cohérent). 3.5 non régressée.

Diagnostic crash dense-HTP: ce n'est PAS le HTP (dense single-context HTP marche: cli 36.8/11.4
cohérent, llama-bench pp512=98). Le crash 0x2e (dspqueue_read, flush_pending) survient UNIQUEMENT
en dual-load (option C: 2 instances modèle) appliqué au dense. Or le dense n'a pas besoin de
l'option C (decode HTP 11.4 ≈ CPU 11.7, pas de pénalité GDN). Donc dense -> CPU (ou single-ctx HTP).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 12:11:44 +02:00
Richard Loyer 771d64a998 dist: multi-tour propre (generateRaw + ChatSession) + JNI validé end-to-end natif
Ferme les 2 derniers trous d'intégration:
- generateRaw(prompt) exposé (cœur option C partagé avec generate). EngineLlmEngine.kt: ChatSession
  gère l'historique + construit le ChatML Qwen3.5 validé -> multi-tour propre sans que l'app connaisse
  le template (structure identique à dual_ctx_mt).
- test_jni_native.cpp: dlopen + JNIEnv mock teste le .so shippé bout-en-bout sur device
  (load/generate/generateRaw/free). Résultat: FR cohérent + mémoire conversationnelle OK
  ("Marc, je me souviens parfaitement de ton prénom"). Marshalling JNI réel validé.
libkazeia_engine.so reconstruit (5 symboles). Paquet dist/ prêt à intégrer.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 11:18:20 +02:00
Richard Loyer 6935089459 dist: libkazeia_engine.so rebuild option C (paquet cohérent), notes rebuild MAJ
libkazeia_engine.so reconstruit depuis le JNI option C (37KB strippé, 4 symboles JNI, SHARED,
NEEDED llama/ggml/ggml-base/log/c++_shared). Le paquet dist/ est désormais interne-cohérent:
sources + prebuilts alignés (option C + fix SSM_CONV). Docs: prebuilts à jour, rebuild app-side
recommandé pour ABI/STL. Logique validée via dual_ctx_mt (JNI non testé via Java ici).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 10:45:47 +02:00
Richard Loyer 2699b631a3 dist: prefill HTP corrigé (SSM_CONV gate backend), JNI option C sans OPFILTER
Fix intégré dans libggml-hexagon.so (ql e872623): ggml_hexagon_supported_ssm_conv route le
conv1d multi-token (prefill) sur ggml-cpu (le kernel HTP est faux multi-token pour d_inner
1024/2048). Plus besoin de GGML_HEXAGON_OPFILTER -> retiré du JNI. Validé: oracle SSM_CONV 18/18,
cli -dev HTP0 cohérent, multi-tour cohérent+mémoire, prefill HTP 110-180 t/s. libggml-hexagon.so
rafraîchi. Rebuild requis avant ship: libggml-hexagon.so + libkazeia_engine.so. Docs MAJ.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 10:39:08 +02:00
Richard Loyer 2c89ec01a2 dist: JNI option C câblé (prefill HTP / decode CPU), validé multi-tour
generate() = prefill prompt sur instance HTP (ngl99, device HTP0, OPFILTER=SSM_CONV +
GDN_PREFILL posés au load) -> llama_state_seq transfère le KV -> decode sur instance CPU
(ngl0, t4+fa, KV f16). 2 instances (~4.7GB). Sans état entre appels (app passe l'historique).
Validé multi-tour via jni/dual_ctx_mt.cpp: 3 tours cohérents FR + mémoire conversationnelle
(rappelle prénom/âge du tour 1 au tour 3), prefill HTP 103-144 t/s, decode CPU ~7-9.
Compile+linke OK (4 symboles JNI, CMakeLists inchangé). Rebuild libkazeia_engine.so requis
avant ship (le .so livré = ancienne version CPU-only/q8_0).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 10:24:55 +02:00
Richard Loyer 501abb67e5 dist: prefill HTP RÉCUPÉRABLE — charabia = 1 op (SSM_CONV) cassée, fix OPFILTER
Investigation détaillée: décomposé le prefill HTP charabia op par op (test-backend-ops -b HTP0
par op + OPFILTER bisect en génération). Coupable unique = SSM_CONV (conv1d) cassé sur HTP en
multi-token (prefill) pour d_inner=1024/2048 (oracle FAIL ERR~1.3; decode n=1 OK; 1536 passe;
bug backend hexagon, HVX+scalaire HTP faux, ggml-cpu correct). FIX immédiat: GGML_HEXAGON_OPFILTER
=SSM_CONV (conv sur CPU, reste HTP) -> prefill HTP 181 t/s + sortie FR cohérente, x13 vs CPU 14.
Renverse le "prefill HTP mort": il est récupérable. 3 configs (A CPU-only livrée / B mono-ctx
HTP+OPFILTER 181/6.4 / C dual-ctx 181/10.9 +2.3GB). TODO: corriger SSM_CONV HTP (gate oracle).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 10:12:37 +02:00
Richard Loyer 2256c077c9 dist: prefill HTP = CASSÉ (sortie charabia), prefill obligatoirement CPU
Vérifié 27/05 batterie pleine, 3 fois (harness dual-ctx, device HTP0 explicite, llama-cli
-dev HTP0 sortant de l'anglais cassé sur prompt FR). Le débit HTP (126-189 t/s) est réel mais
l'état/logits produits sont corrompus -> generation inutilisable. Preuve que c'est le prefill et
non le transfert: decode CPU depuis état prefillé-CPU = FR cohérent, depuis état prefillé-HTP =
charabia. Dense Qwen3-4B sur HTP crashe (V79 0x2e). Donc les "189/98/285 prefill HTP" cités partout
= débit jamais validé en sortie. Renverse l'hypothèse de fond "prefill HTP utilisable".

=> JNI reste ngl0 (CPU prefill 14 + CPU decode 10.9), seule config correcte. jni/dual_ctx.cpp =
harness de validation (prouve aussi que le KV transfer 2-contextes CPU->CPU est cohérent et prêt
le jour où le prefill HTP sera numériquement correct = bug backend frontière). Docs corrigées.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 09:42:59 +02:00
Richard Loyer c9d4e625eb dist: métriques vérifiées batterie pleine — KV f16 (pas q8_0), q35-lmq4 HTP=189
Reconfirmé device froid 90% (les chiffres throttlés d'hier soir étaient faux):
- KV f16 >> q8_0 au decode: q35-lmq4 f16=10.9 vs q8_0=6.5 (-40%, idem d=512). Le déquant KV
  flash-attn coûte plus que le BW. JNI corrigé type_k/v=F16 (rebuild .so requis avant ship;
  le .so livré=q8_0 validé, inchangé).
- q35-lmq4 prefill HTP=189 ~= 2x Qwen3.5-Q4_0 (98): embeds/output Q4 restent sur NPU vs Q6_K
  fallback CPU. Argument fort de plus pour q35-lmq4 (+5% decode ET ~2x prefill HTP).
- decode sain: q35-lmq4 10.9, dense 11.7. prefill CPU JNI=14 (t4).
Decision KV résolue; decision prefill CPU-only vs HTP ouverte (189 motive le câblage).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 09:23:57 +02:00
Richard Loyer fac50d69ce dist: bandeau HANDOFF source de vérité sur README/INTEGRATION (9B historique)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 23:34:15 +02:00
Richard Loyer 9417aba6cb dist: handoff intégration aligné décisions 26/05 (modèle q35-lmq4, perf, prompt)
HANDOFF.md = point d'entrée: modèle Speaker tranché = q35-lmq4 (éval qualité), 9B écarté,
kernel GDN clos. État JNI: config OK (t4/fa/thinking-off/greedy) MAIS CPU-only (ngl0) ->
2 décisions ouvertes documentées (prefill CPU vs HTP non câblé; KV q8_0 à revérifier, peut
coûter au decode). system_fr.txt = prompt prod (garde-fous 3114 + tutoiement + ne-pas-présumer,
correctifs issus de l'éval). MODELS/PERF/STATUS réalignés (decode 10.8, prefill 89.5 HTP capacité
mais JNI=CPU ~19, quant sous-Q4 morte). package.sh réassemble lib/ depuis ql/b.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 23:33:41 +02:00
Richard Loyer b2fc564f04 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
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 15:53:14 +02:00
Richard Loyer 1252f32bd3 Rapport R&D complet: synthese session, perf, cascade, #277, briques, reste a faire
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 22:27:34 +02:00
Richard Loyer 9b62420089 v4 fix #277: ngl0 CPU decode 14tok/s, 4s/tour, usable 2026-05-25 10:18:31 +02:00
Richard Loyer 7a5780ca1d Bridge v3 utilisable: thinking-off ChatML, sys+usr, cap; static intact 2026-05-25 09:41:04 +02:00
Richard Loyer 76f21a21cb Bridge STATIC autonome (42MB): zero NEEDED partage, fix collision TTS libllama, valide device 2026-05-24 22:43:45 +02:00
Richard Loyer f877902903 STATUS.md: validé/limites pour integrateur 2026-05-24 22:17:42 +02:00
Richard Loyer c5c2738281 Valide device: generate() bout-en-bout OK (test_native), bridge pret integration 2026-05-24 22:05:44 +02:00
Richard Loyer 7dbf38db97 Doc complete: README+MODELS+PERF+PITFALLS, build nettoye 2026-05-24 21:59:56 +02:00
Richard Loyer 15b9baf6b2 JNI bridge complet: generate() prefill+decode, build arm64 OK (libkazeia_engine.so 209K) 2026-05-24 21:58:00 +02:00
Richard Loyer 0f92fa723f Dist Kazeia-Engine: libs arm64+headers+JNI bridge+INTEGRATION/TTS doc; STT reste ORT 2026-05-24 21:55:01 +02:00