diff --git a/Dockerfile.fish b/Dockerfile.fish index bf34099..895c888 100644 --- a/Dockerfile.fish +++ b/Dockerfile.fish @@ -11,8 +11,14 @@ FROM nvidia/cuda:12.8.0-runtime-ubuntu24.04 ENV DEBIAN_FRONTEND=noninteractive +# build-essential + python3-dev are REQUIRED on Blackwell: torch.compile +# (Inductor) shells out to gcc at runtime to build CUDA kernels as Python +# extension modules, which needs both the C toolchain AND Python.h. Without +# either, the first synth call crashes the worker with either "Failed to find +# C compiler" or "CalledProcessError ... cuda_utils.c". RUN apt-get update && apt-get install -y --no-install-recommends \ - python3 python3-pip ffmpeg libsndfile1 curl ca-certificates \ + python3 python3-pip python3-dev ffmpeg libsndfile1 curl ca-certificates \ + build-essential \ && rm -rf /var/lib/apt/lists/* WORKDIR /app diff --git a/docker-compose.yml b/docker-compose.yml index 59c26e1..ca96749 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -21,6 +21,10 @@ services: - "${FISH_PORT:-8092}:8092" volumes: - ${FISH_REFERENCES_DIR:-/mnt/data/fish-references}:/app/references + # .dockerignore excludes .venv/, so bind-mount from the host checkout. + # Dockerfile comment claims COPY . includes them, but it doesn't. + - /home/ava/dev/fish-speech/.venv:/app/.venv:ro + - /home/ava/dev/fish-speech/checkpoints:/app/checkpoints:ro environment: - NVIDIA_VISIBLE_DEVICES=${FISH_GPU:-1} deploy: @@ -34,8 +38,8 @@ services: test: ["CMD", "python3", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8092/v1/health')"] interval: 30s timeout: 10s - start_period: 180s - retries: 3 + start_period: 600s # torch.compile warmup can take ~3-5 min from cold + retries: 5 protovoice: build: . diff --git a/docs/reference/tts-backends.md b/docs/reference/tts-backends.md index 7e1e1a1..a225954 100644 --- a/docs/reference/tts-backends.md +++ b/docs/reference/tts-backends.md @@ -33,6 +33,10 @@ Runs as the `fish-speech` sidecar container. Build context is `../fish-speech` ( See [Clone a Voice](/guides/clone-a-voice). +### Exposing Fish as an OpenAI-compatible endpoint + +Fish's native `POST /v1/tts` uses its own `ServeTTSRequest` shape, not OpenAI's `/v1/audio/speech`. To put Fish behind a LiteLLM gateway (or any OpenAI SDK client), run the external shim at [`protoLabsAI/lab` → `experiments/fish-openai-shim/`](https://github.com/protoLabsAI/lab). It wraps `POST /v1/audio/speech` and forwards to this sidecar, supporting `wav` (one-shot), `pcm` (streaming), and `mp3` (streaming via ffmpeg). The shim is separate from protoVoice itself because it's deployment-infra, not part of the voice pipeline. + ### Env | Variable | Default | Purpose | diff --git a/docs/tutorials/docker-compose.md b/docs/tutorials/docker-compose.md index e786eaa..49c022f 100644 --- a/docs/tutorials/docker-compose.md +++ b/docs/tutorials/docker-compose.md @@ -35,6 +35,8 @@ START_VLLM=0 LLM_URL=http://10.0.0.10:8000/v1 docker compose up -d - `HF_HOME` → `/models` — HuggingFace cache. Default: `/mnt/models/huggingface`. - `FISH_REFERENCES_DIR` → `/app/references` — persists saved voice references across restarts. +- **`../fish-speech/.venv` → `/app/.venv`** (read-only) — bind-mounted because Fish's `.dockerignore` excludes `.venv/`, so the image ships without it. Without this mount the container crashes at startup with `/app/.venv/bin/python: No such file or directory`. +- **`../fish-speech/checkpoints` → `/app/checkpoints`** (read-only) — same rationale; S2-Pro weights are too large to bake into the image. Keep them in the host checkout and mount. ## GPU allocation @@ -49,6 +51,12 @@ On a single-GPU host, set `TTS_BACKEND=kokoro` to skip Fish entirely and keep ev Fish Audio's first call triggers a ~2-minute `torch.compile` codegen. protoVoice's `prewarm()` on startup sends a single silent utterance to absorb this — you should never see that hit in a real turn. +The sidecar's healthcheck uses `start_period: 600s` so Docker doesn't mark the container unhealthy and restart-loop while `torch.compile` is still running. If you observe the container repeatedly bouncing on first boot, confirm that value hasn't been lowered. + +### Fish image needs a C toolchain + Python headers + +`Dockerfile.fish` installs `build-essential` and `python3-dev` on top of `nvidia/cuda:runtime`. Both are **required** — torch.compile's Inductor backend shells out to `gcc` at synth time to build CUDA kernels as Python extension modules. Missing either produces `Failed to find C compiler` or `CalledProcessError ... cuda_utils.c` on first synth, followed by an infinite restart loop. If you ever strip these from the Dockerfile for image size, Fish will stop working on any `torch.compile`-gated build. + Whisper takes ~2 s to load + warm. vLLM takes 30-60 s to load + warm depending on model size.