MLX-format weights for Silero VAD v6 (16 kHz branch), converted from the
official silero_vad PyPI package.
This is the v6 companion to mlx-community/silero-vad, which contains the older v5 weights.
Both are independent ports of different Silero release lines.
The two ports differ only in which Silero checkpoint they wrap — the
architecture is identical (STFT → 4× Conv1d+ReLU → LSTM(128) → Conv1d → Sigmoid).
Quality and per-chunk latency are essentially equivalent on long-form English
meeting audio (see Quality below).
Architecture
Input: audio (1, 576) = 64-sample context + 512-sample chunk
+ LSTM state (h: 1×128, c: 1×128)
Pre-process: Reflection pad right (+64) → 640 samples
Learned STFT: Conv1d(1, 258, k=256, s=128) → magnitude → (1, 4, 129)
Encoder: Conv1d(129→128) → ReLU
Conv1d(128→64, s=2) → ReLU
Conv1d(64→64, s=2) → ReLU
Conv1d(64→128) → ReLU → (1, 1, 128)
LSTM: LSTMCell(128, 128) — state carried across chunks for streaming
Decoder: ReLU → Conv1d(128→1, k=1) → Sigmoid → probability
Total parameters: ~309K, ~1.2 MB on disk
Streaming: carry (h, c) across calls; per-chunk decision in <1 ms
All Conv1d weights are stored in MLX channels-last layout [O, K, I].
LSTM bias is the sum of PyTorch's bias_ih + bias_hh (single-tensor MLX convention).
Files
model.safetensors — MLX-format weights (16 kHz branch, vad_16k.* layout). Same weights serve both inference modes.
example.py — 32ms streaming inference example (per-chunk decisions; live mic / streaming use cases)
example_256ms.py — 256ms unified inference example (8 internal chunks per call with noisy-OR aggregation; faster wall time for offline ASR preprocessing)
Conversion
The bundled convert.py produces this repo's model.safetensors from the
upstream PyPI silero_vad package:
Both examples read weights directly from this repo via huggingface_hub. The
same model.safetensors serves both modes; only the inference loop differs.
Choosing a mode
32ms streaming (example.py)
256ms unified (example_256ms.py)
Per-call output
1 probability per 32 ms
1 probability per 256 ms (8 internal chunks aggregated via noisy-OR)
Decision latency
32 ms
256 ms
MLX wall throughput
1×
~1.7× faster (fewer mx.eval barriers)
Best for
Live microphone, real-time gating
Offline ASR preprocessing, batch / file-based VAD
Manual loading
python
1import mlx.core as mx
2from huggingface_hub import hf_hub_download
3from safetensors.numpy import load_file
45path = hf_hub_download("mlx-community/silero-vad-v6","model.safetensors")6weights = load_file(path)7weights ={k: mx.array(v)for k, v in weights.items()}8# weights["vad_16k.stft_conv.weight"].shape == (258, 256, 1)
For the full forward pass, see example.py (≈ 80 lines, no external dependencies
beyond mlx, numpy, safetensors, huggingface_hub).
Streaming protocol
Per-chunk inputs (32 ms at 16 kHz):
64 context samples carried from the previous chunk's tail
512 new audio samples
LSTM h, c state ([1, 128] each) carried across chunks
Output: scalar speech probability ∈ [0, 1]. A standard threshold of 0.5 works
well on most material; tune via config.json::threshold for your use case.
Quality
Frame-level F1 against VibeVoice ASR
segment-derived speech labels on a 44-minute English meeting clip
(playback-eng-16k.wav, 83,190 chunks at 32 ms resolution, GT speech ratio 98.9%):
Threshold
v6 (this repo) F1
v5 (mlx-community/silero-vad) F1
Δ
0.30
0.8656
0.8692
+0.004 v5
0.40
0.8612
0.8649
+0.004 v5
0.50
0.8572
0.8607
+0.003 v5
0.60
0.8534
0.8561
+0.003 v5
0.70
0.8492
0.8510
+0.002 v5
At threshold 0.5: precision ≈ 0.998 for both, recall 0.751 vs 0.757.
The two versions are essentially equivalent within measurement noise on this
sample. The v5 edge of ~0.4% F1 is too small relative to single-sample variance,
GT labeling granularity (segment-level rather than word-level), and the high
class imbalance to draw a generalised "v5 is better" conclusion.
A broader multi-domain quality comparison (clean / noisy / far-field / multilingual)
would be needed for a definitive ranking.
Performance
Bit-exact parity with the upstream PyTorch JIT model (max|Δ| = 0.0 across 83K
chunks of test audio).
On newer hardware (M5 Max), per-chunk async-batched throughput drops to
~0.17 ms/chunk in CPU stream mode (≈ 187× real-time), per
lucasnewman's PR701 benchmark.
256ms unified vs 32ms streaming, offline VAD on 10-min English meeting (M1 Max):
Mode
VAD wall time
Speedup vs 32ms
32ms streaming MLX
~36 s
1.0×
256ms unified MLX
~16 s
~2.3× faster
CoreML 256ms (FluidInference, native Apple HW)
~12 s
~3.0× faster
The 256ms unified mode is the right choice for offline ASR preprocessing;
its eight internal 32ms chunks per outer call amortise MLX dispatch overhead
through mx.eval barrier reduction. CoreML 256ms remains the absolute fastest
on Apple Silicon (ANE/BNNS-tuned), but pure-MLX 256ms closes ~50% of the gap.