# -*- coding: utf-8 -*-
"""Copy of VoxCPM2_Gradio_Colab_AIQUEST.ipynb
Automatically generated by Colab.
Original file is located at
https://colab.research.google.com/drive/1Qv6hRNMMm0Afyxyy85UyfUb4WsWKN9cJ
ποΈ VoxCPM2 β Multilingual TTS
Google Colab Edition β Created by AIQUEST
T4 GPU (16GB VRAM) | 2B Parameters Β· 30 Languages Β· 48kHz Output Β· Voice Design & Cloning
---
---
### β οΈ Quick Start
1. Go to **Runtime β Change runtime type β T4 GPU**
2. Run all cells in order
3. The Gradio UI link will appear at the bottom
"""
#@title π¦ Install Dependencies
#@title β
Verify GPU & VRAM
import torch
assert torch.cuda.is_available(), "β No GPU detected! Go to Runtime β Change runtime type β T4 GPU"
gpu_name = torch.cuda.get_device_name(0)
vram_gb = torch.cuda.get_device_properties(0).total_memory / 1e9
print(f"β
GPU: {gpu_name} | VRAM: {vram_gb:.1f} GB")
#@title π Load VoxCPM2 Model
import torch
import torch._dynamo
# Disable torch.compile globally BEFORE model loads
torch._dynamo.config.suppress_errors = True
torch._dynamo.config.disable = True
from voxcpm import VoxCPM
print("Loading VoxCPM2 with denoiser (quality mode)...")
print(f"GPU: {torch.cuda.get_device_name(0)}")
print(f"VRAM: {torch.cuda.get_device_properties(0).total_memory / 1e9:.1f} GB")
model = VoxCPM.from_pretrained(
"openbmb/VoxCPM2",
load_denoiser=True, # β denoiser ON for better quality
optimize=False, # β eager mode (avoids torch.compile threading bugs)
)
SAMPLE_RATE = model.tts_model.sample_rate
# Warm-up
print("Warming up...")
warmup_chunks = []
for chunk in model.generate(
text="Hello, warm up test.",
inference_timesteps=5,
):
warmup_chunks.append(chunk)
used = torch.cuda.memory_allocated() / 1e9
total = torch.cuda.get_device_properties(0).total_memory / 1e9
print(f"β
Model loaded! VRAM: {used:.1f} / {total:.1f} GB")
print(f"Sample rate: {SAMPLE_RATE} Hz")
#@title ποΈ Launch Gradio Interface
import gradio as gr
import soundfile as sf
import numpy as np
import tempfile
import os
import random
CSS = """
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap');
* { font-family: 'Inter', sans-serif !important; }
.gradio-container { max-width: 1000px !important; margin: auto !important; }
.brand-header { text-align: center; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 28px; border-radius: 15px; margin-bottom: 20px; box-shadow: 0 10px 25px rgba(102,126,234,0.3); }
.brand-title { color: white; font-size: 2em; font-weight: 700; margin: 0 0 6px 0; }
.brand-subtitle { color: rgba(255,255,255,0.88); font-size: 1em; margin-bottom: 16px; }
.btn-row { display: flex; justify-content: center; gap: 10px; flex-wrap: wrap; }
.social-btn { display: inline-flex; align-items: center; justify-content: center; min-width: 150px; padding: 10px 18px; border-radius: 10px; font-weight: 700; font-size: 13px; text-decoration: none; color: white; white-space: nowrap; }
.yt-btn { background: #FF0000; box-shadow: 0 4px 12px rgba(255,0,0,0.3); }
.x-btn { background: #000000; box-shadow: 0 4px 12px rgba(0,0,0,0.25); }
.sup-btn { background: linear-gradient(135deg,#f6d365,#fda085); box-shadow: 0 4px 12px rgba(253,160,133,0.35); }
button.primary { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important; color: white !important; font-weight: 600 !important; border-radius: 12px !important; }
"""
BRAND_HTML = """
ποΈ VoxCPM2 β Multilingual TTS
Created by AIQuest Academy | 2B Parameters Β· 30 Languages Β· 48kHz Output Β· Voice Design & Cloning
"""
# ββ Helper ββββ
def save_wav(wav_array: np.ndarray) -> str:
tmp = tempfile.NamedTemporaryFile(suffix=".wav", delete=False)
sf.write(tmp.name, wav_array, SAMPLE_RATE)
return tmp.name
def collect_audio(generator) -> np.ndarray:
chunks = []
for chunk in generator:
arr = np.asarray(chunk)
if arr.ndim == 0:
arr = arr.reshape(1)
chunks.append(arr)
if not chunks:
raise gr.Error("Model returned no audio.")
return np.concatenate(chunks)
def resolve_seed(seed, locked):
if locked and seed is not None and seed >= 0:
s = int(seed)
else:
s = random.randint(0, 2**31 - 1)
torch.manual_seed(s)
torch.cuda.manual_seed_all(s)
return s
# ββ Tab 1: Text-to-Speech ββββ
def tts_generate(text, cfg, steps, seed, locked):
if not text.strip():
raise gr.Error("Please enter some text.")
used_seed = resolve_seed(seed, locked)
gen = model.generate(text=text, cfg_value=cfg, inference_timesteps=int(steps))
wav = collect_audio(gen)
return save_wav(wav), used_seed
# ββ Tab 2: Voice Design ββββ
def voice_design(description, text, cfg, steps, seed, locked):
if not text.strip():
raise gr.Error("Please enter text content.")
if not description.strip():
raise gr.Error("Please enter a voice description.")
combined = f"({description.strip()}){text.strip()}"
used_seed = resolve_seed(seed, locked)
gen = model.generate(text=combined, cfg_value=cfg, inference_timesteps=int(steps))
wav = collect_audio(gen)
return save_wav(wav), used_seed
# ββ Tab 3: Voice Cloning ββββ
def voice_clone(text, ref_audio, style, cfg, steps, seed, locked):
if not text.strip():
raise gr.Error("Please enter text.")
if ref_audio is None:
raise gr.Error("Please upload reference audio.")
if style and style.strip():
text = f"({style.strip()}){text.strip()}"
used_seed = resolve_seed(seed, locked)
gen = model.generate(
text=text,
reference_wav_path=ref_audio,
cfg_value=cfg,
inference_timesteps=int(steps),
)
wav = collect_audio(gen)
return save_wav(wav), used_seed
# ββ Tab 4: Ultimate Cloning ββββ
def ultimate_clone(text, ref_audio, transcript, cfg, steps, seed, locked):
if not text.strip():
raise gr.Error("Please enter text.")
if ref_audio is None:
raise gr.Error("Please upload reference audio.")
if not transcript.strip():
raise gr.Error("Please enter the reference audio transcript.")
used_seed = resolve_seed(seed, locked)
gen = model.generate(
text=text,
prompt_wav_path=ref_audio,
prompt_text=transcript,
reference_wav_path=ref_audio,
cfg_value=cfg,
inference_timesteps=int(steps),
)
wav = collect_audio(gen)
return save_wav(wav), used_seed
# ββ Seed UI ββββ
def seed_row():
with gr.Row():
seed = gr.Number(value=-1, label="Seed", precision=0, scale=3)
locked = gr.Checkbox(value=False, label="π Lock Seed", scale=1)
return seed, locked
# ββ Build UI ββββ
with gr.Blocks(theme=gr.themes.Soft(), css=CSS) as demo:
gr.HTML(BRAND_HTML)
with gr.Tab("π£οΈ Text-to-Speech"):
with gr.Accordion("π Instructions", open=False):
gr.Markdown(
"Enter any text and the model will synthesize speech with natural prosody.\n\n"
"- **CFG Scale**: Higher = more adherence to text, lower = more natural/relaxed\n"
"- **Inference Steps**: Higher = better quality but slower (try 6-10 for speed)\n"
"- **Seed**: Shows the seed used. Check **π Lock Seed** to reuse it for reproducible results.\n"
"- **Supported Languages (30):** Arabic, Burmese, Chinese, Danish, Dutch, English, "
"Finnish, French, German, Greek, Hebrew, Hindi, Indonesian, Italian, Japanese, Khmer, "
"Korean, Lao, Malay, Norwegian, Polish, Portuguese, Russian, Spanish, Swahili, Swedish, "
"Tagalog, Thai, Turkish, Vietnamese\n"
"- **Chinese Dialects:** εε·θ―, η²€θ―, ε΄θ―, δΈεθ―, ζ²³εθ―, ιθ₯Ώθ―, ε±±δΈθ―, 倩ζ΄₯θ―, ι½εθ―"
)
with gr.Row():
with gr.Column():
tts_text = gr.Textbox(label="Text", lines=4, placeholder="Enter text in any of the 30 supported languages...")
with gr.Row():
tts_cfg = gr.Slider(0.5, 5.0, value=2.8, step=0.1, label="CFG Scale")
tts_steps = gr.Slider(5, 30, value=15, step=1, label="Inference Steps")
tts_seed, tts_locked = seed_row()
tts_btn = gr.Button("π£οΈ Generate Speech", variant="primary", size="lg")
with gr.Column():
tts_out = gr.Audio(label="Output", type="filepath")
tts_btn.click(tts_generate, [tts_text, tts_cfg, tts_steps, tts_seed, tts_locked], [tts_out, tts_seed])
with gr.Tab("π¨ Voice Design"):
with gr.Accordion("π Instructions", open=False):
gr.Markdown(
"Create a brand-new voice from a natural-language description β no reference audio needed!\n\n"
"**How it works:** Describe the voice you want (gender, age, tone, emotion, pace, accent) "
"and the model will create it.\n\n"
"**Examples:**\n"
"- `A young woman, gentle and sweet voice`\n"
"- `An elderly British man, deep and authoritative`\n"
"- `A cheerful child, energetic and playful`\n"
"- `A calm female narrator with a warm tone`\n\n"
"π‘ *Results may vary between runs β try 1-3 times to get the desired voice.*\n"
"π *Lock the seed to reproduce a voice you liked.*"
)
with gr.Row():
with gr.Column():
vd_desc = gr.Textbox(label="Voice Description", lines=2, placeholder="A young woman, gentle and sweet voice")
vd_text = gr.Textbox(label="Text Content", lines=3, placeholder="Hello, welcome to VoxCPM2!")
with gr.Row():
vd_cfg = gr.Slider(0.5, 5.0, value=2.8, step=0.1, label="CFG Scale")
vd_steps = gr.Slider(5, 30, value=15, step=1, label="Inference Steps")
vd_seed, vd_locked = seed_row()
vd_btn = gr.Button("π¨ Design Voice", variant="primary", size="lg")
with gr.Column():
vd_out = gr.Audio(label="Output", type="filepath")
vd_btn.click(voice_design, [vd_desc, vd_text, vd_cfg, vd_steps, vd_seed, vd_locked], [vd_out, vd_seed])
with gr.Tab("ποΈ Voice Cloning"):
with gr.Accordion("π Instructions", open=False):
gr.Markdown(
"Upload a short reference audio clip to clone the voice.\n\n"
"- The model clones **timbre, accent, and speaking style** from the reference\n"
"- Optionally add a **style description** to control emotion/pace while preserving timbre\n"
"- Reference audio should be **clear and 5-30 seconds** for best results\n"
"- The model accepts **16kHz input** and outputs **48kHz audio**\n\n"
"**Style control examples:**\n"
"- `slightly faster, cheerful tone`\n"
"- `slow and dramatic`\n"
"- `whispering, intimate`"
)
with gr.Row():
with gr.Column():
vc_ref = gr.Audio(label="Reference Audio", type="filepath")
vc_text = gr.Textbox(label="Text to Synthesize", lines=3, placeholder="This is a cloned voice generated by VoxCPM2.")
vc_style = gr.Textbox(label="Style Description (optional)", lines=1, placeholder="slightly faster, cheerful tone")
with gr.Row():
vc_cfg = gr.Slider(0.5, 5.0, value=2.8, step=0.1, label="CFG Scale")
vc_steps = gr.Slider(5, 30, value=15, step=1, label="Inference Steps")
vc_seed, vc_locked = seed_row()
vc_btn = gr.Button("ποΈ Clone Voice", variant="primary", size="lg")
with gr.Column():
vc_out = gr.Audio(label="Output", type="filepath")
vc_btn.click(voice_clone, [vc_text, vc_ref, vc_style, vc_cfg, vc_steps, vc_seed, vc_locked], [vc_out, vc_seed])
with gr.Tab("ποΈ Ultimate Cloning"):
with gr.Accordion("π Instructions", open=False):
gr.Markdown(
"Provide reference audio **and** its exact transcript for maximum fidelity cloning.\n\n"
"- This mode reproduces **every vocal nuance**: timbre, rhythm, emotion, and style\n"
"- The model continues seamlessly from the reference audio\n"
"- **Both** the reference audio and its transcript are required\n"
"- For best results, use the **same audio file** as both reference and prompt\n\n"
"π‘ *This is the highest quality cloning mode β use it when you need perfect voice reproduction.*"
)
with gr.Row():
with gr.Column():
uc_ref = gr.Audio(label="Reference Audio", type="filepath")
uc_transcript = gr.Textbox(label="Reference Audio Transcript", lines=2, placeholder="The exact transcript of the reference audio.")
uc_text = gr.Textbox(label="Text to Synthesize", lines=3, placeholder="This is an ultimate cloning demonstration.")
with gr.Row():
uc_cfg = gr.Slider(0.5, 5.0, value=2.8, step=0.1, label="CFG Scale")
uc_steps = gr.Slider(5, 30, value=15, step=1, label="Inference Steps")
uc_seed, uc_locked = seed_row()
uc_btn = gr.Button("ποΈ Ultimate Clone", variant="primary", size="lg")
with gr.Column():
uc_out = gr.Audio(label="Output", type="filepath")
uc_btn.click(ultimate_clone, [uc_text, uc_ref, uc_transcript, uc_cfg, uc_steps, uc_seed, uc_locked], [uc_out, uc_seed])
# Launch with share=True for a public Colab link
demo.queue().launch(share=True, debug=True)
"""---
β‘ Made with β€οΈ by AIQUEST Academy Β· aiquest.site Β· Β© All rights reserved
---
"""