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:
@@ -154,36 +154,37 @@ each independently shippable. Slice order is chosen for fastest visible result.
|
||||
`ratatoskr:donut → "donut"` directly. NOTE the case: chatterbox wants lowercase
|
||||
`"donut"` (Zonos used `"Donut"`). Non-interview agents fall to the chatterbox
|
||||
default `"glados_25s"` (was Zonos `"Cora"`, which does not exist on chatterbox).
|
||||
- **DEC-9 — hold English (amended 2026-08-07; the "nothing to drift" call was WRONG).**
|
||||
The Zonos `language:"en-us"` pin is dropped — chatterbox has no `language` field. BUT the
|
||||
initial "English-only, nothing to drift" rationale was FALSIFIED by an operator report the
|
||||
same day: the Turbo checkpoint drifts into German partway through a long turn. infra-ops's
|
||||
authoritative root-cause (source-read, thread 01KZEDMJ…): **Turbo has latent multilingual
|
||||
capacity that leaks**, and the drift is **length-driven** — the gateway's adaptive scheduler
|
||||
ratchets chunk size upward with NO cap, so a long turn collapses into essentially ONE long
|
||||
generation after the first 2-3 sentences, and the sampler wanders off English on that single
|
||||
long decode (generation state DOES reset per chunk — cross-chunk carry is not the mechanism;
|
||||
it's the unbounded per-chunk length). Two-layer response:
|
||||
- **Sampling curbs (shipped, no redeploy) — REDUCE drift probability, do NOT guarantee it.**
|
||||
`gateway_body` tightens below the gateway defaults: `_TTS_TOP_K = 80` (from 1000 — the
|
||||
highest-leverage knob; the huge default admits off-language tokens), `_TTS_TOP_P = 0.85`
|
||||
(from 0.95), `_TTS_TEMPERATURE = 0.5` (from 0.8). Escalation if still drifting: temp
|
||||
0.3-0.4, rep_penalty 1.2→1.3.
|
||||
- **Length-bounding (the ROBUST fix) — GUARANTEES English by keeping each generation short.**
|
||||
Two paths, operator's call: (a) return to short CLIENT-side chunking (~1-2 sentences per
|
||||
/tts call, each a fresh re-anchored generation; partially reverses DEC-10; works today, no
|
||||
redeploy; loses the gateway's seamless internal streaming); (b) infra-ops adds a SERVER-side
|
||||
max-chunk cap to the scheduler (keeps seamless streaming AND holds English; needs a
|
||||
chatterbox-fast redeploy + operator greenlight on the card-shared fleet service — then the
|
||||
consumer reverts to sending full text).
|
||||
The persona's dialogue-only rewrite in `docs/characters/donut.md` still stands (removes the
|
||||
asterisk-RP-voiced-verbatim vector regardless of engine). (Original Zonos DEC-9 below.)
|
||||
- **DEC-9 — hold English: RESOLVED SERVER-SIDE 2026-08-07 (client sends full text, default
|
||||
sampling).** The Zonos `language:"en-us"` pin is dropped — chatterbox has no `language` field.
|
||||
The long-turn garble ("swaps to German halfway through") went through two WRONG hypotheses
|
||||
before the real cause surfaced under the operator's clean-diagnosis push (thread 01KZEDMJ…):
|
||||
- WRONG-1: "English-only, nothing to drift" (infra-ops Q8) — falsified by the operator report.
|
||||
- WRONG-2: "multilingual leak, curb with tighter sampling" — I shipped `top_k 1000→80` /
|
||||
`top_p 0.95→0.85` / `temp 0.8→0.5`. This made it WORSE: tight sampling pulls the degradation
|
||||
onset to a SHORTER length (garble by ~200 chars vs ~300 at default knobs).
|
||||
- **REAL CAUSE (infra-ops, signal-measured): the 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 lib itself filters OOV tokens + pads silence). The
|
||||
scheduler's unbounded buffer-ratchet built 300-600 char mega-chunks landing squarely in that
|
||||
zone, and streaming concatenated each bad tail. The "German" was that tail garble mis-heard
|
||||
(compounded by shared-3090 OOM garbage, now gone — Zonos was moved off the 3090).
|
||||
- **FIX (deployed server-side, image :v2): `max_chunk_chars=250`** on the gateway scheduler,
|
||||
bounding each generation below the ~300-char onset → clean 3-4 sentence chunks with a full
|
||||
prosodic arc (verified: voiced-tail ZCR 1.58x→0.64x; operator ear-confirmed clean audio AND
|
||||
clean paragraph joins — chatterbox's low emotiveness keeps the seams smooth). Per-request
|
||||
`max_chunk_chars` override available for per-call tuning.
|
||||
- **CONSUMER SIDE (this is what the code does): send FULL text with the gateway's DEFAULT
|
||||
sampling.** The WRONG-2 sampling curbs were REVERTED (they degrade audio earlier and fight
|
||||
the :v2 cap). `gateway_body` is back to `{text, voice, format, stream}` — no client chunking
|
||||
(DEC-10 stays retired; the server chunks at 250), no sampling overrides. The persona's
|
||||
dialogue-only rewrite in `docs/characters/donut.md` still stands. (Original Zonos DEC-9 below.)
|
||||
|
||||
- **DEC-9a — OOM on long single generations → empty 200 (infra-ops 2026-08-07).** chatterbox-fast
|
||||
shares the RTX 3090 with Zonos2 (~1 GB headroom). A long single generation can OOM the card;
|
||||
the gateway then returns HTTP **200 with a 0-byte body** (not a 5xx). `tts_endpoint` treats an
|
||||
empty 200 body as a synthesis failure → 503 (INV-TTS-4 visible skip), never a silent empty
|
||||
audio/wav stream. Length-bounding (DEC-9 above) fixes the OOM too — small chunks don't OOM.
|
||||
- **DEC-9a — empty-200 OOM guard: KEPT as hygiene (OOM itself resolved).** chatterbox-fast used
|
||||
to share the RTX 3090 with Zonos2 (~1 GB headroom); a long single generation could OOM the card
|
||||
and the gateway then returned HTTP **200 with a 0-byte body**. The OOM is resolved (Zonos moved
|
||||
off the 3090; the :v2 250-char cap keeps generations small), but `tts_endpoint` KEEPS treating an
|
||||
empty 200 body as a synthesis failure → 503 (INV-TTS-4 visible skip) — good hygiene regardless
|
||||
(infra-ops-endorsed), never a silent empty audio/wav stream.
|
||||
- **DEC-10 — long-form chunk-and-concatenate. RETIRED 2026-08-07 (chatterbox
|
||||
migration).** chatterbox-fast has NO per-synth token/duration cap (Zonos capped at
|
||||
6144 tok / 71.2s) and chunks arbitrary-length text INTERNALLY via its adaptive
|
||||
@@ -247,8 +248,9 @@ tts_stream(text, *, voice, client: httpx.AsyncClient, url=CHATTERBOX_TTS_URL) ->
|
||||
# YIELD wav chunks as they synthesize. Pass through verbatim — never buffer, never rewrite the placeholder
|
||||
# header. chatterbox chunks arbitrary-length text INTERNALLY (no per-synth cap, DEC-10 RETIRED), so this
|
||||
# SINGLE call voices a whole turn — no client-side chunk-and-concatenate wrapper.
|
||||
# gateway_body(text, voice) = {text, voice, format:"wav", stream:true, temperature:_TTS_TEMPERATURE}.
|
||||
# temperature < gateway-default 0.8 holds English across a long turn (DEC-9). NO dials, NO language (RETIRED).
|
||||
# gateway_body(text, voice) = {text, voice, format:"wav", stream:true}. Full text, DEFAULT sampling — the
|
||||
# :v2 server caps each generation at 250 chars, which fixes the long-turn tail garble (DEC-9). NO dials,
|
||||
# NO language, NO client sampling curbs (a curb was counterproductive — it pulled the garble onset earlier).
|
||||
precondition: text non-empty. Voice membership in GET /voices is GATEWAY-enforced, not client-asserted.
|
||||
postcondition: yields the gateway's chunked int16 streaming WAV bytes unmodified (0xFFFFFFFF placeholder
|
||||
sizes intact), one leading header then s16le PCM @ 24000 Hz to EOF.
|
||||
|
||||
@@ -48,7 +48,7 @@ _As of 2026-08-07:_
|
||||
|
||||
**✅ TTS MIGRATED off Zonos → chatterbox-fast (this session; COMMITTED, not pushed).** `tts.py` repointed from the Zonos gateway (:8890 `/v1/audio/speech`) to **chatterbox-fast** (`http://10.100.79.3:8197/tts` — bespoke non-OpenAI `{text,voice,format,stream}` schema, no auth, 24kHz, infra-ops-verified against image `local/chatterbox-fast:v1`). Three subsystems DELETED: (1) **affect** — Turbo has no emotion knob, so `PadState`/`EmotionDials`/`pad_to_dials` + `/api/tts` `p`/`a` fields + browser `pad` arg are gone (DEC-7 retired; operator-directed "drop it for chatterbox"); (2) **client-side chunking** — no per-synth cap (gateway chunks internally), so `chunk_text`/`tts_stream_long`/`_pcm_after_header` gone, one `tts_stream` call voices a whole turn (DEC-10 retired, the mid-stream `yielded_any` degrade folded into `tts_stream`); (3) **language pin** — English-only, no `language` field (DEC-9 re-purposed, below). **Browser SR 44100→24000** (load-bearing correctness fix). Default voice `Cora`→`glados_25s`; `donut` registered lowercase at `/refs/donut.wav`. 518 suite green, live-smoked (real 24kHz synth + endpoint proxy + bounced `ratatoskr-web`). Contract `donut_voiced_interview.contract.md` amended (migration banner; DEC-1/3/8 amended; DEC-7/9/10 retired w/ historical notes). `tts.py` is the single swap seam; `RATATOSKR_TTS_URL` overrides (no env pin, uses the code default).
|
||||
|
||||
**⚠️ ENGLISH-DRIFT curb + PENDING cap verify (this session).** Operator: Donut "swaps to German halfway through." Root cause (infra-ops source-read, thread `01KZEDMJ…`): **Turbo is multilingual-leaky AND the drift is LENGTH-driven** — the gateway's adaptive scheduler ratchets chunk size UPWARD with no cap, so a long turn collapses into one giant generation that (a) wanders off English and (b) OOMs the shared 3090 → HTTP **200 with a 0-byte body**. SHIPPED consumer-side (no redeploy): sampling curbs in `gateway_body` — `top_k 1000→80` (the prime knob, never pulled before), `top_p 0.95→0.85`, `temp 0.8→0.5` (`_TTS_TOP_K`/`_TTS_TOP_P`/`_TTS_TEMPERATURE`, DEC-9 re-purposed); + `/api/tts` empty-200→503 OOM guard (DEC-9a). Knobs REDUCE drift probability, do NOT GUARANTEE it on a long single generation. **REAL FIX = (b) infra-ops SERVER-SIDE max-chunk cap — GREENLIT by operator 2026-08-07; infra-ops implementing + redeploying chatterbox-fast.** Went straight to (b) (never added interim client chunking), so ratatoskr is ALREADY sending full text — nothing to revert. **PENDING (next session), on infra-ops's "cap deployed" ping: (1) verify a long donut turn holds English end-to-end; (2) optionally relax the sampling knobs toward defaults now that length is bounded server-side.**
|
||||
**✅ ENGLISH-DRIFT — RESOLVED SERVER-SIDE (this session; fix deployed + operator ear-confirmed).** Operator: Donut "swaps to German halfway through." TWO wrong hypotheses before the real cause (infra-ops, thread `01KZEDMJ…`): (W1) "English-only, nothing to drift" — falsified; (W2) "multilingual leak → tighten sampling" — I shipped `top_k 1000→80`/`top_p 0.95→0.85`/`temp 0.8→0.5` and it made it WORSE (tight sampling pulls the garble onset to ~200 chars vs ~300 at default). **REAL CAUSE (signal-measured): the Turbo model OVER-RUNS its generation TAIL** — garble/dead-air in the final ~2-3s of a long single generation (voiced-tail ZCR 1.58x the middle). The scheduler's unbounded ratchet built 300-600 char mega-chunks landing in that zone; the "German" was tail garble mis-heard (+ shared-3090 OOM garbage, now gone — Zonos moved off the 3090). **FIX = infra-ops server-side `max_chunk_chars=250` (image :v2), operator ear-confirmed clean audio + clean joins (ZCR 1.58x→0.64x).** CONSUMER SIDE (shipped): **REVERTED the W2 sampling knobs** — `gateway_body` back to `{text,voice,format,stream}`, send FULL text + gateway DEFAULT sampling (the curbs fought the :v2 cap); **KEPT** the `/api/tts` empty-200→503 guard as hygiene (DEC-9a; OOM itself resolved). Per-request `max_chunk_chars` override available if per-call tuning ever wanted. **Loop CLOSED — nothing pending.**
|
||||
|
||||
**✅ Donut interview character — voice + memory + honesty + query-formulation ALL DONE, on origin.** Deleted+redefined on Worldtree's **canonical recall branch (personal WT v1.0.0b183)**. Persona (`docs/characters/donut.md`) carries three layered behaviors, all committed+pushed: (1) **anti-fabrication** — her memory IS what `reference_knowledge` returns; LOW/no-on-target → deflect in character, never confabulate; (2) **near-miss LEAD rule** (`37b67a5`) — a weak-but-named candidate → offer the NAME the tool returned ("do you mean The Juicer?"), never invented detail; (3) **expand-don't-distill query formulation** (`2cc670e`) — pass the FULL descriptive phrase, enrich toward entity vocab, never boil to bare keywords. Push live edits: `python -m ratatoskr.tier3 patch ratatoskr:donut --system-prompt "$(awk '/^## System prompt/{f=1;next} f' docs/characters/donut.md)"`.
|
||||
|
||||
@@ -197,7 +197,7 @@ relational-dynamics verify (bind `--bifrost-url :8392`); WT #356 resume-durabili
|
||||
Chronological log of decisions with `[YYYY-MM-DD]` prefix. One line per
|
||||
decision. Captures rationale that won't be obvious from code alone.
|
||||
|
||||
- `[2026-08-07]` **TTS migrated Zonos→chatterbox-fast (`:8197` bespoke schema); affect DROPPED (Turbo has no emotion knob, operator "drop it for chatterbox"), client-chunking DROPPED (no per-synth cap), language pin DROPPED, browser SR 44100→24000.** English drift ("swaps to German halfway") root-caused by infra-ops as Turbo multilingual-leak + LENGTH-driven scheduler ratchet (+ shared-3090 OOM → empty 200); curbed via `top_k 1000→80`/`top_p 0.95→0.85`/`temp 0.8→0.5` + `/api/tts` empty-200→503 guard. **Real fix = infra-ops server-side max-chunk cap, GREENLIT by operator — awaiting redeploy ping (then verify long-turn English + maybe relax knobs).** Contract `donut_voiced_interview.contract.md` amended. Committed, not pushed.
|
||||
- `[2026-08-07]` **TTS migrated Zonos→chatterbox-fast (`:8197` bespoke schema); affect DROPPED (Turbo has no emotion knob, operator "drop it for chatterbox"), client-chunking DROPPED (no per-synth cap), language pin DROPPED, browser SR 44100→24000.** Pushed `19b499a`. English "German drift" real cause (after 2 wrong hypotheses) = Turbo model OVER-RUNS its generation TAIL on long single generations (garble in final ~2-3s, ZCR 1.58x); **fixed SERVER-SIDE by infra-ops (`max_chunk_chars=250`, image :v2, operator ear-confirmed).** Consumer: **REVERTED my interim `top_k/top_p/temp` curbs** (they made it WORSE — pulled garble onset earlier), send full text + default sampling; KEPT the `/api/tts` empty-200→503 guard as hygiene. Contract `donut_voiced_interview.contract.md` amended. Loop closed.
|
||||
- `[2026-08-07]` **order_by=chapter tool flag → FILED as Worldtree #397 (DEFERRED to next session's contract pass).** Narrative/temporal-query gap ("first encounter in the dungeon"): `reference_knowledge` sorts by relevance not chronology; `provenance.chapter` is on every chunk but the consumer can't reorder native results (kb_bridge retired). Operator ruled the upstream sort flag the clean fix; worldtree-dev accepted, our fixture is the measurement instrument. Tracked at **Worldtree #397** (+ althing thread `01KZED2T3XHJ2WMS5NCYK42W6R`).
|
||||
- `[2026-08-07]` **#393 (descriptive-query subject binding) CLOSED — persona-expand lever the win (4/10→9/10), tool directive the fleet floor.** `docs/diagnostics/descriptive_query_binding.py` is the canonical #393 fixture; two-mechanism split (cross-wing dilution vs fiction-scope selection). Commits `6c83a3b`/`4f4b5ad`/`2cc670e`.
|
||||
- `[2026-08-07]` **Donut expand-don't-distill persona lever (`2cc670e`)** — keep full descriptive phrase + enrich toward entity vocab, never distill to bare keywords; measured 4/10→9/10 roid-rage binds persona-alone. Composes with near-miss LEAD (`37b67a5`).
|
||||
|
||||
+14
-31
@@ -21,12 +21,15 @@ Foot-guns (infra-ops-verified 2026-08-07 against image local/chatterbox-fast:v1)
|
||||
streaming shape stays byte-identical to the Zonos path.
|
||||
- Body field names are the live pydantic schema: `text` (NOT `input`), `format`
|
||||
(NOT `response_format`). No `model` field, no `language` field (English-only).
|
||||
- English is NOT guaranteed by the model alone: the Turbo checkpoint drifts into
|
||||
foreign-sounding phonemes partway through a long generation (operator report
|
||||
2026-08-07: "swaps to German halfway through"). There is no `language` pin to
|
||||
stop it — the only English-stability lever the wire exposes is a LOWER sampling
|
||||
`temperature` (below the gateway default 0.8), which curbs the wander onto
|
||||
off-distribution tokens. See `_TTS_TEMPERATURE`.
|
||||
- Long-turn garble ("swaps to German halfway through", operator 2026-08-07) was NOT a
|
||||
language leak — it was the Turbo model OVER-RUNNING its generation tail (garble/dead-air
|
||||
in the final ~2-3s of a long single generation; infra-ops measured voiced-tail
|
||||
zero-crossing rate at 1.58x the middle). FIXED SERVER-SIDE (image :v2): a
|
||||
`max_chunk_chars=250` cap on the gateway's scheduler bounds each generation below the
|
||||
~300-char degradation onset → clean prosodic chunks. So the client SENDS FULL TEXT and
|
||||
uses the gateway's DEFAULT sampling — an earlier client-side temperature/top_k curb was
|
||||
counterproductive (tight sampling pulls the garble onset to a SHORTER length). Per-request
|
||||
`max_chunk_chars` override is available if per-call tuning is ever wanted.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -41,19 +44,6 @@ import httpx
|
||||
# Overridable per deployment via app.state.tts_url (RATATOSKR_TTS_URL) — the swap seam + tests.
|
||||
CHATTERBOX_TTS_URL = "http://10.100.79.3:8197/tts"
|
||||
|
||||
# English-stability sampling curbs (DEC-9; infra-ops-authoritative 2026-08-07, thread 01KZEDMJ…).
|
||||
# The Turbo checkpoint has latent multilingual capacity that LEAKS under high-entropy sampling on
|
||||
# a long generation (operator: "swaps to German halfway through"). chatterbox has no `language`
|
||||
# field, so these tighten the sample below the gateway defaults (temp 0.8 / top_p 0.95 / top_k
|
||||
# 1000) to hold the decode on the English manifold. top_k is the highest-leverage knob — the
|
||||
# default 1000 admits very-low-probability off-language tokens; infra-ops named it the prime
|
||||
# suspect. These REDUCE drift probability but do NOT GUARANTEE English on an arbitrarily long
|
||||
# single generation — the robust fix is bounding generation LENGTH (infra-ops's server-side
|
||||
# max-chunk cap, or a return to short client-side chunking). See DEC-9.
|
||||
_TTS_TEMPERATURE = 0.5
|
||||
_TTS_TOP_P = 0.85
|
||||
_TTS_TOP_K = 80
|
||||
|
||||
|
||||
class TtsUnavailable(Exception):
|
||||
"""The gateway failed, was unreachable, or returned a non-wav body.
|
||||
@@ -71,18 +61,11 @@ class TtsUnavailable(Exception):
|
||||
def gateway_body(text: str, voice: str) -> dict:
|
||||
"""The chatterbox-fast POST body. `format:"wav"` (DEC-3) so the streaming shape is a
|
||||
placeholder-header WAV the browser decoder strips; `stream:true` for play-as-it-arrives
|
||||
(DEC-2); tightened `temperature`/`top_p`/`top_k` (DEC-9) to hold English across a long turn.
|
||||
Field names are the live pydantic schema: `text` (not `input`), `format` (not
|
||||
`response_format`); no `language` (English-only) and no affect dials (DEC-7 retired)."""
|
||||
return {
|
||||
"text": text,
|
||||
"voice": voice,
|
||||
"format": "wav",
|
||||
"stream": True,
|
||||
"temperature": _TTS_TEMPERATURE,
|
||||
"top_p": _TTS_TOP_P,
|
||||
"top_k": _TTS_TOP_K,
|
||||
}
|
||||
(DEC-2). Field names are the live pydantic schema: `text` (not `input`), `format` (not
|
||||
`response_format`). Send the FULL text with the gateway's DEFAULT sampling: the :v2 server
|
||||
caps each generation at 250 chars, which fixes the long-turn tail garble (DEC-9); a client
|
||||
sampling curb was counterproductive. No `language` (English-only), no affect dials (DEC-7)."""
|
||||
return {"text": text, "voice": voice, "format": "wav", "stream": True}
|
||||
|
||||
|
||||
async def tts_stream(
|
||||
|
||||
+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