voice-activity-detection Β· audio Β· WASM (onnxruntime-web) Β· ~2 MB
A voice activity detector answers one small, useful question, thirty-odd times a second: is someone speaking right now? Silero VAD is a tiny (~2 MB) recurrent network that reads audio in 512-sample frames and emits a speech probability for each one. It's the quiet workhorse in front of almost every speech system β it decides what to send to a transcriber, when to stop recording, and where the pauses are. Here it runs entirely on your device.
| Model | onnx-community/silero-vad (Silero VAD v5) |
|---|---|
| Task | voice-activity-detection β a per-frame speech/non-speech probability |
| Runtime | onnxruntime-web directly β transformers.js has no VAD pipeline, so this page drives ONNX Runtime Web itself (isolated to this model's worker) |
| Architecture | Small stateful RNN (LSTM). Inputs: input [1Γ512] frame Β· state [2Γ1Γ128] LSTM state Β· sr (16000). Outputs: speech probability + next state. |
| Frame | 512 samples @ 16 kHz = 32 ms per decision; the LSTM state carries context across frames |
| Quantization | fp32 ONNX (the whole model is ~2 MB β no quantisation needed) |
| Backend | WebAssembly via onnxruntime-web (single-threaded; runs anywhere) |
| Download | ~2 MB, cached in Cache Storage after first load (auto-inits next visit) |
| License | MIT |
| Web APIs | WebAssembly, Web Workers, Web Audio, MediaRecorder, Cache Storage, Canvas β all Baseline widely available |
Pick a sample, drop an audio file, or record from your mic, then hit Analyse. Silero walks the clip frame-by-frame and marks where speech is.
The bundled Speech clip alone (not the other samples) is a JFK inaugural excerpt (20 January 1961), spoken by John F. Kennedy β public domain, U.S. government work Β· JFK audio source and attribution record.
The VAD doesn't return "speech: yes/no" β it returns a probability for every 32 ms frame. Everything else (segments, trimming, live meters) is what you do with that curve. Below is the real per-frame probability the model produced, with your decision threshold (dashed) and the frames above it shaded. Under it, the speech segments after a threshold + hysteresis pass (a frame must stay quiet for the "min silence" you set before a segment ends).
Detected speech segments (green = speech):
Analyse a clip to see its probability curve and speech segments.
VAD is infrastructure. It's cheap, it's fast, and it makes everything downstream better β which is exactly why it belongs on-device: no audio needs to leave the browser just to decide whether it's worth processing.
Is there speech in this clip? Get a yes/no plus the probability curve behind it.
Trim the silence and split a clip into speech segments you can export.
A live mic talk-meter β watch the speech probability move in real time as you talk.
VAD β Whisper: transcribe only the speech segments, skipping the silence.
There's no pipeline() for VAD β you drive onnxruntime-web directly. It's a stateful loop: feed 512-sample frames, carry the LSTM state forward, read the probability out.
import * as ort from "onnxruntime-web";
const session = await ort.InferenceSession.create(
"https://huggingface.co/onnx-community/silero-vad/resolve/main/onnx/model.onnx",
{ executionProviders: ["wasm"] },
);
let state = new ort.Tensor("float32", new Float32Array(2 * 1 * 128), [2, 1, 128]);
const sr = new ort.Tensor("int64", [16000n], []); // scalar
for (const frame of frames512) { // Float32Array, 512 samples @ 16 kHz
const input = new ort.Tensor("float32", frame, [1, 512]);
const { output, stateN } = await session.run({ input, state, sr });
const speechProb = output.data[0]; // 0 β¦ 1 for this 32 ms frame
state = stateN; // carry the recurrent state forward
}
This page decodes files / mic recordings to 16 kHz mono with an OfflineAudioContext,
runs the frame loop inside a Web Worker so the UI never janks, caches the ~2 MB model in Cache
Storage (so a return visit auto-initialises with no download), and turns the raw curve into
segments with a threshold + hysteresis pass.