# IndexTTS-2 — Bilibili's emotion-controllable zero-shot TTS, served # behind our own thin FastAPI wrapper (stacks/index-tts/app.py). # # Why this stack exists alongside qwen3-tts and cosyvoice: # IndexTTS-2 disentangles timbre from emotion — emotion can be cloned # from a separate audio reference, set via 8-vector, or derived from # free text. Neither qwen3-tts nor cosyvoice expose this cleanly in # English. See stacks/index-tts/README.md for the full rationale. # # Build: image is local, built from the Dockerfile in this dir. Pinned # upstream SHA lives in .env as INDEX_TTS_SHA so rebuilds are # reproducible. # # Model: ~5-7 GB IndexTTS-2 weights download on first start via the # entrypoint, persisted under ${INDEX_TTS_CACHE_DIR}. # # License note: weights carry a custom Bilibili license (free at our # scale, but not OSI-open). The wrapper code is ours, MIT-by-default. # # All tunables live in .env — edit that, not this file. services: index-tts: image: local/index-tts:${INDEX_TTS_TAG} build: context: . dockerfile: Dockerfile args: INDEX_TTS_SHA: ${INDEX_TTS_SHA} container_name: index-tts restart: unless-stopped runtime: nvidia ports: - "${INDEX_TTS_BIND:-0.0.0.0}:${INDEX_TTS_PORT}:8000" environment: - NVIDIA_VISIBLE_DEVICES=${INDEX_TTS_GPU_DEVICES:-all} - INDEX_TTS_MODEL_DIR=/app/checkpoints - INDEX_TTS_VOICES_DIR=/app/voices - INDEX_TTS_EMOTIONS_DIR=/app/emotions - INDEX_TTS_FP16=${INDEX_TTS_FP16:-1} - INDEX_TTS_DEVICE=${INDEX_TTS_DEVICE:-} - INDEX_TTS_LOG_LEVEL=${INDEX_TTS_LOG_LEVEL:-INFO} volumes: - ${INDEX_TTS_CACHE_DIR}:/app/checkpoints - ${INDEX_TTS_VOICES_DIR}:/app/voices - ${INDEX_TTS_EMOTIONS_DIR}:/app/emotions healthcheck: # Match Dockerfile's healthcheck. Compose-level entry overrides the # image-level one if anything ever needs tweaking per-deploy. test: ["CMD-SHELL", "wget -q -O /dev/null http://localhost:8000/healthz || exit 1"] interval: 30s timeout: 10s retries: 3 # First boot: ~5-7 GB HF download + IndexTTS-2 import (touches several # auxiliary HF repos for MaskGCT, campplus, BigVGAN, w2v-bert) + initial # CUDA warmup. Generous deadline to ride that out. start_period: 600s labels: - homepage.group=AI - Dormant - homepage.name=IndexTTS-2 - homepage.icon=mdi-account-music - homepage.description=Emotion-controllable TTS w/ voice cloning (irv-ml1) - homepage.href=http://irv-ml1.nh3.internal:${INDEX_TTS_PORT}