# Zonos-v0.1 (Zyphra's expressive multilingual open-weight TTS) served # via the OFFICIAL Zyphra/Zonos repo's Gradio interface. # # Why this stack exists alongside the other TTS: # * Apache-2.0, 44 kHz output, zero-shot voice cloning from a # 10-30 s sample, and explicit emotion/conditioning sliders — # a different control surface from tag-based engines. # * Multilingual (EN/JA/ZH/FR/DE), trained on 200k+ hours. # * Cheap to run (~6 GB VRAM, transformer variant ~3.6 GB weights). # # CAVEAT — this is an AUDITION/EVAL surface, not a skaldsong-pluggable # engine yet: the official repo ships a Gradio WebUI + Python SDK, NOT # an OpenAI-compatible /v1/audio/speech endpoint. To wire Zonos into # skaldsong's router we'd need the community FastAPI fork (Zyphra/Zonos # PR #73) or a thin adapter. Bench it by ear first; promote later if it # earns a slot. # # Image is built locally from the upstream repo's Dockerfile via docker # buildx git-context. All tunables live in .env — edit that, not this. services: zonos: image: local/zonos:${ZONOS_TAG} build: # Single Dockerfile at repo root; bundles espeak-ng (required for # Zonos's eSpeak phonemization). context: https://github.com/Zyphra/Zonos.git#${ZONOS_SHA} dockerfile: Dockerfile container_name: zonos restart: unless-stopped runtime: nvidia # Upstream's Dockerfile sets NO CMD — it launches the app from its own # compose instead. Without this the NVIDIA entrypoint prints the CUDA # banner and exits 0, looping forever (nothing binds 7860). Mirror # upstream: python3 gradio_interface.py (demo.launch binds 0.0.0.0:7860). command: ["python3", "gradio_interface.py"] ports: - "${ZONOS_BIND:-0.0.0.0}:${ZONOS_PORT}:7860" environment: - NVIDIA_VISIBLE_DEVICES=${ZONOS_GPU_DEVICES:-0} - NVIDIA_DRIVER_CAPABILITIES=compute,utility # Make Gradio bind all interfaces inside the container so the host # port-map reaches it (Gradio otherwise may bind 127.0.0.1 only). - GRADIO_SERVER_NAME=0.0.0.0 # Explicit: gradio_interface.py reads GRADIO_SHARE (defaults False). # Pin it off so a missing default never tries a public share tunnel # (irv-ml1 has no egress for that). - GRADIO_SHARE=False - HF_HOME=/app/hf_cache volumes: - ${ZONOS_CACHE_DIR}:/app/hf_cache healthcheck: # No JSON status route on the Gradio app — just probe the root # page for liveness. start_period covers the first-boot model pull. test: ["CMD-SHELL", "python3 -c \"import urllib.request,sys; urllib.request.urlopen('http://127.0.0.1:7860/', timeout=5); sys.exit(0)\""] interval: 30s timeout: 10s retries: 3 start_period: 600s labels: - homepage.group=AI Systems - homepage.name=Zonos - 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