Files
esh-pfi-infrastructure/stacks/zonos/README.md
T
vh ba0ec64ac3 docs(zonos-gateway): capture the live :8890 gateway stack + emotion-preset system
Captures the production Zonos TTS path that the repo was blind to: stock ZONOS2
:1920 engine (stacks/zonos-engine) fronted by zonos-gateway:0.2.0 :8890, reached
via the LiteLLM ext-tts alias. Documents the emotion-preset system (neutral/warm/
excited/sad/intense/whisper, the simple preset: caller path), the API, and the
measured real-time cost (calibrated steering free at RTF~0.52, cfg1.5 ~0.625 —
still realtime). Flags the gateway source (~/zonos-gateway on irv-ml1) as not yet
in gitea. Marks stacks/zonos (v0.1 Gradio) dead/superseded. Records the emotion-
lever finding (text-priming flat -> native steering works) in persistent memory.
2026-07-17 15:56:11 -07:00

93 lines
4.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Zonos
> **⚠️ SUPERSEDED / NOT DEPLOYED (2026-07-17).** This stack is Zonos **v0.1**
> (Gradio UI + a v0.1 SDK adapter) and is **no longer running** anywhere on the
> fleet. The live Zonos TTS path is **ZONOS2** — see `stacks/zonos-engine`
> (the `:1920` engine) + `stacks/zonos-gateway` (the `:8890` OpenAI-compatible
> gateway with the emotion-preset system, reached via the LiteLLM `ext-tts`
> alias). Kept for history; do not deploy.
Zyphra's expressive multilingual open-weight TTS
([Zyphra/Zonos](https://github.com/Zyphra/Zonos)) — 44 kHz output,
zero-shot voice cloning, and explicit emotion/conditioning controls —
served via the **official repo's Gradio interface**.
Models ([`Zonos.from_pretrained()`](https://github.com/Zyphra/Zonos)):
| Variant | HF repo | Notes |
|---|---|---|
| transformer | [Zyphra/Zonos-v0.1-transformer](https://huggingface.co/Zyphra/Zonos-v0.1-transformer) | ~3.6 GB, no special kernels (default) |
| hybrid | [Zyphra/Zonos-v0.1-hybrid](https://huggingface.co/Zyphra/Zonos-v0.1-hybrid) | Mamba-SSM; needs Ampere+ GPU + extra build deps |
**Server:** irv-ml1 (Irvine, WireGuard-only)
**Ports:** 8199 Gradio eval UI (container 7860) · 8203 REST adapter (container 8000)
**GPUs:** pins to device 0 (RTX 3090) by default; ~6 GB VRAM
**Image:** `local/zonos:v1` — built locally from a pinned git SHA of the
upstream repo via docker buildx's git URL context
**Upstream:** [Zyphra/Zonos](https://github.com/Zyphra/Zonos) (Apache-2.0),
trained on 200k+ hours; multilingual EN/JA/ZH/FR/DE
## Why this stack exists
A different *control surface* from the rest of the bench: Zonos exposes
**emotion/conditioning sliders** plus pitch/rate conditioning and 44 kHz
output, where Chatterbox/Dia use inline tags and Fish uses
natural-language paralinguistic tags. Worth A/B-ing by ear against
Chatterbox-Turbo (the research that prompted this stack explicitly said
"benchmark Zonos against Chatterbox before choosing").
## Two surfaces: Gradio eval (8199) + REST adapter (8203)
The official repo ships a **Gradio WebUI + Python SDK only** — no REST
endpoint. So this stack runs two services:
- **`zonos`** (8199) — upstream Gradio UI, for *auditioning quality by ear*.
- **`zonos-api`** (8203) — a thin OpenAI-ish adapter we built
(`adapter/server.py`) exposing `POST /v1/audio/speech` so **asset-engine**
can route to Zonos like every other TTS in the catalog. Returns a JSON
envelope `{audio: <base64>, audio_format, seed}` — the `seed` rides back
so regenerate/fork can pin it (Zonos is the fleet's first seedable TTS).
The adapter is built `FROM local/zonos:<tag>` (reuses torch/CUDA/SDK) and
loads its own copy of the model (~6 GB on top of the Gradio service). Once
Zonos earns a permanent slot, drop the Gradio service and keep the adapter.
The community FastAPI fork ([PR #73](https://github.com/Zyphra/Zonos/pull/73))
was the alternative; we chose the self-owned adapter over pinning to an
unmerged fork.
### Adapter request (example)
```bash
curl -sS http://10.100.79.3:8203/v1/audio/speech \
-H 'content-type: application/json' \
-d '{"input":"Hello from Zonos.","language":"en-us","seed":420}' \
| python3 -c 'import sys,json,base64; d=json.load(sys.stdin); open("out.wav","wb").write(base64.b64decode(d["audio"])); print("seed",d["seed"])'
```
Cloning: drop a 1030s WAV in `/worktank/zonos/voices/` and pass its
filename as `"voice"`. `GET /v1/audio/voices` lists what's available.
## Deploy
```bash
# from this workstation (irv-ml1 is WG-only — routes via ana-wg):
scripts/deploy-stack.sh irv-ml1 zonos
# then on irv-ml1, first run builds the image from the pinned SHA:
# docker compose up -d --build
```
Open `http://10.100.79.3:8199/` for the Gradio UI. First boot pulls the
model (~3.6 GB) into `ZONOS_CACHE_DIR`; the 600 s `start_period` covers
it.
## Notes
- **Pin `ZONOS_SHA`** to a full 40-char commit before relying on this —
`.env.example` ships `main`, which is not reproducible.
- The upstream image bundles **espeak-ng** (required for Zonos's
phonemization) via its Dockerfile.
- `GRADIO_SERVER_NAME=0.0.0.0` is set so the in-container Gradio binds
all interfaces and the host port-map reaches it. If a future upstream
hardcodes `server_name`, the API fork above is the cleaner path.