Files
esh-pfi-infrastructure/stacks/fish-s2/compose.yaml
T
vh 68f3cd05fe voxtral: mount patched stage YAML to dodge hardcoded 0.8 GPU util; fish-s2: --half + streaming wins
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.
2026-04-28 00:35:55 -07:00

106 lines
5.1 KiB
YAML
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.
# 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 ~515 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}