Tuning VAD before diarization: settings that change the speaker output
A VAD change looks local and is not. Thresholds, padding, and minimum silence propagate into speaker turns, timestamps, and every score computed afterwards.
Voice activity detection is usually treated as a cleanup step that runs before the interesting work. In a diarization pipeline it is a decision about where the system is allowed to look for speakers, and its errors are invisible in its own output. A 300 ms gap that the VAD fills removes one of the places where the speaker could change.
The four knobs that matter
The pyannote VAD pipeline takes them directly: vad = Pipeline.from_pretrained("pyannote/voice-activity-detection", use_auth_token=TOKEN), then speech = vad("file.wav", onset=0.6, offset=0.45, min_duration_on=0.1, min_duration_off=0.2).
onset and offset are two thresholds rather than one, and the gap between them is the point. A frame starts speech when it crosses onset and only stops when it falls below offset, so a signal hovering near the boundary does not produce a stream of one-frame detections. Setting them equal gives you exactly that chatter.
min_duration_on deletes detections too short to be speech, but a real 80 ms backchannel is also short, so raising it removes precisely the short utterances a diarization system needs to see. min_duration_off fills short gaps, and it is the most consequential of the four, because every filled gap is a speaker change that can no longer happen.
Measure, do not listen
The errors that matter here are 100 to 300 ms, which is below what you can hear at normal speed. Build a small reference instead: ten minutes of your own audio with speech regions marked by hand. A waveform view at a coarse zoom is enough, because you are marking boundaries to roughly 50 ms, not to the frame.
Then score coverage at a tolerance. Expand each reference region by 50 ms and count how many are fully contained in some detected region: hit = sum(any(hs <= rs + 0.05 and he >= re - 0.05 for hs, he in detected) for rs, re in reference). The result is the share of real speech the VAD kept.
Run the same test in reverse to get the false-alarm side: detected regions with no reference support. Two numbers, both interpretable, and neither one is a single threshold value.
Watch the chain, not the VAD
Run the diarization twice, once per VAD setting, and compare three things: the number of speaker turns, the total speech duration assigned, and the three DER components separately.
The first-order effects are predictable. A stricter VAD raises misses and lowers false alarms; a permissive one does the opposite. The effect that catches people is on confusion. If the VAD removes the short pause where a speaker change happens, two speakers merge into one cluster, and confusion rises even though the VAD metrics look unchanged or better. This is why a VAD cannot be tuned against VAD metrics alone.
Padding is not optional
Most VADs trim to the detected boundary, which clips the first few tens of milliseconds of a word onset and the final fricative of the word before it. For diarization that shifts turn boundaries. For alignment it costs you the word entirely.
Silero exposes the fix as speech_pad_ms: model = load_silero_vad(), wav = read_audio("file.wav", sampling_rate=16000), then get_speech_timestamps(wav, model, threshold=0.5, min_speech_duration_ms=250, min_silence_duration_ms=100, speech_pad_ms=30). The 30 ms default is a floor rather than a good value. For diarization, 50 to 100 ms is safer, and the added duration has to be counted when you report a speech ratio.
A tuning order that saves time
Fix the padding first, because it is a constant rather than a trade-off. Then set min_duration_off from your own audio: a histogram of gaps between detected regions in the 0.1 to 1.0 second range shows you the pause length that separates turns in this recording condition.
Only after those two are settled should you touch onset and offset, and only if the coverage numbers are bad. Re-score the whole chain for every change, not the VAD in isolation. Freeze the settings once they hold, and re-check them when the recording conditions change, because a VAD tuned on headset audio will be wrong on far-field audio by a wide margin.