Magpie-TTS Multilingual

Apple Silicon 上の NVIDIA Magpie-TTS Multilingual 357M の Swift 実装 — NeMo の 22.05 kHz Nano-Codec をベースにした自己回帰型マルチコードブック TTS モデル。9 言語(英語、スペイン語、ドイツ語、フランス語、イタリア語、ベトナム語、ヒンディー語、中国語、日本語)、5 つの組み込みスピーカー。INT4(約 247 MB)または INT8(約 411 MB)で量子化。ストリーミング対応、初回パケット遅延約 120 ms。

Magpie が向くケース

1 つの小さなバンドルで 9 言語を一貫した声で話したい場面に最適です。5 つの組み込みスピーカーは全言語でアイデンティティが安定します — 多言語アシスタント、教育アプリ、言語切り替えのあるオーディオブック朗読など。ゼロショット声質クローニングが必要なら CosyVoice3Qwen3-TTS BaseVoxCPM2 を使ってください。

アーキテクチャ

Magpie は 4 バンドルの MLX パイプライン:テキストエンコーダ → クロスアテンション付きデコーダ → LocalTransformer コードブックヘッド → 因果的 HiFi-GAN オーディオコーデック。バンドルは prefill と step のエントリポイントでデコーダ重みを共有し、上流の FluidInference の CoreML レイアウトと互換性を保ちます。

段階モジュール詳細
1. トークン化MagpieTokenizer言語ごとの G2P(IPA 辞書 / byT5 バイト / ピンイン / カタカナ)、共有 2360 トークン語彙 + トークナイザごとのオフセット、常に EOS 付加
2. テキストエンコーダMagpieTextEncoder因果 Transformer 6 層、d=768、k=3 畳み込み FFN
3. デコーダ prefillMagpieDecoderクロスアテンション付き因果 12 層。110 フレームの組み込みスピーカーコンテキスト + BOS を KV キャッシュにシード。
4. LocalTransformerMagpieLocalTransformer1 層のコードブック AR ヘッド、d=256。デコーダの hidden を条件として 1 フレーム 8 コードブックを逐次サンプリング。
5. デコーダ stepMagpieDecoderEOS または 500 フレーム上限(約 23 秒)まで 1 フレームずつ AR 推進。
6. NanoCodecMagpieNanoCodecFSQ 逆変換 → 因果 HiFi-GAN → 22.05 kHz モノラル波形。

言語と G2P

9 言語すべてが SDK の testMultilingualRoundTrip で Qwen3-ASR ラウンドトリップを通過します。それぞれ専用のパイプラインを持ちます:

言語コードG2P パイプライン
英語enCMU IPA 辞書(12.5 万語、同梱)
スペイン語esスペイン語 IPA 辞書(同梱)
ドイツ語deドイツ語 IPA 辞書(同梱)
フランス語frbyT5 UTF-8 バイトエンコーダ
イタリア語itbyT5 UTF-8 バイトエンコーダ
ベトナム語vibyT5 UTF-8 バイトエンコーダ
ヒンディー語hiデーヴァナーガリー コードポイント検索 + last-wins サブ語彙
中国語普通話zhNLTokenizer(.simplifiedChinese) 単語分割 + Apple .mandarinToLatin + 同梱ピンイン→IPA 辞書 + #N 声調マーカー
日本語jaCFStringTokenizer 漢字読み + NFC で保持される濁点 + 平板アクセントマーカー + 助詞/挨拶オーバーライド

共有 2360 トークン語彙は各言語のサブトークナイザをオフセット付きで連結(MagpieSubVocab に記録)。テキスト埋め込みは BOS / EOS 用に 2 行余分にあり、eos_id = 2361 が常に入力末尾に追加されます。

組み込みスピーカー

チェックポイントには 5 つのスピーカーコンテキスト(各 110 フレーム × 768 次元)が埋め込まれ、AR デコードの先頭に付与されます。スピーカーの同一性は 9 言語すべてで一貫しています。

番号CLI 名アイデンティティ
0sofiaSofia(デフォルト)
1ariaAria
2jasonJason
3leoLeo
4johnJohn Van Stan

モデルバリアント

バリアントディスクRAM(ロード+デコード)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

両バンドルとも MLX の flat affine 量子化(mlx_affine_flat、group size 64)を使い、ロード時に FP32 に逆量子化されるため実行時のアクティベーションはフル精度です。本モデルの INT4 と INT8 は聴感上区別できないので、ストレージに余裕がない限り INT4 で十分です。

CLI 使用法

# 英語、貪欲デコード
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

# 日本語 — 確率的デコードが必要(貪欲は最初のフレーズで止まる)
speech speak "こんにちは世界、これは音声合成システムです。" \
    --engine magpie --language ja --magpie-temperature 0.6 \
    --magpie-top-k 80 --seed 42 -o out.wav

# ストリーミング合成 + 再生
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組み込みスピーカー:sofiaariajasonleojohn
--magpie-temperature0.6サンプリング温度(0 = 貪欲)
--magpie-top-k80Top-k サンプリングフィルタ
--magpie-max-frames500コーデックフレームの上限(約 23 秒)
--magpie-min-frames4EOS を許可する最小フレーム数
--magpie-prephonemizedOFF入力を IPA / 音素ストリームとして扱い、言語ごとの G2P をスキップ
--languageenglish言語ごとのトークナイザを選択
--streamOFF単一の WAV ではなく AsyncStream<AudioChunk> を出力
--seed再現可能な Gumbel サンプリング
日本語サンプリングのヒント

1 単語より長い日本語入力には確率的デコードが必要です(--magpie-temperature 0.6 --magpie-top-k 80 --seed 42 は NeMo の参照テストに対応)。貪欲は最初のフレーズで止まります — 平板アクセントのヒューリスティックが単語ごとの実値から外れるため。

声質クローニング — 非対応

Magpie モデルにはゼロショットのスピーカー条件付けがありません。バンドルには 5 つの組み込みアイデンティティのみが含まれます。CLI は共通の --voice-sample--speaker--instruct フラグを実行可能なエラーで拒否し、--magpie-speaker またはクローニング対応エンジン(Qwen3-TTS BaseCosyVoice3VoxCPM2)への切り替えを案内します。

パフォーマンス(M4 Pro)

設定音声所要時間RTF
バッチ INT4 貪欲、短いプロンプト2.8 s0.88 s0.32
バッチ INT4 貪欲、文5.8 s1.35 s0.23
バッチ INT4 サンプリング、23 秒出力23 s5.6 s0.24
ストリーミング INT4 サンプリング23 s21.6 s0.93

ストリーミング時のロード後の初回パケット遅延は約 120 ms。ストリーミング RTF が高いのは、各チャンク出力でコーデックがフルコードバッファに再実行されるため(将来的に状態キャッシュを追加可能)。

Swift API

import MagpieTTS

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

// バッチ合成(en/es/de/fr/it/vi/hi/zh — 貪欲で OK)
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))

// ストリーミング(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 は 22.05 kHz モノラル Float32
}

CoreML バックエンド(--engine magpie-coreml)

MLX バンドルに加えて、Magpie には CoreML バンドル(aufklarer/Magpie-TTS-Multilingual-357M-CoreML-8bit、~342 MB INT8)があります。4 つの .mlmodelc パッケージ — text_encoderdecoder_prefilldecoder_stepnanocodec_decoder — は ANE / GPU で実行されます。Swift 側の FSQ 逆変換が、サンプリングされたコードをコーデックが消費する 32 次元の潜在変数に変換します。

# 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 は自動的に MLX バックエンドにルーティング(stderr ノート)
speech speak "こんにちは" --engine magpie-coreml --language ja -o ja.wav

--engine magpie との注意点:

話者の順序は CoreML バンドルの speaker_info.json と一致します(0=John, 1=Sofia, 2=Aria, 3=Jason, 4=Leo — MLX とは異なる)。話者の列挙型は内部でマップされるため、CLI 名は両エンジンで機能します。

実装メモ

NeMo 風の多言語 TTS を移植する際に知っておくべきバグ 3 点:

3 つの修正はすべて Swift モジュール 内にインラインで記載しています。

出典

ライセンス