import gradio as gr import torch import soundfile as sf from qwen_tts import Qwen3TTSModel from langdetect import detect import os # Load model - optimized for BF16 to save memory device = "cuda" if torch.cuda.is_available() else "cpu" model_id = "Qwen/Qwen3-TTS-12Hz-1.7B-CustomVoice" print(f"Loading model to {device}...") model = Qwen3TTSModel.from_pretrained( model_id, device_map=device, torch_dtype=torch.bfloat16 if device == "cuda" else torch.float32 ) def smart_tts(text, voice, instructions, auto_detect): try: # Smart Language Detection lang_map = { 'zh': 'Chinese', 'en': 'English', 'jp': 'Japanese', 'ko': 'Korean', 'de': 'German', 'fr': 'French', 'ru': 'Russian', 'pt': 'Portuguese', 'es': 'Spanish', 'it': 'Italian' } detected_lang = "English" # Default if auto_detect: try: raw_lang = detect(text).split('-')[0] detected_lang = lang_map.get(raw_lang, "English") except: pass # Generate Audio # The CustomVoice model uses instructions for style/emotion wavs, sr = model.generate_custom_voice( language=detected_lang, speaker=voice, instruct=instructions, text=text ) output_path = "output.wav" sf.write(output_path, wavs[0], sr) return output_path, f"Detected Language: {detected_lang}" except Exception as e: return None, str(e) # UI Layout with gr.Blocks(theme=gr.themes.Soft()) as demo: gr.Markdown(f"# 🗣️ Qwen3-TTS Smart Studio") gr.Markdown("Experience natural speech with style control using Qwen3-TTS-12Hz.") with gr.Row(): with gr.Column(): input_text = gr.Textbox( label="Input Text", placeholder="Type something here...", lines=4 ) with gr.Row(): voice_select = gr.Dropdown( choices=["Vivian", "Ryan", "Bella", "Daisy", "George"], value="Vivian", label="Speaker" ) auto_lang = gr.Checkbox(label="Auto-detect Language", value=True) style_instruct = gr.Textbox( label="Style Instruction (e.g., 'Speak with a happy tone')", placeholder="Angry, Sad, Excited, Whisper...", value="Speak naturally" ) generate_btn = gr.Button("Generate Speech", variant="primary") with gr.Column(): audio_output = gr.Audio(label="Generated Audio", type="filepath") status_info = gr.Label(label="System Status") generate_btn.click( fn=smart_tts, inputs=[input_text, voice_select, style_instruct, auto_lang], outputs=[audio_output, status_info] ) if __name__ == "__main__": demo.launch()