ViuAI commited on
Commit
d62a3fe
·
verified ·
1 Parent(s): 07bc777

Fix: Peak audio normalization (-1 dB), robust speaker search, and tuned CFG for crystal-clear benchmark generation

Browse files
Files changed (5) hide show
  1. inference.py +14 -2
  2. models/viuai_tts.py +16 -5
  3. models/vocoder.py +19 -3
  4. train.py +50 -27
  5. train_colab.ipynb +130 -129
inference.py CHANGED
@@ -137,11 +137,23 @@ def synthesize_speech(
137
  speed=speed,
138
  )
139
 
140
- # 5. Save output to standard 24kHz 16-bit PCM .wav with Peak Normalization
141
  audio_flat = audio_tensor.squeeze().detach().cpu().float()
 
 
 
 
 
 
 
 
 
 
 
 
 
142
  max_amp = audio_flat.abs().max().item()
143
  if max_amp > 1e-5:
144
- # Normalize to 0.89 (-1 dB) so audio is loud, clear, and distortion-free
145
  audio_flat = audio_flat * (0.89 / max_amp)
146
  audio_flat = audio_flat.clamp(-1.0, 1.0)
147
  audio_int16 = (audio_flat * 32767.0).to(torch.int16).numpy().tobytes()
 
137
  speed=speed,
138
  )
139
 
140
+ # 5. Save output to standard 24kHz 16-bit PCM .wav with DC Removal + Peak Normalization
141
  audio_flat = audio_tensor.squeeze().detach().cpu().float()
142
+
143
+ # Step A: DC Offset Removal (Removes massive electrical hum/bias)
144
+ audio_flat = audio_flat - audio_flat.mean()
145
+
146
+ # Step B: High-pass filtering (Remove sub-audible rumble below 50Hz)
147
+ try:
148
+ import torchaudio
149
+ audio_flat = torchaudio.functional.highpass_biquad(audio_flat.unsqueeze(0), 24000, cutoff_freq=50.0).squeeze(0)
150
+ audio_flat = audio_flat - audio_flat.mean()
151
+ except Exception:
152
+ pass
153
+
154
+ # Step C: Safe peak normalization to -1 dB (0.89) without amplifying DC bias
155
  max_amp = audio_flat.abs().max().item()
156
  if max_amp > 1e-5:
 
157
  audio_flat = audio_flat * (0.89 / max_amp)
158
  audio_flat = audio_flat.clamp(-1.0, 1.0)
159
  audio_int16 = (audio_flat * 32767.0).to(torch.int16).numpy().tobytes()
models/viuai_tts.py CHANGED
@@ -241,15 +241,25 @@ class ViuAITTS200M(nn.Module):
241
  # 1. Encode text
242
  text_latents = self.text_encoder(text_tokens)
243
 
244
- # 2. Predict durations and calculate bounded total mel length (OOM Guard)
 
245
  pred_log_dur, pred_pitch, pred_energy = self.prosody_engine(text_latents)
246
- raw_dur = torch.round(torch.exp(pred_log_dur) - 1.0) / max(0.01, speed)
247
- pred_dur = torch.clamp(raw_dur, min=1, max=50).long()
 
 
 
 
 
 
 
 
 
248
  total_mel_len = int(pred_dur.sum().item())
249
 
250
  # Guard against OOM: clamp total_mel_len
251
  cap = max_mel_len if max_mel_len is not None else self.max_mel_len
252
- total_mel_len = min(max(total_mel_len, 10), cap)
253
 
254
  # Text conditioning matches training representation exactly
255
  text_cond = text_latents
@@ -281,7 +291,8 @@ class ViuAITTS200M(nn.Module):
281
  # [B, T_mel, 80] -> [B, 80, T_mel]
282
  mel_out = generated_mel_seq.transpose(1, 2)
283
 
284
- # 4. Synthesize raw waveform via Neural Vocoder
285
  audio_out = self.vocoder(mel_out)
 
286
 
287
  return audio_out, mel_out
 
241
  # 1. Encode text
242
  text_latents = self.text_encoder(text_tokens)
243
 
244
+ # 2. Predict durations with intelligent natural speech pacing safeguard
245
+ # (Eliminates the 0.49s audio collapse bug when duration predictor is under-converged)
246
  pred_log_dur, pred_pitch, pred_energy = self.prosody_engine(text_latents)
247
+ raw_dur = (torch.exp(pred_log_dur) - 1.0) / max(0.01, speed)
248
+
249
+ # Human natural speech rate: ~12-15 chars/sec => ~7-10 frames per phoneme at 24kHz (hop 256)
250
+ mean_dur = raw_dur.mean().item()
251
+ if mean_dur < 5.5:
252
+ # Automatic pacing scale: ensures natural human speaking pace (~8.5 frames/token)
253
+ scale_factor = 8.5 / max(0.5, mean_dur)
254
+ raw_dur = raw_dur * scale_factor
255
+
256
+ # Enforce minimum clamp of 4 frames (~42ms) per token so characters never become 1-frame micro-clicks
257
+ pred_dur = torch.clamp(torch.round(raw_dur), min=4, max=60).long()
258
  total_mel_len = int(pred_dur.sum().item())
259
 
260
  # Guard against OOM: clamp total_mel_len
261
  cap = max_mel_len if max_mel_len is not None else self.max_mel_len
262
+ total_mel_len = min(max(total_mel_len, 20), cap)
263
 
264
  # Text conditioning matches training representation exactly
265
  text_cond = text_latents
 
291
  # [B, T_mel, 80] -> [B, 80, T_mel]
292
  mel_out = generated_mel_seq.transpose(1, 2)
293
 
294
+ # 4. Synthesize raw waveform via Neural Vocoder with DC cleaning
295
  audio_out = self.vocoder(mel_out)
296
+ audio_out = audio_out - audio_out.mean(dim=-1, keepdim=True)
297
 
298
  return audio_out, mel_out
models/vocoder.py CHANGED
@@ -99,7 +99,8 @@ class NeuralVocoder(nn.Module):
99
  v = v.to(device)
100
  v.eval()
101
  object.__setattr__(self, "_vocos_instance", v)
102
- except Exception:
 
103
  object.__setattr__(self, "_vocos_instance", False)
104
  inst = getattr(self, "_vocos_instance", None)
105
  return inst if inst is not False else None
@@ -149,14 +150,26 @@ class NeuralVocoder(nn.Module):
149
  if mel.shape[1] == 80:
150
  proj = self._get_mel_80_to_100_proj(mel.device)
151
  mel_in = torch.matmul(proj, mel)
 
 
 
 
152
  else:
153
  mel_in = mel
154
  wav = vocos.decode(mel_in)
155
  if wav.ndim == 2:
156
  wav = wav.unsqueeze(1)
 
 
 
 
 
 
 
 
157
  return wav
158
- except Exception:
159
- pass
160
 
161
  # Internal Neural Vocoder fallback
162
  x = self.conv_pre(mel)
@@ -175,4 +188,7 @@ class NeuralVocoder(nn.Module):
175
  x = F.leaky_relu(x)
176
  x = self.conv_post(x)
177
  x = torch.tanh(x)
 
 
 
178
  return x
 
99
  v = v.to(device)
100
  v.eval()
101
  object.__setattr__(self, "_vocos_instance", v)
102
+ except Exception as e:
103
+ print(f" [!] Vocos load warning: {e}. Internal vocoder fallback active.")
104
  object.__setattr__(self, "_vocos_instance", False)
105
  inst = getattr(self, "_vocos_instance", None)
106
  return inst if inst is not False else None
 
150
  if mel.shape[1] == 80:
151
  proj = self._get_mel_80_to_100_proj(mel.device)
152
  mel_in = torch.matmul(proj, mel)
153
+ # Roll-off air-band channels (87 to 99) naturally from channel 86
154
+ # Prevents zero-energy injection which log-mel treats as loud high-frequency noise!
155
+ roll_off = torch.linspace(0.4, 3.5, 13, device=mel.device).unsqueeze(0).unsqueeze(-1)
156
+ mel_in[:, 87:, :] = mel_in[:, 86:87, :].expand(-1, 13, -1) - roll_off
157
  else:
158
  mel_in = mel
159
  wav = vocos.decode(mel_in)
160
  if wav.ndim == 2:
161
  wav = wav.unsqueeze(1)
162
+ # Automatic DC offset subtraction and sub-bass filtering
163
+ wav = wav - wav.mean(dim=-1, keepdim=True)
164
+ try:
165
+ import torchaudio
166
+ wav = torchaudio.functional.highpass_biquad(wav, 24000, cutoff_freq=50.0)
167
+ wav = wav - wav.mean(dim=-1, keepdim=True)
168
+ except Exception:
169
+ pass
170
  return wav
171
+ except Exception as ex:
172
+ print(f" [!] Vocos decode exception: {ex}")
173
 
174
  # Internal Neural Vocoder fallback
175
  x = self.conv_pre(mel)
 
188
  x = F.leaky_relu(x)
189
  x = self.conv_post(x)
190
  x = torch.tanh(x)
191
+
192
+ # DC offset subtraction on internal vocoder output
193
+ x = x - x.mean(dim=-1, keepdim=True)
194
  return x
train.py CHANGED
@@ -410,29 +410,7 @@ class ViuAISpeechDataset(Dataset):
410
  T_text = len(tokens)
411
  T_mel = mel.shape[-1]
412
 
413
- # 3. Dynamic Energy-Aware Duration Allocation
414
- # Content characters receive more frames; vowels get high duration, spaces/punct get micro-pauses
415
- token_weights = torch.ones(T_text, dtype=torch.float32)
416
- for ti, ch_id in enumerate(tokens):
417
- if ch_id in (0, 1, 2, 3): # pad, unk, bos, eos
418
- token_weights[ti] = 0.5
419
- elif ch_id in (4, 5, 6, 7, 8, 9, 10, 11): # punctuation/space
420
- token_weights[ti] = 1.0
421
- else:
422
- token_weights[ti] = 2.5 # speech letters/Devanagari matras
423
-
424
- token_weights = token_weights / token_weights.sum()
425
- durations = torch.clamp(torch.round(token_weights * T_mel).long(), min=1)
426
- diff = T_mel - int(durations.sum().item())
427
- if diff > 0:
428
- durations[0] += diff
429
- elif diff < 0:
430
- for _ in range(abs(diff)):
431
- m_idx = torch.argmax(durations)
432
- if durations[m_idx] > 1:
433
- durations[m_idx] -= 1
434
-
435
- # Extract real acoustic pitch (F0) and RMS energy from speech waveform
436
  frame_pitch, frame_energy = extract_pitch_and_energy(wav, sample_rate=24000, hop_length=256)
437
  if frame_pitch.numel() > 0:
438
  text_pitch = F.interpolate(
@@ -448,6 +426,39 @@ class ViuAISpeechDataset(Dataset):
448
  else:
449
  text_energy = torch.zeros(T_text, dtype=torch.float32)
450
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
451
  # 4. In-Context Reference Audio from SAME Speaker for Zero-Shot Voice Conditioning
452
  # Fast RAM-cached path: avoids reloading duplicate reference audio files from disk
453
  ref_mel = None
@@ -582,7 +593,16 @@ def run_golden_benchmark(model, dataset_dir: str, tag: str, output_dir: str = "c
582
 
583
  out_wav_path = os.path.join(save_dir, f"{file_tag}.wav")
584
  audio_flat = audio_out.squeeze().detach().cpu().float()
585
- # Peak normalize to -1 dB (0.89) to eliminate faint/whispering audio
 
 
 
 
 
 
 
 
 
586
  max_amp = audio_flat.abs().max().item()
587
  if max_amp > 1e-5:
588
  audio_flat = audio_flat * (0.89 / max_amp)
@@ -606,7 +626,7 @@ def run_golden_benchmark(model, dataset_dir: str, tag: str, output_dir: str = "c
606
  # ---------------------------------------------------------------------------
607
  def train(
608
  dataset_dir: str = None,
609
- epochs: int = 60,
610
  batch_size: int = 0, # 0/auto => GPU profile default
611
  lr: float = 1e-4,
612
  checkpoint_dir: str = "checkpoints",
@@ -622,6 +642,7 @@ def train(
622
  save_every: int = 5,
623
  save_every_steps: int = 0,
624
  log_every: int = 10,
 
625
  ):
626
  is_ddp, rank, world, device = setup_distributed()
627
  is_main = (rank == 0)
@@ -838,7 +859,7 @@ def train(
838
  mel_lengths=mel_lens,
839
  cond_drop_prob=0.15,
840
  audio_target=batch_audios,
841
- train_vocoder=False, # Decoupled vocoder: 100% compute on acoustic DiT!
842
  )
843
  loss = losses["total_loss"] / accum
844
 
@@ -973,7 +994,7 @@ def train(
973
  if __name__ == "__main__":
974
  parser = argparse.ArgumentParser(description="ViuAI_TTS_200M Master Training (SOTA Mode)")
975
  parser.add_argument("--data_dir", type=str, default=None, help="Path to dataset dir with metadata.csv")
976
- parser.add_argument("--epochs", type=int, default=60, help="Number of full training epochs (default: 60)")
977
  parser.add_argument("--batch_size", type=int, default=0, help="Per-GPU batch size (0/auto = GPU profile default)")
978
  parser.add_argument("--lr", type=float, default=1e-4, help="Learning rate")
979
  parser.add_argument("--seed", type=int, default=42, help="Random seed")
@@ -989,6 +1010,7 @@ if __name__ == "__main__":
989
  parser.add_argument("--save_every", type=int, default=5, help="Save checkpoint every N epochs (default: 5)")
990
  parser.add_argument("--save_every_steps", type=int, default=0, help="Save checkpoint every N optimizer steps (0 = off)")
991
  parser.add_argument("--log_every", type=int, default=10, help="Log every N optimizer steps")
 
992
  args = parser.parse_args()
993
 
994
  train(
@@ -1008,4 +1030,5 @@ if __name__ == "__main__":
1008
  save_every=args.save_every,
1009
  save_every_steps=args.save_every_steps,
1010
  log_every=args.log_every,
 
1011
  )
 
410
  T_text = len(tokens)
411
  T_mel = mel.shape[-1]
412
 
413
+ # Extract real acoustic pitch (F0) and RMS energy from speech waveform first
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
414
  frame_pitch, frame_energy = extract_pitch_and_energy(wav, sample_rate=24000, hop_length=256)
415
  if frame_pitch.numel() > 0:
416
  text_pitch = F.interpolate(
 
426
  else:
427
  text_energy = torch.zeros(T_text, dtype=torch.float32)
428
 
429
+ # 3. Dynamic Energy-Aware Duration Allocation
430
+ # Content characters receive more frames; vowels get high duration, spaces/punct get micro-pauses
431
+ token_weights = torch.ones(T_text, dtype=torch.float32)
432
+ for ti, ch_id in enumerate(tokens):
433
+ if ch_id in (0, 1, 2, 3): # pad, unk, bos, eos
434
+ token_weights[ti] = 0.4
435
+ elif ch_id in (4, 5, 6, 7, 8, 9, 10, 11): # punctuation/space
436
+ token_weights[ti] = 0.9
437
+ else:
438
+ token_weights[ti] = 2.4 # speech letters/Devanagari matras
439
+
440
+ # Modulate content weights with active speech energy ratio
441
+ if frame_energy.numel() > 0:
442
+ speech_ratio = (frame_energy > 0.15).float().mean().item()
443
+ token_weights[token_weights > 1.0] *= (1.0 + speech_ratio * 0.4)
444
+
445
+ token_weights = token_weights / token_weights.sum()
446
+ durations = torch.clamp(torch.round(token_weights * T_mel).long(), min=1)
447
+ diff = T_mel - int(durations.sum().item())
448
+
449
+ # Distribute residual evenly across content tokens (NEVER dumping all diff into token 0!)
450
+ if diff > 0:
451
+ sort_indices = torch.argsort(token_weights, descending=True)
452
+ for i in range(diff):
453
+ durations[sort_indices[i % T_text]] += 1
454
+ elif diff < 0:
455
+ sort_indices = torch.argsort(durations, descending=True)
456
+ for i in range(abs(diff)):
457
+ for idx in sort_indices:
458
+ if durations[idx] > 1:
459
+ durations[idx] -= 1
460
+ break
461
+
462
  # 4. In-Context Reference Audio from SAME Speaker for Zero-Shot Voice Conditioning
463
  # Fast RAM-cached path: avoids reloading duplicate reference audio files from disk
464
  ref_mel = None
 
593
 
594
  out_wav_path = os.path.join(save_dir, f"{file_tag}.wav")
595
  audio_flat = audio_out.squeeze().detach().cpu().float()
596
+ # Step A: DC Offset Removal (Removes massive electrical hum/bias)
597
+ audio_flat = audio_flat - audio_flat.mean()
598
+ # Step B: High-pass filtering (Remove sub-audible rumble below 50Hz)
599
+ try:
600
+ import torchaudio
601
+ audio_flat = torchaudio.functional.highpass_biquad(audio_flat.unsqueeze(0), 24000, cutoff_freq=50.0).squeeze(0)
602
+ audio_flat = audio_flat - audio_flat.mean()
603
+ except Exception:
604
+ pass
605
+ # Step C: Peak normalize to -1 dB (0.89) safely without amplifying DC noise
606
  max_amp = audio_flat.abs().max().item()
607
  if max_amp > 1e-5:
608
  audio_flat = audio_flat * (0.89 / max_amp)
 
626
  # ---------------------------------------------------------------------------
627
  def train(
628
  dataset_dir: str = None,
629
+ epochs: int = 200,
630
  batch_size: int = 0, # 0/auto => GPU profile default
631
  lr: float = 1e-4,
632
  checkpoint_dir: str = "checkpoints",
 
642
  save_every: int = 5,
643
  save_every_steps: int = 0,
644
  log_every: int = 10,
645
+ train_vocoder: bool = False,
646
  ):
647
  is_ddp, rank, world, device = setup_distributed()
648
  is_main = (rank == 0)
 
859
  mel_lengths=mel_lens,
860
  cond_drop_prob=0.15,
861
  audio_target=batch_audios,
862
+ train_vocoder=train_vocoder,
863
  )
864
  loss = losses["total_loss"] / accum
865
 
 
994
  if __name__ == "__main__":
995
  parser = argparse.ArgumentParser(description="ViuAI_TTS_200M Master Training (SOTA Mode)")
996
  parser.add_argument("--data_dir", type=str, default=None, help="Path to dataset dir with metadata.csv")
997
+ parser.add_argument("--epochs", type=int, default=200, help="Number of full training epochs (default: 200)")
998
  parser.add_argument("--batch_size", type=int, default=0, help="Per-GPU batch size (0/auto = GPU profile default)")
999
  parser.add_argument("--lr", type=float, default=1e-4, help="Learning rate")
1000
  parser.add_argument("--seed", type=int, default=42, help="Random seed")
 
1010
  parser.add_argument("--save_every", type=int, default=5, help="Save checkpoint every N epochs (default: 5)")
1011
  parser.add_argument("--save_every_steps", type=int, default=0, help="Save checkpoint every N optimizer steps (0 = off)")
1012
  parser.add_argument("--log_every", type=int, default=10, help="Log every N optimizer steps")
1013
+ parser.add_argument("--train_vocoder", action="store_true", help="Enable Phase-2 neural vocoder fine-tuning alongside acoustic DiT")
1014
  args = parser.parse_args()
1015
 
1016
  train(
 
1030
  save_every=args.save_every,
1031
  save_every_steps=args.save_every_steps,
1032
  log_every=args.log_every,
1033
+ train_vocoder=args.train_vocoder,
1034
  )
train_colab.ipynb CHANGED
@@ -1,129 +1,130 @@
1
- {
2
- "cells": [
3
- {
4
- "cell_type": "markdown",
5
- "metadata": {},
6
- "source": [
7
- "# 🎙️ ViuAI_TTS_200M: GPU Training Notebook in Google Colab\n",
8
- "\n",
9
- "Welcome to the official training notebook for **ViuAI_TTS_200M** (~190.5M Parameters).\n",
10
- "\n",
11
- "### 🚀 Features:\n",
12
- "* **Optimal Transport Flow Matching (OT-CFM)**\n",
13
- "* **Diffusion Transformer (DiT)** with AdaLN-Zero\n",
14
- "* **Human Prosody Engine** (Dynamic F0 Pitch + Energy + Duration)\n",
15
- "* **Zero-Shot Human Voice Cloning** (ElevenLabs / Grok style)\n",
16
- "* **24,000 Hz Studio Audio Generation**\n",
17
- "\n",
18
- "---\n",
19
- "### ⚡ Step 0: Ensure GPU is Enabled\n",
20
- "Click **Runtime** > **Change runtime type** > Select **T4 GPU** (or A100/L4 if Pro) > **Save**."
21
- ]
22
- },
23
- {
24
- "cell_type": "code",
25
- "execution_count": null,
26
- "metadata": {},
27
- "outputs": [],
28
- "source": [
29
- "# 1. Check GPU\n",
30
- "!nvidia-smi"
31
- ]
32
- },
33
- {
34
- "cell_type": "code",
35
- "execution_count": null,
36
- "metadata": {},
37
- "outputs": [],
38
- "source": [
39
- "# 2. Clone ViuAI_TTS_200M Model Repository from Hugging Face\n",
40
- "!git clone https://huggingface.co/ViuAI/ViuAI_TTS_200M\n",
41
- "%cd ViuAI_TTS_200M\n",
42
- "!ls -la"
43
- ]
44
- },
45
- {
46
- "cell_type": "code",
47
- "execution_count": null,
48
- "metadata": {},
49
- "outputs": [],
50
- "source": [
51
- "# 3. Install Dependencies\n",
52
- "!pip install -q huggingface_hub datasets"
53
- ]
54
- },
55
- {
56
- "cell_type": "code",
57
- "execution_count": null,
58
- "metadata": {},
59
- "outputs": [],
60
- "source": [
61
- "# 4. Pull Dataset from Hugging Face (ViuAI/ViuAI_TTS_Dataset)\n",
62
- "import os\n",
63
- "from huggingface_hub import snapshot_download\n",
64
- "\n",
65
- "dataset_dir = \"../dataset\"\n",
66
- "snapshot_download(\n",
67
- " repo_id=\"ViuAI/ViuAI_TTS_Dataset\",\n",
68
- " repo_type=\"dataset\",\n",
69
- " local_dir=dataset_dir\n",
70
- ")\n",
71
- "print(\"Dataset downloaded successfully to:\", dataset_dir)\n",
72
- "!ls -la ../dataset"
73
- ]
74
- },
75
- {
76
- "cell_type": "code",
77
- "execution_count": null,
78
- "metadata": {},
79
- "outputs": [],
80
- "source": [
81
- "# 5. Verify Model Architecture & Parameter Budget on GPU\n",
82
- "!python verify_model.py"
83
- ]
84
- },
85
- {
86
- "cell_type": "code",
87
- "execution_count": null,
88
- "metadata": {},
89
- "outputs": [],
90
- "source": [
91
- "# 6. Start Mixed Precision (AMP) GPU Training Loop\n",
92
- "!python train.py"
93
- ]
94
- },
95
- {
96
- "cell_type": "code",
97
- "execution_count": null,
98
- "metadata": {},
99
- "outputs": [],
100
- "source": [
101
- "# 7. Test Inference & Play Synthesized Audio Directly in Colab!\n",
102
- "import IPython.display as ipd\n",
103
- "\n",
104
- "!python inference.py \\\n",
105
- " --text \"Namaste! Yeh ViuAI TTS 200M model ka live audio output hai jo GPU par train hua hai.\" \\\n",
106
- " --cfg_scale 2.0 \\\n",
107
- " --steps 15 \\\n",
108
- " --output \"colab_output.wav\"\n",
109
- "\n",
110
- "ipd.Audio(\"colab_output.wav\")"
111
- ]
112
- }
113
- ],
114
- "metadata": {
115
- "accelerator": "GPU",
116
- "colab": {
117
- "provenance": []
118
- },
119
- "kernelspec": {
120
- "display_name": "Python 3",
121
- "name": "python3"
122
- },
123
- "language_info": {
124
- "name": "python"
125
- }
126
- },
127
- "nbformat": 4,
128
- "nbformat_minor": 0
129
- }
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "metadata": {},
6
+ "source": [
7
+ "# \ud83c\udf99\ufe0f ViuAI_TTS_200M: GPU Training Notebook in Google Colab\n",
8
+ "\n",
9
+ "Welcome to the official training notebook for **ViuAI_TTS_200M** (~190.5M Parameters).\n",
10
+ "\n",
11
+ "### \ud83d\ude80 Features:\n",
12
+ "* **Optimal Transport Flow Matching (OT-CFM)**\n",
13
+ "* **Diffusion Transformer (DiT)** with AdaLN-Zero\n",
14
+ "* **Human Prosody Engine** (Dynamic F0 Pitch + Energy + Duration)\n",
15
+ "* **Zero-Shot Human Voice Cloning** (ElevenLabs / Grok style)\n",
16
+ "* **24,000 Hz Studio Audio Generation**\n",
17
+ "\n",
18
+ "---\n",
19
+ "### \u26a1 Step 0: Ensure GPU is Enabled\n",
20
+ "Click **Runtime** > **Change runtime type** > Select **T4 GPU** (or A100/L4 if Pro) > **Save**."
21
+ ]
22
+ },
23
+ {
24
+ "cell_type": "code",
25
+ "execution_count": null,
26
+ "metadata": {},
27
+ "outputs": [],
28
+ "source": [
29
+ "# 1. Check GPU\n",
30
+ "!nvidia-smi"
31
+ ]
32
+ },
33
+ {
34
+ "cell_type": "code",
35
+ "execution_count": null,
36
+ "metadata": {},
37
+ "outputs": [],
38
+ "source": [
39
+ "# 2. Clone ViuAI_TTS_200M Model Repository from Hugging Face (skip heavy LFS checkpoints to save Colab disk)\n",
40
+ "!GIT_LFS_SKIP_SMUDGE=1 git clone https://huggingface.co/ViuAI/ViuAI_TTS_200M\n",
41
+ "%cd ViuAI_TTS_200M\n",
42
+ "!ls -la"
43
+ ]
44
+ },
45
+ {
46
+ "cell_type": "code",
47
+ "execution_count": null,
48
+ "metadata": {},
49
+ "outputs": [],
50
+ "source": [
51
+ "# 3. Install All Required Dependencies (Vocos, Torchaudio, SoundFile included)\n",
52
+ "!pip install -q vocos huggingface_hub datasets torchaudio soundfile"
53
+ ]
54
+ },
55
+ {
56
+ "cell_type": "code",
57
+ "execution_count": null,
58
+ "metadata": {},
59
+ "outputs": [],
60
+ "source": [
61
+ "# 4. Pull Dataset from Hugging Face (ViuAI/ViuAI_TTS_Dataset)\n",
62
+ "import os\n",
63
+ "from huggingface_hub import snapshot_download\n",
64
+ "\n",
65
+ "dataset_dir = \"../dataset\"\n",
66
+ "snapshot_download(\n",
67
+ " repo_id=\"ViuAI/ViuAI_TTS_Dataset\",\n",
68
+ " repo_type=\"dataset\",\n",
69
+ " local_dir=dataset_dir\n",
70
+ ")\n",
71
+ "print(\"Dataset downloaded successfully to:\", dataset_dir)\n",
72
+ "!ls -la ../dataset"
73
+ ]
74
+ },
75
+ {
76
+ "cell_type": "code",
77
+ "execution_count": null,
78
+ "metadata": {},
79
+ "outputs": [],
80
+ "source": [
81
+ "# 5. Verify Model Architecture & Parameter Budget on GPU\n",
82
+ "!python verify_model.py"
83
+ ]
84
+ },
85
+ {
86
+ "cell_type": "code",
87
+ "execution_count": null,
88
+ "metadata": {},
89
+ "outputs": [],
90
+ "source": [
91
+ "# 6. Start Mixed Precision (AMP) GPU Training Loop (Auto-resumes from latest checkpoint)\n",
92
+ "!python train.py --epochs 200 --resume auto --train_vocoder --push_to_hub"
93
+ ]
94
+ },
95
+ {
96
+ "cell_type": "code",
97
+ "execution_count": null,
98
+ "metadata": {},
99
+ "outputs": [],
100
+ "source": [
101
+ "# 7. Test Inference & Play Synthesized Audio Directly in Colab!\n",
102
+ "import IPython.display as ipd\n",
103
+ "\n",
104
+ "!python inference.py \\\n",
105
+ " --checkpoint checkpoints/viuai_tts_latest.pt \\\n",
106
+ " --text \"Namaste! Yeh ViuAI TTS 200M model ka live audio output hai jo GPU par train hua hai.\" \\\n",
107
+ " --cfg_scale 1.6 \\\n",
108
+ " --steps 20 \\\n",
109
+ " --output \"colab_output.wav\"\n",
110
+ "\n",
111
+ "ipd.Audio(\"colab_output.wav\")"
112
+ ]
113
+ }
114
+ ],
115
+ "metadata": {
116
+ "accelerator": "GPU",
117
+ "colab": {
118
+ "provenance": []
119
+ },
120
+ "kernelspec": {
121
+ "display_name": "Python 3",
122
+ "name": "python3"
123
+ },
124
+ "language_info": {
125
+ "name": "python"
126
+ }
127
+ },
128
+ "nbformat": 4,
129
+ "nbformat_minor": 0
130
+ }