Downloads · 30 days
0
openEuler/silero-vad
silero-vad is a voice activity detection model from openEuler. Use it for the voice activity detection task on the model card, and read the license before you ship it in a product. The card lists the license as apache-2.0.
Silero VAD v6 — a small streaming voice-activity detector — packaged for the IB-Robot framework. It consumes one 576-sample chunk plus a carried LSTM state and returns a per-frame speech probability and the next state…
Downloads · 30 days
0
Access
Public
Updated Sep 10, 2026
Repo size
15.5 MB
Likes
0
Public
Click a slice to open those files.
.om12 MB · 77%
From the Hugging Face model README
Silero VAD v6 — a small streaming voice-activity detector — packaged for the IB-Robot framework. It consumes one 576-sample chunk plus a carried LSTM state and returns a per-frame speech probability and the next state. It is the gate in front of the STT stage: the wake word opens a session, this model decides where the utterance ends.
This revision replaces an incorrect model card. The previously published card on this repo was a copy of the ZipVoice-Distill card (title, TTS tags and
pipeline_tag: text-to-speech) and described a different model. See Changelog — the 310P artifact was also corrected.
| deployment | backend | artifact | notes |
|---|---|---|---|
ascend_310p | Ascend ACL (Ascend310P1) | silero_vad_v6_310p_mixed16.om | recommended, mixed-precision build |
ascend_310b | Ascend ACL (Ascend310B1) | silero_vad_v6_310b_fp16.om | 310B board-side build |
torch_cpu | ONNX Runtime CPU | assets/silero_vad.onnx | host-side, dynamic shapes, takes an sr input |
Two further 310P1 builds ship in the repo without their own deployment entry, matching the convention across this organisation that one hardware target carries one deployment and the precision variant lives in the filename:
| file | ATC precision flag | notes |
|---|---|---|
silero_vad_v6_310p_fp16.om | --precision_mode_v2=fp16 | pure fp16 build |
silero_vad_v6_310p.om | --precision_mode=allow_mix_precision | a second mixed-precision mode; not a true fp32 baseline, which would need --precision_mode=must_keep_origin_dtype |
Both are declared in bundle.files and load by pointing an ACL session at the
file directly. Accuracy for all three is reported below; the short version is
that they differ by ~1e-3 in carried state and by nothing that reaches the VAD
decision.
Shared contract: tensor_model/silero_vad/vad
(host.silero.audio [1,576] + host.silero.sample_rate [] -> host.silero.prob [1,1]),
preprocessing mono-16khz-float32-chunk576-lstm-state-v1, output
speech-probability-float32-per-frame-v1.
All four OM builds are compiled to fixed shapes and drop the sr input
(they are 16 kHz only):
inputs input float32 [1, 576] 576 = 512-sample frame + 64-sample left context
state float32 [2, 1, 128] carried LSTM state, zeros at stream start
outputs output float32 [1, 1] speech probability in [0, 1]
stateN float32 [2, 1, 128] feed back as `state` on the next chunk
The caller advances by frame_size = 512 samples per step and keeps the
trailing 64 samples as the next chunk's left context. state must be
carried across chunks; resetting it every chunk changes the output.
assets/silero_vad.onnx (the torch_cpu deployment) is the dynamic-shape
upstream export and takes a third input sr (int64 scalar); pass 16000.
inference_manifest.json — deployment routing (schema v3)assets/adapter.json — adapter identity (silero_vad / vad)assets/silero_vad.onnx — upstream dynamic-shape ONNX exportassets/silero_vad_openvino_16k_sim.onnx — the 16 kHz-specialised, shape-fixed,
onnx-simplified fp32 graph that the OMs were actually compiled from, and the
reference the accuracy numbers below are measured againstartifacts/ascend/ascend_310p/*.om — three Ascend 310P1 buildsartifacts/ascend_310b/*.om — Ascend 310B1 buildUpstream is Silero VAD v6.2. The manifest's logical revision is
silero-vad@v6-openvino-16k: it names the 16 kHz OpenVINO graph the OMs are
actually compiled from, not the upstream release tag.
assets/silero_vad.onnx is byte-identical to the file shipped in the
upstream repository at tags v6.2 and v6.2.1
(src/silero_vad/data/silero_vad.onnx, verified by sha256):
| file | bytes | sha256 | upstream |
|---|---|---|---|
assets/silero_vad.onnx | 2,327,524 | 1a153a22f4509e292a94e67d6f9b85e8deb25b4988682b7e174c65279d8788e3 | snakers4/[email protected] — identical bytes |
assets/silero_vad_openvino_16k_sim.onnx | 1,251,290 | 94b26dfea7b8fdfb2524e291a3a7014be9dbf336c341af35fa48998892e92eb2 | derived from silero_vad_openvino_16k.onnx (see below) |
(The same file at v6.0/v6.1 has sha256 597d30b3…, so this bundle is
specifically ≥ v6.2.)
assets/silero_vad_openvino_16k_sim.onnx is the 16 kHz-specialised,
shape-fixed graph the OMs were actually compiled from — sr folded away and
[1,576] / [2,1,128] pinned, which is what ATC requires. It is derived from
upstream src/silero_vad/data/silero_vad_openvino_16k.onnx
(commit 1a26f187,
"add openvino model", 1,288,203 bytes,
sha256 7776b81ad1b0350c15d7f1555943b9232eb53e9ca5d989c6d0cea9ebc8664d87),
with the LSTM lowered to MatMul and the graph simplified: 167 nodes with 98
inline Constant tensors become 32 nodes with 27 initializers. Both graphs
report producer_name: spox, opset 16, and the identical IO signature.
The derivation is verified at weight level, not asserted:
Constant;(1,512,128) LSTM matrix is an exact 128-row gate-block permutation
of its upstream (512,128) counterpart — the same permutation [0,2,3,1]
for both, i.e. the ONNX-LSTM gate order rewritten for the fused MatMul form,
with every value preserved;(1,1024) bias is the concatenation of the two upstream (512,) biases.No upstream weight is altered; the transformation is structural only.
Compiled artifacts (ATC, --soc_version=Ascend310P1 unless noted):
| file | bytes | sha256 |
|---|---|---|
silero_vad_v6_310p_mixed16.om | 2,993,746 | e53992ea55de81900f236220b951a2e595d134ddbb7f4ee6292b6b1055e5cc28 |
silero_vad_v6_310p_fp16.om | 2,975,416 | 4ac1d447ab95afd99f473d25c73e80a164f436cfc52959964b39ecde5b1c1446 |
silero_vad_v6_310p.om | 2,993,101 | 808c426f6dcfbce243c90d618c8dda8680d4c39496a18aed06b51fbb1537dd3a |
silero_vad_v6_310b_fp16.om (Ascend310B1) | 3,000,931 | 74893fe18a9258b73c53e4d46f540ed1722fc4f632dbb2bc33a975c55e21a694 |
Measured on a real Ascend 310P1, ONNX Runtime fp32 reference and OM running on the same board.
Streaming — 20 consecutive chunks with the OM's own stateN fed back:
output cosine min 1.000000 max 1.000000
stateN cosine min 0.999999 max 1.000000
first chunk 12.25 ms
steady state 3.10 ms mean
Single-step, five synthetic inputs (threshold_cosine = 0.999), on
silero_vad_v6_310p_mixed16.om:
| case | input | output (om / ref) | stateN cosine | verdict |
|---|---|---|---|---|
| silence | zeros | 0.00186 / 0.00167 | 0.999379 | pass |
| noise | gaussian ×0.1 | 0.01610 / 0.01612 | 1.000000 | pass |
| tone160 | 160 Hz ×0.2 | 0.21277 / 0.19426 | 0.999641 | pass |
| speech_like | mixed tones + noise | 0.09076 / 0.09085 | 1.000000 | pass |
| loud | 440 Hz ×5.0 | 0.00067 / 0.03803 | 0.338508 | fail |
The suite reports all_passed: false because of loud. Two things about that
case are worth stating precisely rather than leaving as a bare failure:
loud is a sine at amplitude
5.0. Audio decoded from int16 PCM is bounded in [-1, 1], so no real
capture path — including the robot's — can produce this input. It is a
synthetic overflow probe, not a reachable operating point.output cosine = 1.000000 for every case is a degenerate
metric, not evidence of accuracy: the output is a single scalar [1,1], and
the cosine of two 1-element vectors of the same sign is always exactly 1. The
meaningful output column is the om/ref pair above. On the four in-domain
cases those agree to ≤0.019 absolute (worst case tone160); on loud they do
not (0.0007 vs 0.038), and the carried state diverges hard — stateN cosine
0.34 with max_abs 1.9995, i.e. a value saturated to +1 in one graph and −1 in
the other, which is the signature of a fp16 range overflow inside the LSTM.So the practical reading is: the four in-domain cases pass and the one failure is an out-of-domain input.
The gap left by the suite above — does a real, reachable, full-scale input
break it? — has since been measured on the 310P1. Five in-domain worst cases,
each run against all three precision builds, ONNX Runtime fp32 as reference,
judged by absolute output error (≤0.02, well inside the 0.5 decision
threshold) and stateN cosine (≥0.999):
| case | input | output (om / ref) | abs err | stateN cosine | verdict |
|---|---|---|---|---|---|
| fullscale_sine | 440 Hz ×1.0 | 0.00410 / 0.00375 | 3.5e-4 | 0.999745 | pass |
| clipped_sine | 440 Hz ×3.0 hard-clipped to ±1 | 0.00368 / 0.00365 | 3.2e-5 | 0.999993 | pass |
| fullscale_noise | gaussian ×0.5 clipped to ±1 | 0.00329 / 0.00328 | 4.8e-6 | 0.999999 | pass |
| step | DC step 0 → 1.0 | 0.00080 / 0.00080 | 3.0e-6 | 0.999998 | pass |
| fullscale_warmstate | 440 Hz ×1.0, non-zero initial state | 0.00871 / 0.00850 | 2.1e-4 | 0.999832 | pass |
| loud ×5.0 | unreachable, kept for reference | 0.00067 / 0.03803 | 3.7e-2 | 0.338508 | out of domain |
Clipping is not a problem. The hardest reachable input — a hard-clipped sine, which is what an overloaded microphone actually produces — is the second most accurate case in the table. The suspicion recorded in earlier revisions of this card, that full-scale input might sit close to an overflow, is not borne out.
The out-of-domain divergence is not a precision problem. On the amplitude-5
case the fp32 build diverges from the ONNX reference by exactly the same
0.0374, with the same stateN cosine 0.3385, as mixed16 and fp16. If this
were the fp16 range overflow that earlier revisions of this card assumed, the
fp32 build would have fixed it. It does not, so the cause is in the
ATC-compiled graph, not in storage precision.
How much do the three builds actually differ? Over 50 randomised in-domain inputs (random amplitude 0.01–1.0, random non-zero initial state):
| pair | output identical | state identical | state max abs diff |
|---|---|---|---|
fp32 vs mixed16 | yes, bit-exact on all 50 | no | 4.9e-4 |
fp16 vs mixed16 | no | no | 9.8e-4 |
So the builds are not interchangeable bit-for-bit, but they differ by ~1e-3
in the carried state and by nothing that reaches the VAD decision (threshold
0.5, in-domain output error ≤3.5e-4 against the fp32 ONNX reference for every
build). Choose a build on size and latency, not on accuracy — and note
that the allow_mix_precision build buys no extra headroom on the loud case.
A caveat on the labels: neither extra build is a true fp32 reference.
silero_vad_v6_310p.om was compiled with
--precision_mode=allow_mix_precision, so the "fp32 vs mixed16 is
bit-exact" row above compares two mixed-precision modes, and does not by
itself show that reducing precision is lossless. The evidence for that is the
comparison against the fp32 ONNX reference in the tables above.
Select a deployment through the IB-Robot unified inference runtime:
from inference_manifest import load_inference_manifest
validated = load_inference_manifest("models/silero-vad", "ascend_310p")
Per chunk: feed input and the carried state, read output as the speech
probability, and store stateN as the next state. Zero the state at the
start of each stream.
revision 2
silero_vad_v6_310p_mixed16.om had sha256 4ac1d447…, which is the
fp16 build, not the mixed16 build. All three 310P1 builds are now
shipped under their own names, each listed with its sha256, so the precision
variant in use is unambiguous. Anyone who pinned the old sha256 was running
fp16.assets/silero_vad_openvino_16k_sim.onnx, the graph the OMs were
compiled from — previously the bundle shipped only the dynamic-shape ONNX,
which cannot reproduce the OMs.bundle.files, with
their ATC precision flags documented. They do not get separate deployment
entries: every other model in this organisation exposes exactly one
deployment per hardware target and distinguishes builds by filename.Code and packaging: Apache-2.0. Silero VAD weights follow the upstream snakers4/silero-vad license (MIT).
@misc{Silero VAD,
author = {Silero Team},
title = {Silero VAD: pre-trained enterprise-grade Voice Activity Detector (VAD), Number Detector and Language Classifier},
year = {2024},
publisher = {GitHub},
journal = {GitHub repository},
howpublished = {\url{https://github.com/snakers4/silero-vad}},
commit = {be95df9152c0d7618fa1edfeb296fc3dae32376f}
}
@software{ib_robot,
title = {IB-Robot: Intelligence Boom Robot},
url = {https://atomgit.com/openeuler/IB_Robot},
license = {Apache-2.0}
}