From ab696ecbd1d5d35967e8514cb264957ea78a4a70 Mon Sep 17 00:00:00 2001 From: Vuong Hoang Date: Sat, 25 Apr 2026 14:25:06 -0700 Subject: [PATCH] stacks/index-tts: revert git-lfs build attempt; document the LFS budget hazard + media-CDN workaround MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tried adding git-lfs install + git lfs pull to the build to get real example WAVs into the image — failed with: Error downloading object: examples/emo_hate.wav: Smudge error: batch response: This repository exceeded its LFS budget. The account responsible for the budget should increase it to restore access. The index-tts org's LFS bandwidth quota is exhausted upstream and out of our control. Reverting the Dockerfile change. The examples aren't needed for the wrapper to work; emotion_text and emotion_vector are sufficient for end-to-end testing without any WAV file at all. For users who want the bundled example clips as starter audio, README now documents the media-CDN URL trick — same LFS objects served via a different code path that doesn't count against the LFS API budget. INDEX_TTS_TAG stays at v1. --- stacks/index-tts/.env.example | 6 ++---- stacks/index-tts/Dockerfile | 25 ++++++++++++++----------- stacks/index-tts/README.md | 16 ++++++++++++++++ 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/stacks/index-tts/.env.example b/stacks/index-tts/.env.example index f8d60bc..ac7b338 100644 --- a/stacks/index-tts/.env.example +++ b/stacks/index-tts/.env.example @@ -6,10 +6,8 @@ INDEX_TTS_SHA=830f6f8f94a51fea23ab1d639027a86200075a4e # Local image tag — bump when you change build context (Dockerfile, -# app.py, entrypoint.sh) to force a fresh layer build. v2 = git-lfs -# added so the example WAVs in /opt/index-tts/examples/ come down as -# real audio (v1 left them as LFS pointer stubs). -INDEX_TTS_TAG=v2 +# app.py, entrypoint.sh) to force a fresh layer build. +INDEX_TTS_TAG=v1 # ── network ────────────────────────────────────────────────────────── # Host port. Container listens on 8000 internally. diff --git a/stacks/index-tts/Dockerfile b/stacks/index-tts/Dockerfile index c91dd23..7e2d47c 100644 --- a/stacks/index-tts/Dockerfile +++ b/stacks/index-tts/Dockerfile @@ -15,25 +15,28 @@ ENV DEBIAN_FRONTEND=noninteractive \ RUN apt-get update \ && apt-get install -y --no-install-recommends \ python3.10 python3.10-venv python3-pip \ - git git-lfs ffmpeg libsndfile1 \ + git ffmpeg libsndfile1 \ ca-certificates wget \ && rm -rf /var/lib/apt/lists/* \ - && python3.10 -m venv /opt/venv \ - && git lfs install --system + && python3.10 -m venv /opt/venv # Pinned IndexTTS-2 SHA — bump in stack .env (INDEX_TTS_SHA build arg) # when you want upstream updates. # -# `git lfs pull` after the checkout fetches examples/emo_*.wav and the -# example/voice_*.wav reference clips that are stored as LFS objects. -# Without it, the .wav files come down as ~130-byte LFS pointer text -# files, and `docker cp`-ing them out as starter material for -# /worktank/index-tts/{voices,emotions} produces unusable garbage. +# Note on LFS: examples/emo_*.wav and examples/voice_*.wav in the +# upstream repo are Git LFS objects, but the index-tts org has +# repeatedly exhausted GitHub's LFS bandwidth budget — `git lfs pull` +# in the build aborts with "This repository exceeded its LFS budget". +# We don't need the examples for the wrapper to work; they're just +# convenient starter audio. To stage real LFS-backed examples on the +# host, fetch them once via the media CDN (a different code path that +# doesn't count against the LFS API budget): +# +# curl -fsSL -o /worktank/index-tts/emotions/hate.wav \ +# https://media.githubusercontent.com/media/index-tts/index-tts/main/examples/emo_hate.wav ARG INDEX_TTS_SHA=830f6f8f94a51fea23ab1d639027a86200075a4e RUN git clone https://github.com/index-tts/index-tts.git /opt/index-tts \ - && cd /opt/index-tts \ - && git checkout ${INDEX_TTS_SHA} \ - && git lfs pull + && cd /opt/index-tts && git checkout ${INDEX_TTS_SHA} # CUDA 12.8 torch wheels (per IndexTTS pyproject.toml's tool.uv.index # pin — same versions, same source). diff --git a/stacks/index-tts/README.md b/stacks/index-tts/README.md index 83ddd03..688f583 100644 --- a/stacks/index-tts/README.md +++ b/stacks/index-tts/README.md @@ -127,6 +127,22 @@ ssh irv-ml1 ' - **Model download** — happens in the entrypoint on first start; the config.yaml file in the cache dir is the gate. To force a re-download, delete that file and recreate the container. +- **Bundled example WAVs are LFS pointers, not audio.** Upstream stores + `examples/emo_*.wav` and `examples/voice_*.wav` as Git LFS objects. + The image clones the repo without `git lfs pull` (the index-tts org + has exhausted GitHub's LFS bandwidth budget repeatedly, so doing it + in the Dockerfile aborts the build). If you want the IndexTTS-2 + example clips as starter material, fetch them once via the media + CDN — that's a separate code path that doesn't count against the + LFS API budget: + + ```bash + ssh irv-ml1 ' + cd /worktank/index-tts/emotions + curl -fsSL -o hate.wav https://media.githubusercontent.com/media/index-tts/index-tts/main/examples/emo_hate.wav + curl -fsSL -o sad.wav https://media.githubusercontent.com/media/index-tts/index-tts/main/examples/emo_sad.wav + ' + ``` - **HF cache pinning** — `infer_v2.py` pins `HF_HUB_CACHE` at import time to `./checkpoints/hf_cache`. The wrapper sets this env var before importing, so auxiliary HF assets (MaskGCT, campplus, BigVGAN,