feat(zonos): OpenAI-ish REST adapter for asset-engine routing

Upstream Zonos ships only Gradio + Python SDK — no REST surface — so
asset-engine (which routes a clean JSON POST to /v1/audio/speech) can't
target it directly. Add a thin FastAPI adapter (stacks/zonos/adapter/):
POST /v1/audio/speech in front of the Zonos SDK, built FROM local/zonos
to reuse torch/CUDA/SDK. Returns a JSON envelope {audio, audio_format,
seed} — the seed rides back so asset-engine regenerate/fork can pin it
(Zonos is the fleet's first genuinely seedable TTS). compose gains a
zonos-api service on 8201; .env.example gains the port + voices dir.
This commit is contained in:
vh
2026-05-31 13:59:10 -07:00
parent 71df6f7474
commit 81efa8da96
7 changed files with 283 additions and 10 deletions
+37
View File
@@ -63,3 +63,40 @@ services:
- homepage.icon=mdi-waveform
- homepage.description=Expressive multilingual TTS + cloning, 44kHz (Gradio eval, irv-ml1)
- homepage.href=http://10.100.79.3:${ZONOS_PORT}
# OpenAI-ish REST adapter (POST /v1/audio/speech) that asset-engine
# routes to — upstream Zonos has no REST surface, only Gradio + SDK.
# Built FROM the gradio image above (reuses torch/CUDA/SDK); loads its
# own copy of the model, so it adds ~6 GB VRAM on top of the gradio
# service. Drop the gradio service once Zonos earns a permanent slot.
zonos-api:
image: local/zonos-api:${ZONOS_TAG}
build:
context: ./adapter
dockerfile: Dockerfile
args:
ZONOS_BASE: local/zonos:${ZONOS_TAG}
container_name: zonos-api
restart: unless-stopped
runtime: nvidia
depends_on:
- zonos
ports:
- "${ZONOS_BIND:-0.0.0.0}:${ZONOS_API_PORT}:8000"
environment:
- NVIDIA_VISIBLE_DEVICES=${ZONOS_GPU_DEVICES:-0}
- NVIDIA_DRIVER_CAPABILITIES=compute,utility
- HF_HOME=/app/hf_cache
- ZONOS_MODEL=${ZONOS_MODEL:-Zyphra/Zonos-v0.1-transformer}
- ZONOS_VOICES_DIR=/app/voices
volumes:
- ${ZONOS_CACHE_DIR}:/app/hf_cache
# Reference clips for zero-shot cloning, selected by the `voice`
# request field (filename under this dir).
- ${ZONOS_VOICES_DIR}:/app/voices:ro
healthcheck:
test: ["CMD-SHELL", "python3 -c \"import urllib.request,sys; urllib.request.urlopen('http://127.0.0.1:8000/health', timeout=5); sys.exit(0)\""]
interval: 30s
timeout: 10s
retries: 3
start_period: 600s