Skip to content

fix: skip batched decoding when VAD finds no speech - #555

Open
ANDROIDHASSAN wants to merge 1 commit into
collabora:mainfrom
ANDROIDHASSAN:fix/batch-vad-no-speech
Open

ANDROIDHASSAN wants to merge 1 commit into
collabora:mainfrom
ANDROIDHASSAN:fix/batch-vad-no-speech

Conversation

@ANDROIDHASSAN

Copy link
Copy Markdown

Problem

With --batch_inference, a chunk where VAD finds no speech is still decoded when it lands in a batch of 2 or more requests.

prepare_features only drops the non-speech audio if speech_chunks:. When get_speech_timestamps returns [], the full unfiltered chunk is kept, so speech_duration is never 0.0. The "no speech detected" early return in _process_multi is therefore never reached for VAD requests, and the whole chunk goes through encode + generate.

The non-batched path (transcriber.transcribe, also used by the batch worker for a single request) collects chunks unconditionally. collect_chunks(audio, []) returns one empty array, so transcribe returns None, None and nothing is emitted. As a result, the same audio gives different output depending on how many sessions happen to share the batch window.

Fix

prepare_features now does what transcriber.transcribe does:

speech_chunks = get_speech_timestamps(audio, vad_opts)
audio_chunks, _ = collect_chunks(audio, speech_chunks)
audio = np.concatenate(audio_chunks, axis=0)

With no speech, the audio is empty and speech_duration is 0.0. The existing early return then sends back [] without touching the GPU.

Tests

  • New test test_vad_without_speech_skips_decoding. It runs two use_vad=True requests where VAD returns [] and checks that encode is not called and both results are [].
    • It fails on main with Expected 'encode' to not have been called. Called 1 times.
    • It passes with this change.
    • Restoring the old guard makes it fail again.
  • pytest tests/test_batch_inference.py tests/test_batch_timeout.py: 24 passed.
  • Across all of tests/, the results are the same as on main apart from the new test. In my venv, main gives 109 passed and this branch gives 110. The same 2 failures and the same 8 collection errors show up on both, from optional deps I did not install (openvino, etc.).
  • flake8 with the CI's --select=E9,F63,F7,F82 reports 0 on both files.

Real model check, run on CPU with tiny int8. assets/jfk.flac (first 10 s) is submitted at falling gains as 5 batched use_vad=True requests, and each result is compared with transcriber.transcribe(..., vad_filter=True) on the same audio:

gain VAD chunks batch, main batch, this PR transcribe
1.0 – 0.01 1–2 text text (unchanged) text
0.003 0 ['And so my fellow Americans ask not what your country can do for you ask what you can do for your'] [] []

All rows where VAD finds speech give the same output before and after the change.

Scope

One function in whisper_live/batch_inference.py and one test. The single-request path and the non-batched path are untouched.

This branch has not been deployed

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

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant