fix(tts): revert sampling knobs — real cause was Turbo AR-tail over-run, fixed server-side
The long-turn "swaps to German" garble was NOT a language leak (infra-ops's
initial framing) and NOT the sampling entropy my interim curb targeted. The real
cause, signal-measured by infra-ops: the Chatterbox Turbo model over-runs its
generation TAIL — a long single generation degrades into garble/dead-air in its
final ~2-3s (voiced-tail zero-crossing rate 1.58x the middle). The gateway's
unbounded chunk-size ratchet built 300-600 char mega-chunks that landed in that
zone, and streaming concatenated each bad tail.
My interim curb (top_k 1000->80, top_p 0.95->0.85, temp 0.8->0.5) made it WORSE:
tight sampling pulls the degradation onset to a shorter length (~200 chars vs
~300 at defaults), so it fights the server-side fix rather than helping.
Fixed server-side (infra-ops, chatterbox-fast image :v2): a max_chunk_chars=250
cap bounds each generation below the ~300-char onset -> clean prosodic chunks
(verified ZCR 1.58x -> 0.64x; operator ear-confirmed clean audio + clean joins).
Consumer side, this commit:
- Revert the sampling knobs: gateway_body back to {text, voice, format, stream},
send full text with the gateway's default sampling. The server chunks at 250.
- Keep the /api/tts empty-200 -> 503 guard as hygiene (DEC-9a; the shared-3090
OOM that produced empty 200s is also resolved — Zonos moved off the card).
Contract DEC-9 rewritten with the resolved root cause + the two wrong hypotheses;
DEC-9a marked kept-as-hygiene. 520 green.
This commit is contained in:
+7
-11
@@ -12,9 +12,6 @@ import pytest
|
||||
import respx
|
||||
|
||||
from ratatoskr.tts import (
|
||||
_TTS_TEMPERATURE,
|
||||
_TTS_TOP_K,
|
||||
_TTS_TOP_P,
|
||||
CHATTERBOX_TTS_URL,
|
||||
TtsUnavailable,
|
||||
gateway_body,
|
||||
@@ -60,15 +57,14 @@ class TestGatewayBody:
|
||||
assert b["format"] == "wav" # DEC-3 — "format", not "response_format"
|
||||
assert b["stream"] is True # DEC-2 — play-as-it-arrives
|
||||
|
||||
def test_sampling_curbs_below_gateway_defaults_hold_english(self) -> None:
|
||||
# DEC-9: the model has no `language` pin and Turbo's multilingual capacity leaks under
|
||||
# high-entropy sampling on long turns. gateway_body tightens temperature/top_p/top_k
|
||||
# below the gateway defaults (0.8 / 0.95 / 1000) to hold English — top_k the highest-
|
||||
# leverage. Pin presence + the below-default relationship (infra-ops-authoritative).
|
||||
def test_default_sampling_no_client_side_curbs(self) -> None:
|
||||
# DEC-9 (real cause): the long-turn garble was Turbo over-running its GENERATION TAIL,
|
||||
# fixed SERVER-SIDE (:v2 max_chunk_chars=250). A client sampling curb was
|
||||
# counterproductive (tight sampling pulls the garble onset earlier), so gateway_body
|
||||
# sends NO temperature/top_p/top_k — the gateway's defaults govern.
|
||||
b = gateway_body("a long turn", "donut")
|
||||
assert b["temperature"] == _TTS_TEMPERATURE and _TTS_TEMPERATURE < 0.8
|
||||
assert b["top_p"] == _TTS_TOP_P and _TTS_TOP_P < 0.95
|
||||
assert b["top_k"] == _TTS_TOP_K and _TTS_TOP_K < 1000
|
||||
for knob in ("temperature", "top_p", "top_k"):
|
||||
assert knob not in b
|
||||
|
||||
def test_no_zonos_era_fields(self) -> None:
|
||||
# The Zonos body fields are gone: no OpenAI `input`/`response_format`, no
|
||||
|
||||
Reference in New Issue
Block a user