mirror of
https://github.com/index-tts/index-tts.git
synced 2026-09-19 01:50:39 +08:00
docs: add a setup guide written for coding agents
Users increasingly hand a repo URL to an agent and ask it to "get this running". The README is written for a person on a fresh machine, so an agent following it re-downloads ~10 GB of wheels and ~5 GB of weights that an existing IndexTTS-2 install already has, and it has no way to tell which verification commands actually prove anything. This guide is written for that reader: probe commands to run before touching anything, the decision points for reusing an existing .venv or HuggingFace cache, how to check local weights against the remote manifest instead of re-downloading, and a table of the failure signatures seen while running the README end-to-end on a clean Linux box. Notable points it records, since none are obvious from the code: - `uv lock --check` compares pyproject.toml against uv.lock and says nothing about what is installed; `uv sync --dry-run` is the environment check. - `ensure_models_available()` migrates an old HF cache layout instead of downloading, saving ~4.5 GB — but it copies rather than symlinks. - Auxiliary models are not in the model repo; they arrive in hf_cache/ on first run, and the ModelScope 404 for BigVGAN is benign fallback noise. - The WebUI binds 0.0.0.0 with no authentication.
This commit is contained in:
@@ -0,0 +1,245 @@
|
||||
# Agent Setup Guide
|
||||
|
||||
Instructions for a coding agent (Claude Code, Cursor, Codex, …) asked to get
|
||||
IndexTTS running on a user's machine. A user may hand you only the URL of this
|
||||
file; everything you need is here.
|
||||
|
||||
Your goal: a working inference run. Your constraint: **do not redo work the
|
||||
machine has already done.** A full setup downloads ~10 GB of wheels and ~5 GB of
|
||||
weights. Users upgrading from IndexTTS-2 usually have most of it already.
|
||||
|
||||
Never guess state — run the probe commands and read the output.
|
||||
|
||||
## 0. Probe before you touch anything
|
||||
|
||||
```bash
|
||||
# repo
|
||||
git -C . rev-parse --abbrev-ref HEAD 2>/dev/null; git -C . log --oneline -1 2>/dev/null
|
||||
git -C . status --short
|
||||
|
||||
# toolchain
|
||||
uv --version # required; see step 2 if missing
|
||||
python3 -VV
|
||||
nvidia-smi --query-gpu=name,memory.total,driver_version --format=csv,noheader
|
||||
ls -d /usr/local/cuda* 2>/dev/null; nvcc --version 2>/dev/null | tail -2
|
||||
|
||||
# existing env
|
||||
ls -d .venv && .venv/bin/python -c "import torch;print(torch.__version__, torch.version.cuda)" 2>/dev/null
|
||||
|
||||
# existing weights, anywhere on the box
|
||||
ls checkpoints checkpoints_2 checkpoints_25 2>/dev/null
|
||||
du -sh ~/.cache/huggingface/hub 2>/dev/null
|
||||
ls ~/.cache/huggingface/hub 2>/dev/null | grep -iE "w2v-bert|maskgct|campplus|bigvgan"
|
||||
df -h . | tail -1
|
||||
```
|
||||
|
||||
Record: CUDA toolkit version, free disk, whether a `.venv` exists, and which
|
||||
model files already exist. Decide the branch points in steps 3–5 from that.
|
||||
|
||||
## 1. Requirements that are not negotiable
|
||||
|
||||
| Requirement | Why |
|
||||
| --- | --- |
|
||||
| Python `>=3.10,<3.12` | `pyproject.toml` pins it; `uv` installs a matching interpreter itself |
|
||||
| CUDA Toolkit **12.8+** | wheels come from a `cu128` index |
|
||||
| `uv` | the lockfile is the only supported dependency path |
|
||||
| ~35 GB free disk | ~10 GB venv + ~5 GB weights (2.5) + build/cache overhead |
|
||||
|
||||
CPU-only and Apple Silicon can install, but inference expects CUDA. Say so
|
||||
early rather than after a 20-minute download.
|
||||
|
||||
## 2. Update the code
|
||||
|
||||
If a repo already exists, do not clone over it — the user may have local edits
|
||||
and a warm `.venv` next to it.
|
||||
|
||||
```bash
|
||||
git stash list # note anything already stashed
|
||||
git status --short # local edits? ask before discarding
|
||||
git pull --ff-only # or: git fetch && git checkout <branch>
|
||||
```
|
||||
|
||||
Fresh machine:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/index-tts/index-tts.git && cd index-tts
|
||||
pip install -U uv # or: curl -LsSf https://astral.sh/uv/install.sh | sh
|
||||
```
|
||||
|
||||
Git LFS is not required.
|
||||
|
||||
## 3. Dependencies
|
||||
|
||||
```bash
|
||||
uv sync --all-extras
|
||||
```
|
||||
|
||||
That creates `.venv`, picks the interpreter, and installs from `uv.lock`. It is
|
||||
incremental: an existing `.venv` is reconciled, not rebuilt. Extras are
|
||||
`webui`, `deepspeed`, `accel`, `torch_compile`, `test`; drop `--all-extras` and
|
||||
name individual ones with `--extra <name>` if the user wants a smaller install.
|
||||
|
||||
Reusing an env from IndexTTS-2: run `uv sync` in the updated checkout and let it
|
||||
converge. Do not `pip install` into `.venv` by hand, and do not activate a conda
|
||||
env first — `uv` manages the environment itself and a pre-activated one causes
|
||||
conflicts.
|
||||
|
||||
Verify, then stop touching dependencies:
|
||||
|
||||
```bash
|
||||
uv sync --all-extras --dry-run # expect "Would make no changes"
|
||||
uv run tools/gpu_check.py # expect your GPUs listed
|
||||
```
|
||||
|
||||
`uv lock --check` only compares `pyproject.toml` against `uv.lock`. It says
|
||||
nothing about what is installed — use `uv sync --dry-run` for that.
|
||||
|
||||
### Slow networks (mainland China)
|
||||
|
||||
```bash
|
||||
export UV_HTTP_TIMEOUT=900
|
||||
uv sync --all-extras --default-index "https://mirrors.cloud.tencent.com/pypi/simple"
|
||||
export HF_ENDPOINT=https://hf-mirror.com # for model downloads in step 4
|
||||
```
|
||||
|
||||
For the torch wheels specifically, edit the `url` inside the
|
||||
`[[tool.uv.index]]` block in `pyproject.toml` (e.g. to
|
||||
`https://mirror.nju.edu.cn/pytorch/whl/cu128`). Do **not** set that mirror via
|
||||
`UV_INDEX="pytorch-cuda=..."` — that drops `explicit = true`, turns the torch
|
||||
mirror into a general index, and its stale copies of unrelated packages will
|
||||
fabricate resolution conflicts.
|
||||
|
||||
### If a build fails
|
||||
|
||||
Errors naming `flash-attn` or `deepspeed` are build-environment problems, not
|
||||
resolution problems. Both are source distributions that need the project's
|
||||
CUDA-enabled torch at build time; `pyproject.toml` handles this with
|
||||
`[tool.uv.extra-build-dependencies]`. Two failure signatures:
|
||||
|
||||
- `ModuleNotFoundError: No module named 'setuptools'` — something switched these
|
||||
packages to `no-build-isolation`. That mode uses `.venv` as the build
|
||||
environment, and a fresh `.venv` has no `setuptools` yet. Keep
|
||||
`extra-build-dependencies` instead.
|
||||
- a long `nvcc` compile for flash-attn — it should download a prebuilt wheel
|
||||
matching your torch version and C++ ABI. Compiling means the guessed wheel
|
||||
name missed. Check `CUDA_HOME` points at 12.8 and that GitHub releases are
|
||||
reachable.
|
||||
|
||||
`accel` (flash-attn) and `torch_compile` are optional speedups. If they will not
|
||||
build, drop those extras and continue — the model runs without them.
|
||||
|
||||
## 4. Models — check before downloading
|
||||
|
||||
IndexTTS-2.5 is 22 files / ~5.1 GiB. Auxiliary models (w2v-bert-2.0, MaskGCT
|
||||
codec, CAMPPlus, BigVGAN) are **not** in that repo; they land in
|
||||
`{model_dir}/hf_cache/` on first run.
|
||||
|
||||
```bash
|
||||
uv tool install "huggingface-hub[hf_xet]"
|
||||
hf download IndexTeam/IndexTTS-2.5 --local-dir=checkpoints
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```bash
|
||||
uv tool install "modelscope"
|
||||
modelscope download --model IndexTeam/IndexTTS-2.5 --local_dir checkpoints
|
||||
```
|
||||
|
||||
Verify against the remote manifest instead of re-downloading blind:
|
||||
|
||||
```bash
|
||||
curl -s "https://huggingface.co/api/models/IndexTeam/IndexTTS-2.5/tree/main?recursive=true" \
|
||||
| python3 -c 'import json,os,sys
|
||||
for f in json.load(sys.stdin):
|
||||
if f["type"]!="file": continue
|
||||
want=(f.get("lfs") or {}).get("size") or f.get("size") or 0
|
||||
p=os.path.join("checkpoints",f["path"])
|
||||
have=os.path.getsize(p) if os.path.exists(p) else -1
|
||||
if have!=want: print("REDOWNLOAD", f["path"], want, have)'
|
||||
```
|
||||
|
||||
Silence means the local copy matches; skip the download entirely. If that URL
|
||||
times out, swap `huggingface.co` for `hf-mirror.com` — the API host is blocked
|
||||
on some networks even when downloads work.
|
||||
|
||||
### Reusing caches from an IndexTTS-2 install
|
||||
|
||||
Do this before any auxiliary download — it saves ~4.5 GB.
|
||||
|
||||
`ensure_models_available()` in `indextts/utils/model_download.py` searches
|
||||
`{model_dir}/hf_cache/` and then `$HF_HUB_CACHE` (default
|
||||
`~/.cache/huggingface/hub`) for the old
|
||||
`models--{owner}--{name}/snapshots/{hash}/` layout, and copies what it finds
|
||||
instead of downloading. So if the user has an old HuggingFace cache, just point
|
||||
at it:
|
||||
|
||||
```bash
|
||||
export HF_HUB_CACHE=~/.cache/huggingface/hub
|
||||
```
|
||||
|
||||
It **copies** rather than symlinks, so budget disk for a second copy of
|
||||
w2v-bert-2.0 (~2.2 GB).
|
||||
|
||||
Keeping 2.0 alongside 2.5: 2.5 weights in `checkpoints/`, 2.0 weights in
|
||||
`checkpoints_2/`. Nothing is shared between the two, and neither overwrites the
|
||||
other. If disk is tight, one `checkpoints*` tree can be a symlink to weights
|
||||
already on another volume.
|
||||
|
||||
## 5. Example audio
|
||||
|
||||
`examples/*.wav` is not tracked in git. It is fetched automatically the first
|
||||
time the WebUI starts. The `infer_v2_5.py` entrypoint does **not** fetch it, and
|
||||
its default `--prompt_wav` is `examples/voice_01.wav`, so a script run on a
|
||||
fresh clone fails with `FileNotFoundError`. Fetch it first:
|
||||
|
||||
```bash
|
||||
uv run python -c "from indextts.utils.examples_downloader import ensure_examples_available; ensure_examples_available()"
|
||||
```
|
||||
|
||||
Idempotent — existing files are skipped.
|
||||
|
||||
## 6. Smoke test
|
||||
|
||||
```bash
|
||||
PYTHONPATH="$PYTHONPATH:." uv run indextts/infer_v2_5.py \
|
||||
--cfg_path checkpoints/config.yaml \
|
||||
--model_dir checkpoints \
|
||||
--text "Hello world" \
|
||||
--lang EN
|
||||
```
|
||||
|
||||
Success looks like `>> wav file saved to: gen.wav` plus an `RTF:` line. Confirm
|
||||
`gen.wav` is non-trivial (tens of KB, not 0). On first run this also populates
|
||||
`hf_cache/`, which takes several GB and several minutes.
|
||||
|
||||
Then the WebUI:
|
||||
|
||||
```bash
|
||||
uv run webui.py # 2.5, default
|
||||
```
|
||||
|
||||
Serves on `http://127.0.0.1:7860`. Note it binds `0.0.0.0` by default and has no
|
||||
authentication — on a shared or internet-reachable machine, pass
|
||||
`--host 127.0.0.1` or put it behind something that authenticates. Report this to
|
||||
the user rather than silently exposing it.
|
||||
|
||||
## Known traps
|
||||
|
||||
| Symptom | Cause | Action |
|
||||
| --- | --- | --- |
|
||||
| `FileNotFoundError: examples/voice_01.wav` | examples are WebUI-fetched only | step 5 |
|
||||
| `ValueError: vocab_file checkpoints/bpe.model does not exist` | `indextts/infer_v2.py` hardcodes `checkpoints/` and is a benchmark loop, not a CLI | use the Python API for 2.0, or point `checkpoints/` at 2.0 weights |
|
||||
| `HTTPError: <Response [404]>` mentioning `nvidia/bigvgan_*` | BigVGAN is absent from ModelScope | benign — the code falls back to hf-mirror and continues; check for a later `>> All auxiliary models ready.` |
|
||||
| `ModuleNotFoundError: No module named 'setuptools'` while building | `no-build-isolation` on a fresh `.venv` | see step 3 |
|
||||
| `triton-windows ... only has wheels for win_amd64` | that package is Windows-only | it must carry `sys_platform == 'win32'`; Linux gets `triton` via torch |
|
||||
| `does not have an extra named 'cli'` | modern `huggingface-hub` dropped it | use `huggingface-hub[hf_xet]` |
|
||||
| `uv pip check` reports `deepspeed requires nvidia-ml-py` | upstream declares it, the lockfile omits it | pre-existing and harmless for inference |
|
||||
| `unknown field 'preview-features'` | not a valid `[tool.uv]` key | remove it; the whole `[tool.uv]` table is ignored while it is present |
|
||||
|
||||
## Reporting back
|
||||
|
||||
State plainly: what you reused vs installed, what you downloaded, which
|
||||
verification commands you ran and their result, and anything you skipped. If the
|
||||
smoke test did not produce audio, say that instead of describing the setup as
|
||||
complete.
|
||||
Reference in New Issue
Block a user