From 5ffb84b427d2d7e8fa597cc4f5e31c2b30cfd492 Mon Sep 17 00:00:00 2001 From: Arcitec <38923130+Arcitec@users.noreply.github.com> Date: Mon, 8 Sep 2025 12:56:10 +0200 Subject: [PATCH 01/14] fix: Improve .gitignore and re-add config file - Improves organization and removes extra junk files. - Unignores *.yaml files such as config.yaml from the /checkpoints/ directory since we need that file. --- .gitignore | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 0db34f7..1dd404e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,31 @@ -venv/ -__pycache__ -*.egg-info -*.DS_Store +# Development Tools. +.mypy_cache/ +.ruff_cache/ +__pycache__/ .idea/ .vscode/ -checkpoints/* -outputs/ -build/ + +# Environments. +.venv*/ +venv*/ +conda_env*/ + +# Python Bytecode. *.py[cod] + +# Distribution/Packaging. +/build/ +/dist/ *.egg-info/ -.venv +.pypirc + +# Operating System Junk. +*.DS_Store +Thumbs.db +desktop.ini + +# IndexTTS. +/cache/ +/checkpoints/* +!/checkpoints/*.yaml +/outputs/ From 3e64c4ac11c12d119567fa3a1b47da577170fbc8 Mon Sep 17 00:00:00 2001 From: Arcitec <38923130+Arcitec@users.noreply.github.com> Date: Mon, 8 Sep 2025 12:57:53 +0200 Subject: [PATCH 02/14] fix: Update pandas to fix Gradio errors Gradio requires Pandas >= 2.2.0, otherwise it will throw errors in some situations (such as when GPU is Out of Memory). --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index e17b10b..3faeadf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,7 +11,7 @@ json5==0.10.0 keras==2.9.0 numba==0.58.1 numpy==1.26.2 -pandas==2.1.3 +pandas==2.3.2 matplotlib==3.8.2 munch==4.0.0 opencv-python==4.9.0.80 From d5cdb5eb3cfb34cbb901e4da4a0302c07e6a5e06 Mon Sep 17 00:00:00 2001 From: Arcitec <38923130+Arcitec@users.noreply.github.com> Date: Mon, 8 Sep 2025 12:59:35 +0200 Subject: [PATCH 03/14] fix: Suppress pandas PyArrow future dependency warning Moving the import of pandas *after* we've suppressed FutureWarning, to hide a big and useless warning saying that "Pandas 3.x will require PyArrow". --- webui.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webui.py b/webui.py index ecac7f2..fbd3a51 100644 --- a/webui.py +++ b/webui.py @@ -7,11 +7,11 @@ import time import warnings -import pandas as pd - warnings.filterwarnings("ignore", category=FutureWarning) warnings.filterwarnings("ignore", category=UserWarning) +import pandas as pd + current_dir = os.path.dirname(os.path.abspath(__file__)) sys.path.append(current_dir) sys.path.append(os.path.join(current_dir, "indextts")) From 55b7d321495b530c5467ecdf0e06fb996a011a71 Mon Sep 17 00:00:00 2001 From: Arcitec <38923130+Arcitec@users.noreply.github.com> Date: Mon, 8 Sep 2025 13:01:40 +0200 Subject: [PATCH 04/14] fix: Fix character encoding in examples --- examples/cases.jsonl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/cases.jsonl b/examples/cases.jsonl index d688b8d..1b71672 100644 --- a/examples/cases.jsonl +++ b/examples/cases.jsonl @@ -1,4 +1,4 @@ -{"prompt_audio":"voice_01.wav","text":"Translate for me,what is a surprise!","emo_mode":0} +{"prompt_audio":"voice_01.wav","text":"Translate for me, what is a surprise!","emo_mode":0} {"prompt_audio":"voice_02.wav","text":"The palace is strict, no false rumors, Lady Qi!","emo_mode":0} {"prompt_audio":"voice_03.wav","text":"这个呀,就是我们精心制作准备的纪念品,大家可以看到这个色泽和这个材质啊,哎呀多么的光彩照人。","emo_mode":0} {"prompt_audio":"voice_04.wav","text":"你就需要我这种专业人士的帮助,就像手无缚鸡之力的人进入雪山狩猎,一定需要最老练的猎人指导。","emo_mode":0} From 5f0b0a9f9c57c05440d6d3992e90792d70023ae5 Mon Sep 17 00:00:00 2001 From: Arcitec <38923130+Arcitec@users.noreply.github.com> Date: Mon, 8 Sep 2025 13:08:36 +0200 Subject: [PATCH 05/14] feat(i18n): Add missing UI translation strings --- tools/i18n/locale/en_US.json | 2 ++ tools/i18n/locale/zh_CN.json | 4 +++- webui.py | 6 +++--- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/tools/i18n/locale/en_US.json b/tools/i18n/locale/en_US.json index 8ef3daf..45e486b 100644 --- a/tools/i18n/locale/en_US.json +++ b/tools/i18n/locale/en_US.json @@ -37,6 +37,8 @@ "情感控制方式": "Emotion control method", "GPT2 采样设置": "GPT-2 Sampling Configuration", "参数会影响音频多样性和生成速度详见": "Influence both the diversity of the generated audio and the generation speed. For further details, refer to", + "是否进行采样": "Enable GPT-2 sampling", + "生成Token最大数量,过小导致音频被截断": "Maximum number of tokens to generate. If text exceeds this, the audio will be cut off.", "请上传情感参考音频": "Please upload emotion reference audio", "当前模型版本": "Current model version ", "请输入目标文本": "Please input text to synthesize", diff --git a/tools/i18n/locale/zh_CN.json b/tools/i18n/locale/zh_CN.json index 26a7596..95aaf56 100644 --- a/tools/i18n/locale/zh_CN.json +++ b/tools/i18n/locale/zh_CN.json @@ -36,5 +36,7 @@ "Token数": "Token数", "情感控制方式": "情感控制方式", "GPT2 采样设置": "GPT2 采样设置", - "参数会影响音频多样性和生成速度详见": "参数会影响音频多样性和生成速度详见" + "参数会影响音频多样性和生成速度详见": "参数会影响音频多样性和生成速度详见", + "是否进行采样": "是否进行采样", + "生成Token最大数量,过小导致音频被截断": "生成Token最大数量,过小导致音频被截断" } \ No newline at end of file diff --git a/webui.py b/webui.py index fbd3a51..13fecf8 100644 --- a/webui.py +++ b/webui.py @@ -209,9 +209,9 @@ with gr.Blocks(title="IndexTTS Demo") as demo: with gr.Accordion(i18n("高级生成参数设置"), open=False): with gr.Row(): with gr.Column(scale=1): - gr.Markdown(f"**{i18n('GPT2 采样设置')}** _{i18n('参数会影响音频多样性和生成速度详见')}[Generation strategies](https://huggingface.co/docs/transformers/main/en/generation_strategies)_") + gr.Markdown(f"**{i18n('GPT2 采样设置')}** _{i18n('参数会影响音频多样性和生成速度详见')} [Generation strategies](https://huggingface.co/docs/transformers/main/en/generation_strategies)._") with gr.Row(): - do_sample = gr.Checkbox(label="do_sample", value=True, info="是否进行采样") + do_sample = gr.Checkbox(label="do_sample", value=True, info=i18n("是否进行采样")) temperature = gr.Slider(label="temperature", minimum=0.1, maximum=2.0, value=0.8, step=0.1) with gr.Row(): top_p = gr.Slider(label="top_p", minimum=0.0, maximum=1.0, value=0.8, step=0.01) @@ -220,7 +220,7 @@ with gr.Blocks(title="IndexTTS Demo") as demo: with gr.Row(): repetition_penalty = gr.Number(label="repetition_penalty", precision=None, value=10.0, minimum=0.1, maximum=20.0, step=0.1) length_penalty = gr.Number(label="length_penalty", precision=None, value=0.0, minimum=-2.0, maximum=2.0, step=0.1) - max_mel_tokens = gr.Slider(label="max_mel_tokens", value=1500, minimum=50, maximum=tts.cfg.gpt.max_mel_tokens, step=10, info="生成Token最大数量,过小导致音频被截断", key="max_mel_tokens") + max_mel_tokens = gr.Slider(label="max_mel_tokens", value=1500, minimum=50, maximum=tts.cfg.gpt.max_mel_tokens, step=10, info=i18n("生成Token最大数量,过小导致音频被截断"), key="max_mel_tokens") # with gr.Row(): # typical_sampling = gr.Checkbox(label="typical_sampling", value=False, info="不建议使用") # typical_mass = gr.Slider(label="typical_mass", value=0.9, minimum=0.0, maximum=1.0, step=0.1) From 1845e60aa54ff2433171b8902fe9f0e7cf05dcb1 Mon Sep 17 00:00:00 2001 From: Arcitec <38923130+Arcitec@users.noreply.github.com> Date: Mon, 8 Sep 2025 13:17:34 +0200 Subject: [PATCH 06/14] refactor(i18n): Improve description of generation segmentation --- tools/i18n/locale/en_US.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/i18n/locale/en_US.json b/tools/i18n/locale/en_US.json index 45e486b..a381b94 100644 --- a/tools/i18n/locale/en_US.json +++ b/tools/i18n/locale/en_US.json @@ -28,8 +28,8 @@ "功能设置": "Settings", "分句设置": "Sentence segmentation settings", "参数会影响音频质量和生成速度": "Parameters below affect audio quality and generation speed", - "分句最大Token数": "Max tokens per sentence", - "建议80~200之间,值越大,分句越长;值越小,分句越碎;过小过大都可能导致音频质量不高": "Recommended between 80 and 200. The larger the value, the longer the sentences; the smaller the value, the more fragmented the sentences. Values that are too small or too large may lead to poor audio quality.", + "分句最大Token数": "Max tokens per generation segment", + "建议80~200之间,值越大,分句越长;值越小,分句越碎;过小过大都可能导致音频质量不高": "Recommended range: 80 - 200. Larger values require more VRAM but improves the flow of the speech, while lower values require less VRAM but means more fragmented sentences. Values that are too small or too large may lead to less coherent speech.", "预览分句结果": "Preview sentence segmentation result", "序号": "Index", "分句内容": "Content", From cb0e07f9825c64691372e6da47df214d0b6d005d Mon Sep 17 00:00:00 2001 From: Arcitec <38923130+Arcitec@users.noreply.github.com> Date: Mon, 8 Sep 2025 13:22:49 +0200 Subject: [PATCH 07/14] refactor(i18n): More accurate emotion translations to improve clarity - Matches training data better. - Easier to understand the purpose of the sliders. - Consistent use of adjectives so that the user interface looks nicer. - Reasoning: * Hate -> Disgusted: The original Chinese word expresses disgust, not hatred. Hatred is an angry emotion and was confusing since there's already an Angry slider. * Low -> Melancholic: The original Chinese word talks about feeling melancholic / down low, a state of slow speech and subdued emotions, which is not the same as sadness or depression. The word "Low" is very confusing for this emotion. The most accurate word for the emotion is "melancholic". * Neutral -> Calm: The original Chinese word describes a state of being at peace and tranquility. It's not a neutral, non-emotional state. It's a state of being calm and relaxed. --- tools/i18n/locale/en_US.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/i18n/locale/en_US.json b/tools/i18n/locale/en_US.json index a381b94..620bb36 100644 --- a/tools/i18n/locale/en_US.json +++ b/tools/i18n/locale/en_US.json @@ -11,11 +11,11 @@ "喜": "Happy", "怒": "Angry", "哀": "Sad", - "惧": "Fear", - "厌恶": "Hate", - "低落": "Low", - "惊喜": "Surprise", - "平静": "Neutral", + "惧": "Afraid", + "厌恶": "Disgusted", + "低落": "Melancholic", + "惊喜": "Surprised", + "平静": "Calm", "情感描述文本": "Emotion description", "请输入情感描述文本": "Please input emotion description", "高级生成参数设置": "Advanced generation parameter settings", From feba5010137460ec8decaba2603da7819cb963e6 Mon Sep 17 00:00:00 2001 From: Arcitec <38923130+Arcitec@users.noreply.github.com> Date: Mon, 8 Sep 2025 13:35:17 +0200 Subject: [PATCH 08/14] fix: Fix internal text-to-emotion vector labels - The order of the `convert_dict` now matches the desired order of the emotion vectors, for clarity. - Internal text labels now match the updated English translations. - This (and the previous commit) also fixes a bug: The previous, inaccurate Emotion translations meant that QwenEmotion could not understand words such as "low" at all (no emotion mapping), and it always mapped "hate" to "angry". With the fixed translations, QwenEmotion now correctly maps text-to-emotions from English inputs when users input the words that they've been taught by the user interface. --- indextts/infer_v2.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/indextts/infer_v2.py b/indextts/infer_v2.py index 3ab0861..7c5484c 100644 --- a/indextts/infer_v2.py +++ b/indextts/infer_v2.py @@ -603,17 +603,17 @@ class QwenEmotion: ) self.prompt = "文本情感分类" self.convert_dict = { - "愤怒": "angry", "高兴": "happy", - "恐惧": "fear", - "反感": "hate", + "愤怒": "angry", "悲伤": "sad", - "低落": "low", - "惊讶": "surprise", - "自然": "neutral", + "恐惧": "afraid", + "反感": "disgusted", + "低落": "melancholic", + "惊讶": "surprised", + "自然": "calm", } - self.backup_dict = {"happy": 0, "angry": 0, "sad": 0, "fear": 0, "hate": 0, "low": 0, "surprise": 0, - "neutral": 1.0} + self.backup_dict = {"happy": 0, "angry": 0, "sad": 0, "afraid": 0, "disgusted": 0, "melancholic": 0, + "surprised": 0, "calm": 1.0} self.max_score = 1.2 self.min_score = 0.0 From 58ad225fb41c99ebf873f3b1694391f8164ac0d3 Mon Sep 17 00:00:00 2001 From: Arcitec <38923130+Arcitec@users.noreply.github.com> Date: Mon, 8 Sep 2025 14:00:23 +0200 Subject: [PATCH 09/14] fix: Fast and robust text-to-emotion algorithm - The new algorithm is now very fast and uses less memory, since it doesn't chain multiple `.replace()` calls or create a bunch of temporary strings and temporary dictionaries and lists anymore. - Parses the JSON output from the QwenEmotion model directly instead of trying to manually parse it. If JSON parsing fails, it falls back to a fast and highly-accurate RegEx search which finds all key-value pairs. - The desired emotion vector order is now stored as a static class attribute instead of being created from scratch on every call. - The emotion dictionary creation has been completely rewritten to use a clear algorithm which takes the QwenEmotion answers, builds a new dictionary using `self.desired_vector_order`, maps each key's name to their English translations, fetches the values from QwenEmotion's answers or 0.0 if no value was given by QE, and clamps the values to the min/max ranges. - The `backup_dict` is now removed, since it was error-prone and fragile. It could grow out of sync with the code if not carefully maintained to keep the correct order and labels. - To handle the "fallback" dictionary creation, we now automatically scan the final emotion vectors, and if none of them are above 0.0 (meaning we didn't detect any emotions in the input text), we give the final vectors a "calm: 1.0" value. This means that we never have to worry about the fallback dictionary's correctness. - The previous algorithm had multiple bugs. This rewrite fixes a serious vector order bug: The old algorithm built the dictionary via the found keys, and only checked if there's 8 keys in QwenEmotion's response, but it didn't check that the keys were valid. When building the final emotion dict, it skipped any values if they were not found in QE's response. Meaning that if the QE response only contained 4 of the 8 expected emotion vector labels, those would all be added at the start of the new dictionary as the "first 4 dict slots". After that, it looped through the "backup_dict" and appended any missing values at the end. This resulted in a final emotion dictionary with the wrong order for the emotion vectors. The new code always produces the correct emotion vector order. - Discovered another bug in the text-to-emotion handling for the "melancholic" emotion, which has never worked for Chinese or English at all. It will be fixed in an upcoming patch. --- indextts/infer_v2.py | 83 +++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 43 deletions(-) diff --git a/indextts/infer_v2.py b/indextts/infer_v2.py index 7c5484c..b851055 100644 --- a/indextts/infer_v2.py +++ b/indextts/infer_v2.py @@ -2,6 +2,8 @@ import os from subprocess import CalledProcessError os.environ['HF_HUB_CACHE'] = './checkpoints/hf_cache' +import json +import re import time import librosa import torch @@ -315,8 +317,9 @@ class IndexTTS2: # assert emo_alpha == 1.0 if emo_text is None: emo_text = text - emo_dict, content = self.qwen_emo.inference(emo_text) + emo_dict = self.qwen_emo.inference(emo_text) print(emo_dict) + # convert ordered dict to list of vectors; the order is VERY important! emo_vector = list(emo_dict.values()) if emo_vector is not None: @@ -602,59 +605,41 @@ class QwenEmotion: device_map="auto" ) self.prompt = "文本情感分类" - self.convert_dict = { + self.cn_key_to_en = { "高兴": "happy", "愤怒": "angry", "悲伤": "sad", "恐惧": "afraid", "反感": "disgusted", + # TODO: the "低落" (melancholic) emotion will always be mapped to + # "悲伤" (sad) by QwenEmotion's text analysis. it doesn't know the + # difference between those emotions even if user writes exact words. "低落": "melancholic", "惊讶": "surprised", "自然": "calm", } - self.backup_dict = {"happy": 0, "angry": 0, "sad": 0, "afraid": 0, "disgusted": 0, "melancholic": 0, - "surprised": 0, "calm": 1.0} + self.desired_vector_order = ["高兴", "愤怒", "悲伤", "恐惧", "反感", "低落", "惊讶", "自然"] self.max_score = 1.2 self.min_score = 0.0 + def clamp_score(self, value): + return max(self.min_score, min(self.max_score, value)) + def convert(self, content): - content = content.replace("\n", " ") - content = content.replace(" ", "") - content = content.replace("{", "") - content = content.replace("}", "") - content = content.replace('"', "") - parts = content.strip().split(',') - print(parts) - parts_dict = {} - desired_order = ["高兴", "愤怒", "悲伤", "恐惧", "反感", "低落", "惊讶", "自然"] - for part in parts: - key_value = part.strip().split(':') - if len(key_value) == 2: - parts_dict[key_value[0].strip()] = part - # 按照期望顺序重新排列 - ordered_parts = [parts_dict[key] for key in desired_order if key in parts_dict] - parts = ordered_parts - if len(parts) != len(self.convert_dict): - return self.backup_dict + # generate emotion vector dictionary: + # - insert values in desired order (Python 3.7+ `dict` remembers insertion order) + # - convert Chinese keys to English + # - clamp all values to the allowed min/max range + # - use 0.0 for any values that were missing in `content` + emotion_dict = { + self.cn_key_to_en[cn_key]: self.clamp_score(content.get(cn_key, 0.0)) + for cn_key in self.desired_vector_order + } - emotion_dict = {} - for part in parts: - key_value = part.strip().split(':') - if len(key_value) == 2: - try: - key = self.convert_dict[key_value[0].strip()] - value = float(key_value[1].strip()) - value = max(self.min_score, min(self.max_score, value)) - emotion_dict[key] = value - except Exception: - continue - - for key in self.backup_dict: - if key not in emotion_dict: - emotion_dict[key] = 0.0 - - if sum(emotion_dict.values()) <= 0: - return self.backup_dict + # default to a calm/neutral voice if all emotion vectors were empty + if all(val <= 0.0 for val in emotion_dict.values()): + print(">> no emotions detected; using default calm/neutral voice") + emotion_dict["calm"] = 1.0 return emotion_dict @@ -687,9 +672,21 @@ class QwenEmotion: except ValueError: index = 0 - content = self.tokenizer.decode(output_ids[index:], skip_special_tokens=True).strip("\n") - emotion_dict = self.convert(content) - return emotion_dict, content + content = self.tokenizer.decode(output_ids[index:], skip_special_tokens=True) + + # decode the JSON emotion detections as a dictionary + try: + content = json.loads(content) + except json.decoder.JSONDecodeError: + # invalid JSON; fallback to manual string parsing + # print(">> parsing QwenEmotion response", content) + content = { + m.group(1): float(m.group(2)) + for m in re.finditer(r'([^\s":.,]+?)"?\s*:\s*([\d.]+)', content) + } + # print(">> dict result", content) + + return self.convert(content) if __name__ == "__main__": From a6a955d2aa18d6400b2f4cdaad35e792d5bb231b Mon Sep 17 00:00:00 2001 From: Arcitec <38923130+Arcitec@users.noreply.github.com> Date: Mon, 8 Sep 2025 14:07:35 +0200 Subject: [PATCH 10/14] fix: Add support for melancholic emotion in text-to-emotion vectors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - The "低落" (melancholic) emotion will always be mapped to "悲伤" (sad) by QwenEmotion's text analysis. It doesn't know the difference between those emotions even if the user writes the exact words. - Since the words and their meanings are so similar, it might not be possible to train QwenEmotion to learn the difference. - As a workaround, we perform input text analysis and look for words that mean "melancholic", and swap the "sad" detection result, to make the melancholic/low-energy speech emotion work correctly for users via text-to-emotion. --- indextts/infer_v2.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/indextts/infer_v2.py b/indextts/infer_v2.py index b851055..4d53e99 100644 --- a/indextts/infer_v2.py +++ b/indextts/infer_v2.py @@ -614,11 +614,22 @@ class QwenEmotion: # TODO: the "低落" (melancholic) emotion will always be mapped to # "悲伤" (sad) by QwenEmotion's text analysis. it doesn't know the # difference between those emotions even if user writes exact words. + # SEE: `self.melancholic_words` for current workaround. "低落": "melancholic", "惊讶": "surprised", "自然": "calm", } self.desired_vector_order = ["高兴", "愤怒", "悲伤", "恐惧", "反感", "低落", "惊讶", "自然"] + self.melancholic_words = { + # emotion text phrases that will force QwenEmotion's "悲伤" (sad) detection + # to become "低落" (melancholic) instead, to fix limitations mentioned above. + "低落", + "melancholy", + "melancholic", + "depression", + "depressed", + "gloomy", + } self.max_score = 1.2 self.min_score = 0.0 @@ -686,6 +697,15 @@ class QwenEmotion: } # print(">> dict result", content) + # workaround for QwenEmotion's inability to distinguish "悲伤" (sad) vs "低落" (melancholic). + # if we detect any of the IndexTTS "melancholic" words, we swap those vectors + # to encode the "sad" emotion as "melancholic" (instead of sadness). + text_input_lower = text_input.lower() + if any(word in text_input_lower for word in self.melancholic_words): + # print(">> before vec swap", content) + content["悲伤"], content["低落"] = content.get("低落", 0.0), content.get("悲伤", 0.0) + # print(">> after vec swap", content) + return self.convert(content) From dfe1bd41d8534ee2532950107821c4547a33426b Mon Sep 17 00:00:00 2001 From: Arcitec <38923130+Arcitec@users.noreply.github.com> Date: Mon, 8 Sep 2025 16:17:17 +0200 Subject: [PATCH 11/14] refactor: Remove code duplication in DeepSpeed dependency check --- indextts/infer_v2.py | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/indextts/infer_v2.py b/indextts/infer_v2.py index 4d53e99..2f0f1d3 100644 --- a/indextts/infer_v2.py +++ b/indextts/infer_v2.py @@ -82,23 +82,15 @@ class IndexTTS2: else: self.gpt.eval() print(">> GPT weights restored from:", self.gpt_path) - if self.is_fp16: - use_deepspeed = True - try: - import deepspeed - except (ImportError, OSError, CalledProcessError) as e: - use_deepspeed = False - print(f">> DeepSpeed加载失败,回退到标准推理: {e}") - self.gpt.post_init_gpt2_config(use_deepspeed=use_deepspeed, kv_cache=True, half=True) - else: - use_deepspeed = True - try: - import deepspeed - except (ImportError, OSError, CalledProcessError) as e: - use_deepspeed = False - print(f">> DeepSpeed加载失败,回退到标准推理: {e}") - self.gpt.post_init_gpt2_config(use_deepspeed=use_deepspeed, kv_cache=True, half=False) + use_deepspeed = True + try: + import deepspeed + except (ImportError, OSError, CalledProcessError) as e: + use_deepspeed = False + print(f">> DeepSpeed加载失败,回退到标准推理: {e}") + + self.gpt.post_init_gpt2_config(use_deepspeed=use_deepspeed, kv_cache=True, half=self.is_fp16) if self.use_cuda_kernel: # preload the CUDA kernel for BigVGAN From 17359d3582462ed84f742508304c936fbcb96e76 Mon Sep 17 00:00:00 2001 From: Arcitec <38923130+Arcitec@users.noreply.github.com> Date: Mon, 8 Sep 2025 16:55:49 +0200 Subject: [PATCH 12/14] refactor: Change build system to "uv" to ensure robust installation - Remove legacy "requirements.txt" support, since "pip" is too basic and very often leads to broken installations. - Require "uv" installation method to ensure user success. --- README.md | 18 ++++++++++----- pyproject.toml | 9 +++++--- requirements.txt | 30 ------------------------- uv.lock | 58 ++++++++++++++++++++++++++++++------------------ 4 files changed, 55 insertions(+), 60 deletions(-) delete mode 100644 requirements.txt diff --git a/README.md b/README.md index 3465bc4..c4b90e2 100644 --- a/README.md +++ b/README.md @@ -95,25 +95,31 @@ The key contributions of **indextts2** are summarized as follows: ## Usage Instructions ### Environment Setup + 1. Download this repository: ```bash git clone https://github.com/index-tts/index-tts.git git lfs pull # fetch example files ``` -2. Install dependencies: -We use `uv` to manage the project’s dependency environment. + +2. Install the [uv](https://docs.astral.sh/uv/getting-started/installation/) package + manager. It is *required* for a reliable, modern installation environment. + +3. Install dependencies: + +We use `uv` to manage the project's dependency environment. ```bash uv sync ``` -3. Download models: +4. Download models: -Download by `huggingface-cli`: +Download via `huggingface-cli`: ```bash hf download IndexTeam/IndexTTS-2 --local-dir=checkpoints ``` -Or download by `modelscope` +Or download via `modelscope` ```bash modelscope download --model IndexTeam/IndexTTS-2 --local_dir checkpoints ``` @@ -158,7 +164,7 @@ tts.infer(spk_audio_prompt='examples/voice_07.wav', text=text, output_path="gen. ``` -4. It’s also possible to omit the emotional reference audio and instead provide an 8-float list specifying the intensity of each base emotion (Happy | Angery | Sad | Fear | Hate | Low | Surprise | Neutral). You can additionally control the `use_random` parameter to decide whether to introduce stochasticity during inference; the default is `False`, and setting it to `True` increases randomness: +4. It's also possible to omit the emotional reference audio and instead provide an 8-float list specifying the intensity of each base emotion (Happy | Angery | Sad | Fear | Hate | Low | Surprise | Neutral). You can additionally control the `use_random` parameter to decide whether to introduce stochasticity during inference; the default is `False`, and setting it to `True` increases randomness: ```python from indextts.infer_v2 import IndexTTS2 tts = IndexTTS2(cfg_path="checkpoints/config.yaml", model_dir="checkpoints", is_fp16=False, use_cuda_kernel=False) diff --git a/pyproject.toml b/pyproject.toml index 1e972cf..fe693c2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,6 +5,7 @@ description = "Add your description here" readme = "README.md" requires-python = ">=3.10" dependencies = [ + # IMPORTANT: Always run `uv lock` to resolve and update the lockfile after edits: "accelerate==1.8.1", "cn2an==0.5.22", "cython==3.0.7", @@ -24,7 +25,7 @@ dependencies = [ "numpy==1.26.2", "omegaconf>=2.3.0", "opencv-python==4.9.0.80", - "pandas==2.1.3", + "pandas==2.3.2", "safetensors==0.5.2", "sentencepiece>=0.2.1", "tensorboard==2.9.1", @@ -32,8 +33,10 @@ dependencies = [ "tokenizers==0.21.0", "tqdm>=4.67.1", "transformers==4.52.1", - "wetext>=0.0.9;sys_platform != 'linux'", - "WeTextProcessing;sys_platform == 'linux'", + + # Use "wetext" on Windows/Mac, otherwise "WeTextProcessing" on Linux." + "wetext>=0.0.9; sys_platform != 'linux'", + "WeTextProcessing; sys_platform == 'linux'", ] [tool.uv] diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 3faeadf..0000000 --- a/requirements.txt +++ /dev/null @@ -1,30 +0,0 @@ -accelerate==1.8.1 -descript-audiotools==0.7.2 -transformers==4.52.1 -tokenizers==0.21.0 -cn2an==0.5.22 -ffmpeg-python==0.2.0 -Cython==3.0.7 -g2p-en==2.1.0 -jieba==0.42.1 -json5==0.10.0 -keras==2.9.0 -numba==0.58.1 -numpy==1.26.2 -pandas==2.3.2 -matplotlib==3.8.2 -munch==4.0.0 -opencv-python==4.9.0.80 -tensorboard==2.9.1 -librosa==0.10.2.post1 -safetensors==0.5.2 -deepspeed==0.17.1 -modelscope==1.27.0 -omegaconf -sentencepiece -gradio -tqdm -textstat - -WeTextProcessing; platform_machine == "Linux" -wetext; platform_system != "Linux" diff --git a/uv.lock b/uv.lock index f9e9d09..2a2f555 100644 --- a/uv.lock +++ b/uv.lock @@ -1176,7 +1176,7 @@ requires-dist = [ { name = "numpy", specifier = "==1.26.2" }, { name = "omegaconf", specifier = ">=2.3.0" }, { name = "opencv-python", specifier = "==4.9.0.80" }, - { name = "pandas", specifier = "==2.1.3" }, + { name = "pandas", specifier = "==2.3.2" }, { name = "safetensors", specifier = "==0.5.2" }, { name = "sentencepiece", specifier = ">=0.2.1" }, { name = "tensorboard", specifier = "==2.9.1" }, @@ -2153,7 +2153,7 @@ wheels = [ [[package]] name = "pandas" -version = "2.1.3" +version = "2.3.2" source = { registry = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple" } dependencies = [ { name = "numpy" }, @@ -2161,26 +2161,42 @@ dependencies = [ { name = "pytz" }, { name = "tzdata" }, ] -sdist = { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/86/ff/662dde2193fc93b8547b073db20472b9676f944d907247a46c9c5bc45bfc/pandas-2.1.3.tar.gz", hash = "sha256:22929f84bca106921917eb73c1521317ddd0a4c71b395bcf767a106e3494209f", size = 4272855, upload-time = "2023-11-10T19:19:47.654Z" } +sdist = { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/79/8e/0e90233ac205ad182bd6b422532695d2b9414944a280488105d598c70023/pandas-2.3.2.tar.gz", hash = "sha256:ab7b58f8f82706890924ccdfb5f48002b83d2b5a3845976a9fb705d36c34dcdb", size = 4488684, upload-time = "2025-08-21T10:28:29.257Z" } wheels = [ - { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/6a/81/711b32480f508dcf29cb501f61c4f1c3c72409e9168c6625145440c1c320/pandas-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:acf08a73b5022b479c1be155d4988b72f3020f308f7a87c527702c5f8966d34f", size = 11722181, upload-time = "2023-11-10T19:13:33.959Z" }, - { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/fc/85/ec986ea64f55013d8c669da657f0da86383a15668f9814be2001e08a4807/pandas-2.1.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3cc4469ff0cf9aa3a005870cb49ab8969942b7156e0a46cc3f5abd6b11051dfb", size = 10909806, upload-time = "2023-11-10T19:13:48.923Z" }, - { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/8e/e4/29e1fa38caba5d5d6db1807ff0f4152b51b7fb3af3a8446095b0a7619d54/pandas-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35172bff95f598cc5866c047f43c7f4df2c893acd8e10e6653a4b792ed7f19bb", size = 14768086, upload-time = "2023-11-10T19:14:07.281Z" }, - { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/1b/fa/4e5d054549faf1524230ffcd57ca98bb7350a4ed62ef722daabde4cb7632/pandas-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59dfe0e65a2f3988e940224e2a70932edc964df79f3356e5f2997c7d63e758b4", size = 12263333, upload-time = "2023-11-10T19:14:21.703Z" }, - { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/49/73/5fe14264e2c9e53f40f946782f0e38240f0a6d577609aca440f7223facd6/pandas-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0296a66200dee556850d99b24c54c7dfa53a3264b1ca6f440e42bad424caea03", size = 13065932, upload-time = "2023-11-10T19:14:40.51Z" }, - { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/3d/c6/9bb3a165e915b9a43b2fd1d35620977bf1371e08538f3649585a1d7b4794/pandas-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:465571472267a2d6e00657900afadbe6097c8e1dc43746917db4dfc862e8863e", size = 10666082, upload-time = "2023-11-10T19:14:57.838Z" }, - { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/1b/ef/63136f5ab2dab6f119ded7c5d31b6294e825059b57d4e5b03042fd557b46/pandas-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:04d4c58e1f112a74689da707be31cf689db086949c71828ef5da86727cfe3f82", size = 11618611, upload-time = "2023-11-10T19:15:13.366Z" }, - { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/d6/7c/20e737300f9bec011fb79c01d8948bc38c854876aac2da2cfcdd0992b153/pandas-2.1.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7fa2ad4ff196768ae63a33f8062e6838efed3a319cf938fdf8b95e956c813042", size = 10777582, upload-time = "2023-11-10T19:15:30.139Z" }, - { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/84/d5/dbd0140e9b2cc27566c8213f9f55426487815b3cf1cdabca3edaf5472e35/pandas-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4441ac94a2a2613e3982e502ccec3bdedefe871e8cea54b8775992485c5660ef", size = 14778000, upload-time = "2023-11-10T19:15:48.391Z" }, - { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/08/de/d4448c423484537ebc9373d3da2496a2e47f42ea11ff48e025cf49665471/pandas-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5ded6ff28abbf0ea7689f251754d3789e1edb0c4d0d91028f0b980598418a58", size = 12231870, upload-time = "2023-11-10T19:16:04.867Z" }, - { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/8c/76/26e0d50e9fa0ddedd23f0098e5940273a984aac7a0a84493e07d502b21e2/pandas-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fca5680368a5139d4920ae3dc993eb5106d49f814ff24018b64d8850a52c6ed2", size = 13065063, upload-time = "2023-11-10T19:16:22.157Z" }, - { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/97/d8/dc2f6bff06a799a5603c414afc6de39c6351fe34892d50b6a077df3be6ac/pandas-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:de21e12bf1511190fc1e9ebc067f14ca09fccfb189a813b38d63211d54832f5f", size = 10612232, upload-time = "2023-11-10T19:16:36.174Z" }, - { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/2b/eb/9c6d267f7f35e3150da9abdc70a39e2a98ece154909b61f3ac939ec38811/pandas-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a5d53c725832e5f1645e7674989f4c106e4b7249c1d57549023ed5462d73b140", size = 11354802, upload-time = "2023-11-10T19:16:51.56Z" }, - { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/a0/68/265225df9e90ade0c332db4148e9aff8c9bcb4e8dd6c681ec4f512770765/pandas-2.1.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7cf4cf26042476e39394f1f86868d25b265ff787c9b2f0d367280f11afbdee6d", size = 10611390, upload-time = "2023-11-10T19:17:05.783Z" }, - { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/64/06/6a7e7135cfe2173edae5f5d0a08f7b4b4e37c36b66618b2a1cc077e338ce/pandas-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:72c84ec1b1d8e5efcbff5312abe92bfb9d5b558f11e0cf077f5496c4f4a3c99e", size = 14246847, upload-time = "2023-11-10T19:17:22.607Z" }, - { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/ae/a5/5d1deab99008002dfe2c6122352687fd4c2f82688775177729cb0d67556d/pandas-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f539e113739a3e0cc15176bf1231a553db0239bfa47a2c870283fd93ba4f683", size = 11660377, upload-time = "2023-11-10T19:17:37.247Z" }, - { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/cd/ff/b425420750328dddfd72448712d29f5b7d873f48162c07e70dd86acc3007/pandas-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fc77309da3b55732059e484a1efc0897f6149183c522390772d3561f9bf96c00", size = 12371733, upload-time = "2023-11-10T19:17:54.732Z" }, - { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/df/92/a3fa053c74198f9f0224b2c04dc74f41d2e14e30329c082f7a657f9ca4c5/pandas-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:08637041279b8981a062899da0ef47828df52a1838204d2b3761fbd3e9fcb549", size = 10497639, upload-time = "2023-11-10T19:18:08.466Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/2e/16/a8eeb70aad84ccbf14076793f90e0031eded63c1899aeae9fdfbf37881f4/pandas-2.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:52bc29a946304c360561974c6542d1dd628ddafa69134a7131fdfd6a5d7a1a35", size = 11539648, upload-time = "2025-08-21T10:26:36.236Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/47/f1/c5bdaea13bf3708554d93e948b7ea74121ce6e0d59537ca4c4f77731072b/pandas-2.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:220cc5c35ffaa764dd5bb17cf42df283b5cb7fdf49e10a7b053a06c9cb48ee2b", size = 10786923, upload-time = "2025-08-21T10:26:40.518Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/bb/10/811fa01476d29ffed692e735825516ad0e56d925961819e6126b4ba32147/pandas-2.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42c05e15111221384019897df20c6fe893b2f697d03c811ee67ec9e0bb5a3424", size = 11726241, upload-time = "2025-08-21T10:26:43.175Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/c4/6a/40b043b06e08df1ea1b6d20f0e0c2f2c4ec8c4f07d1c92948273d943a50b/pandas-2.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc03acc273c5515ab69f898df99d9d4f12c4d70dbfc24c3acc6203751d0804cf", size = 12349533, upload-time = "2025-08-21T10:26:46.611Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/e2/ea/2e081a2302e41a9bca7056659fdd2b85ef94923723e41665b42d65afd347/pandas-2.3.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d25c20a03e8870f6339bcf67281b946bd20b86f1a544ebbebb87e66a8d642cba", size = 13202407, upload-time = "2025-08-21T10:26:49.068Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/f4/12/7ff9f6a79e2ee8869dcf70741ef998b97ea20050fe25f83dc759764c1e32/pandas-2.3.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:21bb612d148bb5860b7eb2c10faacf1a810799245afd342cf297d7551513fbb6", size = 13837212, upload-time = "2025-08-21T10:26:51.832Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/d8/df/5ab92fcd76455a632b3db34a746e1074d432c0cdbbd28d7cd1daba46a75d/pandas-2.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:b62d586eb25cb8cb70a5746a378fc3194cb7f11ea77170d59f889f5dfe3cec7a", size = 11338099, upload-time = "2025-08-21T10:26:54.382Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/7a/59/f3e010879f118c2d400902d2d871c2226cef29b08c09fb8dc41111730400/pandas-2.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1333e9c299adcbb68ee89a9bb568fc3f20f9cbb419f1dd5225071e6cddb2a743", size = 11563308, upload-time = "2025-08-21T10:26:56.656Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/38/18/48f10f1cc5c397af59571d638d211f494dba481f449c19adbd282aa8f4ca/pandas-2.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:76972bcbd7de8e91ad5f0ca884a9f2c477a2125354af624e022c49e5bd0dfff4", size = 10820319, upload-time = "2025-08-21T10:26:59.162Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/95/3b/1e9b69632898b048e223834cd9702052bcf06b15e1ae716eda3196fb972e/pandas-2.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b98bdd7c456a05eef7cd21fd6b29e3ca243591fe531c62be94a2cc987efb5ac2", size = 11790097, upload-time = "2025-08-21T10:27:02.204Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/8b/ef/0e2ffb30b1f7fbc9a588bd01e3c14a0d96854d09a887e15e30cc19961227/pandas-2.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d81573b3f7db40d020983f78721e9bfc425f411e616ef019a10ebf597aedb2e", size = 12397958, upload-time = "2025-08-21T10:27:05.409Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/23/82/e6b85f0d92e9afb0e7f705a51d1399b79c7380c19687bfbf3d2837743249/pandas-2.3.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e190b738675a73b581736cc8ec71ae113d6c3768d0bd18bffa5b9a0927b0b6ea", size = 13225600, upload-time = "2025-08-21T10:27:07.791Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/e8/f1/f682015893d9ed51611948bd83683670842286a8edd4f68c2c1c3b231eef/pandas-2.3.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c253828cb08f47488d60f43c5fc95114c771bbfff085da54bfc79cb4f9e3a372", size = 13879433, upload-time = "2025-08-21T10:27:10.347Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/a7/e7/ae86261695b6c8a36d6a4c8d5f9b9ede8248510d689a2f379a18354b37d7/pandas-2.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:9467697b8083f9667b212633ad6aa4ab32436dcbaf4cd57325debb0ddef2012f", size = 11336557, upload-time = "2025-08-21T10:27:12.983Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/ec/db/614c20fb7a85a14828edd23f1c02db58a30abf3ce76f38806155d160313c/pandas-2.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3fbb977f802156e7a3f829e9d1d5398f6192375a3e2d1a9ee0803e35fe70a2b9", size = 11587652, upload-time = "2025-08-21T10:27:15.888Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/99/b0/756e52f6582cade5e746f19bad0517ff27ba9c73404607c0306585c201b3/pandas-2.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1b9b52693123dd234b7c985c68b709b0b009f4521000d0525f2b95c22f15944b", size = 10717686, upload-time = "2025-08-21T10:27:18.486Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/37/4c/dd5ccc1e357abfeee8353123282de17997f90ff67855f86154e5a13b81e5/pandas-2.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bd281310d4f412733f319a5bc552f86d62cddc5f51d2e392c8787335c994175", size = 11278722, upload-time = "2025-08-21T10:27:21.149Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/d3/a4/f7edcfa47e0a88cda0be8b068a5bae710bf264f867edfdf7b71584ace362/pandas-2.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96d31a6b4354e3b9b8a2c848af75d31da390657e3ac6f30c05c82068b9ed79b9", size = 11987803, upload-time = "2025-08-21T10:27:23.767Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/f6/61/1bce4129f93ab66f1c68b7ed1c12bac6a70b1b56c5dab359c6bbcd480b52/pandas-2.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:df4df0b9d02bb873a106971bb85d448378ef14b86ba96f035f50bbd3688456b4", size = 12766345, upload-time = "2025-08-21T10:27:26.6Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/8e/46/80d53de70fee835531da3a1dae827a1e76e77a43ad22a8cd0f8142b61587/pandas-2.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:213a5adf93d020b74327cb2c1b842884dbdd37f895f42dcc2f09d451d949f811", size = 13439314, upload-time = "2025-08-21T10:27:29.213Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/28/30/8114832daff7489f179971dbc1d854109b7f4365a546e3ea75b6516cea95/pandas-2.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:8c13b81a9347eb8c7548f53fd9a4f08d4dfe996836543f805c987bafa03317ae", size = 10983326, upload-time = "2025-08-21T10:27:31.901Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/27/64/a2f7bf678af502e16b472527735d168b22b7824e45a4d7e96a4fbb634b59/pandas-2.3.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0c6ecbac99a354a051ef21c5307601093cb9e0f4b1855984a084bfec9302699e", size = 11531061, upload-time = "2025-08-21T10:27:34.647Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/54/4c/c3d21b2b7769ef2f4c2b9299fcadd601efa6729f1357a8dbce8dd949ed70/pandas-2.3.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c6f048aa0fd080d6a06cc7e7537c09b53be6642d330ac6f54a600c3ace857ee9", size = 10668666, upload-time = "2025-08-21T10:27:37.203Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/50/e2/f775ba76ecfb3424d7f5862620841cf0edb592e9abd2d2a5387d305fe7a8/pandas-2.3.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0064187b80a5be6f2f9c9d6bdde29372468751dfa89f4211a3c5871854cfbf7a", size = 11332835, upload-time = "2025-08-21T10:27:40.188Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/8f/52/0634adaace9be2d8cac9ef78f05c47f3a675882e068438b9d7ec7ef0c13f/pandas-2.3.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ac8c320bded4718b298281339c1a50fb00a6ba78cb2a63521c39bec95b0209b", size = 12057211, upload-time = "2025-08-21T10:27:43.117Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/0b/9d/2df913f14b2deb9c748975fdb2491da1a78773debb25abbc7cbc67c6b549/pandas-2.3.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:114c2fe4f4328cf98ce5716d1532f3ab79c5919f95a9cfee81d9140064a2e4d6", size = 12749277, upload-time = "2025-08-21T10:27:45.474Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/87/af/da1a2417026bd14d98c236dba88e39837182459d29dcfcea510b2ac9e8a1/pandas-2.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:48fa91c4dfb3b2b9bfdb5c24cd3567575f4e13f9636810462ffed8925352be5a", size = 13415256, upload-time = "2025-08-21T10:27:49.885Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/22/3c/f2af1ce8840ef648584a6156489636b5692c162771918aa95707c165ad2b/pandas-2.3.2-cp313-cp313-win_amd64.whl", hash = "sha256:12d039facec710f7ba305786837d0225a3444af7bbd9c15c32ca2d40d157ed8b", size = 10982579, upload-time = "2025-08-21T10:28:08.435Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/f3/98/8df69c4097a6719e357dc249bf437b8efbde808038268e584421696cbddf/pandas-2.3.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:c624b615ce97864eb588779ed4046186f967374185c047070545253a52ab2d57", size = 12028163, upload-time = "2025-08-21T10:27:52.232Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/0e/23/f95cbcbea319f349e10ff90db488b905c6883f03cbabd34f6b03cbc3c044/pandas-2.3.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0cee69d583b9b128823d9514171cabb6861e09409af805b54459bd0c821a35c2", size = 11391860, upload-time = "2025-08-21T10:27:54.673Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/ad/1b/6a984e98c4abee22058aa75bfb8eb90dce58cf8d7296f8bc56c14bc330b0/pandas-2.3.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2319656ed81124982900b4c37f0e0c58c015af9a7bbc62342ba5ad07ace82ba9", size = 11309830, upload-time = "2025-08-21T10:27:56.957Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/15/d5/f0486090eb18dd8710bf60afeaf638ba6817047c0c8ae5c6a25598665609/pandas-2.3.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b37205ad6f00d52f16b6d09f406434ba928c1a1966e2771006a9033c736d30d2", size = 11883216, upload-time = "2025-08-21T10:27:59.302Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/10/86/692050c119696da19e20245bbd650d8dfca6ceb577da027c3a73c62a047e/pandas-2.3.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:837248b4fc3a9b83b9c6214699a13f069dc13510a6a6d7f9ba33145d2841a012", size = 12699743, upload-time = "2025-08-21T10:28:02.447Z" }, + { url = "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/packages/cd/d7/612123674d7b17cf345aad0a10289b2a384bff404e0463a83c4a3a59d205/pandas-2.3.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d2c3554bd31b731cd6490d94a28f3abb8dd770634a9e06eb6d2911b9827db370", size = 13186141, upload-time = "2025-08-21T10:28:05.377Z" }, ] [[package]] From dcdb0614bf7fc29fe560969324478c29928b1695 Mon Sep 17 00:00:00 2001 From: Arcitec <38923130+Arcitec@users.noreply.github.com> Date: Mon, 8 Sep 2025 17:04:19 +0200 Subject: [PATCH 13/14] fix: Use WeTextProcessing on Linux, and wetext on other platforms --- indextts/utils/front.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indextts/utils/front.py b/indextts/utils/front.py index e6c2e44..bc7262c 100644 --- a/indextts/utils/front.py +++ b/indextts/utils/front.py @@ -91,7 +91,7 @@ class TextNormalizer: import platform if self.zh_normalizer is not None and self.en_normalizer is not None: return - if platform.system() == "Darwin": + if platform.system() != "Linux": # Mac and Windows from wetext import Normalizer self.zh_normalizer = Normalizer(remove_erhua=False, lang="zh", operator="tn") From 45b2f1f3eb4d95472ff4a70225e6c61b04da88e3 Mon Sep 17 00:00:00 2001 From: Arcitec <38923130+Arcitec@users.noreply.github.com> Date: Mon, 8 Sep 2025 17:17:59 +0200 Subject: [PATCH 14/14] chore: Add metadata to pyproject.toml --- pyproject.toml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index fe693c2..10bcd41 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,9 @@ [project] name = "index-tts" -version = "0.1.0" -description = "Add your description here" +version = "2.0.0" +description = "IndexTTS2: A Breakthrough in Emotionally Expressive and Duration-Controlled Auto-Regressive Zero-Shot Text-to-Speech" +license = "Apache-2.0" +license-files = ["LICEN[CS]E*", "INDEX_MODEL_LICENSE*"] readme = "README.md" requires-python = ">=3.10" dependencies = [ @@ -39,6 +41,10 @@ dependencies = [ "WeTextProcessing; sys_platform == 'linux'", ] +[project.urls] +Homepage = "https://github.com/index-tts/index-tts" +Repository = "https://github.com/index-tts/index-tts.git" + [tool.uv] extra-index-url = ["https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple"] no-build-isolation-package = ["deepspeed"]