68f3cd05fe
Voxtral final fix (8th iteration): * The bundled voxtral_tts.yaml hardcodes gpu_memory_utilization: 0.8 on the language_model stage — overrides the CLI flag. Mounted a patched copy (0.4) at /etc/voxtral/voxtral_tts.yaml and pointed --stage-configs-path there. * With Kyutai stopped to free 5 GB on the 3090, both stages fit (target 9.4 + 2.4 GB ≈ 11.8 GB; 17 GB free post-kyutai-stop). * Voxtral now healthy on GPU 0 — bench: 1.9-2.7 s TTFB, real WAV. Fish s2-pro optimization (per-request sweep, no model swap): * `streaming: true` in request body drops TTFB from 7.7 s → 0.026 s (300×). Total time goes up ~1 s (chunked HTTP overhead) but perceived latency = TTFB. Use stream:true for any interactive use. * `latency: "balanced"` actually slower than default — bad name; skip. * `use_memory_cache: "on"` no measurable benefit. * `chunk_length: 100` (default 200) no TTFB benefit non-streaming. * Server-side `--half` (fp16 inference) added via compose `command` override — passes through start_server.sh's $@ unchanged into api_server.py. Should reduce total time too. Validation pending the post-restart bench. Kyutai stopped to free GPU 0 budget — the bench numbers earlier (3.4 s avg) were unimpressive vs Voxtral's 2.3 s in the same multilingual slot. Kept the stack files for future re-deploy if needed; just the running container is gone.
106 lines
5.1 KiB
YAML
106 lines
5.1 KiB
YAML
# Fish Audio S2-Pro — the most expressive open-source TTS as of
|
||
# 2026-04. 4B params, dual-AR architecture (Slow AR for semantic
|
||
# codebook + Fast AR for 9 residual codebooks), trained on 10M+ hours
|
||
# across 80+ languages. ~150 ms streaming TTFB on warm GPU.
|
||
#
|
||
# Why this stack alongside the existing TTS:
|
||
# * Headline feature: 15,000+ paralinguistic / emotion tags via
|
||
# natural language, e.g. [laugh] [whispers] [super happy] [sigh].
|
||
# Chatterbox Turbo only has 9 fixed tags — Fish's vocabulary is
|
||
# dramatically richer for any emotive use case.
|
||
# * 91.61% paralinguistic win rate on EmergentTTS-Eval — currently
|
||
# the leader on that benchmark.
|
||
# * Voice cloning + native multi-speaker / multi-turn generation.
|
||
# * MIT-style license (weights, training code, inference engine all
|
||
# open).
|
||
#
|
||
# Image is built locally from upstream's repo via docker buildx
|
||
# git-context. Upstream ships a compose with `--profile server` for
|
||
# the API path; we adapt that to our `restart: unless-stopped`
|
||
# convention + bind-mount layout.
|
||
#
|
||
# All tunables live in .env — edit that, not this file.
|
||
|
||
services:
|
||
fish-s2:
|
||
image: local/fish-s2:${FISH_S2_TAG}
|
||
build:
|
||
context: https://github.com/fishaudio/fish-speech.git#${FISH_S2_SHA}
|
||
# The REAL production Dockerfile is at docker/Dockerfile (per
|
||
# upstream's compose.base.yml). The repo also ships a
|
||
# `dockerfile.dev` at root which is a thin
|
||
# `FROM ghcr.io/fishaudio/fish-speech:${VERSION}` wrapper meant
|
||
# for dev iteration on top of a private base image — that path
|
||
# 403s on anonymous pulls. Build from source via docker/Dockerfile
|
||
# instead.
|
||
dockerfile: docker/Dockerfile
|
||
# Multi-stage Dockerfile — `server` stage installs start_server.sh
|
||
# and exposes the API. The default last stage is `webui` (gradio
|
||
# only), which crashloops silently because start_server.sh isn't
|
||
# there. Target=server is what upstream's compose.yml does.
|
||
target: server
|
||
args:
|
||
# Build args mirror upstream compose.base.yml defaults.
|
||
# CUDA_VER 12.9 + UV_EXTRA cu129 = the CUDA 12.9 PyTorch wheels.
|
||
# irv-ml1's driver (595.58.03 / CUDA 13.2 capable) is
|
||
# backward-compatible with 12.9-built images.
|
||
BACKEND: cuda
|
||
CUDA_VER: "12.9.0"
|
||
UV_EXTRA: cu129
|
||
UV_VERSION: "0.8.15"
|
||
container_name: fish-s2
|
||
restart: unless-stopped
|
||
runtime: nvidia
|
||
ports:
|
||
- "${FISH_S2_BIND:-0.0.0.0}:${FISH_S2_PORT}:8080"
|
||
environment:
|
||
- NVIDIA_VISIBLE_DEVICES=${FISH_S2_GPU_DEVICES:-1}
|
||
- BACKEND=cuda
|
||
# COMPILE=1 enables torch.compile — upstream claims ~10× speedup
|
||
# on the autoregressive forward, at the cost of ~60 s warmup the
|
||
# first time each input shape is seen. Worth the speedup; turn
|
||
# off via .env if you hit a torch.compile bug on a future model
|
||
# checkpoint.
|
||
- COMPILE=${FISH_S2_COMPILE:-1}
|
||
- API_PORT=8080
|
||
# Model selection. Override Fish's Dockerfile defaults so we can
|
||
# swap variants via .env without rebuilding. Both checkpoints are
|
||
# pre-pulled by the deploy playbook into bind-mounted checkpoints/.
|
||
# s2-pro — 4B class, ~17 GB VRAM, slow but highest quality
|
||
# s1-mini — lighter, ~3-5× smaller model.pth, much faster
|
||
- LLAMA_CHECKPOINT_PATH=checkpoints/${FISH_S2_MODEL:-s2-pro}
|
||
- DECODER_CHECKPOINT_PATH=checkpoints/${FISH_S2_MODEL:-s2-pro}/codec.pth
|
||
# Hugging Face cache for model weights — first start pulls
|
||
# fishaudio/s2-pro (~9 GB BF16) into this dir.
|
||
- HF_HOME=/app/hf_cache
|
||
volumes:
|
||
# Model checkpoints (auto-downloaded on first run, then cached).
|
||
- ${FISH_S2_CHECKPOINT_DIR}:/app/checkpoints
|
||
# Reference audio for voice cloning — drop ~5–15 s WAV clips here.
|
||
- ${FISH_S2_REFERENCE_DIR}:/app/references
|
||
# Persistent HF cache so model re-pull only happens on first deploy.
|
||
- ${FISH_S2_CACHE_DIR}:/app/hf_cache
|
||
# Pass --half to start_server.sh → enables fp16 inference on the
|
||
# LLM half. Speeds up the autoregressive loop (the dominant cost
|
||
# in TTFB). Also enables the streaming path's faster total time.
|
||
# build_compile_args() echoes unknown args back to the exec line.
|
||
command: ["--half"]
|
||
healthcheck:
|
||
# Fish ships /v1/health on the API server. python urllib instead
|
||
# of curl because the upstream image is python-based and may not
|
||
# carry curl. 127.0.0.1 explicit to dodge the IPv6-first
|
||
# localhost trap we hit on chatterbox + news-digest.
|
||
test: ["CMD-SHELL", "python3 -c \"import urllib.request,sys; sys.exit(0 if urllib.request.urlopen('http://127.0.0.1:8080/v1/health', timeout=5).status==200 else 1)\""]
|
||
interval: 30s
|
||
timeout: 10s
|
||
retries: 3
|
||
# First boot: torch.compile warmup + first-pull HF download +
|
||
# checkpoint load. Generous deadline.
|
||
start_period: 900s
|
||
labels:
|
||
- homepage.group=AI Systems
|
||
- homepage.name=Fish Audio S2-Pro
|
||
- homepage.icon=mdi-fish
|
||
- homepage.description=Most expressive open-source TTS — 15k+ paralinguistic tags, voice cloning, 80+ languages (irv-ml1)
|
||
- homepage.href=http://10.100.79.3:${FISH_S2_PORT}
|