Qwen3-TTS
Native Laufzeit für Apple · PocketTTS
PocketTTS ergänzt speech-swift um native CoreML-Sprachausgabe. Alle Stufen verwenden standardmäßig nur die CPU. Die englische Stimme Alba liefert jeweils 1.920 Samples mit 24 kHz, also 80 ms pro Audioblock.
Voxtral TTS: Download der vorgegebenen Stimmen
Voxtral TTS lädt bei der ersten Verwendung die Modellgewichte, den Tokenizer, die Konfiguration und alle 20 Stimmdateien herunter. Für das Laden im Offline-Modus muss das vollständige Paket im Cache liegen, einschließlich aller Dateien in voice_embedding/.
Qwen3-TTS ist ein 12-Hz-Codec-Sprachmodell mit Mimi-Decoder für hochwertige Sprachsynthese. Der Standard-MLX-Pfad nutzt jetzt das 1.7B Base bf16-Bundle; 8-bit-Bundles bleiben für kleinere Downloads verfügbar. int4 wurde wegen der TTS-Qualität eingestellt.
VoxCPM2 im Vergleich zu Qwen3-TTS · Stimmenvergleich in fünf Sprachen mit Messmethode.
Pipeline
Die Sprachsynthese folgt einer dreistufigen Pipeline:
- Talker — 28-lagiger Transformer, der Eingabetext in First-Codebook-Tokens mit 12,5 Hz umwandelt
- Code Predictor — 5-lagiger Transformer, der die verbleibenden 15 Codebooks aus den Hidden States des ersten Codebooks vorhersagt
- Mimi-Codec-Decoder — Wandelt alle 16 Codebook-Tokens in eine 24-kHz-Audiowellenform um
Architektur
Talker
Der Talker ist das zentrale autoregressive Modell, das aus Texteingaben Codec-Tokens erzeugt.
| Parameter | Wert |
|---|---|
| Schichten | 28 |
| Hidden-Dimension | 1024 |
| Query-Heads | 16 |
| Key/Value-Heads | 8 (GQA) |
| MLP | SwiGLU |
| Positionskodierung | RoPE |
Code Predictor
Ein leichtgewichtiger 5-lagiger Transformer, der die Hidden States des ersten Codebooks nimmt und die verbleibenden 15 Codebooks parallel vorhersagt. Das vermeidet, den vollen Talker pro Schritt 16 Mal auszuführen.
Mimi-Codec-Decoder
Der Mimi-Decoder wandelt quantisierte Codec-Tokens zurück in Audio:
- RVQ-Decode (16 Codebooks)
- Pre-Convolution (512 auf 1024 Kanäle)
- Pre-Transformer (1024 auf 512 Bottleneck, 8 Schichten, SwiGLU + LayerScale)
- Upsampling (2x, 2x)
- SEANet-Decoder (Upsample-Stufen 8x, 5x, 4x, 3x)
- 24-kHz-Wellenform-Ausgabe
Modellvarianten
| Modell | Größe | HuggingFace |
|---|---|---|
| Qwen3-TTS-0.6B Base (8-bit) | 1.3 GB | aufklarer/Qwen3-TTS-12Hz-0.6B-Base-MLX-8bit |
| Qwen3-TTS-1.7B Base (8-bit) | 2.4 GB | aufklarer/Qwen3-TTS-12Hz-1.7B-Base-MLX-8bit |
| Qwen3-TTS-1.7B Base (bf16, default) | 3.9 GB | aufklarer/Qwen3-TTS-12Hz-1.7B-Base-MLX-bf16 |
| Qwen3-TTS-0.6B CustomVoice (bf16) | 1.8 GB | aufklarer/Qwen3-TTS-12Hz-0.6B-CustomVoice-MLX-bf16 |
| Qwen3-TTS CoreML (FP16) | 2.1 GB | aufklarer/Qwen3-TTS-CoreML |
CoreML-Backend
CoreML führt sechs kompilierte Komponenten aus. Das Rechengerät hängt vom gewählten Bundle ab.
- TextProjector — Projiziert Text-Token-Embeddings in den gemeinsamen Hidden-Raum
- CodeEmbedder — Bettet First-Codebook-Tokens und Kontroll-Tokens ein
- MultiCodeEmbedder — Bettet Tokens aus den Codebooks 1–15 ein
- CodeDecoder — 28-lagiger autoregressiver Transformer mit zustandslosem KV-Cache (max. 256 Positionen)
- MultiCodeDecoder — 5-lagiger Code-Predictor für Codebooks 1–15
- SpeechDecoder — Mimi-Codec-Decoder, wandelt 16 Codebook-Tokens in 24-kHz-Audio um
# CoreML synthesis
.build/release/speech speak "Hello, world!" --engine coreml -o hello.wav
# CoreML uses temperature 0.8 by default (required for quality output)
.build/release/speech speak "Long text here." --engine coreml --temperature 0.9 -o out.wav
0.6B: Der CoreML-CodeDecoder verwendet einen festen KV-Cache mit 256 Positionen. Längere Passagen sollten in einzelne Sätze aufgeteilt werden. Decode-Tokens werden automatisch auf die nach dem Prefill verbleibenden Cache-Slots begrenzt.
Experimenteller CoreML-Export für 1.7B
Der Decoder rechnet mit FP32, da FP16 die Prüfung gegen den Checkpoint nicht bestand; die Cache-Tensoren bleiben FP16.
Der Konverter mit sechs Komponenten unterstützt 1.7B Base und einen zustandsbehafteten CodeDecoder mit 1024 Positionen. Talker und Sprecher-Einbettung haben 2048 Dimensionen; der Code-Prädiktor mit 1024 Dimensionen enthält seine trainierte Eingangsprojektion.
Swift unterstützt 0.6B/256- und 1.7B/1024-Bundles; 0.6B bleibt der Standard. Das experimentelle 1.7B-Bundle verwendet standardmäßig die CPU und benötigt über --speaker-embedding ein vorbereitetes Float32-Sprecher-Embedding im Format .npy mit 2048 Kanälen. GPU/ANE und iOS müssen separat validiert werden.
Der Cache enthält Prompt- und Audiopositionen. SpeechDecoder hat standardmäßig eine separate Grenze von 125 Frames (10 Sekunden); ein größerer CodeDecoder-Cache erweitert sie nicht.
Konvertierungsquellcode und Validierungsanleitung
speech qwen3-tts-coreml "Hello world" \
--model aufklarer/Qwen3-TTS-1.7B-CoreML \
--speaker-embedding speaker-17b.npy --output hello-17b.wav
CLI-Verwendung
Sprache aus Text erzeugen:
.build/release/speech speak "Hello, world!" --output hello.wav
Optionen
| Schalter | Beschreibung |
|---|---|
--engine | TTS-Engine: qwen3 (MLX, Standard), coreml (CoreML/GPU) oder cosyvoice |
--output, -o | Pfad der Ausgabe-WAV-Datei |
--language | Sprache (Standard: english). Weglassen, um den nativen Dialekt des Sprechers zu verwenden. |
--model | Modellvariante: base oder customVoice |
--speaker | Sprecherstimme (benötigt --model customVoice) |
--temperature | Sampling-Temperatur (Standard: 0.3) |
--top-k | Top-k-Sampling-Parameter |
--max-tokens | Maximale Anzahl zu erzeugender Tokens (Standard: 500) |
--stream | Streaming aktivieren — gibt Audio-Chunks während der Erzeugung aus |
--first-chunk-frames | Anzahl der Frames im ersten gestreamten Chunk |
--chunk-frames | Anzahl der Frames pro nachfolgendem gestreamtem Chunk |
--batch-file | Pfad zu einer Textdatei mit einer Äußerung pro Zeile für Stapelsynthese |
--batch-size | Anzahl paralleler Äußerungen im Stapelmodus |
Beispiele
# Basic synthesis
.build/release/speech speak "The quick brown fox." -o fox.wav
# Streaming output
.build/release/speech speak "Long passage of text..." --stream -o stream.wav
# Batch synthesis from file
.build/release/speech speak --batch-file sentences.txt --batch-size 4 -o output_dir/
Streaming
Der Schalter --stream aktiviert die gestückelte Audio-Ausgabe während der Erzeugung. Statt auf den Abschluss der kompletten Äußerung zu warten, wird Audio als Chunks ausgegeben, während Tokens produziert werden. Verwende --first-chunk-frames und --chunk-frames, um die Chunk-Größe zu steuern.
Stapelmodus
Zum Synthetisieren mehrerer Äußerungen verwende --batch-file mit einer Textdatei, die eine Äußerung pro Zeile enthält. Der Schalter --batch-size steuert, wie viele Äußerungen parallel verarbeitet werden.
Leistung
Auf einem M2 Max erreicht Qwen3-TTS einen RTF (Echtzeitfaktor) von ungefähr 0,55, d. h. es erzeugt Sprache schneller als Echtzeit. Mit compile()-Aufwärmen dauert jeder Schritt etwa 37 ms.
Das Standardmaximum liegt bei 500 Tokens, was bei 12,5 Hz ungefähr 40 Sekunden Audio ergibt. Höhere Werte riskieren ein Überschreiten des Metal-GPU-Watchdog-Timeouts, was auf Apple Silicon einen Systemneustart auslösen kann, da sich die GPU den Compositor teilt.
Sprachen
Qwen3-TTS unterstützt mehrsprachige Sprachsynthese. Das Modell erkennt automatisch die Eingabesprache und erzeugt entsprechend Sprache.
Swift-API
import Qwen3TTS
import AudioCommon
let model = try await Qwen3TTSModel.fromPretrained()
let audio = model.synthesize(text: "Hello, world!", language: "english")
try WAVWriter.write(samples: audio, sampleRate: 24000, to: URL(filePath: "hello.wav"))
Rein lokale Bundles
Verwende fromLocal, wenn die App Beschaffung und Ablage des Modells selbst verwaltet. Die Verzeichnisse für das TTS-Hauptmodell und den Speech-Tokenizer werden getrennt übergeben. Der Aufruf löst keinen Cache auf, kontaktiert kein Netzwerk und liest vor der MLX-Modulzuweisung die config.json des Haupt-Bundles.
let model = try Qwen3TTSModel.fromLocal(
modelDirectory: ttsDirectory,
tokenizerDirectory: speechTokenizerDirectory
)
fromLocal verwendet standardmäßig .none und ändert das prozessweite Metal-Wired-Memory-Limit nicht. fromPretrained behält .pin(fraction: 0.9) bei. Beide Pretrained-Loader akzeptieren ein separates tokenizerCacheDir.
Diagnose
Qwen3-TTS sendet Diagnosemeldungen zum Modellladen und zur Inferenz an AudioLog.modelLoading und AudioLog.inference statt an stdout oder stderr. Anzahlen, Formen und Zeitwerte bleiben sichtbar; vom Aufrufer angegebene Sprach- und Sprecherwerte bleiben privat und Eingabetext wird nie protokolliert.
Voxtral TTS
Voxtral 4B TTS 2603 läuft über das Modul VoxtralTTS lokal auf Apple Silicon: 20 voreingestellte Stimmen, neun Sprachen und Mono-Sprache mit 24 kHz.
speech speak "Hello, welcome to Voxtral." --engine voxtral --voxtral-voice casual_male --stream --voxtral-chunk-frames 3 -o hello.wav
speech speak --engine voxtral --list-speakers
speech speak "Bonjour." --engine voxtral --voxtral-voice fr_female --voxtral-max-frames 500 --voxtral-seed 0 -o bonjour.wavNur vorgegebene Stimmen; das Klonen anhand von Referenzaudio ist nicht verfügbar. SDK, CLI, WebSocket und HTTP PCM geben Audio während der Erzeugung aus. Der Eingabetext muss zu Beginn vollständig vorliegen. Die Modellgewichte stehen unter CC BY-NC 4.0.