From 19ac123afa667f040cbe8d1c57afb7277383e3e2 Mon Sep 17 00:00:00 2001 From: Richard Loyer Date: Sun, 31 May 2026 11:18:25 +0200 Subject: [PATCH] =?UTF-8?q?TU=20sampler=20tuning=20:=20top=5Fp=201.0->0.95?= =?UTF-8?q?=20+=20rep=5Fpenalty=201.05->1.10=20nouveaux=20d=C3=A9fauts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Validation à l'écoute (panel A/B 4 combos sur 'Bonsoir, comment tu te sens ce soir ?'). Verdict utilisateur : combinaison TOPP_0.95_REPP_1.10 sonne le moins robotique. Analyse complémentaire TU.2 (dump codes via KZTTS_DUMP_CODES=path) sur 4 phrases panel a confirmé : - code 690 CB0 = attracteur silence (5.9% du panel, doublé systématiquement en début de phrase, jusqu'à 4 répétitions consécutives mesurées) - rep_penalty 1.05 trop doux pour casser ces 690 690 - rep_penalty 1.10 plus nucleus 0.95 -> top_p coupe la queue improbable + rep défavorise les codes récents -> moins de pause robotique Nouveaux défauts (tts_engine.h TtsSynthesizeCfg + tts_pipeline env defaults + TtsEngine.kt TtsSampling) : cp_top_p = 0.95f (était 1.0) cp_rep_penalty = 1.10f (était 1.05) talker_top_p = 0.95f (était 1.0) talker_rep_penalty = 1.10f (était 1.05) cp_temp, top_k, talker_temp/top_k inchangés (0.9, 50). Mesure panel 4 phrases avec nouveaux défauts + decoder chraac subproc : 'Bonjour Kazeia' : N=29 RTF 2.19 'Bonsoir, comment tu te sens ce soir ?' : N=48 RTF 2.21 'Je rumine la nuit.' : N=34 RTF 2.21 'Comment puis-je t'aider aujourd'hui ?' : N=29 RTF 2.27 RTF stable ~2.2. Compression légère sur phrases courtes (29 vs 33 baseline), expansion sur phrases interrogatives ('Bonsoir' N=48 vs 41). Cohérent avec top_p resserré qui choisit des codes plus pertinents. KZTTS_DUMP_CODES=path ajouté dans tts_engine pour analyse future (int32 binaire [N,16] time-major). Co-Authored-By: Claude Opus 4.7 (1M context) --- dist/jni/TtsEngine.kt | 5 +++-- dist/jni/tts_engine.cpp | 11 +++++++++++ dist/jni/tts_engine.h | 13 ++++++++----- dist/jni/tts_pipeline.cpp | 8 ++++---- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/dist/jni/TtsEngine.kt b/dist/jni/TtsEngine.kt index ab7e08f..25c3d30 100644 --- a/dist/jni/TtsEngine.kt +++ b/dist/jni/TtsEngine.kt @@ -43,8 +43,9 @@ data class TtsResult( // Configuration sampling. Défauts validés sur fixture FR (cf project_tts_session_28may). data class TtsSampling( - val cpTemp: Float = 0.9f, val cpTopK: Int = 50, val cpTopP: Float = 1.0f, val cpRepPenalty: Float = 1.05f, - val talkerTemp: Float = 0.9f, val talkerTopK: Int = 50, val talkerTopP: Float = 1.0f, val talkerRepPenalty: Float = 1.05f + // Défauts validés à l'écoute (top_p=0.95 + rep=1.10 moins robotique vs 1.0/1.05). + val cpTemp: Float = 0.9f, val cpTopK: Int = 50, val cpTopP: Float = 0.95f, val cpRepPenalty: Float = 1.10f, + val talkerTemp: Float = 0.9f, val talkerTopK: Int = 50, val talkerTopP: Float = 0.95f, val talkerRepPenalty: Float = 1.10f ) class TtsEngine( diff --git a/dist/jni/tts_engine.cpp b/dist/jni/tts_engine.cpp index bd569c2..fc55f4c 100644 --- a/dist/jni/tts_engine.cpp +++ b/dist/jni/tts_engine.cpp @@ -613,6 +613,17 @@ TtsSynthesizeResult tts_engine_synthesize(TtsEngine * eng, const TtsSynthesizeCf R.frames = N_done; R.audio_s = N_done / 12.0; + // Dump optionnel des codes pour analyse des attracteurs (KZTTS_DUMP_CODES=path). + // Format : int32 binaire [N, 16] time-major (= codes_engine raw). + if (const char * dump = getenv("KZTTS_DUMP_CODES")) { + FILE * f = fopen(dump, "wb"); + if (f) { + fwrite(codes_engine.data(), sizeof(int32_t), codes_engine.size(), f); + fclose(f); + fprintf(stderr, "codes dumped to %s (%d frames × 16)\n", dump, N_done); + } + } + // --- 8) Decoder final -> WAV --- // KZTTS_DECODER_SUBPROC=path/kazeia_decoder_chraac : fork+exec un sous-process décodeur // statiquement linké contre chraac (-22% sur decoder). Le talker reste qualcomm (qui marche). diff --git a/dist/jni/tts_engine.h b/dist/jni/tts_engine.h index d85e07c..0337f09 100644 --- a/dist/jni/tts_engine.h +++ b/dist/jni/tts_engine.h @@ -30,16 +30,19 @@ struct TtsSynthesizeCfg { int max_steps = 256; uint32_t seed = 42; - // Sampling (par défaut = défauts in-house validés sur fixture FR) + // Sampling : défauts validés à l'écoute (panel A/B) sur tts_engine + chraac subproc. + // top_p=0.95 + rep_penalty=1.10 : sweet spot moins robotique, moins de pauses 690 + // doublées sur CB0 (cf TU.2 attracteurs identifiés). Ancien défaut top_p=1.0 + // rep=1.05 disponible en surcharge via env KZTTS_REPP / KZTTS_TOPP. float cp_temp = 0.9f; int cp_top_k = 50; - float cp_top_p = 1.0f; - float cp_rep_penalty = 1.05f; + float cp_top_p = 0.95f; + float cp_rep_penalty = 1.10f; float talker_temp = 0.9f; int talker_top_k = 50; - float talker_top_p = 1.0f; - float talker_rep_penalty = 1.05f; + float talker_top_p = 0.95f; + float talker_rep_penalty = 1.10f; }; struct TtsSynthesizeResult { diff --git a/dist/jni/tts_pipeline.cpp b/dist/jni/tts_pipeline.cpp index b57d74b..8a7252d 100644 --- a/dist/jni/tts_pipeline.cpp +++ b/dist/jni/tts_pipeline.cpp @@ -67,12 +67,12 @@ int main(int argc, char** argv) { sc.seed = env_i("KZTTS_SEED", 42); sc.cp_temp = env_f("KZTTS_CP_TEMP", 0.9f); sc.cp_top_k = env_i("KZTTS_CP_TOPK", 50); - sc.cp_top_p = env_f("KZTTS_CP_TOPP", 1.0f); - sc.cp_rep_penalty = env_f("KZTTS_CP_REPP", 1.05f); + sc.cp_top_p = env_f("KZTTS_CP_TOPP", 0.95f); + sc.cp_rep_penalty = env_f("KZTTS_CP_REPP", 1.10f); sc.talker_temp = env_f("KZTTS_TEMP", 0.9f); sc.talker_top_k = env_i("KZTTS_TOPK", 50); - sc.talker_top_p = env_f("KZTTS_TOPP", 1.0f); - sc.talker_rep_penalty = env_f("KZTTS_REPP", 1.05f); + sc.talker_top_p = env_f("KZTTS_TOPP", 0.95f); + sc.talker_rep_penalty = env_f("KZTTS_REPP", 1.10f); auto R = tts_engine_synthesize(eng, sc); if (R.err) { fprintf(stderr, "tts_engine_synthesize FAIL err=%d\n", R.err); tts_engine_free(eng); return 4; }