Download docker/Dockerfile from notmax123/BlueV2: direct link, hf CLI and curl.
- Browser
- Download file 5.48 kB
-
https://huggingface.co/spaces/notmax123/BlueV2/resolve/main/docker/Dockerfile
- Command line
-
hf download hf://spaces/notmax123/BlueV2/docker/Dockerfile
-
curl -L -o Dockerfile https://huggingface.co/spaces/notmax123/BlueV2/resolve/main/docker/Dockerfile
5.48 kB
| # BlueTTS 2.5 ONNX + NVIDIA GPU for RunPod Serverless (no gradio). | |
| # Build from repo root: | |
| # docker buildx build --platform linux/amd64 -f docker/Dockerfile \ | |
| # -t maxme123/blue-v2:serverless-v8 --push . | |
| # | |
| # Russian is included: RUAccent + RUPhon and their ~1 GB of weights are baked in | |
| # below so a cold worker does not download them on its first Russian job. They | |
| # need torch, which is installed from the CPU wheel index — the front end runs on | |
| # CPU by design (BLUE_RU_G2P_DEVICE), and the CUDA torch build would add ~2 GB of | |
| # libraries that duplicate what the base image and onnxruntime-gpu already carry. | |
| # Build with --build-arg WITH_RUSSIAN=0 for a torch-free image without Russian. | |
| ARG CUDA_IMAGE=nvidia/cuda:12.6.3-cudnn-runtime-ubuntu24.04 | |
| FROM ${CUDA_IMAGE} | |
| ENV DEBIAN_FRONTEND=noninteractive \ | |
| PYTHONUNBUFFERED=1 \ | |
| PIP_NO_CACHE_DIR=1 \ | |
| VIRTUAL_ENV=/opt/venv \ | |
| PATH="/opt/venv/bin:$PATH" \ | |
| PYTHONPATH=/app \ | |
| BLUE_DOCKER=1 \ | |
| BLUE_ONNX_GPU=1 \ | |
| BLUE_SERVE_MODE=serverless \ | |
| BLUE_SKIP_GRADIO=1 \ | |
| GRADIO_ANALYTICS_ENABLED=False \ | |
| HF_HUB_DISABLE_TELEMETRY=1 \ | |
| ORT_NUM_THREADS=4 \ | |
| MAX_CONCURRENCY=4 | |
| RUN apt-get update && apt-get install -y --no-install-recommends \ | |
| python3 \ | |
| python3-pip \ | |
| python3-venv \ | |
| python3-dev \ | |
| git \ | |
| ffmpeg \ | |
| espeak-ng \ | |
| libespeak-ng1 \ | |
| libsndfile1 \ | |
| ca-certificates \ | |
| curl \ | |
| && python3 --version \ | |
| && ffmpeg -version | head -1 \ | |
| && python3 -m venv /opt/venv \ | |
| && rm -rf /var/lib/apt/lists/* | |
| WORKDIR /app | |
| ARG WITH_RUSSIAN=1 | |
| COPY docker/requirements-serverless.txt /app/docker/requirements-serverless.txt | |
| COPY docker/requirements-russian.txt /app/docker/requirements-russian.txt | |
| # Order matters, and not for readability: ruphon depends on the CPU `onnxruntime`, | |
| # which unpacks over the same directory as `onnxruntime-gpu`. Whichever pip writes | |
| # last wins, so the Russian deps go in first and the serverless set — which pins | |
| # onnxruntime-gpu — goes in last. The assert below is what turns a future flip | |
| # into a failed build instead of a silently CPU-bound image. | |
| RUN pip install --upgrade pip setuptools wheel \ | |
| && if [ "$WITH_RUSSIAN" = "1" ]; then \ | |
| pip install --index-url https://download.pytorch.org/whl/cpu torch \ | |
| && pip install -r /app/docker/requirements-russian.txt; \ | |
| fi \ | |
| && pip install -r /app/docker/requirements-serverless.txt \ | |
| && python -c "import onnxruntime as ort, sys; \ | |
| p = ort.get_available_providers(); \ | |
| print('ORT', ort.__version__, p); \ | |
| sys.exit('CUDAExecutionProvider missing — the CPU onnxruntime wheel clobbered the GPU one; check install order above') \ | |
| if 'CUDAExecutionProvider' not in p else None" \ | |
| && if [ "$WITH_RUSSIAN" != "1" ]; then \ | |
| python -c "import torch" 2>/dev/null && echo 'ERROR: torch should not be installed' && exit 1 || echo 'OK: no torch'; \ | |
| fi | |
| COPY app.py download_models.py tts.json vocab.json /app/ | |
| COPY g2p /app/g2p | |
| COPY voices /app/voices | |
| COPY onnx_slim /app/onnx_slim | |
| COPY renikud.onnx /app/renikud.onnx | |
| COPY docker/entrypoint.sh /app/docker/entrypoint.sh | |
| COPY docker/rp_handler.py /app/docker/rp_handler.py | |
| # Fail the build, not the first job, if the bundle is incomplete. `stats.npz` is | |
| # what the vocoder input is denormalized with and `uncond.npz` is what makes | |
| # cfg_scale do anything, so a v2 bundle baked in here would be a silent | |
| # quality regression rather than a crash. | |
| # | |
| # The freshness markers are (re)written here rather than copied, so the baked-in | |
| # weights are trusted at startup. Without them every cold start re-downloads | |
| # renikud.onnx — 310 MB on the critical path of each new serverless worker. | |
| RUN chmod +x /app/docker/entrypoint.sh \ | |
| && for f in vocoder.onnx text_encoder.onnx vector_estimator.onnx \ | |
| duration_predictor_style.onnx stats.npz uncond.npz vocab.json; do \ | |
| test -s "/app/onnx_slim/$f" || { echo "MISSING onnx_slim/$f"; exit 1; }; \ | |
| done \ | |
| && test -s /app/renikud.onnx \ | |
| && python -c "import sys, os; \ | |
| from download_models import VOICE_CATALOG, BLUE_REPO, ONNX_BUNDLE_STAMP, RENIKUD_REPO, RENIKUD_STAMP; \ | |
| missing=[m['file'] for m in VOICE_CATALOG.values() if not os.path.exists('/app/voices/'+m['file'])]; \ | |
| sys.exit('MISSING voices: %s' % missing) if missing else print('voices OK:', list(VOICE_CATALOG)); \ | |
| open('/app/.renikud_repo','w').write(RENIKUD_REPO+chr(10)+RENIKUD_STAMP+chr(10)); \ | |
| open('/app/onnx_slim/.repo_id','w').write(BLUE_REPO+chr(10)+ONNX_BUNDLE_STAMP+chr(10)); \ | |
| open('/app/voices/.repo_id','w').write(BLUE_REPO+chr(10)+ONNX_BUNDLE_STAMP+chr(10)); \ | |
| print('markers written')" | |
| # Bake the Russian weights in. RUAccent's dictionary + omograph model and RUPhon's | |
| # graph are ~1 GB fetched on first use, which would otherwise land on the first | |
| # Russian job of every cold worker. Phonemizing one sentence is what triggers the | |
| # download, and it doubles as a build-time check that the front end actually loads | |
| # (the transformers/tokenizer patch in g2p/russian_g2p.py is version-sensitive). | |
| RUN if [ "$WITH_RUSSIAN" = "1" ]; then \ | |
| python -c "from g2p.russian_g2p import phonemize_russian; \ | |
| print('ru warm:', phonemize_russian('Взгляну́в на Санкт-Петербург, я всё понял.'))"; \ | |
| fi | |
| # No HEALTHCHECK — RunPod serverless uses the runpod SDK job loop, not HTTP probes. | |
| CMD ["/app/docker/entrypoint.sh"] | |