Skip to content

fix(audio/indextts2): declare the missing IndexTTS2 virtualenv dependencies (#5201)#5223

Open
OliverBryant wants to merge 2 commits into
xorbitsai:mainfrom
OliverBryant:fix/indextts2-venv-deps-5201
Open

fix(audio/indextts2): declare the missing IndexTTS2 virtualenv dependencies (#5201)#5223
OliverBryant wants to merge 2 commits into
xorbitsai:mainfrom
OliverBryant:fix/indextts2-venv-deps-5201

Conversation

@OliverBryant

Copy link
Copy Markdown
Collaborator

Summary

Follow-up to #5201 (and complementary to #5203). As reported in #5201 (comment), IndexTTS2 cannot launch at all on the slim v3.0.0 GPU image: the model spec's virtualenv package list omits most of the runtime dependencies of the bundled thirdparty/indextts inference code, and the slim image no longer provides them globally. Launch fails with a chain of ModuleNotFoundError (librosa, then einops, then more) before inference can start.

Changes

xinference/model/audio/model_spec.json — complete the IndexTTS2 virtualenv declaration with the packages actually imported on the infer_v2 code path (traced statically from infer_v2.py through the indextts.* import graph, then verified empirically, see below):

  • librosa, soundfile — audio I/O (infer_v2 loads prompts via librosa.load; the wrapper encodes responses with soundfile)
  • einops, omegaconf, sentencepiece, textstat — imported by the GPT/s2mel/text-frontend modules
  • accelerate — declared by upstream index-tts as a hard dependency
  • #system_torchaudio#infer_v2 imports torchaudio at module level (only #system_torch# was declared)
  • WeTextProcessing ; sys_platform == 'linux' and platform_machine == 'x86_64' and wetext ; sys_platform != 'linux' or platform_machine != 'x86_64' — the text normalizers indextts/utils/front.py selects at runtime. WeTextProcessing depends on pynini, which only publishes x86_64 manylinux wheels, hence the split markers (standard PEP 508 markers pass through the spec filter to uv untouched).

xinference/thirdparty/indextts/utils/front.pyTextNormalizer.load() hard-selected tn (WeTextProcessing) whenever platform.system() == "Linux", which can never work on linux aarch64 (no pynini wheel; the image is built for both amd64 and arm64). It now falls back to wetext when tn is not importable. Behavior on linux x86_64 is unchanged (still tn).

Verification

All checks were run in containers reproducing the slim image's environment:

  • linux/amd64, py3.12: installing exactly the new package list (placeholders resolved to torch/torchaudio/numpy; modelscope present as in the parent env), import indextts.infer_v2 succeeds, and TextNormalizer().load() + normalize() work for both zh and en via WeTextProcessing 1.2.0.
  • linux/arm64, py3.12: the markers select wetext (+kaldifst, which does ship aarch64 wheels), and the new fallback path normalizes zh text correctly.
  • TorchCodec sanity (why no Dockerfile change is needed): on ubuntu:22.04 with the Dockerfile's exact deadsnakes python3.12 + apt ffmpeg (4.4, shared libs) layers and torch==2.11.0/torchaudio==2.11.0/torchcodec==0.14.0 per requirements-runtime.txt, torchcodec loads its FFmpeg-4 core and torchaudio.save/load round-trip successfully — the v2.12.0-era loading failure from [Bug] IndexTTS2 /v1/audio/speech returns 500 at WAV save: libtorchcodec cannot load in v2.12.0 Docker #5201/升级到v2.9.0后,加载Eembedding和reranker模型报错 Could not load libtorchcodec. #4960 (mismatched torchcodec 0.10 + a static FFmpeg 6 without shared libraries) is already resolved by the current slim-image pins. The remaining launch blocker was purely the venv declaration fixed here.

Fixes the launch failure reported in #5201's v3.0.0 follow-up testing; with #5203 merged, the original WAV-save failure is bypassed as well.

…encies

The IndexTTS2 model spec's virtualenv package list omitted most of the
runtime dependencies of the bundled thirdparty/indextts inference code
(librosa, soundfile, einops, omegaconf, sentencepiece, textstat, and the
WeTextProcessing/wetext text normalizers). On the slim v3 GPU image,
which no longer ships these globally, launching IndexTTS2 fails with a
chain of ModuleNotFoundError before inference can start.

Complete the declaration with the packages actually imported on the
infer_v2 code path, add #system_torchaudio# (infer_v2 imports
torchaudio), and select the text normalizer per platform:
WeTextProcessing on linux x86_64, wetext elsewhere, since pynini only
publishes x86_64 manylinux wheels. Teach TextNormalizer.load() to fall
back to wetext when WeTextProcessing is unavailable so linux aarch64
works as well.
@XprobeBot XprobeBot added bug Something isn't working gpu labels Jul 22, 2026
@XprobeBot XprobeBot added this to the v3.x milestone Jul 22, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the virtualenv package dependencies for an audio model specification and refactors the text normalizer import logic in xinference/thirdparty/indextts/utils/front.py to fall back to wetext on non-x86_64 Linux architectures. Feedback suggests raising the ImportError on x86_64 Linux instead of falling back to wetext (which is not installed on that architecture) to avoid a secondary ModuleNotFoundError, and recommends passing the machine architecture as an explicit parameter to the utility function.

Comment thread xinference/thirdparty/indextts/utils/front.py
On linux x86_64 the venv installs WeTextProcessing, not wetext; falling
back to wetext there would mask a broken tn/pynini environment behind a
misleading wetext ModuleNotFoundError. Only fall back on architectures
where pynini has no prebuilt wheels.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working gpu

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants