Complete guide for text-to-speech generation with custom German voice cloning using Qwen3-TTS on macOS (Apple Silicon).
- Prerequisites
- Initial Setup
- Voice Cloning Setup
- Usage Examples
- Available Scripts
- Voice Style Control
- Tips & Best Practices
- Troubleshooting
- macOS with Apple Silicon (M1/M2/M3/M4)
- Python 3.10+ (Python 3.9 will NOT work due to dependency requirements)
- Homebrew (for installing dependencies)
- ~5-10 GB free disk space for models
- 8GB+ RAM (16GB recommended for 1.7B model)
# Install Python 3.11 via Homebrew
brew install python@3.11
# Verify installation
python3.11 --version# Navigate to your project directory
cd ~/Documents/code/qwen3-tts
# Create virtual environment with Python 3.11
python3.11 -m venv qwen-tts-env
# Activate the environment
source qwen-tts-env/bin/activate
# You should see (qwen-tts-env) in your prompt# Upgrade pip
pip install --upgrade pip
# Install qwen-tts (this will take a few minutes)
pip install qwen-tts
# Optional: Install ffmpeg for audio processing
brew install ffmpeg
# Optional: Install sox for additional audio tools
brew install sox# Check if MPS (Metal Performance Shaders) is available
python check_acceleration.pyExpected output:
PyTorch version: 2.10.0
MPS (Metal) available: True
MPS built: True
✓ Using Apple Silicon GPU acceleration via MPS
You need a 3-second audio sample of clear German speech.
# From M4A file (adjust -ss to select the best 3-second segment)
ffmpeg -i stephan.m4a -ss 00:00:02 -t 00:00:03 -ar 24000 -ac 1 geek_voice.wav
# From MP3
ffmpeg -i input.mp3 -ss 00:00:05 -t 00:00:03 -ar 24000 -ac 1 geek_voice.wav
# From video
ffmpeg -i video.mp4 -ss 00:00:10 -t 00:00:03 -ar 24000 -ac 1 geek_voice.wavParameters:
-ss 00:00:02= start at 2 seconds-t 00:00:03= duration of 3 seconds-ar 24000= sample rate 24kHz (optimal for model)-ac 1= mono audio
afplay geek_voice.wavYou need the exact text spoken in your 3-second sample.
Option A: Manual transcription
- Listen to the audio and type what you hear
Option B: Automatic transcription with Whisper
# Install Whisper
pip install openai-whisper
# Transcribe
python -c "import whisper; model = whisper.load_model('base'); result = model.transcribe('geek_voice.wav', language='de'); print(result['text'])"In all generation scripts, update these variables:
reference_audio = "geek_voice.wav"
reference_text = "Was glaubst du wie geht's da jetzt weiter, also in der gesamten Customer"Replace reference_text with your actual transcript.
# Activate environment first
source qwen-tts-env/bin/activate
# Generate with default text
python generate_geek.py
# Generate with custom text
python generate_geek.py "Guten Tag! Wie geht es dir heute?"
# Generate with style
python generate_geek_styled.py "Das ist fantastisch!" excited
# Play the output
afplay geek_output.wav# Edit batch_generate_geek.py to add your texts
python batch_generate_geek.py
# Play all generated files
afplay geek_batch_01.wav
afplay geek_batch_02.wav
# etc.python interactive_geek.pyThen type your texts interactively:
[1] Text: Hallo, wie geht es dir?
Generating...
✓ Saved: geek_interactive_001.wav
🎧 afplay geek_interactive_001.wav
[2] Text: Das Wetter ist schön heute.
...
Type quit or exit to stop.
Check if Apple Silicon GPU acceleration (MPS) is available.
python check_acceleration.pyTest pre-defined voices (no cloning).
python test_german.pyAvailable speakers: aiden, dylan, eric, ono_anna, ryan, serena, sohee, uncle_fu, vivian
Generate samples with multiple pre-defined speakers for comparison.
python test_german_multi.py
afplay german_serena.wav
afplay german_ono_anna.wavBasic voice cloning test.
python clone_geek_voice.py
afplay geek_cloned_output.wavGenerate single audio with cloned voice.
# With default text
python generate_geek.py
# With custom text (use single quotes for special characters)
python generate_geek.py 'Dein Text hier!'Generate with emotion/style control.
python generate_geek_styled.py "Your text" [style]Available styles:
excited- High energy and enthusiasmcalm- Peaceful and relaxedprofessional- Clear and confidentfriendly- Warm and approachableserious- Formal with authorityhappy- Joyful and cheerfulsad- Melancholic tonefast- Quick and energeticslow- Deliberate and measuredneutral- No style modification (default)
Examples:
python generate_geek_styled.py "Das ist unglaublich!" excited
python generate_geek_styled.py "Alles wird gut." calm
python generate_geek_styled.py "Lassen Sie uns das besprechen." professionalGenerate multiple texts at once.
Edit the texts list in the script, then run:
python batch_generate_geek.pyInteractive text-to-speech generation (keeps model loaded).
python interactive_geek.pyBest for: Experimenting with different texts without reloading the model each time.
You can control emotion, pace, and style using natural language:
output = model.generate_voice_clone(
text="Dein Text hier",
ref_audio="geek_voice.wav",
ref_text="Dein Referenztext",
lang="german",
instruction="Speak with high energy and excitement" # ← Style control
)Emotion:
"Speak with joy and happiness, upbeat and cheerful""Speak with sadness and melancholy""Speak with anger and frustration""Speak with surprise and amazement"
Energy Level:
"Speak with high energy and excitement""Speak calmly and peacefully, very relaxed""Speak with moderate energy, conversational tone"
Pace:
"Speak quickly and energetically, rapid pace""Speak slowly and deliberately, taking time with each word""Speak at a normal conversational pace"
Style:
"Speak in a professional, clear, and confident manner""Speak in a warm, friendly, and approachable way""Whisper softly and quietly, as if sharing a secret""Speak with authority and seriousness"
Combined:
"Speak with enthusiasm and joy, at a fast pace, very energetic""Speak calmly and slowly, with a warm friendly tone""Speak professionally and clearly, with moderate energy"
Use punctuation and formatting to influence prosody:
# Excitement
"WOW! Das ist UNGLAUBLICH! Ich bin total BEGEISTERT!"
# Pauses
"Nun... lass uns das mal in Ruhe betrachten... ganz entspannt..."
# Questions
"Wirklich? Ist das wahr? Kannst du das glauben?"
# Emphasis
"Das ist SEHR wichtig! Hör mir GUT zu!"For best voice cloning results:
✅ DO:
- Use clear, noise-free recordings
- Choose segments with natural speech (not shouting/whispering)
- Use good quality audio (16kHz+ sample rate)
- Select segments with varied intonation
- Use native or fluent German speakers
- Keep it exactly 3 seconds
❌ DON'T:
- Use audio with background music or noise
- Use segments with long pauses or hesitations
- Use audio with multiple speakers
- Use compressed/low-quality audio
- Use more or less than 3 seconds
First run: Model download takes 5-10 minutes (~3-5 GB)
Subsequent runs:
- Generation time: ~10-15 seconds per sentence on Apple Silicon
- Longer texts take proportionally longer
Speed optimization:
- Use the 0.6B model for faster generation (lower quality):
model = Qwen3TTSModel.from_pretrained("Qwen/Qwen3-TTS-12Hz-0.6B-Base")
- Keep model loaded for multiple generations (use interactive mode)
- MPS acceleration is automatic on Apple Silicon
- Language: The model supports German, but works best with clear, grammatically correct text
- Length: No strict limit, but very long texts may take time
- Special characters: Punctuation affects prosody (use naturally)
- Numbers: Write out numbers as words for better pronunciation
- ❌ "Ich habe 1000 Euro"
- ✅ "Ich habe eintausend Euro"
Error: Cannot install qwen-tts or dependency conflicts
Solution:
# Ensure Python 3.10+
python3.11 --version
# Recreate environment
deactivate
rm -rf qwen-tts-env
python3.11 -m venv qwen-tts-env
source qwen-tts-env/bin/activate
pip install --upgrade pip
pip install qwen-ttsError: does not support generate_voice_clone
Solution: Make sure you're using the Base model, not CustomVoice:
# ✅ Correct for voice cloning
model = Qwen3TTSModel.from_pretrained("Qwen/Qwen3-TTS-12Hz-1.7B-Base")
# ❌ Wrong - only has pre-defined voices
model = Qwen3TTSModel.from_pretrained("Qwen/Qwen3-TTS-12Hz-1.7B-CustomVoice")Error: AudioFileOpen failed ('wht?')
Solution: The file wasn't created properly. Check:
# Verify file exists and has content
ls -lh geek_output.wav
# Try regenerating
python generate_geek.py "Test"Possible causes:
- Low-quality reference audio → Re-record with better quality
- Incorrect transcript → Verify transcript matches audio exactly
- Reference audio too short/long → Must be exactly 3 seconds
- Background noise in reference → Use noise-free audio
Problem: Special characters in command line arguments
Solutions:
# Use single quotes
python generate_geek.py 'Text with special chars!'
# Escape special characters
python generate_geek.py "Text with special chars\!"
# Or use interactive mode (no quote issues)
python interactive_geek.pyError: CUDA/MPS out of memory
Solutions:
- Use smaller model:
model = Qwen3TTSModel.from_pretrained("Qwen/Qwen3-TTS-12Hz-0.6B-Base")
- Close other applications
- Restart your Mac
- Generate shorter texts
| Model | Size | Use Case | Voice Cloning |
|---|---|---|---|
Qwen3-TTS-12Hz-1.7B-Base |
1.7B | Best quality, voice cloning | ✅ Yes |
Qwen3-TTS-12Hz-0.6B-Base |
0.6B | Faster, voice cloning | ✅ Yes |
Qwen3-TTS-12Hz-1.7B-CustomVoice |
1.7B | Pre-defined voices only | ❌ No |
Qwen3-TTS-12Hz-0.6B-CustomVoice |
0.6B | Pre-defined voices only | ❌ No |
- German (
germanorde) - English (
englishoren) - Chinese (
chineseorzh) - Japanese (
japaneseorja) - Korean (
koreanorko) - French (
frenchorfr) - Spanish (
spanishores) - Italian (
italianorit) - Portuguese (
portugueseorpt) - Russian (
russianorru) - Auto-detect (
auto)
cd ~/Documents/code/qwen3-tts
source qwen-tts-env/bin/activatedeactivate# Quick generation
python generate_geek.py "Dein Text"
# With style
python generate_geek_styled.py "Dein Text" excited
# Interactive mode
python interactive_geek.py
# Batch generation
python batch_generate_geek.py
# Play audio
afplay geek_output.wavqwen3-tts/
├── qwen-tts-env/ # Virtual environment (don't commit)
├── geek_voice.wav # Your 3-second reference audio
├── stephan.m4a # Original audio source
├── check_acceleration.py # Check GPU acceleration
├── test_german.py # Test pre-defined voices
├── clone_geek_voice.py # Basic cloning test
├── generate_geek.py # Simple generation
├── generate_geek_styled.py # Generation with style control
├── batch_generate_geek.py # Batch generation
├── interactive_geek.py # Interactive mode
├── README.md # This file
└── *.wav # Generated audio files
- Official Repo: https://github.com/QwenLM/Qwen3-TTS
- Model Cards: https://huggingface.co/Qwen
- Documentation: https://github.com/QwenLM/Qwen3-TTS/blob/main/README.md
Qwen3-TTS is released under the Apache 2.0 License. See the official repository for details.
Last Updated: 2026-02-03