Magpie-TTS Multilingual

NVIDIA Magpie-TTS Multilingual 357M ใน Swift บน Apple Silicon — โมเดลข้อความเป็นเสียงพูดแบบ autoregressive หลาย codebook บน Nano-Codec 22.05 kHz ของ NeMo รองรับ 9 ภาษา (อังกฤษ สเปน เยอรมัน ฝรั่งเศส อิตาลี เวียดนาม ฮินดี จีนกลาง ญี่ปุ่น) พร้อมเอกลักษณ์ผู้พูดสำเร็จรูป 5 ตัว ปล่อยในรูปแบบที่ผ่านการลดความละเอียดเป็น INT4 (~247 MB) หรือ INT8 (~411 MB) พร้อมรองรับ streaming และมีหน่วงของแพ็กเก็ตแรกประมาณ 120 ms

เมื่อใดควรเลือก Magpie

Magpie คือตัวเลือกที่ถูกต้องเมื่อคุณต้องการ bundle ขนาดเล็กตัวเดียวที่พูดได้ 9 ภาษาด้วยเสียงสม่ำเสมอ ผู้พูดสำเร็จรูปทั้ง 5 คนยังคงเอกลักษณ์เสถียรข้ามภาษา — เป็นประโยชน์สำหรับผู้ช่วยหลายภาษา แอปการศึกษา หรือการบรรยายหนังสือเสียงที่มีการสลับภาษา สำหรับการโคลนเสียงแบบ zero-shot ให้ใช้ CosyVoice3, Qwen3-TTS Base หรือ VoxCPM2 แทน

สถาปัตยกรรม

Magpie คือ pipeline MLX 4 bundle: text encoder → decoder cross-attention → หัว codebook LocalTransformer → codec เสียง Causal HiFi-GAN bundle เหล่านี้ใช้ trọng số decoder ร่วมกันระหว่างจุดเข้า prefill และ step เพื่อให้ตรงกับ layout CoreML ของ FluidInference upstream

ขั้นตอนโมดูลรายละเอียด
1. TokenisationMagpieTokenizerPer-language G2P (IPA dict / byT5 bytes / pinyin / katakana), shared 2360-token vocab with per-tokenizer offsets, always-appended EOS
2. Text encoderMagpieTextEncoder6 causal Transformer layers, d=768, k=3 conv FFN
3. Decoder prefillMagpieDecoder12 causal layers with cross-attention. Seeds the 110-frame baked speaker context + BOS into the KV cache.
4. LocalTransformerMagpieLocalTransformer1-layer codebook AR head, d=256. Samples the 8 codebooks per frame sequentially given the decoder hidden.
5. Decoder stepMagpieDecoderOne AR step per frame until EOS or 500-frame cap (~23 s).
6. NanoCodecMagpieNanoCodecFSQ inverse → causal HiFi-GAN → 22.05 kHz mono waveform.

ภาษาและ G2P

ทั้ง 9 ภาษาผ่านการ round-trip ผ่าน Qwen3-ASR ใน testMultilingualRoundTrip ของ SDK แต่ละภาษามี pipeline ที่ปรับแต่งเฉพาะ:

ภาษารหัสPipeline G2P
อังกฤษenพจนานุกรม CMU IPA (125k รายการ มาด้วย)
สเปนesพจนานุกรม IPA สเปน (มาด้วย)
เยอรมันdeพจนานุกรม IPA เยอรมัน (มาด้วย)
ฝรั่งเศสfrตัวเข้ารหัสไบต์ UTF-8 byT5
อิตาลีitตัวเข้ารหัสไบต์ UTF-8 byT5
เวียดนามviตัวเข้ารหัสไบต์ UTF-8 byT5
ฮินดีhiการค้นหา codepoint Devanagari + sub-vocab last-wins
จีนกลางzhการแบ่งคำ NLTokenizer(.simplifiedChinese) + Apple .mandarinToLatin + พจนานุกรม pinyin → IPA ที่มาด้วย + เครื่องหมายเสียงวรรณยุกต์ #N
ญี่ปุ่นjaการอ่าน kanji ผ่าน CFStringTokenizer + dakuten ที่รักษา NFC + เครื่องหมาย pitch heiban + override สำหรับคำเชื่อม/คำทักทาย

Vocab ที่ใช้ร่วมกัน 2360 รายการเชื่อม sub-tokenizer ของแต่ละภาษาตามลำดับด้วย offset เฉพาะภาษา (บันทึกใน MagpieSubVocab) Text-embedding เพิ่มอีก 2 แถวหลัง vocab สำหรับ BOS / EOS; eos_id = 2361 ถูกเพิ่มเข้าทุกลำดับอินพุต

ผู้พูดสำเร็จรูป

Checkpoint ฝัง context ผู้พูด 5 ตัว (110 frame × 768 มิติแต่ละตัว) ใช้เป็น prefix ของทุกการถอดรหัส AR เอกลักษณ์ผู้พูดสม่ำเสมอทั่วทั้ง 9 ภาษา

ดัชนีชื่อ CLIเอกลักษณ์
0sofiaSofia (ค่าเริ่มต้น)
1ariaAria
2jasonJason
3leoLeo
4johnJohn Van Stan

รุ่นย่อยของโมเดล

รุ่นย่อยดิสก์RAM (load + decode)HuggingFace
INT4 (ค่าเริ่มต้น)~247 MB~1.3 GBaufklarer/Magpie-TTS-Multilingual-357M-MLX-4bit
INT8~411 MB~1.6 GBaufklarer/Magpie-TTS-Multilingual-357M-MLX-8bit

ทั้งสอง bundle ใช้การลดความละเอียดแบบ flat affine ของ MLX (mlx_affine_flat, group size 64) และคืนความละเอียดกลับเป็น FP32 เมื่อโหลด — activation ในเวลา runtime อยู่ที่ความละเอียดเต็ม INT4 แยกไม่ออกจาก INT8 ทางการได้ยินสำหรับโมเดลนี้; เลือก INT4 เว้นแต่คุณมีพื้นที่จัดเก็บเหลือเฟือ

การใช้งาน CLI

# ภาษาอังกฤษ การถอดรหัสแบบ greedy
speech speak "Hello, world." --engine magpie --magpie-speaker aria \
    --magpie-temperature 0 -o out.wav

# สเปน (ใช้ภาษาใดก็ได้จาก 9 ภาษา — เลือกด้วย --language)
speech speak "Hola, mundo." --engine magpie --language es \
    --magpie-speaker aria -o out.wav

# ญี่ปุ่น — ต้องการการถอดรหัสแบบสุ่ม (greedy ติดอยู่ที่วลีแรก)
speech speak "こんにちは世界、これは音声合成システムです。" \
    --engine magpie --language ja --magpie-temperature 0.6 \
    --magpie-top-k 80 --seed 42 -o out.wav

# การสังเคราะห์แบบ streaming พร้อมเล่นเสียง
speech speak "Streaming test" --engine magpie --stream --play

# แสดงรายการผู้พูดสำเร็จรูป 5 ตัว
speech speak --engine magpie --list-speakers

# IPA ที่ถอดเสียงล่วงหน้าจะข้าม G2P เฉพาะภาษา
speech speak "həˈloʊ" --engine magpie --magpie-prephonemized -o out.wav

ตัวเลือก

ตัวเลือกค่าเริ่มต้นคำอธิบาย
--magpie-variantint4รุ่นย่อยการลดความละเอียด: int4 หรือ int8
--magpie-speakersofiaผู้พูดสำเร็จรูป: sofia, aria, jason, leo, john
--magpie-temperature0.6อุณหภูมิการสุ่ม (0 = greedy)
--magpie-top-k80ตัวกรอง top-k สำหรับการสุ่ม
--magpie-max-frames500ขีดจำกัดสูงสุดของจำนวน frame ของ codec (~23 s)
--magpie-min-frames4จำนวน frame ขั้นต่ำก่อนอนุญาต EOS
--magpie-prephonemizedoffถือว่าอินพุตเป็นสตรีม IPA / phoneme; ข้าม G2P เฉพาะภาษา
--languageenglishเลือก pipeline tokenizer ตามภาษา
--streamoffส่งออก AsyncStream<AudioChunk> แทน WAV เดียว
--seedการสุ่ม Gumbel ที่สามารถทำซ้ำได้
เคล็ดลับการสุ่มภาษาญี่ปุ่น

อินพุตภาษาญี่ปุ่นที่ยาวเกินคำเดียวต้องการการถอดรหัสแบบสุ่ม (--magpie-temperature 0.6 --magpie-top-k 80 --seed 42 สะท้อนการทดสอบอ้างอิงของ NeMo) Greedy ติดอยู่ที่วลีแรกเพราะ heuristic ของ pitch-accent heiban ออกนอกความจริงตามคำ

การโคลนเสียง — ไม่รองรับ

Magpie ไม่มีการกำหนดเงื่อนไขผู้พูดแบบ zero-shot ในโมเดล; มีเพียงเอกลักษณ์สำเร็จรูป 5 ตัวที่มาใน bundle CLI ปฏิเสธแฟล็กที่ใช้ร่วมกัน --voice-sample, --speaker และ --instruct พร้อมข้อผิดพลาดที่สามารถปฏิบัติได้ ชี้ผู้ใช้ไปที่แฟล็ก --magpie-speaker หรือ engine ที่รองรับการโคลน (Qwen3-TTS Base, CosyVoice3, VoxCPM2)

ประสิทธิภาพ (M4 Pro)

การตั้งค่าเสียงเวลาจริงRTF
Batch, INT4, greedy, prompt สั้น2.8 s0.88 s0.32
Batch, INT4, greedy, ประโยค5.8 s1.35 s0.23
Batch, INT4, sampled, เอาต์พุต 23 s23 s5.6 s0.24
Streaming, INT4, sampled23 s21.6 s0.93

หน่วงของแพ็กเก็ตแรกในโหมด streaming อยู่ที่ ≈120 ms หลังโหลดโมเดล RTF ของ streaming สูงกว่าเพราะ codec ถูกเรียกใหม่บน buffer code ทั้งหมดในทุกการส่ง chunk (เวอร์ชันในอนาคตสามารถ cache สถานะ codec ได้)

API Swift

import MagpieTTS

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

// การสังเคราะห์แบบ batch (en/es/de/fr/it/vi/hi/zh — greedy ใช้ได้)
let audio = try model.synthesize(
    text: "Hello, world.",
    speaker: .aria,
    language: .english,
    params: MagpieTTSParams(temperature: 0, topK: 1, maxSteps: 500))

// ญี่ปุ่น — ใช้การสุ่มแบบสุ่ม
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 เป็น Float32 mono 22.05 kHz
}

Backend CoreML (--engine magpie-coreml)

ควบคู่ไปกับ bundle MLX, Magpie ปล่อย bundle CoreML (aufklarer/Magpie-TTS-Multilingual-357M-CoreML-8bit, ~342 MB INT8) สี่แพ็กเกจ .mlmodelctext_encoder, decoder_prefill, decoder_step, nanocodec_decoder — ทำงานบน ANE / GPU; FSQ inverse ฝั่ง Swift แปลง code ที่สุ่มแล้วเป็น latent 32 มิติที่ codec ใช้

# 8 ภาษา (ไม่มีญี่ปุ่น), 5 ผู้พูดสำเร็จรูป
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 จะ route อัตโนมัติไปยัง backend MLX (มีโน้ตใน stderr)
speech speak "こんにちは" --engine magpie-coreml --language ja -o ja.wav

ข้อควรระวังเทียบกับ --engine magpie:

ลำดับผู้พูดตรงกับ speaker_info.json ของ bundle CoreML (0=John, 1=Sofia, 2=Aria, 3=Jason, 4=Leo — ต่างจาก MLX) และ enum ผู้พูดถูก map ภายในเพื่อให้ชื่อ CLI ใช้ได้กับทั้งสอง engine

หมายเหตุการนำไปใช้

สามบั๊กที่ควรรู้หากคุณกำลัง port TTS หลายภาษาสไตล์ NeMo:

การแก้ทั้งสามอย่างได้รับการบันทึก inline ใน โมดูล Swift

แหล่งที่มา

สัญญาอนุญาต