aspirant312 commited on
Commit
38f66d3
·
1 Parent(s): 5481f58

Optimize TTS for speed - add fp16, batch processing, remove sentence splitting

Browse files
Files changed (1) hide show
  1. api.py +40 -41
api.py CHANGED
@@ -40,10 +40,20 @@ if DEVICE == "cuda":
40
 
41
  print("Loading Indic Parler-TTS model...")
42
  model = ParlerTTSForConditionalGeneration.from_pretrained(MODEL_ID).to(DEVICE)
 
 
 
 
 
 
43
  tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
44
  description_tokenizer = AutoTokenizer.from_pretrained(model.config.text_encoder._name_or_path)
45
  SAMPLE_RATE = model.config.sampling_rate
46
- print("Model loaded!")
 
 
 
 
47
 
48
  # Named speakers
49
  SPEAKERS = {
@@ -92,10 +102,8 @@ def split_sentences(text):
92
 
93
 
94
  def clean_urdu_text(text):
95
- """Clean and normalize Urdu text."""
96
- text = re.sub(r'[a-zA-Z]+', '', text)
97
- text = re.sub(r'\s+', ' ', text)
98
- text = text.strip()
99
  if text and text[-1] not in '۔.!?،':
100
  text += '۔'
101
  return text
@@ -103,7 +111,7 @@ def clean_urdu_text(text):
103
 
104
  @spaces.GPU()
105
  def generate_speech_internal(text, speaker, pitch, rate, temperature, do_sample):
106
- """Internal function for speech generation."""
107
  if not text.strip():
108
  return None
109
 
@@ -113,47 +121,38 @@ def generate_speech_internal(text, speaker, pitch, rate, temperature, do_sample)
113
  gender = "female" if "Female" in speaker or speaker in ["Divya", "Rani"] else "male"
114
  description = build_description(speaker_name, gender, pitch, rate)
115
 
116
- sentences = split_sentences(text)
117
- if not sentences:
118
- sentences = [text.strip()]
119
 
120
- all_audio = []
121
  seed = torch.randint(0, 2**32, (1,)).item()
122
-
123
- for sentence in sentences:
124
- desc_tokens = description_tokenizer(description, return_tensors="pt")
125
- prompt_tokens = tokenizer(sentence, return_tensors="pt")
126
-
127
- torch.manual_seed(seed)
128
- if torch.cuda.is_available():
129
- torch.cuda.manual_seed(seed)
130
-
131
- with torch.no_grad():
132
- generation = model.generate(
133
- input_ids=desc_tokens.input_ids.to(DEVICE),
134
- attention_mask=desc_tokens.attention_mask.to(DEVICE),
135
- prompt_input_ids=prompt_tokens.input_ids.to(DEVICE),
136
- prompt_attention_mask=prompt_tokens.attention_mask.to(DEVICE),
137
- do_sample=do_sample,
138
- temperature=temperature if do_sample else 1.0,
139
- min_new_tokens=10,
140
- )
141
-
142
- audio_chunk = generation.cpu().numpy().squeeze()
143
- audio_chunk = (audio_chunk * 32767).astype(np.int16)
144
- all_audio.append(audio_chunk)
145
-
146
- silence = np.zeros(int(SAMPLE_RATE * 0.3), dtype=np.int16)
147
- all_audio.append(silence)
148
-
149
- if not all_audio:
150
- return None
151
-
152
- audio = np.concatenate(all_audio)
153
  return audio
154
 
155
  except Exception as e:
156
  print(f"Error generating speech: {e}")
 
 
157
  return None
158
 
159
 
 
40
 
41
  print("Loading Indic Parler-TTS model...")
42
  model = ParlerTTSForConditionalGeneration.from_pretrained(MODEL_ID).to(DEVICE)
43
+
44
+ # Optimize model for inference
45
+ if DEVICE == "cuda":
46
+ model = model.half() # Use half precision (fp16) for faster inference
47
+ model.eval()
48
+
49
  tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
50
  description_tokenizer = AutoTokenizer.from_pretrained(model.config.text_encoder._name_or_path)
51
  SAMPLE_RATE = model.config.sampling_rate
52
+
53
+ # Disable gradients for inference
54
+ torch.set_grad_enabled(False)
55
+
56
+ print("Model loaded and optimized!")
57
 
58
  # Named speakers
59
  SPEAKERS = {
 
102
 
103
 
104
  def clean_urdu_text(text):
105
+ """Minimal text cleaning - preserve content."""
106
+ text = re.sub(r'\s+', ' ', text).strip()
 
 
107
  if text and text[-1] not in '۔.!?،':
108
  text += '۔'
109
  return text
 
111
 
112
  @spaces.GPU()
113
  def generate_speech_internal(text, speaker, pitch, rate, temperature, do_sample):
114
+ """Internal function for speech generation - optimized for speed."""
115
  if not text.strip():
116
  return None
117
 
 
121
  gender = "female" if "Female" in speaker or speaker in ["Divya", "Rani"] else "male"
122
  description = build_description(speaker_name, gender, pitch, rate)
123
 
124
+ # Tokenize in batch for efficiency
125
+ desc_tokens = description_tokenizer(description, return_tensors="pt").to(DEVICE)
126
+ prompt_tokens = tokenizer(text, return_tensors="pt").to(DEVICE)
127
 
128
+ # Set seed for reproducibility
129
  seed = torch.randint(0, 2**32, (1,)).item()
130
+ torch.manual_seed(seed)
131
+ if torch.cuda.is_available():
132
+ torch.cuda.manual_seed(seed)
133
+
134
+ # Generate audio in one pass
135
+ with torch.no_grad():
136
+ generation = model.generate(
137
+ input_ids=desc_tokens.input_ids,
138
+ attention_mask=desc_tokens.attention_mask,
139
+ prompt_input_ids=prompt_tokens.input_ids,
140
+ prompt_attention_mask=prompt_tokens.attention_mask,
141
+ do_sample=do_sample,
142
+ temperature=temperature if do_sample else 1.0,
143
+ min_new_tokens=10,
144
+ max_new_tokens=1024,
145
+ )
146
+
147
+ # Convert to audio format
148
+ audio = generation.cpu().numpy().squeeze()
149
+ audio = (audio * 32767).astype(np.int16)
 
 
 
 
 
 
 
 
 
 
 
150
  return audio
151
 
152
  except Exception as e:
153
  print(f"Error generating speech: {e}")
154
+ import traceback
155
+ traceback.print_exc()
156
  return None
157
 
158