Merge pull request #325 from Arcitec/indextts2-arc
IndexTTS2 New Features & Maintenance Patches
This commit is contained in:
commit
8336824c71
26
README.md
26
README.md
@ -5,7 +5,7 @@
|
||||
</div>
|
||||
|
||||
<div align="center">
|
||||
<a href="doc/README_zh.md" style="font-size: 24px">简体中文</a> |
|
||||
<a href="docs/README_zh.md" style="font-size: 24px">简体中文</a> |
|
||||
<a href="README.md" style="font-size: 24px">English</a>
|
||||
</div>
|
||||
|
||||
@ -174,9 +174,12 @@ will install the correct versions of all dependencies into your `.venv` director
|
||||
uv sync --all-extras
|
||||
```
|
||||
|
||||
If the download is slow, please try a *local mirror*, for example China:
|
||||
If the download is slow, please try a *local mirror*, for example any of these
|
||||
local mirrors in China (choose one mirror from the list below):
|
||||
|
||||
```bash
|
||||
uv sync --all-extras --default-index "https://mirrors.aliyun.com/pypi/simple"
|
||||
|
||||
uv sync --all-extras --default-index "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple"
|
||||
```
|
||||
|
||||
@ -186,7 +189,8 @@ uv sync --all-extras --default-index "https://mirrors.tuna.tsinghua.edu.cn/pypi/
|
||||
> - `--all-extras`: Automatically adds *every* extra feature listed below. You can
|
||||
> remove this flag if you want to customize your installation choices.
|
||||
> - `--extra webui`: Adds WebUI support (recommended).
|
||||
> - `--extra deepspeed`: Adds DeepSpeed support (faster inference).
|
||||
> - `--extra deepspeed`: Adds DeepSpeed support (may speed up inference on some
|
||||
> systems).
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **Important (Windows):** The DeepSpeed library may be difficult to install for
|
||||
@ -259,6 +263,12 @@ uv run webui.py -h
|
||||
|
||||
Have fun!
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **DeepSpeed** *may* speed up inference on some systems, but it could also
|
||||
> make it slower. The performance impact is highly dependent on your specific
|
||||
> hardware, drivers and operating system. Please try with and without it,
|
||||
> to discover what works best on your personal system.
|
||||
|
||||
|
||||
#### 📝 Using IndexTTS2 in Python
|
||||
|
||||
@ -311,6 +321,10 @@ tts.infer(spk_audio_prompt='examples/voice_07.wav', text=text, output_path="gen.
|
||||
during inference; the default is `False`, and setting it to `True` enables
|
||||
randomness:
|
||||
|
||||
> [!NOTE]
|
||||
> Enabling random sampling will reduce the voice cloning fidelity of the speech
|
||||
> synthesis.
|
||||
|
||||
```python
|
||||
from indextts.infer_v2 import IndexTTS2
|
||||
tts = IndexTTS2(cfg_path="checkpoints/config.yaml", model_dir="checkpoints", use_fp16=False, use_cuda_kernel=False, use_deepspeed=False)
|
||||
@ -321,6 +335,8 @@ tts.infer(spk_audio_prompt='examples/voice_10.wav', text=text, output_path="gen.
|
||||
5. Alternatively, you can enable `use_emo_text` to guide the emotions based on
|
||||
your provided `text` script. Your text script will then automatically
|
||||
be converted into emotion vectors.
|
||||
It's recommended to use `emo_alpha` around 0.6 (or lower) when using the text
|
||||
emotion modes, for more natural sounding speech.
|
||||
You can introduce randomness with `use_random` (default: `False`;
|
||||
`True` enables randomness):
|
||||
|
||||
@ -328,7 +344,7 @@ tts.infer(spk_audio_prompt='examples/voice_10.wav', text=text, output_path="gen.
|
||||
from indextts.infer_v2 import IndexTTS2
|
||||
tts = IndexTTS2(cfg_path="checkpoints/config.yaml", model_dir="checkpoints", use_fp16=False, use_cuda_kernel=False, use_deepspeed=False)
|
||||
text = "快躲起来!是他要来了!他要来抓我们了!"
|
||||
tts.infer(spk_audio_prompt='examples/voice_12.wav', text=text, output_path="gen.wav", use_emo_text=True, use_random=False, verbose=True)
|
||||
tts.infer(spk_audio_prompt='examples/voice_12.wav', text=text, output_path="gen.wav", emo_alpha=0.6, use_emo_text=True, use_random=False, verbose=True)
|
||||
```
|
||||
|
||||
6. It's also possible to directly provide a specific text emotion description
|
||||
@ -341,7 +357,7 @@ from indextts.infer_v2 import IndexTTS2
|
||||
tts = IndexTTS2(cfg_path="checkpoints/config.yaml", model_dir="checkpoints", use_fp16=False, use_cuda_kernel=False, use_deepspeed=False)
|
||||
text = "快躲起来!是他要来了!他要来抓我们了!"
|
||||
emo_text = "你吓死我了!你是鬼吗?"
|
||||
tts.infer(spk_audio_prompt='examples/voice_12.wav', text=text, output_path="gen.wav", use_emo_text=True, emo_text=emo_text, use_random=False, verbose=True)
|
||||
tts.infer(spk_audio_prompt='examples/voice_12.wav', text=text, output_path="gen.wav", emo_alpha=0.6, use_emo_text=True, emo_text=emo_text, use_random=False, verbose=True)
|
||||
```
|
||||
|
||||
|
||||
|
||||
@ -153,6 +153,8 @@ uv sync --all-extras
|
||||
如中国大陆地区用户下载缓慢,可选用国内镜像:
|
||||
|
||||
```bash
|
||||
uv sync --all-extras --default-index "https://mirrors.aliyun.com/pypi/simple"
|
||||
|
||||
uv sync --all-extras --default-index "https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple"
|
||||
```
|
||||
|
||||
@ -259,9 +261,9 @@ tts.infer(spk_audio_prompt='examples/voice_07.wav', text=text, output_path="gen.
|
||||
```
|
||||
|
||||
4. 可直接指定8维情感向量 `[高兴, 愤怒, 悲伤, 害怕, 厌恶, 忧郁, 惊讶, 平静]`,可用`use_random`开启随机情感采样(默认False):
|
||||
|
||||
> [!NOTE]
|
||||
> 开启随机采样会降低音色的还原度。
|
||||
>
|
||||
|
||||
```python
|
||||
from indextts.infer_v2 import IndexTTS2
|
||||
@ -276,7 +278,7 @@ tts.infer(spk_audio_prompt='examples/voice_10.wav', text=text, output_path="gen.
|
||||
from indextts.infer_v2 import IndexTTS2
|
||||
tts = IndexTTS2(cfg_path="checkpoints/config.yaml", model_dir="checkpoints", use_fp16=False, use_cuda_kernel=False, use_deepspeed=False)
|
||||
text = "快躲起来!是他要来了!他要来抓我们了!"
|
||||
tts.infer(spk_audio_prompt='examples/voice_12.wav', text=text, output_path="gen.wav", use_emo_text=True, use_random=False, verbose=True)
|
||||
tts.infer(spk_audio_prompt='examples/voice_12.wav', text=text, output_path="gen.wav", emo_alpha=0.6, use_emo_text=True, use_random=False, verbose=True)
|
||||
```
|
||||
|
||||
6. 可直接指定情感文本描述(`emo_text`),实现文本与情感分离控制:
|
||||
@ -286,7 +288,7 @@ from indextts.infer_v2 import IndexTTS2
|
||||
tts = IndexTTS2(cfg_path="checkpoints/config.yaml", model_dir="checkpoints", use_fp16=False, use_cuda_kernel=False, use_deepspeed=False)
|
||||
text = "快躲起来!是他要来了!他要来抓我们了!"
|
||||
emo_text = "你吓死我了!你是鬼吗?"
|
||||
tts.infer(spk_audio_prompt='examples/voice_12.wav', text=text, output_path="gen.wav", use_emo_text=True, emo_text=emo_text, use_random=False, verbose=True)
|
||||
tts.infer(spk_audio_prompt='examples/voice_12.wav', text=text, output_path="gen.wav", emo_alpha=0.6, use_emo_text=True, emo_text=emo_text, use_random=False, verbose=True)
|
||||
```
|
||||
|
||||
### 旧版IndexTTS1使用指南
|
||||
@ -47,10 +47,10 @@ def main():
|
||||
if args.device is None:
|
||||
if torch.cuda.is_available():
|
||||
args.device = "cuda:0"
|
||||
elif torch.mps.is_available():
|
||||
args.device = "mps"
|
||||
elif torch.xpu.is_available():
|
||||
elif hasattr(torch, "xpu") and torch.xpu.is_available():
|
||||
args.device = "xpu"
|
||||
elif hasattr(torch, "mps") and torch.mps.is_available():
|
||||
args.device = "mps"
|
||||
else:
|
||||
args.device = "cpu"
|
||||
args.fp16 = False # Disable FP16 on CPU
|
||||
|
||||
@ -291,9 +291,9 @@ class IndexTTS:
|
||||
- 越大,bucket数量越少,batch越多,推理速度越*快*,占用内存更多,可能影响质量
|
||||
- 越小,bucket数量越多,batch越少,推理速度越*慢*,占用内存和质量更接近于非快速推理
|
||||
"""
|
||||
print(">> start fast inference...")
|
||||
print(">> starting fast inference...")
|
||||
|
||||
self._set_gr_progress(0, "start fast inference...")
|
||||
self._set_gr_progress(0, "starting fast inference...")
|
||||
if verbose:
|
||||
print(f"origin text:{text}")
|
||||
start_time = time.perf_counter()
|
||||
@ -385,7 +385,7 @@ class IndexTTS:
|
||||
processed_num += batch_num
|
||||
# gpt speech
|
||||
self._set_gr_progress(0.2 + 0.3 * processed_num / all_batch_num,
|
||||
f"gpt inference speech... {processed_num}/{all_batch_num}")
|
||||
f"gpt speech inference {processed_num}/{all_batch_num}...")
|
||||
m_start_time = time.perf_counter()
|
||||
with torch.no_grad():
|
||||
with torch.amp.autocast(batch_text_tokens.device.type, enabled=self.dtype is not None,
|
||||
@ -407,7 +407,7 @@ class IndexTTS:
|
||||
gpt_gen_time += time.perf_counter() - m_start_time
|
||||
|
||||
# gpt latent
|
||||
self._set_gr_progress(0.5, "gpt inference latents...")
|
||||
self._set_gr_progress(0.5, "gpt latents inference...")
|
||||
all_idxs = []
|
||||
all_latents = []
|
||||
has_warned = False
|
||||
@ -456,7 +456,7 @@ class IndexTTS:
|
||||
latent_length = len(all_latents)
|
||||
|
||||
# bigvgan chunk decode
|
||||
self._set_gr_progress(0.7, "bigvgan decode...")
|
||||
self._set_gr_progress(0.7, "bigvgan decoding...")
|
||||
tqdm_progress = tqdm(total=latent_length, desc="bigvgan")
|
||||
for items in chunk_latents:
|
||||
tqdm_progress.update(len(items))
|
||||
@ -478,7 +478,7 @@ class IndexTTS:
|
||||
self.torch_empty_cache()
|
||||
|
||||
# wav audio output
|
||||
self._set_gr_progress(0.9, "save audio...")
|
||||
self._set_gr_progress(0.9, "saving audio...")
|
||||
wav = torch.cat(wavs, dim=1)
|
||||
wav_length = wav.shape[-1] / sampling_rate
|
||||
print(f">> Reference audio length: {cond_mel_frame * 256 / sampling_rate:.2f} seconds")
|
||||
@ -509,8 +509,8 @@ class IndexTTS:
|
||||
# 原始推理模式
|
||||
def infer(self, audio_prompt, text, output_path, verbose=False, max_text_tokens_per_segment=120,
|
||||
**generation_kwargs):
|
||||
print(">> start inference...")
|
||||
self._set_gr_progress(0, "start inference...")
|
||||
print(">> starting inference...")
|
||||
self._set_gr_progress(0, "starting inference...")
|
||||
if verbose:
|
||||
print(f"origin text:{text}")
|
||||
start_time = time.perf_counter()
|
||||
@ -578,7 +578,7 @@ class IndexTTS:
|
||||
# print(text_len)
|
||||
progress += 1
|
||||
self._set_gr_progress(0.2 + 0.4 * (progress - 1) / len(segments),
|
||||
f"gpt inference latent... {progress}/{len(segments)}")
|
||||
f"gpt latents inference {progress}/{len(segments)}...")
|
||||
m_start_time = time.perf_counter()
|
||||
with torch.no_grad():
|
||||
with torch.amp.autocast(text_tokens.device.type, enabled=self.dtype is not None, dtype=self.dtype):
|
||||
@ -620,7 +620,7 @@ class IndexTTS:
|
||||
print(f"fix codes shape: {codes.shape}, codes type: {codes.dtype}")
|
||||
print(f"code len: {code_lens}")
|
||||
self._set_gr_progress(0.2 + 0.4 * progress / len(segments),
|
||||
f"gpt inference speech... {progress}/{len(segments)}")
|
||||
f"gpt speech inference {progress}/{len(segments)}...")
|
||||
m_start_time = time.perf_counter()
|
||||
# latent, text_lens_out, code_lens_out = \
|
||||
with torch.amp.autocast(text_tokens.device.type, enabled=self.dtype is not None, dtype=self.dtype):
|
||||
@ -644,7 +644,7 @@ class IndexTTS:
|
||||
# wavs.append(wav[:, :-512])
|
||||
wavs.append(wav.cpu()) # to cpu before saving
|
||||
end_time = time.perf_counter()
|
||||
self._set_gr_progress(0.9, "save audio...")
|
||||
self._set_gr_progress(0.9, "saving audio...")
|
||||
wav = torch.cat(wavs, dim=1)
|
||||
wav_length = wav.shape[-1] / sampling_rate
|
||||
print(f">> Reference audio length: {cond_mel_frame * 256 / sampling_rate:.2f} seconds")
|
||||
|
||||
@ -298,37 +298,45 @@ class IndexTTS2:
|
||||
emo_vector=None,
|
||||
use_emo_text=False, emo_text=None, use_random=False, interval_silence=200,
|
||||
verbose=False, max_text_tokens_per_segment=120, **generation_kwargs):
|
||||
print(">> start inference...")
|
||||
self._set_gr_progress(0, "start inference...")
|
||||
print(">> starting inference...")
|
||||
self._set_gr_progress(0, "starting inference...")
|
||||
if verbose:
|
||||
print(f"origin text:{text}, spk_audio_prompt:{spk_audio_prompt},"
|
||||
f" emo_audio_prompt:{emo_audio_prompt}, emo_alpha:{emo_alpha}, "
|
||||
print(f"origin text:{text}, spk_audio_prompt:{spk_audio_prompt}, "
|
||||
f"emo_audio_prompt:{emo_audio_prompt}, emo_alpha:{emo_alpha}, "
|
||||
f"emo_vector:{emo_vector}, use_emo_text:{use_emo_text}, "
|
||||
f"emo_text:{emo_text}")
|
||||
start_time = time.perf_counter()
|
||||
|
||||
if use_emo_text:
|
||||
if use_emo_text or emo_vector is not None:
|
||||
# we're using a text or emotion vector guidance; so we must remove
|
||||
# "emotion reference voice", to ensure we use correct emotion mixing!
|
||||
emo_audio_prompt = None
|
||||
emo_alpha = 1.0
|
||||
# assert emo_audio_prompt is None
|
||||
# assert emo_alpha == 1.0
|
||||
|
||||
if use_emo_text:
|
||||
# automatically generate emotion vectors from text prompt
|
||||
if emo_text is None:
|
||||
emo_text = text
|
||||
emo_text = text # use main text prompt
|
||||
emo_dict = self.qwen_emo.inference(emo_text)
|
||||
print(emo_dict)
|
||||
print(f"detected emotion vectors from text: {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:
|
||||
emo_audio_prompt = None
|
||||
emo_alpha = 1.0
|
||||
# assert emo_audio_prompt is None
|
||||
# assert emo_alpha == 1.0
|
||||
# we have emotion vectors; they can't be blended via alpha mixing
|
||||
# in the main inference process later, so we must pre-calculate
|
||||
# their new strengths here based on the alpha instead!
|
||||
emo_vector_scale = max(0.0, min(1.0, emo_alpha))
|
||||
if emo_vector_scale != 1.0:
|
||||
# scale each vector and truncate to 4 decimals (for nicer printing)
|
||||
emo_vector = [int(x * emo_vector_scale * 10000) / 10000 for x in emo_vector]
|
||||
print(f"scaled emotion vectors to {emo_vector_scale}x: {emo_vector}")
|
||||
|
||||
if emo_audio_prompt is None:
|
||||
# we are not using any external "emotion reference voice"; use
|
||||
# speaker's voice as the main emotion reference audio.
|
||||
emo_audio_prompt = spk_audio_prompt
|
||||
# must always use alpha=1.0 when we don't have an external reference voice
|
||||
emo_alpha = 1.0
|
||||
# assert emo_alpha == 1.0
|
||||
|
||||
# 如果参考音频改变了,才需要重新生成, 提升速度
|
||||
if self.cache_spk_cond is None or self.cache_spk_audio_prompt != spk_audio_prompt:
|
||||
@ -400,9 +408,10 @@ class IndexTTS2:
|
||||
self._set_gr_progress(0.1, "text processing...")
|
||||
text_tokens_list = self.tokenizer.tokenize(text)
|
||||
segments = self.tokenizer.split_segments(text_tokens_list, max_text_tokens_per_segment)
|
||||
segments_count = len(segments)
|
||||
if verbose:
|
||||
print("text_tokens_list:", text_tokens_list)
|
||||
print("segments count:", len(segments))
|
||||
print("segments count:", segments_count)
|
||||
print("max_text_tokens_per_segment:", max_text_tokens_per_segment)
|
||||
print(*segments, sep="\n")
|
||||
do_sample = generation_kwargs.pop("do_sample", True)
|
||||
@ -421,9 +430,11 @@ class IndexTTS2:
|
||||
gpt_forward_time = 0
|
||||
s2mel_time = 0
|
||||
bigvgan_time = 0
|
||||
progress = 0
|
||||
has_warned = False
|
||||
for sent in segments:
|
||||
for seg_idx, sent in enumerate(segments):
|
||||
self._set_gr_progress(0.2 + 0.7 * seg_idx / segments_count,
|
||||
f"speech synthesis {seg_idx + 1}/{segments_count}...")
|
||||
|
||||
text_tokens = self.tokenizer.convert_tokens_to_ids(sent)
|
||||
text_tokens = torch.tensor(text_tokens, dtype=torch.int32, device=self.device).unsqueeze(0)
|
||||
if verbose:
|
||||
@ -553,7 +564,8 @@ class IndexTTS2:
|
||||
# wavs.append(wav[:, :-512])
|
||||
wavs.append(wav.cpu()) # to cpu before saving
|
||||
end_time = time.perf_counter()
|
||||
self._set_gr_progress(0.9, "save audio...")
|
||||
|
||||
self._set_gr_progress(0.9, "saving audio...")
|
||||
wavs = self.insert_interval_silence(wavs, sampling_rate=sampling_rate, interval_silence=interval_silence)
|
||||
wav = torch.cat(wavs, dim=1)
|
||||
wav_length = wav.shape[-1] / sampling_rate
|
||||
|
||||
@ -65,7 +65,7 @@ dependencies = [
|
||||
[project.optional-dependencies]
|
||||
# To install the WebUI support, use `uv sync --extra webui` (or `--all-extras`).
|
||||
webui = [
|
||||
"gradio>=5.44.1",
|
||||
"gradio==5.44.1",
|
||||
]
|
||||
# To install the DeepSpeed support, use `uv sync --extra deepspeed` (or `--all-extras`).
|
||||
deepspeed = [
|
||||
|
||||
@ -1,47 +1,85 @@
|
||||
import torch
|
||||
|
||||
|
||||
def show_cuda_gpu_list() -> None:
|
||||
def show_device_list(backend: str) -> int:
|
||||
"""
|
||||
Displays a list of all detected GPUs that support the CUDA Torch APIs.
|
||||
Displays a list of all detected devices for a given PyTorch backend.
|
||||
|
||||
Args:
|
||||
backend: The name of the device backend module (e.g., "cuda", "xpu").
|
||||
|
||||
Returns:
|
||||
The number of devices found if the backend is usable, otherwise 0.
|
||||
"""
|
||||
|
||||
num_gpus = torch.cuda.device_count()
|
||||
print(f"Number of GPUs found: {num_gpus}")
|
||||
backend_upper = backend.upper()
|
||||
|
||||
for i in range(num_gpus):
|
||||
gpu_name = torch.cuda.get_device_name(i)
|
||||
print(f'GPU {i}: "{gpu_name}"')
|
||||
try:
|
||||
# Get the backend module from PyTorch, e.g., `torch.cuda`.
|
||||
# NOTE: Backends always exist even if the user has no devices.
|
||||
backend_module = getattr(torch, backend)
|
||||
|
||||
# Determine which vendor brand name to display.
|
||||
brand_name = backend_upper
|
||||
if backend == "cuda":
|
||||
# NOTE: This also checks for PyTorch's official AMD ROCm support,
|
||||
# since that's implemented inside the PyTorch CUDA APIs.
|
||||
# SEE: https://docs.pytorch.org/docs/stable/cuda.html
|
||||
brand_name = "NVIDIA CUDA / AMD ROCm"
|
||||
elif backend == "xpu":
|
||||
brand_name = "Intel XPU"
|
||||
elif backend == "mps":
|
||||
brand_name = "Apple MPS"
|
||||
|
||||
if not backend_module.is_available():
|
||||
print(f"PyTorch: No devices found for {brand_name} backend.")
|
||||
return 0
|
||||
|
||||
print(f"PyTorch: {brand_name} is available!")
|
||||
|
||||
# Show all available hardware acceleration devices.
|
||||
device_count = backend_module.device_count()
|
||||
print(f" * Number of {backend_upper} devices found: {device_count}")
|
||||
|
||||
# NOTE: Apple Silicon devices don't have `get_device_name()` at the
|
||||
# moment, so we'll skip those since we can't get their device names.
|
||||
# SEE: https://docs.pytorch.org/docs/stable/mps.html
|
||||
if backend != "mps":
|
||||
for i in range(device_count):
|
||||
device_name = backend_module.get_device_name(i)
|
||||
print(f' * Device {i}: "{device_name}"')
|
||||
|
||||
return device_count
|
||||
|
||||
except AttributeError:
|
||||
print(
|
||||
f'Error: The PyTorch backend "{backend}" does not exist, or is missing the necessary APIs (is_available, device_count, get_device_name).'
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def check_torch_gpus() -> None:
|
||||
def check_torch_devices() -> None:
|
||||
"""
|
||||
Checks for the availability of various PyTorch GPU acceleration platforms
|
||||
and prints information about the discovered GPUs.
|
||||
Checks for the availability of various PyTorch hardware acceleration
|
||||
platforms and prints information about the discovered devices.
|
||||
"""
|
||||
|
||||
# Check for AMD ROCm/HIP first, since it modifies the CUDA APIs.
|
||||
# NOTE: The unofficial ROCm/HIP backend exposes the AMD features through
|
||||
# the CUDA Torch API calls.
|
||||
if hasattr(torch.backends, "hip") and torch.backends.hip.is_available():
|
||||
print("PyTorch: AMD ROCm/HIP is available!")
|
||||
show_cuda_gpu_list()
|
||||
print("Scanning for PyTorch hardware acceleration devices...\n")
|
||||
|
||||
# Check for NVIDIA CUDA.
|
||||
elif torch.cuda.is_available():
|
||||
print("PyTorch: NVIDIA CUDA is available!")
|
||||
show_cuda_gpu_list()
|
||||
device_count = 0
|
||||
|
||||
# Check for Apple Metal Performance Shaders (MPS).
|
||||
elif torch.backends.mps.is_available():
|
||||
print("PyTorch: Apple MPS is available!")
|
||||
# PyTorch with MPS doesn't have a direct equivalent of `device_count()`
|
||||
# or `get_device_name()` for now, so we just confirm its presence.
|
||||
print("Using Apple Silicon GPU.")
|
||||
device_count += show_device_list("cuda") # NVIDIA CUDA / AMD ROCm.
|
||||
device_count += show_device_list("xpu") # Intel XPU.
|
||||
device_count += show_device_list("mps") # Apple Metal Performance Shaders (MPS).
|
||||
|
||||
if device_count > 0:
|
||||
print("\nHardware acceleration detected. Your system is ready!")
|
||||
else:
|
||||
print("PyTorch: No GPU acceleration detected. Running in CPU mode.")
|
||||
print("\nNo hardware acceleration detected. Running in CPU mode.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
check_torch_gpus()
|
||||
check_torch_devices()
|
||||
|
||||
42
uv.lock
generated
42
uv.lock
generated
@ -1213,7 +1213,7 @@ requires-dist = [
|
||||
{ name = "einops", specifier = ">=0.8.1" },
|
||||
{ name = "ffmpeg-python", specifier = "==0.2.0" },
|
||||
{ name = "g2p-en", specifier = "==2.1.0" },
|
||||
{ name = "gradio", marker = "extra == 'webui'", specifier = ">=5.44.1" },
|
||||
{ name = "gradio", marker = "extra == 'webui'", specifier = "==5.44.1" },
|
||||
{ name = "jieba", specifier = "==0.42.1" },
|
||||
{ name = "json5", specifier = "==0.10.0" },
|
||||
{ name = "keras", specifier = "==2.9.0" },
|
||||
@ -2910,28 +2910,28 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.12.12"
|
||||
version = "0.13.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a8/f0/e0965dd709b8cabe6356811c0ee8c096806bb57d20b5019eb4e48a117410/ruff-0.12.12.tar.gz", hash = "sha256:b86cd3415dbe31b3b46a71c598f4c4b2f550346d1ccf6326b347cc0c8fd063d6", size = 5359915, upload-time = "2025-09-04T16:50:18.273Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/6e/1a/1f4b722862840295bcaba8c9e5261572347509548faaa99b2d57ee7bfe6a/ruff-0.13.0.tar.gz", hash = "sha256:5b4b1ee7eb35afae128ab94459b13b2baaed282b1fb0f472a73c82c996c8ae60", size = 5372863, upload-time = "2025-09-10T16:25:37.917Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/09/79/8d3d687224d88367b51c7974cec1040c4b015772bfbeffac95face14c04a/ruff-0.12.12-py3-none-linux_armv6l.whl", hash = "sha256:de1c4b916d98ab289818e55ce481e2cacfaad7710b01d1f990c497edf217dafc", size = 12116602, upload-time = "2025-09-04T16:49:18.892Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c3/c3/6e599657fe192462f94861a09aae935b869aea8a1da07f47d6eae471397c/ruff-0.12.12-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:7acd6045e87fac75a0b0cdedacf9ab3e1ad9d929d149785903cff9bb69ad9727", size = 12868393, upload-time = "2025-09-04T16:49:23.043Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e8/d2/9e3e40d399abc95336b1843f52fc0daaceb672d0e3c9290a28ff1a96f79d/ruff-0.12.12-py3-none-macosx_11_0_arm64.whl", hash = "sha256:abf4073688d7d6da16611f2f126be86523a8ec4343d15d276c614bda8ec44edb", size = 12036967, upload-time = "2025-09-04T16:49:26.04Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e9/03/6816b2ed08836be272e87107d905f0908be5b4a40c14bfc91043e76631b8/ruff-0.12.12-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:968e77094b1d7a576992ac078557d1439df678a34c6fe02fd979f973af167577", size = 12276038, upload-time = "2025-09-04T16:49:29.056Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9f/d5/707b92a61310edf358a389477eabd8af68f375c0ef858194be97ca5b6069/ruff-0.12.12-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42a67d16e5b1ffc6d21c5f67851e0e769517fb57a8ebad1d0781b30888aa704e", size = 11901110, upload-time = "2025-09-04T16:49:32.07Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9d/3d/f8b1038f4b9822e26ec3d5b49cf2bc313e3c1564cceb4c1a42820bf74853/ruff-0.12.12-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b216ec0a0674e4b1214dcc998a5088e54eaf39417327b19ffefba1c4a1e4971e", size = 13668352, upload-time = "2025-09-04T16:49:35.148Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/98/0e/91421368ae6c4f3765dd41a150f760c5f725516028a6be30e58255e3c668/ruff-0.12.12-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:59f909c0fdd8f1dcdbfed0b9569b8bf428cf144bec87d9de298dcd4723f5bee8", size = 14638365, upload-time = "2025-09-04T16:49:38.892Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/74/5d/88f3f06a142f58ecc8ecb0c2fe0b82343e2a2b04dcd098809f717cf74b6c/ruff-0.12.12-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9ac93d87047e765336f0c18eacad51dad0c1c33c9df7484c40f98e1d773876f5", size = 14060812, upload-time = "2025-09-04T16:49:42.732Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/13/fc/8962e7ddd2e81863d5c92400820f650b86f97ff919c59836fbc4c1a6d84c/ruff-0.12.12-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:01543c137fd3650d322922e8b14cc133b8ea734617c4891c5a9fccf4bfc9aa92", size = 13050208, upload-time = "2025-09-04T16:49:46.434Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/53/06/8deb52d48a9a624fd37390555d9589e719eac568c020b27e96eed671f25f/ruff-0.12.12-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2afc2fa864197634e549d87fb1e7b6feb01df0a80fd510d6489e1ce8c0b1cc45", size = 13311444, upload-time = "2025-09-04T16:49:49.931Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/81/de5a29af7eb8f341f8140867ffb93f82e4fde7256dadee79016ac87c2716/ruff-0.12.12-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:0c0945246f5ad776cb8925e36af2438e66188d2b57d9cf2eed2c382c58b371e5", size = 13279474, upload-time = "2025-09-04T16:49:53.465Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7f/14/d9577fdeaf791737ada1b4f5c6b59c21c3326f3f683229096cccd7674e0c/ruff-0.12.12-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:a0fbafe8c58e37aae28b84a80ba1817f2ea552e9450156018a478bf1fa80f4e4", size = 12070204, upload-time = "2025-09-04T16:49:56.882Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/77/04/a910078284b47fad54506dc0af13839c418ff704e341c176f64e1127e461/ruff-0.12.12-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:b9c456fb2fc8e1282affa932c9e40f5ec31ec9cbb66751a316bd131273b57c23", size = 11880347, upload-time = "2025-09-04T16:49:59.729Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/df/58/30185fcb0e89f05e7ea82e5817b47798f7fa7179863f9d9ba6fd4fe1b098/ruff-0.12.12-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5f12856123b0ad0147d90b3961f5c90e7427f9acd4b40050705499c98983f489", size = 12891844, upload-time = "2025-09-04T16:50:02.591Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/21/9c/28a8dacce4855e6703dcb8cdf6c1705d0b23dd01d60150786cd55aa93b16/ruff-0.12.12-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:26a1b5a2bf7dd2c47e3b46d077cd9c0fc3b93e6c6cc9ed750bd312ae9dc302ee", size = 13360687, upload-time = "2025-09-04T16:50:05.8Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c8/fa/05b6428a008e60f79546c943e54068316f32ec8ab5c4f73e4563934fbdc7/ruff-0.12.12-py3-none-win32.whl", hash = "sha256:173be2bfc142af07a01e3a759aba6f7791aa47acf3604f610b1c36db888df7b1", size = 12052870, upload-time = "2025-09-04T16:50:09.121Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/85/60/d1e335417804df452589271818749d061b22772b87efda88354cf35cdb7a/ruff-0.12.12-py3-none-win_amd64.whl", hash = "sha256:e99620bf01884e5f38611934c09dd194eb665b0109104acae3ba6102b600fd0d", size = 13178016, upload-time = "2025-09-04T16:50:12.559Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/28/7e/61c42657f6e4614a4258f1c3b0c5b93adc4d1f8575f5229d1906b483099b/ruff-0.12.12-py3-none-win_arm64.whl", hash = "sha256:2a8199cab4ce4d72d158319b63370abf60991495fb733db96cd923a34c52d093", size = 12256762, upload-time = "2025-09-04T16:50:15.737Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ac/fe/6f87b419dbe166fd30a991390221f14c5b68946f389ea07913e1719741e0/ruff-0.13.0-py3-none-linux_armv6l.whl", hash = "sha256:137f3d65d58ee828ae136a12d1dc33d992773d8f7644bc6b82714570f31b2004", size = 12187826, upload-time = "2025-09-10T16:24:39.5Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e4/25/c92296b1fc36d2499e12b74a3fdb230f77af7bdf048fad7b0a62e94ed56a/ruff-0.13.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:21ae48151b66e71fd111b7d79f9ad358814ed58c339631450c66a4be33cc28b9", size = 12933428, upload-time = "2025-09-10T16:24:43.866Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/44/cf/40bc7221a949470307d9c35b4ef5810c294e6cfa3caafb57d882731a9f42/ruff-0.13.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:64de45f4ca5441209e41742d527944635a05a6e7c05798904f39c85bafa819e3", size = 12095543, upload-time = "2025-09-10T16:24:46.638Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f1/03/8b5ff2a211efb68c63a1d03d157e924997ada87d01bebffbd13a0f3fcdeb/ruff-0.13.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2b2c653ae9b9d46e0ef62fc6fbf5b979bda20a0b1d2b22f8f7eb0cde9f4963b8", size = 12312489, upload-time = "2025-09-10T16:24:49.556Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/37/fc/2336ef6d5e9c8d8ea8305c5f91e767d795cd4fc171a6d97ef38a5302dadc/ruff-0.13.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4cec632534332062bc9eb5884a267b689085a1afea9801bf94e3ba7498a2d207", size = 11991631, upload-time = "2025-09-10T16:24:53.439Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/39/7f/f6d574d100fca83d32637d7f5541bea2f5e473c40020bbc7fc4a4d5b7294/ruff-0.13.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dcd628101d9f7d122e120ac7c17e0a0f468b19bc925501dbe03c1cb7f5415b24", size = 13720602, upload-time = "2025-09-10T16:24:56.392Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fd/c8/a8a5b81d8729b5d1f663348d11e2a9d65a7a9bd3c399763b1a51c72be1ce/ruff-0.13.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:afe37db8e1466acb173bb2a39ca92df00570e0fd7c94c72d87b51b21bb63efea", size = 14697751, upload-time = "2025-09-10T16:24:59.89Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/57/f5/183ec292272ce7ec5e882aea74937f7288e88ecb500198b832c24debc6d3/ruff-0.13.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0f96a8d90bb258d7d3358b372905fe7333aaacf6c39e2408b9f8ba181f4b6ef2", size = 14095317, upload-time = "2025-09-10T16:25:03.025Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9f/8d/7f9771c971724701af7926c14dab31754e7b303d127b0d3f01116faef456/ruff-0.13.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:94b5e3d883e4f924c5298e3f2ee0f3085819c14f68d1e5b6715597681433f153", size = 13144418, upload-time = "2025-09-10T16:25:06.272Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a8/a6/7985ad1778e60922d4bef546688cd8a25822c58873e9ff30189cfe5dc4ab/ruff-0.13.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03447f3d18479df3d24917a92d768a89f873a7181a064858ea90a804a7538991", size = 13370843, upload-time = "2025-09-10T16:25:09.965Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/64/1c/bafdd5a7a05a50cc51d9f5711da704942d8dd62df3d8c70c311e98ce9f8a/ruff-0.13.0-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:fbc6b1934eb1c0033da427c805e27d164bb713f8e273a024a7e86176d7f462cf", size = 13321891, upload-time = "2025-09-10T16:25:12.969Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bc/3e/7817f989cb9725ef7e8d2cee74186bf90555279e119de50c750c4b7a72fe/ruff-0.13.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:a8ab6a3e03665d39d4a25ee199d207a488724f022db0e1fe4002968abdb8001b", size = 12119119, upload-time = "2025-09-10T16:25:16.621Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/58/07/9df080742e8d1080e60c426dce6e96a8faf9a371e2ce22eef662e3839c95/ruff-0.13.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d2a5c62f8ccc6dd2fe259917482de7275cecc86141ee10432727c4816235bc41", size = 11961594, upload-time = "2025-09-10T16:25:19.49Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6a/f4/ae1185349197d26a2316840cb4d6c3fba61d4ac36ed728bf0228b222d71f/ruff-0.13.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:b7b85ca27aeeb1ab421bc787009831cffe6048faae08ad80867edab9f2760945", size = 12933377, upload-time = "2025-09-10T16:25:22.371Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b6/39/e776c10a3b349fc8209a905bfb327831d7516f6058339a613a8d2aaecacd/ruff-0.13.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:79ea0c44a3032af768cabfd9616e44c24303af49d633b43e3a5096e009ebe823", size = 13418555, upload-time = "2025-09-10T16:25:25.681Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/46/09/dca8df3d48e8b3f4202bf20b1658898e74b6442ac835bfe2c1816d926697/ruff-0.13.0-py3-none-win32.whl", hash = "sha256:4e473e8f0e6a04e4113f2e1de12a5039579892329ecc49958424e5568ef4f768", size = 12141613, upload-time = "2025-09-10T16:25:28.664Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/61/21/0647eb71ed99b888ad50e44d8ec65d7148babc0e242d531a499a0bbcda5f/ruff-0.13.0-py3-none-win_amd64.whl", hash = "sha256:48e5c25c7a3713eea9ce755995767f4dcd1b0b9599b638b12946e892123d1efb", size = 13258250, upload-time = "2025-09-10T16:25:31.773Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e1/a3/03216a6a86c706df54422612981fb0f9041dbb452c3401501d4a22b942c9/ruff-0.13.0-py3-none-win_arm64.whl", hash = "sha256:ab80525317b1e1d38614addec8ac954f1b3e662de9d59114ecbf771d00cf613e", size = 12312357, upload-time = "2025-09-10T16:25:35.595Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
59
webui.py
59
webui.py
@ -25,7 +25,7 @@ parser.add_argument("--port", type=int, default=7860, help="Port to run the web
|
||||
parser.add_argument("--host", type=str, default="0.0.0.0", help="Host to run the web UI on")
|
||||
parser.add_argument("--model_dir", type=str, default="./checkpoints", help="Model checkpoints directory")
|
||||
parser.add_argument("--fp16", action="store_true", default=False, help="Use FP16 for inference if available")
|
||||
parser.add_argument("--use_deepspeed", action="store_true", default=False, help="Use DeepSpeed to accelerate if available")
|
||||
parser.add_argument("--deepspeed", action="store_true", default=False, help="Use DeepSpeed to accelerate if available")
|
||||
parser.add_argument("--cuda_kernel", action="store_true", default=False, help="Use CUDA kernel for inference if available")
|
||||
parser.add_argument("--gui_seg_tokens", type=int, default=120, help="GUI: Max tokens per generation segment")
|
||||
cmd_args = parser.parse_args()
|
||||
@ -55,7 +55,7 @@ MODE = 'local'
|
||||
tts = IndexTTS2(model_dir=cmd_args.model_dir,
|
||||
cfg_path=os.path.join(cmd_args.model_dir, "config.yaml"),
|
||||
use_fp16=cmd_args.fp16,
|
||||
use_deepspeed=cmd_args.use_deepspeed,
|
||||
use_deepspeed=cmd_args.deepspeed,
|
||||
use_cuda_kernel=cmd_args.cuda_kernel,
|
||||
)
|
||||
# 支持的语言列表
|
||||
@ -126,25 +126,26 @@ def gen_single(emo_control_method,prompt, text,
|
||||
}
|
||||
if type(emo_control_method) is not int:
|
||||
emo_control_method = emo_control_method.value
|
||||
if emo_control_method == 0:
|
||||
emo_ref_path = None
|
||||
if emo_control_method == 0: # emotion from speaker
|
||||
emo_ref_path = None # remove external reference audio
|
||||
emo_weight = 1.0
|
||||
if emo_control_method == 1:
|
||||
emo_weight = emo_weight
|
||||
if emo_control_method == 2:
|
||||
if emo_control_method == 1: # emotion from reference audio
|
||||
# emo_weight = emo_weight
|
||||
pass
|
||||
if emo_control_method == 2: # emotion from custom vectors
|
||||
vec = [vec1, vec2, vec3, vec4, vec5, vec6, vec7, vec8]
|
||||
vec_sum = sum([vec1, vec2, vec3, vec4, vec5, vec6, vec7, vec8])
|
||||
if vec_sum > 1.5:
|
||||
if sum(vec) > 1.5:
|
||||
gr.Warning(i18n("情感向量之和不能超过1.5,请调整后重试。"))
|
||||
return
|
||||
else:
|
||||
# don't use the emotion vector inputs for the other modes
|
||||
vec = None
|
||||
|
||||
if emo_text == "":
|
||||
# erase empty emotion descriptions; `infer()` will then automatically use the main prompt
|
||||
emo_text = None
|
||||
|
||||
print(f"Emo control mode:{emo_control_method},vec:{vec}")
|
||||
print(f"Emo control mode:{emo_control_method},weight:{emo_weight},vec:{vec}")
|
||||
output = tts.infer(spk_audio_prompt=prompt, text=text,
|
||||
output_path=output_path,
|
||||
emo_audio_prompt=emo_ref_path, emo_alpha=emo_weight,
|
||||
@ -167,6 +168,7 @@ with gr.Blocks(title="IndexTTS Demo") as demo:
|
||||
<a href='https://arxiv.org/abs/2506.21619'><img src='https://img.shields.io/badge/ArXiv-2506.21619-red'></a>
|
||||
</p>
|
||||
''')
|
||||
|
||||
with gr.Tab(i18n("音频生成")):
|
||||
with gr.Row():
|
||||
os.makedirs("prompts",exist_ok=True)
|
||||
@ -192,12 +194,9 @@ with gr.Blocks(title="IndexTTS Demo") as demo:
|
||||
with gr.Row():
|
||||
emo_upload = gr.Audio(label=i18n("上传情感参考音频"), type="filepath")
|
||||
|
||||
with gr.Row():
|
||||
emo_weight = gr.Slider(label=i18n("情感权重"), minimum=0.0, maximum=1.6, value=0.8, step=0.01)
|
||||
|
||||
# 情感随机采样
|
||||
with gr.Row():
|
||||
emo_random = gr.Checkbox(label=i18n("情感随机采样"),value=False,visible=False)
|
||||
with gr.Row(visible=False) as emotion_randomize_group:
|
||||
emo_random = gr.Checkbox(label=i18n("情感随机采样"), value=False)
|
||||
|
||||
# 情感向量控制部分
|
||||
with gr.Group(visible=False) as emotion_vector_group:
|
||||
@ -217,6 +216,9 @@ with gr.Blocks(title="IndexTTS Demo") as demo:
|
||||
with gr.Row():
|
||||
emo_text = gr.Textbox(label=i18n("情感描述文本"), placeholder=i18n("请输入情绪描述(或留空以自动使用目标文本作为情绪描述)"), value="", info=i18n("例如:高兴,愤怒,悲伤等"))
|
||||
|
||||
with gr.Row(visible=False) as emo_weight_group:
|
||||
emo_weight = gr.Slider(label=i18n("情感权重"), minimum=0.0, maximum=1.6, value=0.8, step=0.01)
|
||||
|
||||
with gr.Accordion(i18n("高级生成参数设置"), open=False):
|
||||
with gr.Row():
|
||||
with gr.Column(scale=1):
|
||||
@ -287,26 +289,30 @@ with gr.Blocks(title="IndexTTS Demo") as demo:
|
||||
segments_preview: gr.update(value=df),
|
||||
}
|
||||
def on_method_select(emo_control_method):
|
||||
if emo_control_method == 1:
|
||||
if emo_control_method == 1: # emotion reference audio
|
||||
return (gr.update(visible=True),
|
||||
gr.update(visible=False),
|
||||
gr.update(visible=False),
|
||||
gr.update(visible=False)
|
||||
gr.update(visible=False),
|
||||
gr.update(visible=True)
|
||||
)
|
||||
elif emo_control_method == 2:
|
||||
elif emo_control_method == 2: # emotion vectors
|
||||
return (gr.update(visible=False),
|
||||
gr.update(visible=True),
|
||||
gr.update(visible=True),
|
||||
gr.update(visible=False)
|
||||
)
|
||||
elif emo_control_method == 3:
|
||||
return (gr.update(visible=False),
|
||||
gr.update(visible=True),
|
||||
gr.update(visible=False),
|
||||
gr.update(visible=True)
|
||||
)
|
||||
else:
|
||||
elif emo_control_method == 3: # emotion text description
|
||||
return (gr.update(visible=False),
|
||||
gr.update(visible=True),
|
||||
gr.update(visible=False),
|
||||
gr.update(visible=True),
|
||||
gr.update(visible=True)
|
||||
)
|
||||
else: # 0: same as speaker voice
|
||||
return (gr.update(visible=False),
|
||||
gr.update(visible=False),
|
||||
gr.update(visible=False),
|
||||
gr.update(visible=False),
|
||||
gr.update(visible=False)
|
||||
@ -315,9 +321,10 @@ with gr.Blocks(title="IndexTTS Demo") as demo:
|
||||
emo_control_method.select(on_method_select,
|
||||
inputs=[emo_control_method],
|
||||
outputs=[emotion_reference_group,
|
||||
emo_random,
|
||||
emotion_randomize_group,
|
||||
emotion_vector_group,
|
||||
emo_text_group]
|
||||
emo_text_group,
|
||||
emo_weight_group]
|
||||
)
|
||||
|
||||
input_text_single.change(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user