diff --git a/indextts/BigVGAN/alias_free_activation/cuda/load.py b/indextts/BigVGAN/alias_free_activation/cuda/load.py index ca5d01d..f4ff4d8 100644 --- a/indextts/BigVGAN/alias_free_activation/cuda/load.py +++ b/indextts/BigVGAN/alias_free_activation/cuda/load.py @@ -14,6 +14,37 @@ Set it to empty stringo avoid recompilation and assign arch flags explicity in e os.environ["TORCH_CUDA_ARCH_LIST"] = "" +import re +import shutil +import tempfile + +# 补丁修复:sources 路径含中文字符时,生成 build.ninja 乱码导致编译失败 +# 使用临时目录来规避 ninja 编译失败(比如中文路径) +def chinese_path_compile_support(sources, buildpath): + pattern = re.compile(r'[\u4e00-\u9fff]') + if not bool(pattern.search(str(sources[0].resolve()))): + return buildpath # 检测非中文路径跳过 + # Create build directory + resolves = [ item.name for item in sources] + ninja_compile_dir = os.path.join(tempfile.gettempdir(), "BigVGAN", "cuda") + os.makedirs(ninja_compile_dir, exist_ok=True) + new_buildpath = os.path.join(ninja_compile_dir, "build") + os.makedirs(new_buildpath, exist_ok=True) + print(f"ninja_buildpath: {new_buildpath}") + # Copy files to directory + sources.clear() + current_dir = os.path.dirname(__file__) + ALLOWED_EXTENSIONS = {'.py', '.cu', '.cpp', '.h'} + for filename in os.listdir(current_dir): + item = pathlib.Path(current_dir).joinpath(filename) + tar_path = pathlib.Path(ninja_compile_dir).joinpath(item.name) + if not item.suffix.lower() in ALLOWED_EXTENSIONS:continue + pathlib.Path(shutil.copy2(item, tar_path)) + if tar_path.name in resolves:sources.append(tar_path) + return new_buildpath + + + def load(): # Check if cuda 11 is installed for compute capability 8.0 cc_flag = [] @@ -58,6 +89,10 @@ def load(): srcpath / "anti_alias_activation.cpp", srcpath / "anti_alias_activation_cuda.cu", ] + + # 兼容方案:ninja 特殊字符路径编译支持处理(比如中文路径) + buildpath = chinese_path_compile_support(sources, buildpath) + anti_alias_activation_cuda = _cpp_extention_load_helper( "anti_alias_activation_cuda", sources, extra_cuda_flags ) diff --git a/indextts/infer.py b/indextts/infer.py index 21a1107..d6a6cd2 100644 --- a/indextts/infer.py +++ b/indextts/infer.py @@ -110,6 +110,9 @@ class IndexTTS: self.normalizer = TextNormalizer() self.normalizer.load() print(">> TextNormalizer loaded") + # 缓存参考音频mel: + self.cache_audio_prompt = None + self.cache_cond_mel = None def preprocess_text(self, text): # chinese_punctuation = ",。!?;:“”‘’()【】《》" @@ -186,15 +189,26 @@ class IndexTTS: normalized_text = self.preprocess_text(text) print(f"normalized text:{normalized_text}") - audio, sr = torchaudio.load(audio_prompt) - audio = torch.mean(audio, dim=0, keepdim=True) - if audio.shape[0] > 1: - audio = audio[0].unsqueeze(0) - audio = torchaudio.transforms.Resample(sr, 24000)(audio) - cond_mel = MelSpectrogramFeatures()(audio).to(self.device) - cond_mel_frame = cond_mel.shape[-1] - if verbose: - print(f"cond_mel shape: {cond_mel.shape}", "dtype:", cond_mel.dtype) + + # 如果参考音频改变了,才需要重新生成 cond_mel, 提升速度 + if self.cache_cond_mel is None or self.cache_audio_prompt != audio_prompt: + audio, sr = torchaudio.load(audio_prompt) + audio = torch.mean(audio, dim=0, keepdim=True) + if audio.shape[0] > 1: + audio = audio[0].unsqueeze(0) + audio = torchaudio.transforms.Resample(sr, 24000)(audio) + cond_mel = MelSpectrogramFeatures()(audio).to(self.device) + cond_mel_frame = cond_mel.shape[-1] + if verbose: + print(f"cond_mel shape: {cond_mel.shape}", "dtype:", cond_mel.dtype) + + self.cache_audio_prompt = audio_prompt + self.cache_cond_mel = cond_mel + else: + cond_mel = self.cache_cond_mel + cond_mel_frame = cond_mel.shape[-1] + pass + auto_conditioning = cond_mel