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.

Verwendung mit Swift und CLI

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/.

Swift-Nutzung und Anforderungen an das Modellpaket

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:

  1. Talker — 28-lagiger Transformer, der Eingabetext in First-Codebook-Tokens mit 12,5 Hz umwandelt
  2. Code Predictor — 5-lagiger Transformer, der die verbleibenden 15 Codebooks aus den Hidden States des ersten Codebooks vorhersagt
  3. 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.

ParameterWert
Schichten28
Hidden-Dimension1024
Query-Heads16
Key/Value-Heads8 (GQA)
MLPSwiGLU
PositionskodierungRoPE

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:

  1. RVQ-Decode (16 Codebooks)
  2. Pre-Convolution (512 auf 1024 Kanäle)
  3. Pre-Transformer (1024 auf 512 Bottleneck, 8 Schichten, SwiGLU + LayerScale)
  4. Upsampling (2x, 2x)
  5. SEANet-Decoder (Upsample-Stufen 8x, 5x, 4x, 3x)
  6. 24-kHz-Wellenform-Ausgabe

Modellvarianten

ModellGrößeHuggingFace
Qwen3-TTS-0.6B Base (8-bit)1.3 GBaufklarer/Qwen3-TTS-12Hz-0.6B-Base-MLX-8bit
Qwen3-TTS-1.7B Base (8-bit)2.4 GBaufklarer/Qwen3-TTS-12Hz-1.7B-Base-MLX-8bit
Qwen3-TTS-1.7B Base (bf16, default)3.9 GBaufklarer/Qwen3-TTS-12Hz-1.7B-Base-MLX-bf16
Qwen3-TTS-0.6B CustomVoice (bf16)1.8 GBaufklarer/Qwen3-TTS-12Hz-0.6B-CustomVoice-MLX-bf16
Qwen3-TTS CoreML (FP16)2.1 GBaufklarer/Qwen3-TTS-CoreML

CoreML-Backend

CoreML führt sechs kompilierte Komponenten aus. Das Rechengerät hängt vom gewählten Bundle ab.

  1. TextProjector — Projiziert Text-Token-Embeddings in den gemeinsamen Hidden-Raum
  2. CodeEmbedder — Bettet First-Codebook-Tokens und Kontroll-Tokens ein
  3. MultiCodeEmbedder — Bettet Tokens aus den Codebooks 1–15 ein
  4. CodeDecoder — 28-lagiger autoregressiver Transformer mit zustandslosem KV-Cache (max. 256 Positionen)
  5. MultiCodeDecoder — 5-lagiger Code-Predictor für Codebooks 1–15
  6. 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
CoreML-KV-Cache-Limit

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

SchalterBeschreibung
--engineTTS-Engine: qwen3 (MLX, Standard), coreml (CoreML/GPU) oder cosyvoice
--output, -oPfad der Ausgabe-WAV-Datei
--languageSprache (Standard: english). Weglassen, um den nativen Dialekt des Sprechers zu verwenden.
--modelModellvariante: base oder customVoice
--speakerSprecherstimme (benötigt --model customVoice)
--temperatureSampling-Temperatur (Standard: 0.3)
--top-kTop-k-Sampling-Parameter
--max-tokensMaximale Anzahl zu erzeugender Tokens (Standard: 500)
--streamStreaming aktivieren — gibt Audio-Chunks während der Erzeugung aus
--first-chunk-framesAnzahl der Frames im ersten gestreamten Chunk
--chunk-framesAnzahl der Frames pro nachfolgendem gestreamtem Chunk
--batch-filePfad zu einer Textdatei mit einer Äußerung pro Zeile für Stapelsynthese
--batch-sizeAnzahl 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.

Sicherheitsgrenze

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
)
Speicherrichtlinie

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.wav

Nur 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.

Voxtral-TTS-Anleitung lesen