VibeVoice
Microsoft VibeVoice é um modelo de síntese de fala de formato longo e multi-locutor para inglês e chinês. Ao contrário de TTS de enunciados curtos, foi projetado para gerar diálogos de duração de podcast, narração de audiolivros e cenas multi-locutor em uma única passagem — até 90 minutos, com até 4 vozes distintas e identidade consistente em toda a saída. Duas variantes são distribuídas: Realtime-0.5B para streaming de baixa latência e 1.5B para qualidade carro-chefe em formato longo.
O que é
- Formato longo em uma passagem — até 90 minutos de áudio com vozes consistentes em toda a saída; sem entregas frase a frase
- Diálogo multi-locutor — 4 locutores distintos ao mesmo tempo, cada um condicionado pelo seu próprio voice cache
- Inglês + chinês — os dados de áudio de treino são apenas EN/ZH; outros idiomas não são suportados (o tokenizer os aceita, mas a saída é ininteligível)
- Saída mono em 24 kHz — PCM Float32, pronto para
AudioCommon.WAVWritereStreamingAudioPlayer - Licença MIT — os pesos do modelo e a nossa porta para Swift são ambos MIT; derivados quantizados em INT4 são permitidos
Arquitetura
Quatro componentes cooperam para produzir áudio um latente de 7,5 Hz por vez:
| Componente | Descrição |
|---|---|
| Split Qwen2 backbone | 24-layer Qwen2.5 decoder (896 hidden, GQA 14/2 for Realtime-0.5B). The model is split: the lower 4 layers form a text LM, the upper 20 layers run as the TTS LM. Text windows (5 tokens at a time) flow through both; generated speech latents flow only through the TTS LM. |
| σ-VAE acoustic tokenizer | Streaming conv stack that encodes 24 kHz audio to a 64-dim latent at 7.5 Hz (3200× temporal downsample) and decodes latents back to waveform. Used for both voice-cache creation and final audio decode. |
| Diffusion head | Small 4-layer DDPM head with adaLN modulation. Samples each speech latent via 20-step DPM-Solver with classifier-free guidance (cfg = 1.3 default for Realtime-0.5B, 1.5 for 1.5B). |
| EOS classifier | Per-step binary classifier on the TTS LM's last hidden state. When sigmoid probability exceeds 0.5, generation stops. |
Clonagem de voz via voice-cache
A identidade do locutor não vem de uma forma de onda de referência no momento da geração. Em vez disso, cada voz é distribuída como um voice cache pré-calculado em .safetensors contendo os caches KV de condicionamento e os estados ocultos para um locutor específico — produzidos ao executar o áudio de referência pelo caminho do encoder offline. Carregar um voice cache é instantâneo em runtime; uma instância do modelo pode trocar de voz a baixo custo entre gerações.
Voice caches de exemplo (licença MIT): mzbac/vibevoice.swift/voice_cache — 7 vozes em inglês, incluindo Carter, Davis, Emma, Frank, Grace, Mike e Samuel com sotaque indiano.
Modelo
| Bundle | Quantização | Tamanho | HuggingFace |
|---|---|---|---|
| Realtime-0.5B | BF16 (source) | ~1 GB | microsoft/VibeVoice-Realtime-0.5B |
| Realtime-0.5B INT4 | Qwen2 INT4, tokenizer + diffusion FP16 | ~350 MB | aufklarer/VibeVoice-Realtime-0.5B-MLX-INT4 |
| Realtime-0.5B INT8 | Qwen2 INT8 | ~570 MB | aufklarer/VibeVoice-Realtime-0.5B-MLX-INT8 |
| 1.5B long-form | BF16 (source) | ~3 GB | microsoft/VibeVoice-1.5B |
| 1.5B INT4 | Qwen2 INT4 | ~1 GB | aufklarer/VibeVoice-1.5B-MLX-INT4 |
A quantização é produzida por models/vibevoice/export/convert.py usando quantização afim por grupos do MLX (grupo 32). Embeddings, normalizações, convoluções do acoustic-tokenizer e o classificador EOS mantêm o dtype original.
Início rápido
import VibeVoiceTTS
let tts = try await VibeVoiceTTSModel.fromPretrained()
try tts.loadVoice(from: "/path/to/voice_cache/en-Mike_man.safetensors")
let pcm = try await tts.generate(text: "Hello world.")
// pcm: [Float] at 24 kHz mono
Predefinição 1.5B de formato longo
let config = VibeVoiceTTSModel.Configuration.longForm1_5B
let tts = try await VibeVoiceTTSModel.fromPretrained(configuration: config)
try tts.loadVoice(from: "voices/narrator.safetensors")
let pcm = try await tts.generate(text: longTranscript) // up to ~90 min
A predefinição longForm1_5B eleva maxSpeechTokens para 4000 e cfgScale para 1,5 para uma saída de formato longo de maior fidelidade.
Trocar vozes entre gerações
try tts.loadVoice(from: "en-Mike_man.safetensors")
let a = try await tts.generate(text: "First speaker line.")
try tts.loadVoice(from: "en-Emma_woman.safetensors")
let b = try await tts.generate(text: "Second speaker line.")
CLI
audio vibevoice "Hello world." \
--voice-cache voice_cache/en-Mike_man.safetensors \
--output hello.wav
# Formato longo 1.5B
audio vibevoice "Long paragraph ..." \
--voice-cache voices/narrator.safetensors \
--long-form \
--max-tokens 4000 \
--output episode.wav
Flags: --steps (passos do DPM-Solver), --cfg (guidance), --model / --tokenizer para substituir IDs do HuggingFace, --long-form para alternar para a predefinição 1.5B, --verbose para tempos.
Escolhendo entre os módulos TTS do speech-swift
| Kokoro-82M | Qwen3-TTS | CosyVoice3 | VibeVoice Realtime | VibeVoice 1.5B | |
|---|---|---|---|---|---|
| Parâmetros | 82M | 7B | 7B | 500M | 1.5B |
| Backend | CoreML (ANE) | MLX | MLX | MLX | MLX |
| Idiomas | 8 | 10+ | 10+ | EN/ZH | EN/ZH |
| Clonagem de voz | Predefinições fixas | Referência ICL | Referência zero-shot | Voice cache | Voice cache |
| Formato longo | Curto/médio | Streaming | Streaming | Streaming | Até 90 min / 4 locutores |
…você precisar de saída em formato longo, multi-locutor ou podcast/audiolivro em inglês ou chinês, com identidade de voz consistente ao longo de minutos de áudio. Para TTS multilíngue curto, Qwen3-TTS ou CosyVoice3 servem melhor. Para enunciados curtos nativos em iOS, Kokoro é a opção mais leve.