Local text-to-speech and speech recognition on Apple Silicon, powered by Qwen3-TTS and mlx-audio. Runs entirely on-device — no API keys, no internet required after the initial model download.
- A Mac with Apple Silicon (M1, M2, M3, or M4)
- Python 3.10 or newer (3.12 recommended)
- Homebrew (the installer uses it to set up dependencies)
If you don't have Homebrew yet, open Terminal and paste:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"Custom Voice — Generate speech with one of nine built-in speaker presets. Add a style instruction to shape tone, pace, and emotion. Supports batch generation for long texts.
Voice Design — Describe a voice in plain language and the model creates it. Designed voices can be saved to the Voice Library. Supports batch generation.
Voice Cloning — Clone a voice from a short reference audio clip (3-30 seconds). Provide the clip and an exact transcript of what was spoken. A "Transcribe Reference" button can auto-fill the transcript using the built-in ASR model. Supports batch generation.
YT Voice Clone — Clone a voice directly from a YouTube video. Paste a URL, select a timestamp range, and the transcript auto-fills from subtitles. A "Transcribe Clip" button is available when subtitles are missing or inaccurate. Clips are cached in .yt_cache/.
Script Mode — Write multi-speaker scripts with SPEAKER: Dialogue formatting and assign a different voice to each speaker. Lines are batched by model type to minimise swaps, then stitched together with configurable silence gaps.
Transcription — Transcribe audio files locally using the Qwen3-ASR model. Upload a file or record with your microphone, pick a language (or leave it on Auto), and get a text transcript. Supports up to ~20 minutes of audio. Transcriptions can be saved as .txt files.
Voice Library — Browse, preview, rename, delete, and import saved voices. Voices from Voice Design, Voice Cloning, and YT Voice Clone all appear here.
History — Every generation is logged with mode, language, text, and duration. Replay audio, save files, or view original parameters.
Settings — Model size and quantization, generation parameters (temperature, top-k, top-p, repetition penalty, max tokens, timeout), output directory, auto-save toggle, export format (WAV/MP3/OGG) with MP3 bitrate selector, post-processing (EBU R128 loudness normalization, silence trimming, reference audio denoising via DeepFilterNet), JIT compilation toggle, ASR model management, YT cache management, and model cache management (view/delete downloaded models).
1. Clone the repository
Open Terminal and run:
git clone https://github.com/g2h0/qwen3-tts-mlx-studio.git
cd qwen3-tts-mlx-studio2. Run the installer
./install.shThe installer will:
- Check that you're on Apple Silicon with a compatible Python version (and offer to install one via Homebrew if needed)
- Install ffmpeg if it's missing (required for audio processing)
- Create a Python virtual environment (
.venv/) - Install all Python dependencies
- Optionally pre-download the TTS models (size varies by quantization) — you can skip this and they'll download automatically the first time you use each mode
Start the app:
./run.shThe UI opens in your browser at http://localhost:7860. Press Ctrl+C in the terminal to stop.
Options:
./run.sh --model-size 0.6B # Smaller, faster model (default: 1.7B)
./run.sh --quant 4bit # 4-bit quantization — smallest footprint
./run.sh --quant 8bit # 8-bit quantization (default: bf16)
./run.sh --host 0.0.0.0 # Listen on all interfaces (e.g. access from another device)
./run.sh --port 8080 # Custom port
./run.sh --share # Create a public Gradio linkThree model variants, one per generation mode. Only one is loaded at a time (~6 GB for 1.7B bf16).
| Mode | Variant | Default Repo |
|---|---|---|
| Custom Voice | CustomVoice | mlx-community/Qwen3-TTS-12Hz-1.7B-CustomVoice-bf16 |
| Voice Design | VoiceDesign | mlx-community/Qwen3-TTS-12Hz-1.7B-VoiceDesign-bf16 |
| Voice Cloning | Base | mlx-community/Qwen3-TTS-12Hz-1.7B-Base-bf16 |
All three variants are available in bf16, 8bit, 6bit, and 4bit quantizations. Select in Settings or via --quant.
A single model used for transcription across all tabs. It loads on demand and unloads automatically after each transcription to free memory.
| Model | Repo |
|---|---|
| Qwen3-ASR 1.7B | mlx-community/Qwen3-ASR-1.7B-8bit |
TTS and ASR models are mutually exclusive — only one can be in memory at a time. Switching between them is handled automatically.
To pre-download models manually:
source .venv/bin/activate
huggingface-cli download mlx-community/Qwen3-TTS-12Hz-1.7B-CustomVoice-bf16
huggingface-cli download mlx-community/Qwen3-TTS-12Hz-1.7B-VoiceDesign-bf16
huggingface-cli download mlx-community/Qwen3-TTS-12Hz-1.7B-Base-bf16
huggingface-cli download mlx-community/Qwen3-ASR-1.7B-8bitReplace bf16 with 8bit, 6bit, or 4bit for smaller models.
Audio is generated at 24 kHz mono and saved to ./outputs/ by default. Supported export formats are WAV (32-bit float), MP3 (configurable bitrate), and OGG/Vorbis — selectable in Settings. Optional post-processing includes EBU R128 loudness normalization and leading/trailing silence trimming (both via ffmpeg). Reference audio for voice cloning can optionally be denoised with DeepFilterNet (toggle in Settings). Transcriptions are saved as .txt files in the same directory. Voice library profiles are stored in ./voices/.
English, Chinese, Japanese, Korean, German, French, Russian, Portuguese, Spanish, Italian
app.py — Gradio UI, tabs, and event wiring
engine.py — Model load/unload/inference (thread-safe, TTS + ASR)
voice_library.py — Voice profile storage
yt_voice.py — YouTube clip extraction and subtitle alignment
audio_utils.py — Audio concatenation, text splitting, and format export
script_parser.py — Multi-speaker script parser
history.py — Generation history log
config.py — Constants and defaults
theme.py — Dark theme and custom CSS
install.sh — One-step installer
uninstall.sh — Remove venv, caches, and downloaded models
run.sh — App launcher
"Virtual environment not found" — Run ./install.sh first before ./run.sh.
Model download is slow — The first run downloads models from HuggingFace (~6 GB for bf16, less for quantized). On a slow connection you can pre-download models (see the Models section above) or let the installer do it.
Out of memory — The 1.7B bf16 model uses ~6 GB of unified memory. If you're running low, try ./run.sh --model-size 0.6B or ./run.sh --quant 4bit for the smallest footprint.
ffmpeg not found — Install it with brew install ffmpeg. It's required for audio processing and YouTube clip extraction.