Spaces:
Running on Zero
Running on Zero
Download app.py from teamup-tech/IndexTTS-2: direct link, hf CLI and curl.
- Browser
- Download file 3.69 kB
-
https://huggingface.co/spaces/teamup-tech/IndexTTS-2/resolve/main/app.py
- Command line
-
hf download hf://spaces/teamup-tech/IndexTTS-2/app.py
-
curl -L -o app.py https://huggingface.co/spaces/teamup-tech/IndexTTS-2/resolve/main/app.py
3.69 kB
| """PyHarp front end for the original IndexTTS2 inference implementation.""" | |
| from __future__ import annotations | |
| import sys | |
| import uuid | |
| from pathlib import Path | |
| import gradio as gr | |
| import spaces | |
| from pyharp import ModelCard, Subcategory, build_endpoint | |
| ROOT = Path(__file__).resolve().parent | |
| sys.path.append(str(ROOT / "indextts")) | |
| from indextts.infer_v2 import IndexTTS2 # noqa: E402 | |
| from tools.download_files import download_model_from_huggingface # noqa: E402 | |
| MODEL_DIR = ROOT / "checkpoints" | |
| OUTPUT_DIR = ROOT / "outputs" | |
| OUTPUT_DIR.mkdir(exist_ok=True) | |
| download_model_from_huggingface(str(MODEL_DIR), str(MODEL_DIR / "hf_cache")) | |
| tts = IndexTTS2( | |
| model_dir=str(MODEL_DIR), | |
| cfg_path=str(MODEL_DIR / "config.yaml"), | |
| use_fp16=False, | |
| use_deepspeed=False, | |
| use_cuda_kernel=False, | |
| ) | |
| def synthesize(text, voice_reference, emotion_reference, emotion_weight): | |
| # Checked before the GPU is reserved, so a request missing an input spends none of the | |
| # caller's ZeroGPU allowance | |
| text = (text or "").strip() | |
| if not text: | |
| raise gr.Error("Please enter text to synthesize.") | |
| if not voice_reference: | |
| raise gr.Error("Please upload a voice reference recording.") | |
| return speak(text, voice_reference, emotion_reference, emotion_weight) | |
| def speak(text, voice_reference, emotion_reference, emotion_weight): | |
| output_path = OUTPUT_DIR / f"harp_{uuid.uuid4().hex}.wav" | |
| try: | |
| return tts.infer( | |
| spk_audio_prompt=voice_reference, | |
| text=text, | |
| output_path=str(output_path), | |
| emo_audio_prompt=emotion_reference or None, | |
| emo_alpha=float(emotion_weight) * 0.8 if emotion_reference else 1.0, | |
| max_text_tokens_per_segment=120, | |
| ) | |
| except Exception as exc: | |
| raise gr.Error(f"IndexTTS2 synthesis failed: {exc}") from exc | |
| with gr.Blocks(title="IndexTTS2") as demo: | |
| input_components = [ | |
| gr.Textbox(label="Text to Synthesize", lines=3).set_info( | |
| "Chinese or English text to synthesize." | |
| ), | |
| gr.Audio(type="filepath", label="Voice Reference").set_info( | |
| "Required voice sample; the model uses up to 15 seconds." | |
| ), | |
| gr.Audio(type="filepath", label="Emotion Reference") | |
| .harp_required(False) | |
| .set_info("Optional. Leave empty to follow the voice reference."), | |
| gr.Slider(0.0, 1.0, value=0.8, step=0.05, label="Emotion Weight").set_info( | |
| "Strength of the optional emotion reference." | |
| ), | |
| ] | |
| output_components = [ | |
| gr.Audio(type="filepath", label="Synthesized Speech").set_info( | |
| "The text spoken in the reference voice." | |
| ), | |
| ] | |
| build_endpoint( | |
| model_card=ModelCard( | |
| name="IndexTTS2", | |
| description=( | |
| "Zero-shot speech synthesis with a voice reference and optional emotion " | |
| "reference. Repository: https://github.com/index-tts/index-tts Paper: " | |
| "https://arxiv.org/abs/2506.21619 Released under the bilibili Model Use " | |
| "License, which forbids using the model or its output to train or " | |
| "improve another AI model, except a non-commercial one." | |
| ), | |
| author="Siyi Zhou, Yiquan Zhou, Yi He, Xun Zhou, Jinchao Wang, Wei Deng, Jingchen Shu", | |
| tags=[Subcategory.TEXT_TO_SPEECH, 'voice-cloning', 'emotion-control'], | |
| ), | |
| input_components=input_components, | |
| output_components=output_components, | |
| process_fn=synthesize, | |
| ) | |
| if __name__ == "__main__": | |
| demo.queue(default_concurrency_limit=1).launch(show_error=True, pwa=True) | |