Audio version — Estimated duration: 5 min 28 sec
Use one of 9 built-in voices with no reference audio required. The CustomVoice model (Qwen3-TTS-12Hz-0.6B-CustomVoice) has speaker embeddings baked in — just pick a name.
Available speakers
| Name | Likely language / style | Notes |
|---|---|---|
Aiden | English, neutral | Default speaker |
Serena | English, warm | Good for narratives |
Vivian | English, bright | |
Uncle_Fu | Chinese / accented English | Distinctive character voice |
Ryan | English, deep | Good for announcements |
Ono_Anna | Japanese / English | Bilingual capable |
Sohee | Korean / English | Bilingual capable |
Eric | English, clear | Good for tutorials |
Dylan | English, casual |
All speaker names are case-insensitive — the script resolves
"serena"→"Serena"automatically. If a name doesn’t match, it falls back to"serena"and prints the available list.
Basic usage
python md_to_audio_custom.py sample.md --speaker "Vivian"Style instructions
The --instruct parameter controls delivery — think of it as a stage direction for the speaker:
python md_to_audio_custom.py sample.md \
--speaker "Ryan" \
--instruct "Speak slowly and clearly, like a news anchor."Instruction examples:
| Instruction | Effect |
|---|---|
Speak naturally. (default) | Neutral, conversational |
Speak slowly and clearly. | Slower pace, crisper enunciation |
Read with enthusiasm and energy. | Higher pitch variation, faster |
Whisper quietly. | Softer delivery |
Speak in a sad and melancholic tone. | Lowered pitch, slower |
Read like a dramatic movie trailer. | Exaggerated emphasis, pauses |
The instruction is passed to every chunk, so keep it short (1 sentence). Longer instructions may degrade quality.
Sampling parameters
These are hardcoded in the script and control the randomness of generation:
| Parameter | Value | Effect |
|---|---|---|
temperature | 0.8 | Lower = more consistent, higher = more varied |
top_k | 50 | Only consider the 50 most likely tokens at each step |
top_p | 0.95 | Nucleus sampling — cumulative probability cutoff |
For most use cases the defaults are fine. If you want to modify them, edit the call to model.generate_custom_voice() in md_to_audio_custom.py around line 175.
Chunk size and speed
The script defaults to --max-chars 150 — tighter than the Base model’s 200. This is intentional:
--max-chars | Trade-off |
|---|---|
| 100 | Fastest per-chunk, ~15 audio tokens generated, but may chop sentences |
| 150 (default) | Good balance for 6 GB VRAM |
| 200–250 | Smoother prosody, more VRAM per chunk |
| 300+ | May overshoot VRAM on 6 GB cards with batch_size > 1 |
Adaptive token budget
The CustomVoice script doesn’t use a fixed max_new_tokens like the Base script. Instead, estimate_max_tokens() calculates a per-chunk budget:
text_tokens ≈ len(chunk) / 4.5 chars per token
audio_tokens ≈ text_tokens × 12 Hz × 1.3 safety margin
clamped: max(256, min(audio_tokens, 1024))
This means a 20-character chunk gets max_new_tokens=256 instead of 1024 — roughly 4× faster for that chunk. The speedup is most noticeable on short documents (< 1000 characters).
Full examples
Article with character voice:
python md_to_audio_custom.py story.md \
--speaker "Uncle_Fu" \
--instruct "Tell this folk tale warmly, like a grandfather." \
--max-chars 180 \
--output story.wavTutorial with clear instruction:
python md_to_audio_custom.py tutorial.md \
--speaker "Eric" \
--instruct "Speak clearly and precisely, emphasizing key terms." \
--dtype bfloat16 \
--output tutorial.wavNext: CLI Reference · GPU Optimization