1# Environment detection
2python3 -c "
3import os
4print('colab' if 'COLAB_' in ''.join(os.environ.keys()) else 'local')
5"
6
7# Install core dependencies
8pip install snac1# Install Colab-specific dependencies
2pip install --no-deps bitsandbytes accelerate xformers==0.0.29.post3 peft trl triton cut_cross_entropy unsloth_zoo
3pip install sentencepiece protobuf 'datasets>=3.4.1,<4.0.0' huggingface_hub hf_transfer
4pip install --no-deps unsloth
5# Environment cleanup (recommended for clean installation)
6pip uninstall torch torchvision torchaudio unsloth unsloth_zoo transformers -y
7pip cache purge
8
9# Install PyTorch with CUDA 12.1 support
10pip install torch==2.4.1+cu121 torchvision==0.19.1+cu121 torchaudio==2.4.1+cu121 --index-url https://download.pytorch.org/whl/cu121
11
12# Install latest Unsloth from source
13pip install "unsloth[colab-new] @ git+https://github.com/unslothai/unsloth.git"
14
15# Additional dependencies
16pip install librosa
17pip install -U datasets1import gradio as gr
2import torch
3from unsloth import FastLanguageModel
4from IPython.display import display, Audio
5import numpy as np
6
7# Global model variables
8model = None
9tokenizer = None
10snac_model = None
11device = None
12def load_models():
13 """Initialize and load all required models for Sanskrit TTS inference."""
14 global model, tokenizer, snac_model, device
15 device = "cuda" if torch.cuda.is_available() else "cpu"
16 print(f"Loading models on: {device}")
17
18 # Load the fine-tuned Sanskrit TTS model
19 model, tokenizer = FastLanguageModel.from_pretrained(
20 "R910/Sanskrit_TTS_v2",
21 max_seq_length=2048,
22 dtype=None,
23 load_in_4bit=False,
24 )
25
26 model = model.to(device)
27 FastLanguageModel.for_inference(model)
28
29 # Load SNAC model for audio generation
30 try:
31 from snac import SNAC
32 snac_model = SNAC.from_pretrained("hubertsiuzdak/snac_24khz").eval()
33 except ImportError:
34 print("Warning: SNAC model import failed. Make sure SNAC is installed.")
35 snac_model.to("cpu")
36
37 print("Models loaded successfully!")
38def redistribute_codes(code_list):
39 """Redistribute generated codes into hierarchical layers for audio synthesis."""
40 layer_1 = []
41 layer_2 = []
42 layer_3 = []
43
44 for i in range((len(code_list)+1)//7):
45 layer_1.append(code_list[7*i])
46 layer_2.append(code_list[7*i+1]-4096)
47 layer_3.append(code_list[7*i+2]-(2*4096))
48 layer_3.append(code_list[7*i+3]-(3*4096))
49 layer_2.append(code_list[7*i+4]-(4*4096))
50 layer_3.append(code_list[7*i+5]-(5*4096))
51 layer_3.append(code_list[7*i+6]-(6*4096))
52
53 codes = [torch.tensor(layer_1).unsqueeze(0),
54 torch.tensor(layer_2).unsqueeze(0),
55 torch.tensor(layer_3).unsqueeze(0)]
56
57 audio_hat = snac_model.decode(codes)
58 return audio_hat
59def sanskrit_tts_inference(sanskrit_text, chosen_voice=""):
60 """
61 Generate Sanskrit speech from input text using the fine-tuned model.
62
63 Args:
64 sanskrit_text (str): Input Sanskrit text in Devanagari script
65 chosen_voice (str): Voice selection parameter (optional)
66
67 Returns:
68 tuple: (audio_data, status_message)
69 """
70 if not sanskrit_text.strip():
71 return None, "Please enter some Sanskrit text."
72
73 try:
74 prompts = [sanskrit_text]
75 chosen_voice = 1070
76
77 # Prepare prompts with voice selection
78 prompts_ = [(f"{chosen_voice}: " + p) if chosen_voice else p for p in prompts]
79
80 # Tokenize input prompts
81 all_input_ids = []
82 for prompt in prompts_:
83 input_ids = tokenizer(prompt, return_tensors="pt").input_ids
84 all_input_ids.append(input_ids)
85
86 # Define special tokens
87 start_token = torch.tensor([[ 128259]], dtype=torch.int64)
88 end_tokens = torch.tensor([[128009, 128260]], dtype=torch.int64)
89
90 # Construct modified input sequences
91 all_modified_input_ids = []
92 for input_ids in all_input_ids:
93 modified_input_ids = torch.cat([start_token, input_ids, end_tokens], dim=1)
94 all_modified_input_ids.append(modified_input_ids)
95
96 # Apply padding and create attention masks
97 all_padded_tensors = []
98 all_attention_masks = []
99 max_length = max([modified_input_ids.shape[1] for modified_input_ids in all_modified_input_ids])
100
101 for modified_input_ids in all_modified_input_ids:
102 padding = max_length - modified_input_ids.shape[1]
103 padded_tensor = torch.cat([torch.full((1, padding), 128263, dtype=torch.int64), modified_input_ids], dim=1)
104 attention_mask = torch.cat([torch.zeros((1, padding), dtype=torch.int64), torch.ones((1, modified_input_ids.shape[1]), dtype=torch.int64)], dim=1)
105 all_padded_tensors.append(padded_tensor)
106 all_attention_masks.append(attention_mask)
107
108 # Batch tensors for inference
109 all_padded_tensors = torch.cat(all_padded_tensors, dim=0)
110 all_attention_masks = torch.cat(all_attention_masks, dim=0)
111
112 input_ids = all_padded_tensors.to(device)
113 attention_mask = all_attention_masks.to(device)
114
115 # Generate audio codes using the model
116 generated_ids = model.generate(
117 input_ids=input_ids,
118 attention_mask=attention_mask,
119 max_new_tokens=1200,
120 do_sample=True,
121 temperature=0.6,
122 top_p=0.95,
123 repetition_penalty=1.1,
124 num_return_sequences=1,
125 eos_token_id=128258,
126 use_cache=True
127 )
128
129 # Post-process generated tokens
130 token_to_find = 128257
131 token_to_remove = 128258
132
133 token_indices = (generated_ids == token_to_find).nonzero(as_tuple=True)
134
135 if len(token_indices[1]) > 0:
136 last_occurrence_idx = token_indices[1][-1].item()
137 cropped_tensor = generated_ids[:, last_occurrence_idx+1:]
138 else:
139 cropped_tensor = generated_ids
140
141 mask = cropped_tensor != token_to_remove
142
143 processed_rows = []
144 for row in cropped_tensor:
145 masked_row = row[row != token_to_remove]
146 processed_rows.append(masked_row)
147
148 # Convert tokens to audio codes
149 code_lists = []
150 for row in processed_rows:
151 row_length = row.size(0)
152 new_length = (row_length // 7) * 7
153 trimmed_row = row[:new_length]
154 trimmed_row = [t - 128266 for t in trimmed_row]
155 code_lists.append(trimmed_row)
156
157 # Generate audio samples
158 my_samples = []
159 for code_list in code_lists:
160 samples = redistribute_codes(code_list)
161 my_samples.append(samples)
162
163 if len(my_samples) > 0:
164 audio_sample = my_samples[0].detach().squeeze().to("cpu").numpy()
165 return (24000, audio_sample), f"✅ Generated audio for: {sanskrit_text}"
166 else:
167 return None, "❌ Failed to generate audio - no valid codes produced."
168
169 except Exception as e:
170 return None, f"❌ Error during inference: {str(e)}"
171# Initialize models
172print("Loading models... This may take a moment.")
173load_models()
174# Create Gradio interface
175with gr.Blocks(title="Sanskrit Text-to-Speech") as demo:
176 gr.Markdown("""
177 # 🕉️ Sanskrit Text-to-Speech
178
179 Enter Sanskrit text in Devanagari script and generate speech using your fine-tuned model.
180 """)
181
182 with gr.Row():
183 with gr.Column():
184 sanskrit_input = gr.Textbox(
185 label="Sanskrit Text",
186 placeholder="Enter Sanskrit text in Devanagari script...",
187 lines=3,
188 value="नमस्ते"
189 )
190
191 generate_btn = gr.Button("🎵 Generate Speech", variant="primary")
192
193 with gr.Column():
194 audio_output = gr.Audio(
195 label="Generated Sanskrit Speech",
196 type="numpy"
197 )
198
199 status_output = gr.Textbox(
200 label="Status",
201 lines=2,
202 interactive=False
203 )
204
205 # Example inputs for demonstration
206 gr.Examples(
207 examples=[
208 ["नमस्ते"],
209 ["संस्कृत एक प्राचीन भाषा है"],
210 ["ॐ शान्ति शान्ति शान्तिः"],
211 ["सर्वे भवन्तु सुखिनः"],
212 ],
213 inputs=[sanskrit_input],
214 outputs=[audio_output, status_output],
215 fn=sanskrit_tts_inference,
216 cache_examples=False
217 )
218
219 # Connect interface components
220 generate_btn.click(
221 fn=sanskrit_tts_inference,
222 inputs=[sanskrit_input],
223 outputs=[audio_output, status_output]
224 )
225# Launch the application
226if __name__ == "__main__":
227 demo.launch(
228 share=True,
229 server_name="0.0.0.0",
230 server_port=7860,
231 show_error=True
232 )| � यदा यदा हि धर्मस्य ग्लानिर्भवति भारत। Bhagavad Gita 4.7 | |
| 🕉️ कर्मण्येवाधिकारस्ते मा फलेषु कदाचन। Bhagavad Gita 2.47 | |
| 📚 विद्या ददाति विनयं Subhashita | |
| 🌟 तमसो मा ज्योतिर्गमय। Brihadaranyaka Upanishad 1.3.28 |
1@inproceedings{indictts,
2 title = {Building Open Sourced and Industry Grade Low-Resource {TTS} for {I}ndian Languages},
3 author = {ID Prakashraj and Abhayjeet Singh and Anusha Prakash and AV Anand Kumar and Shambavi Bhaskar
4 and Varun Srinivas and Vishal Sunder and Hema A Murthy and S Umesh},
5 booktitle = {Proc. Interspeech 2023},
6 year = {2023},
7 pages = {1009--1013},
8 doi = {10.21437/Interspeech.2023-1339}
9}