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를 선택해야 할 때

9개 언어를 하나의 작은 번들로 일관된 음성으로 말해야 할 때 적합합니다. 5개 내장 스피커는 모든 언어에서 정체성이 안정적입니다 — 다국어 어시스턴트, 교육 앱, 코드 스위칭이 있는 오디오북 나레이션에 유용. 제로샷 음성 복제가 필요하면 CosyVoice3, Qwen3-TTS Base, VoxCPM2를 사용하세요.

아키텍처

Magpie는 4-bundle MLX 파이프라인입니다: 텍스트 인코더 → 크로스 어텐션 디코더 → LocalTransformer 코드북 헤드 → 인과적 HiFi-GAN 오디오 코덱. prefill과 step 진입점 사이에서 디코더 가중치를 공유하여 상위 FluidInference의 CoreML 레이아웃과 호환됩니다.

단계모듈세부 정보
1. 토큰화MagpieTokenizer언어별 G2P(IPA 사전 / byT5 바이트 / 병음 / 가타카나), 공유 2360-token 어휘 + tokenizer별 오프셋, 항상 EOS 추가
2. 텍스트 인코더MagpieTextEncoder인과적 Transformer 6층, d=768, k=3 conv FFN
3. Decoder prefillMagpieDecoder크로스 어텐션 인과적 12층. 110-frame 내장 스피커 컨텍스트 + BOS를 KV 캐시에 시드.
4. LocalTransformerMagpieLocalTransformer1층 코드북 AR 헤드, d=256. 디코더 hidden을 조건으로 프레임당 8개 코드북을 순차 샘플링.
5. Decoder stepMagpieDecoderEOS 또는 500-frame 한도(~23초)까지 프레임당 1회 AR 진행.
6. NanoCodecMagpieNanoCodecFSQ 역변환 → 인과적 HiFi-GAN → 22.05 kHz 모노 파형.

언어 및 G2P

SDK의 testMultilingualRoundTrip은 9개 언어 모두 Qwen3-ASR로 라운드트립됨을 검증합니다. 각 언어는 맞춤형 파이프라인을 가집니다:

언어코드G2P 파이프라인
영어enCMU IPA 사전(125k 항목, 번들 포함)
스페인어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-token 어휘는 각 언어의 서브 토크나이저를 오프셋과 함께 연결합니다(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내장 스피커: sofia, aria, jason, leo, john
--magpie-temperature0.6샘플링 온도(0 = 탐욕적)
--magpie-top-k80Top-k 샘플링 필터
--magpie-max-frames500코덱 프레임 하드 한도(~23초)
--magpie-min-frames4EOS 허용 전 최소 프레임 수
--magpie-prephonemized꺼짐입력을 IPA / 음소 스트림으로 처리; 언어별 G2P 건너뜀
--languageenglish언어별 토크나이저 선택
--stream꺼짐단일 WAV 대신 AsyncStream<AudioChunk> 출력
--seed재현 가능한 Gumbel 샘플링
일본어 샘플링 팁

한 단어보다 긴 일본어 입력은 확률적 디코딩이 필요합니다(--magpie-temperature 0.6 --magpie-top-k 80 --seed 42는 NeMo의 참조 테스트와 일치). 탐욕적은 첫 구절에서 멈춤 — 평판 피치 휴리스틱이 단어별 진실값에서 벗어나기 때문.

음성 복제 — 지원 안 됨

Magpie는 모델 자체에 제로샷 스피커 컨디셔닝이 없습니다; 번들에는 5개 내장 정체성만 포함됩니다. CLI는 공유 --voice-sample, --speaker, --instruct 플래그를 거부하며 --magpie-speaker 또는 복제 지원 엔진(Qwen3-TTS Base, CosyVoice3, VoxCPM2)으로 안내합니다.

성능(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 — 탐욕적 작동)
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_encoder, decoder_prefill, decoder_step, nanocodec_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개:

세 가지 수정 모두 Swift 모듈에 인라인으로 문서화되어 있습니다.

출처

라이선스