Skip to content

Add VibeVoice-ASR (Microsoft) — OpenAI-compatible audio transcription#579

Closed
Alfarouk-Baseten wants to merge 3 commits into
mainfrom
add-vibevoice-asr
Closed

Add VibeVoice-ASR (Microsoft) — OpenAI-compatible audio transcription#579
Alfarouk-Baseten wants to merge 3 commits into
mainfrom
add-vibevoice-asr

Conversation

@Alfarouk-Baseten

Copy link
Copy Markdown

Summary

Adds vibevoice-asr/ — a passthrough Truss for microsoft/VibeVoice-ASR running on vllm/vllm-openai:v0.14.1.

  • Native OpenAI chat completions API — any OpenAI-compatible client works
  • Returns transcripts as JSON-stringified segments with speaker labels and timestamps
  • Single H100, ~3-min cold start

Files

vibevoice-asr/
├── config.yaml      (101 lines — docker_server passthrough)
├── data/
│   └── patch.py     (112 lines — applies 3 plugin patches at boot)
└── README.md        (74 lines)

About data/patch.py

Microsoft's vllm_plugin/model.py has three known incompatibilities with current vLLM releases:

  1. KV-cache delegation forwarders on VibeVoiceForCausalLM — required for vLLM 0.14.1; without it, startup crashes with IndexError: list index out of range on available_gpu_memory[0]
  2. get_data_parser on VibeVoiceProcessingInfo — forward-compat for vLLM 0.21+
  3. mm_data_items rename try/except — forward-compat for vLLM 0.15+

patch.py applies these in-place at container boot with assert-checked anchor strings. The script is idempotent and fails loudly at startup if Microsoft pushes an upstream change that breaks the anchors (rather than silent miscompile).

When Microsoft fixes the plugin upstream, delete data/patch.py and remove the python3 /app/data/patch.py line from config.yaml.

Known limitations (documented in README)

  • WAV / FLAC audio only — m4a fails to decode in vLLM 0.14.1's audio loader (returns 400)
  • Size max_tokens proportional to audio length (~20 tok/sec + buffer) — model doesn't reliably emit EOS so over-large max_tokens produces a repetition loop
  • Single audio clip per request (no batching of multiple clips in one chat)

… via vLLM

Adds a passthrough Truss for microsoft/VibeVoice-ASR using vllm/vllm-openai:v0.14.1.
Customers can point any OpenAI-compatible client at the deployment for
speech-to-text with speaker labels and timestamps.

Includes data/patch.py which applies three small in-place fixes to the
installed vllm_plugin/model.py at container boot, working around upstream
plugin/vLLM API incompatibilities.

Verified end-to-end on H100: deployment boots cleanly, transcribes the
JFK sample WAV with the expected JFK quote.
@CLAassistant

CLAassistant commented Jun 16, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

Reformats patch.py per the repo's ruff-format hook:
- blank line after module docstring (PEP 8)
- wrap long assert statements onto multiple lines
- single-quoted strings → double-quoted (ruff's preferred style)
- INSERT_2 triple-singles → triple-doubles (no embedded quotes, safe)

Pure formatting change; patch.py's behavior is unchanged.
Verified locally that all 3 patches still apply to a fresh copy of the
upstream microsoft/VibeVoice plugin.
@Alfarouk-Baseten

Copy link
Copy Markdown
Author

Heads-up on the failing lint check

The lint (pre-commit) check is failing, but not because of changes in this PR. The pre-commit hook runs ruff with --all-files, which touches a pre-existing issue on main that was introduced before this PR.

Where the failure is

triton-inference-server/tensorrtllm-backend/data/model_repository/tensorrt_llm/1/model.py, line 563:

raise pb_utils.TritonModelException(
    f"text_input is missing from the request")

ruff (rule F541: f-string-without-placeholders) wants to strip the unused f prefix:

raise pb_utils.TritonModelException(
    "text_input is missing from the request")

Why this affects our PR

The repo's CI runs pre-commit run --all-files, so every PR's lint check will hit this and fail until main is cleaned up.

Verified

Running ruff check --fix --fix-only --diff on only vibevoice-asr/data/patch.py against ruff v0.11.6 (the version pinned in .pre-commit-config.yaml) reports no changes needed. The file under triton-inference-server/... is the sole source of the failure.

Suggested resolution

Either:

  1. Fix main first with a one-line PR (f"text_input...""text_input...")
  2. Or merge this PR despite the red lint check, since the lint failure isn't from this PR's contents

…load → weights:)

The previous config used snapshot_download in start_command to fetch the
9.2 GB model weights at cold-start. On a first-time customer deployment
(empty /cache/org), this download took >30 min on slower networks and
exceeded the Baseten readiness health-check timeout, killing the container
before vLLM serve started.

Migrate to the post-PR-#573 weights: pattern: Baseten pre-downloads the
weights at build time and mounts them at /models/vibevoice-asr. Cold-starts
now skip the HF download entirely (~3 min instead of ~30 min on empty cache).

The mount turns out to be writable, so generate_tokenizer_files can still
write tokenizer.json etc. into the mount_location alongside the weights —
no --tokenizer flag needed.

Verified end-to-end: pushed to alfarouk as deployment wp587mp, cold-started
in ~3 min (no Fetching N files), JFK WAV smoke test returns the correct
transcript with no regression.
@Alfarouk-Baseten

Copy link
Copy Markdown
Author

Closing in favor of basetenlabs/model-registry#163, which is the canonical path for adding a Baseten Model Library entry. The model-registry sync will publish this Truss to truss-examples automatically on merge to main. No reviewer action needed here.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants