Magpie-TTS Multilingual

NVIDIA Magpie-TTS Multilingual 357M in Swift auf Apple Silicon — ein autoregressives Multi-Codebook-TTS-Modell über NeMos 22.05 kHz Nano-Codec. Neun Sprachen (Englisch, Spanisch, Deutsch, Französisch, Italienisch, Vietnamesisch, Hindi, Mandarin, Japanisch) mit fünf vordefinierten Sprecher-Identitäten. Quantisiert als INT4 (~247 MB) oder INT8 (~411 MB). Streaming-fähig, ~120 ms First-Packet-Latenz.

Wann Magpie die richtige Wahl ist

Magpie ist die richtige Wahl, wenn du ein einziges kleines Bundle brauchst, das neun Sprachen mit einer konsistenten Stimme spricht. Die fünf vordefinierten Sprecher bleiben über alle Sprachen hinweg identitätsstabil — nützlich für mehrsprachige Assistenten, Lern-Apps oder Hörbuch-Narration mit Code-Switching. Für Zero-Shot-Voice-Cloning verwende CosyVoice3, Qwen3-TTS Base oder VoxCPM2.

Architektur

Magpie ist eine 4-Bundle-MLX-Pipeline: Text-Encoder → Cross-Attention-Decoder → LocalTransformer-Codebook-Head → Causal HiFi-GAN-Audio-Codec. Die Bundles teilen Decoder-Gewichte zwischen den Prefill- und Step-Einstiegspunkten, um die CoreML-Layout-Kompatibilität mit FluidInference upstream zu bewahren.

StufeModulDetails
1. TokenisierungMagpieTokenizerSprachspezifisches G2P (IPA-Wörterbuch / byT5-Bytes / Pinyin / Katakana), gemeinsames 2360-Token-Vokabular mit Pro-Tokenizer-Offsets, immer angehängtes EOS
2. Text-EncoderMagpieTextEncoder6 kausale Transformer-Layer, d=768, k=3 Conv-FFN
3. Decoder-PrefillMagpieDecoder12 kausale Layer mit Cross-Attention. Initialisiert den KV-Cache mit dem 110-Frame-Kontext des vordefinierten Sprechers + BOS.
4. LocalTransformerMagpieLocalTransformer1-Layer-Codebook-AR-Head, d=256. Sampled die 8 Codebooks pro Frame sequenziell anhand des Decoder-Hiddens.
5. Decoder-StepMagpieDecoderEin AR-Schritt pro Frame bis EOS oder das 500-Frame-Limit (~23 s).
6. NanoCodecMagpieNanoCodecFSQ-Inverse → kausales HiFi-GAN → 22.05 kHz Mono-Waveform.

Sprachen und G2P

Alle neun Sprachen durchlaufen Qwen3-ASR im testMultilingualRoundTrip des SDKs. Jede hat eine angepasste Pipeline:

SpracheCodeG2P-Pipeline
EnglischenCMU-IPA-Wörterbuch (125k Einträge, mitgeliefert)
SpanischesSpanisches IPA-Wörterbuch (mitgeliefert)
DeutschdeDeutsches IPA-Wörterbuch (mitgeliefert)
FranzösischfrbyT5 UTF-8-Byte-Encoder
ItalienischitbyT5 UTF-8-Byte-Encoder
VietnamesischvibyT5 UTF-8-Byte-Encoder
HindihiDevanagari-Codepoint-Lookup + Last-Wins-Sub-Vokabular
MandarinzhNLTokenizer(.simplifiedChinese)-Wortsegmentierung + Apple .mandarinToLatin + mitgeliefertes Pinyin → IPA-Wörterbuch + #N-Ton-Markierungen
JapanischjaCFStringTokenizer-Kanji-Lesung + NFC-erhaltene Dakuten + Heiban-Pitch-Markierungen + Partikel/Begrüßungs-Overrides

Das gemeinsame 2360-Token-Vokabular verkettet die Sub-Tokenizer jeder Sprache mit einem Pro-Sprach-Offset (in MagpieSubVocab festgehalten). Das Text-Embedding fügt nach dem Vokabular zwei zusätzliche Zeilen für BOS/EOS hinzu; eos_id = 2361 wird an jede Eingabesequenz angehängt.

Vordefinierte Sprecher

Der Checkpoint bettet fünf Sprecher-Kontexte ein (jeweils 110 Frames × 768 Dim), die als Präfix jeder AR-Dekodierung dienen. Die Sprecher-Identität ist über alle neun Sprachen hinweg konsistent.

IndexCLI-NameIdentität
0sofiaSofia (Standard)
1ariaAria
2jasonJason
3leoLeo
4johnJohn Van Stan

Modell-Varianten

VarianteDiskRAM (Laden + Decode)HuggingFace
INT4 (Standard)~247 MB~1.3 GBaufklarer/Magpie-TTS-Multilingual-357M-MLX-4bit
INT8~411 MB~1.6 GBaufklarer/Magpie-TTS-Multilingual-357M-MLX-8bit

Beide Bundles verwenden MLX Flat-Affine-Quantisierung (mlx_affine_flat, Group Size 64) und werden beim Laden auf FP32 dequantisiert — die Runtime-Aktivierungen sind in voller Präzision. INT4 und INT8 sind für dieses Modell akustisch nicht unterscheidbar; wähle INT4, außer du hast Speicher übrig.

CLI-Verwendung

# Englisch, greedy Dekodierung
speech speak "Hello, world." --engine magpie --magpie-speaker aria \
    --magpie-temperature 0 -o out.wav

# Spanisch (eine der 9 Sprachen — wähle mit --language)
speech speak "Hola, mundo." --engine magpie --language es \
    --magpie-speaker aria -o out.wav

# Japanisch — braucht stochastische Dekodierung (greedy bleibt bei erster Phrase hängen)
speech speak "こんにちは世界、これは音声合成システムです。" \
    --engine magpie --language ja --magpie-temperature 0.6 \
    --magpie-top-k 80 --seed 42 -o out.wav

# Streaming-Synthese mit Wiedergabe
speech speak "Streaming test" --engine magpie --stream --play

# Die 5 vordefinierten Sprecher auflisten
speech speak --engine magpie --list-speakers

# Vor-phonemisiertes IPA umgeht das sprachspezifische G2P
speech speak "həˈloʊ" --engine magpie --magpie-prephonemized -o out.wav

Optionen

OptionStandardBeschreibung
--magpie-variantint4Quantisierungs-Variante: int4 oder int8
--magpie-speakersofiaVordefinierter Sprecher: sofia, aria, jason, leo, john
--magpie-temperature0.6Sampling-Temperatur (0 = greedy)
--magpie-top-k80Top-k-Filter fürs Sampling
--magpie-max-frames500Hartes Limit für Codec-Frames (~23 s)
--magpie-min-frames4Minimum-Frames bevor EOS erlaubt ist
--magpie-prephonemizedausBehandelt Eingabe als IPA-/Phonem-Stream; überspringt sprachspezifisches G2P
--languageenglishWählt den sprachspezifischen Tokenizer
--streamausGibt AsyncStream<AudioChunk> statt einer einzelnen WAV aus
--seedReproduzierbares Gumbel-Sampling
Sampling-Tipp Japanisch

Japanische Eingaben länger als ein Wort brauchen stochastische Dekodierung (--magpie-temperature 0.6 --magpie-top-k 80 --seed 42 spiegelt NeMos Referenz-Test). Greedy bleibt bei der ersten Phrase hängen, weil die Heiban-Pitch-Heuristik von der Wahrheit pro Wort abweicht.

Voice Cloning — nicht unterstützt

Magpie hat im Modell kein Zero-Shot-Speaker-Conditioning; nur die 5 vordefinierten Identitäten sind im Bundle. Die CLI lehnt die gemeinsamen Flags --voice-sample, --speaker und --instruct mit einem umsetzbaren Fehler ab, der auf --magpie-speaker oder die Engines mit Cloning-Unterstützung verweist (Qwen3-TTS Base, CosyVoice3, VoxCPM2).

Leistung (M4 Pro)

SettingAudioWall-TimeRTF
Batch, INT4, greedy, kurzer Prompt2.8 s0.88 s0.32
Batch, INT4, greedy, Satz5.8 s1.35 s0.23
Batch, INT4, sampled, 23 s Output23 s5.6 s0.24
Streaming, INT4, sampled23 s21.6 s0.93

First-Packet-Latenz im Streaming-Modus ist ≈120 ms nach Modell-Load. Streaming-RTF ist höher, weil der Codec bei jeder Chunk-Ausgabe auf dem vollen Code-Buffer wiederholt läuft (eine künftige Revision kann den Codec-State cachen).

Swift-API

import MagpieTTS

let model = try await MagpieTTS.fromPretrained(variant: .int4)

// Batch-Synthese (en/es/de/fr/it/vi/hi/zh — greedy funktioniert)
let audio = try model.synthesize(
    text: "Hello, world.",
    speaker: .aria,
    language: .english,
    params: MagpieTTSParams(temperature: 0, topK: 1, maxSteps: 500))

// Japanisch — stochastisches Sampling verwenden
let audioJA = try model.synthesize(
    text: "こんにちは世界、これは音声合成システムです。",
    speaker: .aria,
    language: .japanese,
    params: MagpieTTSParams(temperature: 0.6, topK: 80,
                              maxSteps: 300, seed: 42))

// Streaming (AsyncStream<AudioChunk>)
let stream = model.synthesizeStream(
    text: "Streaming text",
    speaker: .aria,
    language: .english,
    firstChunkFrames: 8,
    framesPerChunk: 25)
for try await chunk in stream {
    // chunk.samples ist 22.05 kHz Mono Float32
}

CoreML-Backend (--engine magpie-coreml)

Neben dem MLX-Bundle gibt es ein CoreML-Bundle (aufklarer/Magpie-TTS-Multilingual-357M-CoreML-8bit, ~342 MB INT8). Vier .mlmodelc-Pakete — text_encoder, decoder_prefill, decoder_step, nanocodec_decoder — laufen auf ANE / GPU; eine FSQ-Inverse in Swift wandelt die gesampelten Codes in die 32-dim Latents um, die der Codec konsumiert.

# 8 Sprachen (kein Japanisch), 5 vordefinierte Sprecher
speech speak "Hello world." --engine magpie-coreml --magpie-speaker aria -o hi.wav
speech speak "Hola mundo." --engine magpie-coreml --language es --magpie-speaker leo -o es.wav

# --language ja leitet automatisch zum MLX-Backend (stderr-Hinweis)
speech speak "こんにちは" --engine magpie-coreml --language ja -o ja.wav

Vorbehalte gegenüber --engine magpie:

Die Sprecher-Reihenfolge entspricht der speaker_info.json des CoreML-Bundles (0=John, 1=Sofia, 2=Aria, 3=Jason, 4=Leo — anders als MLX); das Sprecher-Enum mappt intern, sodass die CLI-Namen für beide Engines funktionieren.

Implementierungshinweise

Drei Bugs, die man beim Portieren von NeMo-Style-Multilingual-TTS kennen sollte:

Alle drei Fixes sind inline im Swift-Modul dokumentiert.

Quellen

Lizenz