trysem commited on
Commit
a12a098
·
verified ·
1 Parent(s): a80e563

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +131 -0
app.py ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
+ import torchaudio as ta
4
+ from huggingface_hub import hf_hub_download
5
+ from peft import PeftModel
6
+ import tempfile
7
+ import sys
8
+ import os
9
+
10
+ # Ensure chatterbox is installed (usually handled via requirements.txt in HF spaces)
11
+ try:
12
+ from chatterbox.tts import ChatterboxTTS
13
+ except ImportError:
14
+ print("chatterbox-tts is not installed. Please add it to your requirements.txt.")
15
+ sys.exit(1)
16
+
17
+ device = "cuda" if torch.cuda.is_available() else "cpu"
18
+ repo_id = "Praha-Labs/PrahaTTS-ML"
19
+
20
+ def load_model():
21
+ print(f"Loading base Chatterbox model on {device}...")
22
+ # Load the base model
23
+ model = ChatterboxTTS.from_pretrained(device=device)
24
+
25
+ print("Downloading and applying custom Indic tokenizer...")
26
+ try:
27
+ # Download tokenizer_indic.json from the adapter repository
28
+ tokenizer_path = hf_hub_download(repo_id=repo_id, filename="tokenizer_indic.json")
29
+
30
+ # Override the default tokenizer.
31
+ # Note: Depending on Chatterbox's exact structure, the tokenizer might be
32
+ # on the text-to-speech backbone component (e.g., model.tokenizer or model.t3.tokenizer).
33
+ # We try assigning it directly if the library supports loading from a custom path.
34
+ if hasattr(model, 'tokenizer'):
35
+ # Some versions use a load/from_file method
36
+ if hasattr(model.tokenizer, 'load_from_file'):
37
+ model.tokenizer.load_from_file(tokenizer_path)
38
+ else:
39
+ print("Warning: Custom tokenizer replacement might require library-specific logic.")
40
+ except Exception as e:
41
+ print(f"Warning during tokenizer load: {e}")
42
+
43
+ print("Loading LoRA adapter weights...")
44
+ try:
45
+ # Load the PEFT adapter onto the LLaMA backbone/Transformer model
46
+ # Chatterbox architecture uses 't3' (Text-to-Speech Token Generator)
47
+ if hasattr(model, 't3'):
48
+ model.t3 = PeftModel.from_pretrained(model.t3, repo_id)
49
+ else:
50
+ # Fallback if the architecture wraps it differently
51
+ model = PeftModel.from_pretrained(model, repo_id)
52
+ print("LoRA adapter loaded successfully.")
53
+ except Exception as e:
54
+ print(f"Failed to load PEFT adapter: {e}")
55
+
56
+ return model
57
+
58
+ # Initialize Model
59
+ tts_model = load_model()
60
+
61
+ def synthesize_audio(text, ref_audio, exaggeration, cfg):
62
+ if not text.strip():
63
+ return None, "Please enter some text."
64
+
65
+ audio_prompt_path = ref_audio if ref_audio else None
66
+
67
+ try:
68
+ # Generate the waveform
69
+ wav = tts_model.generate(
70
+ text,
71
+ audio_prompt_path=audio_prompt_path,
72
+ exaggeration=exaggeration,
73
+ cfg=cfg
74
+ )
75
+
76
+ # Save generated audio to a temporary file for Gradio
77
+ temp_out = tempfile.NamedTemporaryFile(delete=False, suffix=".wav")
78
+ ta.save(temp_out.name, wav.cpu(), tts_model.sr)
79
+ return temp_out.name, "Generation successful!"
80
+
81
+ except Exception as e:
82
+ return None, f"Generation Error: {str(e)}"
83
+
84
+ # Define the Gradio Interface
85
+ with gr.Blocks(title="PrahaTTS-ML: Malayalam TTS", theme=gr.themes.Soft()) as demo:
86
+ gr.Markdown("# 🗣️ PrahaTTS-ML: Malayalam LoRA Adapter for Chatterbox TTS")
87
+ gr.Markdown(
88
+ "This Space runs the [Praha-Labs/PrahaTTS-ML](https://huggingface.co/Praha-Labs/PrahaTTS-ML) model. "
89
+ "It is a Malayalam LoRA adapter built on top of ResembleAI's Chatterbox non-turbo TTS model. \n\n"
90
+ "**Note**: Provide up to 5-10 seconds of clear reference audio for voice cloning capabilities."
91
+ )
92
+
93
+ with gr.Row():
94
+ with gr.Column():
95
+ text_input = gr.Textbox(
96
+ label="Input Text (Malayalam/English)",
97
+ lines=4,
98
+ placeholder="നമസ്കാരം, మీరు ఎలా ఉన్నారు?"
99
+ )
100
+ ref_audio_input = gr.Audio(
101
+ label="Reference Voice Audio (Optional, for Voice Cloning)",
102
+ type="filepath"
103
+ )
104
+
105
+ with gr.Accordion("Advanced Voice Controls", open=False):
106
+ exaggeration_slider = gr.Slider(
107
+ minimum=0.0, maximum=1.0, value=0.5, step=0.05,
108
+ label="Emotion Exaggeration",
109
+ info="Lower for monotone, higher for dramatic/expressive"
110
+ )
111
+ cfg_slider = gr.Slider(
112
+ minimum=0.0, maximum=1.0, value=0.5, step=0.05,
113
+ label="CFG Weight",
114
+ info="Lower if speech is too fast, higher to strictly mimic the reference voice"
115
+ )
116
+
117
+ generate_btn = gr.Button("Synthesize Speech", variant="primary")
118
+
119
+ with gr.Column():
120
+ audio_output = gr.Audio(label="Generated Output", interactive=False)
121
+ status_output = gr.Textbox(label="Status Logging", interactive=False)
122
+
123
+ # Connect logic to UI
124
+ generate_btn.click(
125
+ fn=synthesize_audio,
126
+ inputs=[text_input, ref_audio_input, exaggeration_slider, cfg_slider],
127
+ outputs=[audio_output, status_output]
128
+ )
129
+
130
+ if __name__ == "__main__":
131
+ demo.launch()