Skip to content

Add staged VibeVoice text-to-speech support - #714

Open
justinchuby wants to merge 2 commits into
mainfrom
justinchuby-add-vibevoice-tts
Open

Add staged VibeVoice text-to-speech support#714
justinchuby wants to merge 2 commits into
mainfrom
justinchuby-add-vibevoice-tts

Conversation

@justinchuby

Copy link
Copy Markdown
Member

Summary

  • add Transformers-native vibevoice support pinned to vibevoice/VibeVoice-1.5B-hf@edc39f80f5cae656da37baf8faa8f5502bf7081f; record microsoft/VibeVoice-1.5B@c00898d257e6b46004e3e2866a47534085fb685a as the provenance root, not the executable source
  • export eight explicit ONNX stages: reference audio encoder, acoustic projection, prompt embedding, mask-safe Qwen2 decoder, diffusion head, streaming acoustic decoder, streaming semantic encoder, and semantic projection
  • preserve 28-layer KV state and 34-slot acoustic/semantic convolution state; keep standard Attention for the CFG negative-cache suffix reset because GQA's prefix-length ABI cannot represent that mask
  • package pinned tokenizer/chat template/processor/generation assets and graph-derived advisory metadata
  • add provenance-recorded 24 kHz LibriSpeech fixture plus text-only, reference-audio, and two-speaker contracts

Evidence

  • L1: tests/build_graph_test.py -k vibevoice — 8 passed
  • weight alignment: tests/weight_alignment_test.py -k vibevoice — 2 passed; all 1,204 native checkpoint keys route to trained stage parameters
  • L2: tests/arch_validation_test.py -k vibevoice — 3 passed against the full pinned 1.5B config
  • L3 synthetic: tests/synthetic_parity_test.py -k vibevoice — 1 passed; every stage matches native HF, including non-identity latent scale/bias and ONNX decoder→semantic feedback
  • L3 real weights / L4 / L5: tests/vibevoice_golden_test.py -m "golden or integration" on CUDA — 8 passed
    • exact generated control tokens: [151654, 151654, 151654]
    • exact continuous-latent shape: [1, 3, 64]
    • exact waveform shape: [1, 1, 9600] (3 × 3,200 samples)
    • semantic checks: finite, >99.9% nonzero, non-degenerate RMS/peak, >100 zero crossings, native waveform summaries/first samples
    • real stage-by-stage HF parity and CPU/CUDA generation parity included
  • processor: pinned text-only (1,38), reference (1,116) with 69 audio placeholders, and two-speaker (1,203) with 138 ordered placeholders
  • YAML/schema: 276 passed
  • combined VibeVoice gates: 19 passed
  • CLI: weighted FP16 CUDA-targeted package saved all eight stages plus audio_processor.json, processor_config.json, generation_config.json, tokenizer, chat template, revision metadata, and advisory runtime contract
  • Olive: real weighted acoustic projector quantized with RTN INT4 to MatMulNBits; CPU/CUDA max difference 0.001953125, correlation to FP16 0.9999083, finite non-degenerate output
  • lint: exact lintrunner -a — clean; specialist review rerun after fixes — no findings

Waivers

  • BF16 CUDA end-to-end generation: ORT 1.26 on the RTX A1000 cannot assign the codec's BF16 ConvTranspose nodes. BF16 reference-audio encoder parity was still measured (corr=0.9999813), while full CUDA L4/L5 and CPU/CUDA parity use FP16. No silent dtype downgrade is performed.
  • onnx-genai does not yet orchestrate VibeVoice's dual decoder caches, DPM-Solver loop, and streaming convolution state. The package emits exact graph/processor contracts and an explicit unsupported-by-tested-runtime advisory rather than claiming downstream support.
  • lintrunner f --output oneline --all-files applied formatting but the Ruff subprocess hit Windows WinError 206 from the repository-wide path list in this deep worktree. The required exact changed-file lintrunner -a completed cleanly after pinned linter initialization.
  • the full non-integration repository run recorded 9,810 passes; remaining failures were unrelated pre-existing Windows symlink-privilege and unrelated numerical/hash cases. Every changed VibeVoice/CLI/optimizer surface passes its targeted suite.

Implement the Transformers-native VibeVoice pipeline as explicit ONNX reference-audio, embedding, Qwen2 decoder, diffusion, acoustic decoder, and semantic feedback stages with mask-safe KV and convolution state contracts.

Pin the converted checkpoint and runtime assets, and add L1-L5, real-weight CUDA, CPU/CUDA, processor, provenance, and quantization evidence.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Justin Chu <justinchu@microsoft.com>
@justinchuby
justinchuby requested review from a team and a lite review from Copilot August 31, 2026 15:00
Comment thread src/mobius/_configs/vibevoice.py Fixed
Comment thread src/mobius/_testing/vibevoice_generation.py Fixed
Comment thread src/mobius/models/vibevoice.py Fixed
Comment thread src/mobius/models/vibevoice_test.py Fixed
Comment thread src/mobius/tasks/_vibevoice.py Fixed
Comment thread tests/vibevoice_golden_test.py Fixed
Comment thread tests/vibevoice_golden_test.py Fixed
Comment thread tests/vibevoice_golden_test.py Fixed
@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown

Performance Comparison

Comparing dda71aa63c6349

Model Metric Baseline Current Delta
bert (feature-extraction) model_size_bytes 359 KB 359 KB +0.0%
bert (feature-extraction) num_nodes 68 68 +0.0%
falcon model_size_bytes 364 KB 364 KB +0.0%
falcon num_nodes 66 66 +0.0%
gemma2 model_size_bytes 428 KB 428 KB +0.0%
gemma2 num_nodes 105 105 +0.0%
gpt2 model_size_bytes 324 KB 324 KB +0.0%
gpt2 num_nodes 54 54 +0.0%
llama model_size_bytes 425 KB 425 KB +0.0%
llama num_nodes 60 60 +0.0%
llama (static-cache) model_size_bytes 425 KB 425 KB +0.0%
llama (static-cache) num_nodes 56 56 +0.0%
mamba (ssm-text-generation) model_size_bytes 296 KB 296 KB +0.0%
mamba (ssm-text-generation) num_nodes 94 94 +0.0%
phi3 model_size_bytes 421 KB 421 KB +0.0%
phi3 num_nodes 58 58 +0.0%
phi3 (static-cache) model_size_bytes 421 KB 421 KB +0.0%
phi3 (static-cache) num_nodes 54 54 +0.0%
qwen2 model_size_bytes 425 KB 425 KB +0.0%
qwen2 num_nodes 60 60 +0.0%
qwen2 (static-cache) model_size_bytes 425 KB 425 KB +0.0%
qwen2 (static-cache) num_nodes 56 56 +0.0%
qwen3_5_moe (hybrid-text-generation) model_size_bytes 506 KB 506 KB +0.0%
qwen3_5_moe (hybrid-text-generation) num_nodes 265 265 +0.0%
qwen3_5_text (hybrid-text-generation) model_size_bytes 458 KB 458 KB +0.0%
qwen3_5_text (hybrid-text-generation) num_nodes 127 127 +0.0%
qwen3_5_vl (hybrid-qwen-vl) model_size_bytes 977 KB 977 KB +0.0%
qwen3_5_vl (hybrid-qwen-vl) num_nodes 450 450 +0.0%
t5 (seq2seq) model_size_bytes 836 KB 836 KB +0.0%
t5 (seq2seq) num_nodes 176 176 +0.0%
whisper (speech-to-text) model_size_bytes 1008 KB 1008 KB +0.0%
whisper (speech-to-text) num_nodes 128 128 +0.0%

No performance regressions.

Apply the repository-pinned Ruff formatter and import fixes across every Python file changed by the VibeVoice implementation so the repository lint job sees the same clean result as local validation.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Justin Chu <justinchu@microsoft.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new text-to-speech golden coverage is skipped by the existing e2e golden harness, and current CI golden workflows invoke only tests/e2e_golden_test.py, so VibeVoice L4/L5 goldens risk not running in the main gates unless CI/harness dispatch is updated.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds first-class, staged support for the Transformers-native VibeVoice 1.5B text-to-speech model to Mobius, exporting a multi-graph ONNX package plus test fixtures/contracts to validate the full continuous-token TTS pipeline end-to-end.

Changes:

  • Introduces VibeVoiceForConditionalGeneration + VibeVoiceTask that export 8 explicit ONNX stages (audio encoder/projection, embedding, decoder, diffusion head, audio decoder, semantic encoder/projection), including explicit KV + convolution streaming state.
  • Extends optimization/export plumbing to support “arbitrary attention mask required” decoders (disables GQA fusion) and to pin/propagate the effective source revision into runtime assets and onnx-genai exports.
  • Adds L1/L2/L3/L4/L5 coverage artifacts: tiny-config graph-build tests, synthetic parity harness integration, new golden cases/golden outputs, and a dedicated real-weight golden runner for VibeVoice.
File summaries
File Description
tests/weight_alignment_test.py Adds VibeVoice weight-routing coverage to ensure every stage parameter receives a routed HF key.
tests/vibevoice_golden_test.py New dedicated L4/L5 real-weight + generation golden tests for continuous-token TTS outputs (control logits/latents/waveform).
tests/synthetic_parity_test.py Hooks the dedicated VibeVoice synthetic stage-parity runner into the L3 synthetic parity suite.
tests/e2e_golden_test.py Skips text-to-speech cases in the generic L4 prefill argmax golden harness.
tests/cli_test.py Tests that onnx-genai runtime asset export uses the effective pinned revision from package metadata.
tests/build_graph_test.py Adds VibeVoice stage build/IO/state ABI assertions, registry pin checks, and GQA-disabled attention checks.
tests/_test_configs.py Adds a tiny VibeVoice config entry for shared build/test infrastructure.
testdata/golden/audio/vibevoice-1.5b-text-only.json Adds L4 golden reference for text-only case.
testdata/golden/audio/vibevoice-1.5b-text-only_generation.json Adds L5 golden reference for text-only generation case.
testdata/golden/audio/vibevoice-1.5b-reference.json Adds L4 golden reference for reference-audio case.
testdata/golden/audio/vibevoice-1.5b-reference_generation.json Adds L5 golden reference for reference-audio generation case.
testdata/golden/audio/vibevoice-1.5b-multispeaker.json Adds L4 golden reference for two-speaker ordering contract.
testdata/cases/schema.json Extends YAML schema to include text-to-speech and TTS generation knobs (num_diffusion_steps, guidance_scale).
testdata/cases/audio/vibevoice-1.5b-text-only.yaml Adds a text-only VibeVoice golden case definition.
testdata/cases/audio/vibevoice-1.5b-reference.yaml Adds a reference-audio VibeVoice golden case definition (with provenance notes).
testdata/cases/audio/vibevoice-1.5b-multispeaker.yaml Adds a two-speaker VibeVoice case definition.
testdata/audio_fixture_provenance.json Adds provenance record for the 24kHz LibriSpeech-derived fixture.
src/mobius/tasks/_vibevoice.py New task that builds the 8-stage VibeVoice ModelPackage and declares stage contracts/state.
src/mobius/tasks/init.py Exposes VibeVoiceTask and registers vibevoice-tts in TASK_REGISTRY.
src/mobius/models/vibevoice.py New VibeVoice staged model implementation + weight routing from native HF checkpoint namespaces.
src/mobius/models/vibevoice_test.py New synthetic numerical parity tests for all 8 stages and contracts (including empty-audio embedding).
src/mobius/models/init.py Exports VibeVoiceForConditionalGeneration.
src/mobius/integrations/transformers/_builder.py Pins VibeVoice revision when unspecified and stamps mobius.source_revision metadata for runtime asset resolution.
src/mobius/integrations/transformers/_builder_test.py Tests that the first config probe is revision-pinned for VibeVoice when revision is omitted.
src/mobius/integrations/onnx_genai/auto_export.py Detects VibeVoice topology and exports runtime assets + an explicit “unsupported by runtime” advisory contract.
src/mobius/integrations/onnx_genai/auto_export_test.py Tests that revision is forwarded through runtime asset export paths for VibeVoice.
src/mobius/_testing/vibevoice_generation.py New deterministic disk-backed staged runner used by VibeVoice goldens (diffusion loop + dual-cache orchestration).
src/mobius/_registry.py Registers the vibevoice model_type with pinned test model id/revision and VibeVoice config/module class.
src/mobius/_pipeline_contract.py Adds a graph-level contract flag to declare/require arbitrary attention masks (used to gate optimizations).
src/mobius/_optimizations.py Disables GQA fusion when a decoder declares arbitrary attention masking is required.
src/mobius/_configs/vibevoice.py New config extraction for VibeVoice composite configs (tokenizers + diffusion head) from Transformers.
src/mobius/_configs/init.py Exposes the new VibeVoice config types.
src/mobius/main.py Derives an effective build revision from package metadata for runtime asset downloads when CLI revision is omitted.
docs/model-catalog.md Adds VibeVoice to the model catalog table.
Review details
  • Files reviewed: 34/35 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread tests/e2e_golden_test.py
Comment on lines +2200 to +2204
if case.task_type == "text-to-speech":
pytest.skip(
"Continuous-token TTS uses tests/vibevoice_golden_test.py "
"(control logits, latent frames, and waveform semantics)."
)
@github-actions

Copy link
Copy Markdown

🏗️ Architecture Diff

Comparing dda71aa63c6349

Model Sub-model Changes Status
bert (feature-extraction) model 0
falcon model 0
gemma2 model 0
gemma4 (gemma4) decoder 0
gemma4 (gemma4) embedding 0
gemma4 (gemma4) vision_encoder 0
gemma4_text model 0
gpt2 model 0
llama model 0
llama (static-cache) model 0
mamba (ssm-text-generation) model 0
phi3 model 0
phi3 (static-cache) model 0
qwen model 0
qwen (static-cache) model 0
qwen2 model 0
qwen2 (static-cache) model 0
qwen2_moe model 0
qwen2_moe (static-cache) model 0
qwen3 model 0
qwen3 (static-cache) model 0
qwen3_5_moe (hybrid-text-generation) model 0
qwen3_5_text (hybrid-text-generation) model 0
qwen3_5_vl (hybrid-qwen-vl) decoder 0
qwen3_5_vl (hybrid-qwen-vl) embedding 0
qwen3_5_vl (hybrid-qwen-vl) vision_encoder 0
qwen3_moe model 0
qwen3_moe (static-cache) model 0
qwen3_next (hybrid-text-generation) model 0
t5 (seq2seq) decoder 0
t5 (seq2seq) encoder 0
whisper (speech-to-text) decoder 0
whisper (speech-to-text) encoder 0

No architecture changes detected.


Legend: ⚪ No change · 🔵 Minor (attrs/inits) · 🟡 Moderate (nodes added/removed) · 🔴 Major (interface changed)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants