From 59c05c0765b61f4c8fe5d66ff7fe3c6a960e09e4 Mon Sep 17 00:00:00 2001 From: yrom Date: Fri, 23 May 2025 02:02:27 +0800 Subject: [PATCH] fix: add force_rebuild flag for fused alias_free_activation and update installation instructions --- .gitignore | 3 ++ MANIFEST.in | 4 +- README.md | 52 ++++++++++++------- .../BigVGAN/alias_free_activation/__init__.py | 0 .../alias_free_activation/cuda/load.py | 43 +++++++++++---- indextts/gpt/model.py | 4 +- indextts/infer.py | 19 +++---- pyproject.toml | 3 ++ setup.py | 38 ++++++++++++-- 9 files changed, 120 insertions(+), 46 deletions(-) create mode 100644 indextts/BigVGAN/alias_free_activation/__init__.py create mode 100644 pyproject.toml diff --git a/.gitignore b/.gitignore index 9a078a3..d2eee28 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,6 @@ checkpoints/*.model checkpoints/.cache outputs/ build/ +*.py[cod] +*.egg-info/ +.venv diff --git a/MANIFEST.in b/MANIFEST.in index ad8e99e..a1f90e6 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,3 +1,3 @@ global-exclude *~ *.py[cod] -include *.cu *.cpp -include *.h *.hpp +include indextts/BigVGAN/alias_free_activation/cuda/*.cu indextts/BigVGAN/alias_free_activation/cuda/*.cpp +include indextts/BigVGAN/alias_free_activation/cuda/*.h diff --git a/README.md b/README.md index ffbecb4..26b6bee 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ The main improvements and contributions are summarized as follows: ## Model Download -| **HuggingFace** | **ModelScope** | +| 🤗**HuggingFace** | **ModelScope** | |----------------------------------------------------------|----------------------------------------------------------| | [IndexTTS](https://huggingface.co/IndexTeam/Index-TTS) | [IndexTTS](https://modelscope.cn/models/IndexTeam/Index-TTS) | | [😁IndexTTS-1.5](https://huggingface.co/IndexTeam/IndexTTS-1.5) | [IndexTTS-1.5](https://modelscope.cn/models/IndexTeam/IndexTTS-1.5) | @@ -118,11 +118,36 @@ The main improvements and contributions are summarized as follows: git clone https://github.com/index-tts/index-tts.git ``` 2. Install dependencies: + +Create a new conda environment and install dependencies: + ```bash conda create -n index-tts python=3.10 conda activate index-tts -pip install -r requirements.txt apt-get install ffmpeg +# or use conda to install ffmpeg +conda install -c conda-forge ffmpeg +``` + +Install [PyTorch](https://pytorch.org/get-started/locally/), e.g.: +```bash +pip install torch torchaudio --index-url https://download.pytorch.org/whl/cu118 +``` + +> [!NOTE] +> If you are using Windows you may encounter [an error](https://github.com/index-tts/index-tts/issues/61) when installing `pynini`: +`ERROR: Failed building wheel for pynini` +> In this case, please install `pynini` via `conda`: +> ```bash +> # after conda activate index-tts +> conda install -c conda-forge pynini==2.1.6 +> pip install WeTextProcessing --no-deps +> ``` + +Install `IndexTTS` as a package: +```bash +cd index-tts +pip install -e . ``` 3. Download models: @@ -152,19 +177,22 @@ wget https://huggingface.co/IndexTeam/IndexTTS-1.5/resolve/main/unigram_12000.vo wget https://huggingface.co/IndexTeam/IndexTTS-1.5/resolve/main/config.yaml -P checkpoints ``` +> [!NOTE] +> If you prefer to use the `IndexTTS-1.0` model, please replace `IndexTeam/IndexTTS-1.5` with `IndexTeam/IndexTTS` in the above commands. + + 4. Run test script: ```bash # Please put your prompt audio in 'test_data' and rename it to 'input.wav' -PYTHONPATH=. python indextts/infer.py +python indextts/infer.py ``` 5. Use as command line tool: ```bash # Make sure pytorch has been installed before running this command -pip install -e . indextts "大家好,我现在正在bilibili 体验 ai 科技,说实话,来之前我绝对想不到!AI技术已经发展到这样匪夷所思的地步了!" \ --voice reference_voice.wav \ --model_dir checkpoints \ @@ -179,27 +207,15 @@ indextts --help #### Web Demo ```bash -pip install -e ".[webui]" +pip install -e ".[webui]" --no-build-isolation python webui.py # use another model version: python webui.py --model_dir IndexTTS-1.5 ``` + Open your browser and visit `http://127.0.0.1:7860` to see the demo. -#### Note for Windows Users - -On Windows, you may encounter [an error](https://github.com/index-tts/index-tts/issues/61) when installing `pynini`: -`ERROR: Failed building wheel for pynini` - -In this case, please install `pynini` via `conda`: - -```bash -# after conda activate index-tts -conda install -c conda-forge pynini==2.1.5 -pip install WeTextProcessing==1.0.3 -pip install -e ".[webui]" -``` #### Sample Code ```python diff --git a/indextts/BigVGAN/alias_free_activation/__init__.py b/indextts/BigVGAN/alias_free_activation/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/indextts/BigVGAN/alias_free_activation/cuda/load.py b/indextts/BigVGAN/alias_free_activation/cuda/load.py index f4ff4d8..d567bfa 100644 --- a/indextts/BigVGAN/alias_free_activation/cuda/load.py +++ b/indextts/BigVGAN/alias_free_activation/cuda/load.py @@ -45,7 +45,32 @@ def chinese_path_compile_support(sources, buildpath): -def load(): +def load(force_rebuild=False): + try: + from indextts.BigVGAN.alias_free_activation.cuda import anti_alias_activation_cuda + if not force_rebuild: return anti_alias_activation_cuda + except ImportError: + anti_alias_activation_cuda = None + module_name = "anti_alias_activation_cuda" + # Build path + srcpath = pathlib.Path(__file__).parent.absolute() + buildpath = srcpath / "build" + + _create_build_dir(buildpath) + filepath = buildpath / f"{module_name}{cpp_extension.LIB_EXT}" + if not force_rebuild and os.path.exists(filepath): + import importlib.util + import importlib.abc + # If the file exists, we can load it directly + spec = importlib.util.spec_from_file_location(module_name, filepath) + if spec is not None: + module = importlib.util.module_from_spec(spec) + assert isinstance(spec.loader, importlib.abc.Loader) + spec.loader.exec_module(module) + return module + if not cpp_extension.CUDA_HOME: + raise RuntimeError(cpp_extension.CUDA_NOT_FOUND_MESSAGE) + cpp_extension.verify_ninja_availability() # Check if cuda 11 is installed for compute capability 8.0 cc_flag = [] _, bare_metal_major, _ = _get_cuda_bare_metal_version(cpp_extension.CUDA_HOME) @@ -53,24 +78,18 @@ def load(): cc_flag.append("-gencode") cc_flag.append("arch=compute_80,code=sm_80") - # Build path - srcpath = pathlib.Path(__file__).parent.absolute() - buildpath = srcpath / "build" - _create_build_dir(buildpath) - # Helper function to build the kernels. def _cpp_extention_load_helper(name, sources, extra_cuda_flags): + is_windows = cpp_extension.IS_WINDOWS return cpp_extension.load( name=name, sources=sources, build_directory=buildpath, extra_cflags=[ - "-O3", + "-O3" if not is_windows else "/O2", ], extra_cuda_cflags=[ "-O3", - "-gencode", - "arch=compute_70,code=sm_70", "--use_fast_math", ] + extra_cuda_flags @@ -101,8 +120,9 @@ def load(): def _get_cuda_bare_metal_version(cuda_dir): + nvcc = os.path.join(cuda_dir, 'bin', 'nvcc') raw_output = subprocess.check_output( - [cuda_dir + "/bin/nvcc", "-V"], universal_newlines=True + [nvcc, "-V"], universal_newlines=True ) output = raw_output.split() release_idx = output.index("release") + 1 @@ -115,7 +135,8 @@ def _get_cuda_bare_metal_version(cuda_dir): def _create_build_dir(buildpath): try: - os.mkdir(buildpath) + if not os.path.isdir(buildpath): + os.mkdir(buildpath) except OSError: if not os.path.isdir(buildpath): print(f"Creation of the build directory {buildpath} failed") diff --git a/indextts/gpt/model.py b/indextts/gpt/model.py index 4e64660..31de19d 100644 --- a/indextts/gpt/model.py +++ b/indextts/gpt/model.py @@ -3,7 +3,7 @@ import functools import torch import torch.nn as nn import torch.nn.functional as F -from transformers import GPT2Config, GPT2PreTrainedModel, LogitsProcessorList +from transformers import GPT2Config, GPT2PreTrainedModel, LogitsProcessorList, GenerationMixin from transformers.modeling_outputs import CausalLMOutputWithCrossAttentions from transformers.utils.model_parallel_utils import (assert_device_map, get_device_map) @@ -37,7 +37,7 @@ class ResBlock(nn.Module): return F.relu(self.net(x) + x) -class GPT2InferenceModel(GPT2PreTrainedModel): +class GPT2InferenceModel(GPT2PreTrainedModel, GenerationMixin): def __init__(self, config, gpt, text_pos_emb, embeddings, norm, linear, kv_cache=False): super().__init__(config) # Note: the argument named `text_pos_emb` here actually represents the mel position embedding diff --git a/indextts/infer.py b/indextts/infer.py index 3afe945..14573ef 100644 --- a/indextts/infer.py +++ b/indextts/infer.py @@ -1,11 +1,9 @@ import os -import re +import sys import time from subprocess import CalledProcessError from typing import Dict, List, Tuple -import numpy as np -import sentencepiece as spm import torch import torchaudio from torch.nn.utils.rnn import pad_sequence @@ -90,20 +88,23 @@ class IndexTTS: except (ImportError, OSError, CalledProcessError) as e: use_deepspeed = False print(f">> DeepSpeed加载失败,回退到标准推理: {e}") + print("See more details https://www.deepspeed.ai/tutorials/advanced-install/") self.gpt.post_init_gpt2_config(use_deepspeed=use_deepspeed, kv_cache=True, half=True) else: - self.gpt.post_init_gpt2_config(use_deepspeed=False, kv_cache=False, half=False) + self.gpt.post_init_gpt2_config(use_deepspeed=False, kv_cache=True, half=False) if self.use_cuda_kernel: # preload the CUDA kernel for BigVGAN try: - from indextts.BigVGAN.alias_free_activation.cuda import load - - anti_alias_activation_cuda = load.load() + from indextts.BigVGAN.alias_free_activation.cuda import load as anti_alias_activation_loader + anti_alias_activation_cuda = anti_alias_activation_loader.load() print(">> Preload custom CUDA kernel for BigVGAN", anti_alias_activation_cuda) - except: - print(">> Failed to load custom CUDA kernel for BigVGAN. Falling back to torch.") + except Exception as e: + print(">> Failed to load custom CUDA kernel for BigVGAN. Falling back to torch.", e, file=sys.stderr) + print( + "See more details: https://github.com/index-tts/index-tts/issues/164#issuecomment-2903453206" + ) self.use_cuda_kernel = False self.bigvgan = Generator(self.cfg.bigvgan, use_cuda_kernel=self.use_cuda_kernel) self.bigvgan_path = os.path.join(self.model_dir, self.cfg.bigvgan_checkpoint) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..638dd9c --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["setuptools>=61.0"] +build-backend = "setuptools.build_meta" diff --git a/setup.py b/setup.py index 333c559..f5f9a8a 100644 --- a/setup.py +++ b/setup.py @@ -1,12 +1,41 @@ import platform +import os from setuptools import find_packages, setup - +# add fused `anti_alias_activation` cuda extension if CUDA is available +anti_alias_activation_cuda_ext = None +if platform.system() != "Darwin": + try: + from torch.utils import cpp_extension + if cpp_extension.CUDA_HOME is not None: + anti_alias_activation_cuda_ext = cpp_extension.CUDAExtension( + name="indextts.BigVGAN.alias_free_activation.cuda.anti_alias_activation_cuda", + sources=[ + "indextts/BigVGAN/alias_free_activation/cuda/anti_alias_activation.cpp", + "indextts/BigVGAN/alias_free_activation/cuda/anti_alias_activation_cuda.cu", + ], + include_dirs=["indextts/BigVGAN/alias_free_activation/cuda"], + extra_compile_args={ + "cxx": ["-O3"], + "nvcc": [ + "-O3", + "--use_fast_math", + "-U__CUDA_NO_HALF_OPERATORS__", + "-U__CUDA_NO_HALF_CONVERSIONS__", + "--expt-relaxed-constexpr", + "--expt-extended-lambda", + ], + }, + ) + else: + print("CUDA_HOME is not set. Skipping anti_alias_activation CUDA extension.") + except ImportError: + print("PyTorch is not installed. Skipping torch extension.") setup( name="indextts", - version="0.1.1", + version="0.1.4", author="Index SpeechTeam", author_email="xuanwu@bilibili.com", long_description=open("README.md", encoding="utf8").read(), @@ -32,6 +61,8 @@ setup( extras_require={ "webui": ["gradio"], }, + ext_modules=[anti_alias_activation_cuda_ext] if anti_alias_activation_cuda_ext else [], + cmdclass={"build_ext": cpp_extension.BuildExtension} if anti_alias_activation_cuda_ext else {}, entry_points={ "console_scripts": [ "indextts = indextts.cli:main", @@ -40,9 +71,8 @@ setup( license="Apache-2.0", python_requires=">=3.10", classifiers=[ - "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.10", "Operating System :: OS Independent", - "License :: OSI Approved :: Apache Software License", "Intended Audience :: Science/Research", "Topic :: Scientific/Engineering", "Topic :: Scientific/Engineering :: Artificial Intelligence",