catalog(chatterbox-fast): add streaming TTS service entry (streamable:true)

Land chatterbox-fast in the asset-engine catalog as an additive service, per
asset-engine-dev's shipped streaming-audition path (asset-engine v0.1.17-19):
- streamable:true -> UI routes Generate to an ephemeral progressive-<audio>
  audition (no Job/Asset); re-run on `chatterbox` to keep output.
- New service-level `streamable` bool added to services.schema.json (additive,
  default false; mirrors the Pydantic model asset-engine-dev regenerates).
- Fields: text, voice (select via /voices), temperature/top_p/top_k/
  repetition_penalty/seed, format (pcm default; UI forces wav). exaggeration/
  cfg_weight omitted — Turbo ignores them.
- status experimental until the first real browser audition verifies progressive
  playback (the one thing asset-engine-dev couldn't machine-verify).
- reproducibility + audit entries added. No catalog_version bump (additive).
Validates against the updated schema.
This commit is contained in:
2026-06-02 00:58:57 -07:00
parent 875033ff00
commit e4b786d242
2 changed files with 136 additions and 0 deletions
+5
View File
@@ -589,6 +589,11 @@
"title": "Content Type",
"type": "string"
},
"streamable": {
"default": false,
"title": "Streamable",
"type": "boolean"
},
"model": {
"$ref": "#/$defs/CatalogModel"
},
+131
View File
@@ -379,6 +379,132 @@ services:
and deliberately NOT adopted. Python 3.10 only (wrapper hardcoding);
multilingual (23-language) variant available via the stack .env.
- id: chatterbox-fast
name: Chatterbox Fast (streaming)
description: >
Custom streaming front-end for Chatterbox-Turbo: an adaptive buffer-ratchet
chunker emits the first sentence immediately (~0.5s time-to-first-audio vs
~5s one-shot), then ratchets chunk size up on the model's realtime headroom.
Single-stream interactive. Same Turbo voice + inline paralinguistic tags as
`chatterbox`; the win is sub-second start for streaming consumers.
category: tts
version: 1
status: experimental
host: irv-ml1
lifecycle:
stack: chatterbox-fast
vram_gb: 6
gpu_device_id: 1
endpoint: http://10.100.79.3:8197/tts
method: POST
content_type: application/json
streamable: true
model:
id: ResembleAI/chatterbox-turbo
revision: null
image: local/chatterbox-fast:v1
section_groups:
- id: basic
label: Text & voice
- id: sampling
label: Sampling
fields:
- name: text
type: textarea
label: Text (with optional [tags])
section: basic
required: true
max_length: 5000
description: >
Inline paralinguistic tags honored by Turbo ([laugh] [whispers] [sigh]
etc.). Adaptive-chunking splits on sentence boundaries; a very long
comma-less sentence may show a faint join seam.
- name: voice
type: select
label: Voice
section: basic
default: glados_25s
source_url: http://10.100.79.3:8197/voices
source_jsonpath: $.voices[*]
description: >
Predefined voice (a *.wav stem under /worktank/chatterbox/reference_audio,
shared with the chatterbox stack). Live-enumerated via /voices. Clone
references are passable as an absolute path via the API (not listed here).
- name: temperature
type: slider
section: sampling
min: 0.05
max: 2.0
step: 0.05
default: 0.8
description: Sampling temperature; lower = steadier. Turbo default 0.8.
- name: top_p
type: slider
section: sampling
min: 0.0
max: 1.0
step: 0.05
default: 0.95
description: Nucleus sampling cutoff. Spike-validated default 0.95.
- name: top_k
type: number
section: sampling
required: false
default: 1000
description: Top-k sampling cutoff. Spike-validated default 1000.
- name: repetition_penalty
type: slider
section: sampling
min: 1.0
max: 2.0
step: 0.05
default: 1.2
description: Penalize token repetition. Spike-validated default 1.2.
- name: seed
type: number
section: sampling
required: false
default: 0
description: >
0 = random. A fixed seed repeats a one-shot take (verified byte-exact).
Streaming output is NOT reproducible — adaptive-chunk boundaries depend
on the live-measured realtime factor.
- name: format
type: select
section: basic
options: [pcm, wav]
default: pcm
description: >
pcm = raw s16le @ 24 kHz (lowest latency, for API consumers); wav adds a
header. The streaming-audition UI forces wav for the browser <audio>.
response:
type: audio
mime_from_field: format
reproducibility:
seedable: true
deterministic: false
seed_field: seed
notes: >
One-shot (non-streaming) output is reproducible for a fixed seed + params
(verified byte-identical 2026-06-02). STREAMING output is NOT — adaptive-
chunk boundaries depend on live-measured RTF (wall-clock), so splits vary
run to run; streamable auditions are ephemeral anyway (no Asset). PerTh
watermark is applied unconditionally (Resemble policy).
estimated_latency:
cold_start_s: 16
warm_per_unit: "~0.5s TTFB streaming, ~3.9× realtime (A6000)"
license: MIT
notes: |
Streaming front-end built in-house (eshpfi stacks/chatterbox-fast/): FastAPI
+ ChatterboxTurboTTS + an adaptive buffer-ratchet scheduler. Deployed beside
the buffered `chatterbox` (:8196), which is unchanged. Defaults sourced from
the 2026-06-02 spike (temperature 0.8 / top_p 0.95 / top_k 1000 /
repetition_penalty 1.2). exaggeration / cfg_weight are deliberately omitted —
Turbo ignores them. streamable:true routes the UI to an ephemeral audition
(progressive <audio>, no Asset/library entry); re-run on `chatterbox` to keep
output. Status experimental until the first real browser audition verifies
progressive playback end-to-end.
- id: index-tts
name: IndexTTS-2
description: >
@@ -2000,6 +2126,11 @@ reproducibility_audit:
model_deterministic: false
image_tag_mutable: true
notes: "/tts exposes seed (0=random); temperature-sampled, not byte-exact. PerTh watermark unconditional (Resemble policy). image :latest is mutable — pin a digest/SHA for true repro."
- service: chatterbox-fast
seedable: true
model_deterministic: false
image_tag_mutable: true
notes: "/tts exposes seed (0=random) — one-shot byte-exact for fixed seed+params (verified 2026-06-02); STREAMING non-reproducible (timing-dependent chunk boundaries), auditions ephemeral. PerTh watermark unconditional. image local/chatterbox-fast:v1 is tag-pinned + mutable — pin a digest for true repro."
- service: index-tts
seedable: false
model_deterministic: true