From 53d0796bd54805477aac308c29b8c677bd78f2e3 Mon Sep 17 00:00:00 2001 From: Hitonabi Date: Sun, 28 Jun 2026 01:36:25 +0200 Subject: [PATCH] Fix: Chatterbox lauter/kratzig (Peak-Normalisierung) + sporadischer Generation-Bug (Retry x3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Klon-Output war zu laut/übersteuert -> Peak auf 0.9 normalisiert. alignment_stream_analyzer-NoneType ließ einzelne Sätze fehlschlagen (im Voice-Loop 'Stimme kam nicht') -> bis zu 3 Versuche. Co-Authored-By: Claude Opus 4.8 --- voice_service/app.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/voice_service/app.py b/voice_service/app.py index 7e79baf..a0ee86f 100644 --- a/voice_service/app.py +++ b/voice_service/app.py @@ -183,10 +183,26 @@ def chatterbox_tts(text: str, language: str, ref_path: str) -> bytes: ref = ref_path or active_ref() if ref and os.path.exists(ref): kwargs["audio_prompt_path"] = ref # Zero-Shot Voice-Cloning aus Referenz - wav = model.generate(text, **kwargs) + # Chatterbox hat einen sporadischen Bug (alignment_stream_analyzer → NoneType), der einzelne + # Generierungen fehlschlagen lässt → im Voice-Loop „Stimme kam nicht". Ein Retry klappt meist. + wav = None + last_err: Exception | None = None + for attempt in range(3): + try: + wav = model.generate(text, **kwargs) + break + except Exception as exc: # noqa: BLE001 + last_err = exc + log.warning("Chatterbox-Generation fehlgeschlagen (Versuch %d/3): %s", attempt + 1, exc) + if wav is None: + raise HTTPException(502, f"Chatterbox-Generation fehlgeschlagen: {last_err}") # wav = torch.Tensor [1, N] @ model.sr → in WAV-Bytes serialisieren. import numpy as np arr = wav.squeeze(0).detach().cpu().numpy().astype(np.float32) + # Peak-Normalisierung gegen Übersteuern/Clipping (Klon-Output ist oft zu laut → kratzig). + peak = float(np.max(np.abs(arr))) if arr.size else 0.0 + if peak > 0: + arr = arr / peak * float(os.environ.get("VOICE_CHATTERBOX_PEAK", "0.9")) buf = io.BytesIO() sf.write(buf, arr, int(model.sr), format="WAV", subtype="PCM_16") return buf.getvalue()