Tune the server engine's Silero VAD so batched file transcription stops dropping quiet speech

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Lucas Winther
2026-10-30 00:07:05 +01:00
co-authored by Claude Opus 5.5
parent 9b37c7d26c
commit 1c1806840e
2 changed files with 15 additions and 5 deletions
+13 -5
View File
@@ -27,11 +27,12 @@ interrupt the segment loop of the request in flight.
Decoding strategy by mode (Decisions.md D-WS5a):
"file" faster-whisper's BatchedInferencePipeline with its Silero VAD
(vad_filter=True): silence is dropped, speech is cut into <= 30 s
chunks and BATCH_SIZE chunks decode per forward pass. Segments come
out in bursts (one burst per batch), so a cancel takes effect at the
next burst boundary; the Bun side's heartbeat (D-021) covers the
longer quiet stretch before the first burst.
(vad_filter=True, VAD_PARAMETERS): silence is dropped, speech is cut
into <= 30 s chunks and BATCH_SIZE chunks decode per forward pass.
Without word-level timestamps each chunk is one segment (<= 30 s).
Segments come out in bursts (one burst per batch), so a cancel
takes effect at the next burst boundary; the Bun side's heartbeat
(D-021) covers the longer quiet stretch before the first burst.
"live" the plain sequential WhisperModel.transcribe: server-live passes
are short (<= 29 s, often a few seconds), so batching has nothing to
batch and VAD only adds latency and can clip a short utterance.
@@ -60,6 +61,12 @@ import threading
SAMPLE_RATE = 16000
BATCH_SIZE = 8 # D-WS5a: VAD chunks decoded per batched forward pass
# D-WS5a: Silero VAD tuned for file mode. faster-whisper's batched default
# (threshold 0.5, 400 ms padding) dropped quiet and overlapped speech —
# deletions nearly doubled on en_alien; 0.2 / 800 ms brought WER back to the
# sequential decoder's level. min_silence_duration_ms stays at VadOptions'
# 2000 ms default (a dict replaces the pipeline's 160 ms preset).
VAD_PARAMETERS = {"threshold": 0.2, "speech_pad_ms": 800}
def emit(message):
@@ -156,6 +163,7 @@ def main():
language=language,
task=task,
vad_filter=True,
vad_parameters=dict(VAD_PARAMETERS), # fresh: faster-whisper may mutate it
batch_size=BATCH_SIZE,
)
+2
View File
@@ -519,6 +519,8 @@ describe("server-py/sidecar.py (stubbed faster-whisper, D-WS5a)", () => {
expect(explicit.texts[0]).toContain("batched model=m1");
expect(explicit.texts[0]).toContain("vad_filter=True");
expect(explicit.texts[0]).toContain("batch_size=8");
// Tuned Silero VAD: the default (0.5 / 400 ms) dropped quiet speech (D-WS5a).
expect(explicit.texts[0]).toContain("vad_parameters={'threshold': 0.2, 'speech_pad_ms': 800}");
expect(explicit.texts[0]).toContain("language=da");
expect(explicit.texts[0]).toContain("task=transcribe");