Model Card for Silero VAD v6 (IB-Robot)

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.

Deployments

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.

Tensor contract

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.

Repository Structure

  • inference_manifest.json β€” deployment routing (schema v3)
  • assets/adapter.json β€” adapter identity (silero_vad / vad)
  • assets/silero_vad.onnx β€” upstream dynamic-shape ONNX export
  • assets/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 against
  • artifacts/ascend/ascend_310p/*.om β€” three Ascend 310P1 builds
  • artifacts/ascend_310b/*.om β€” Ascend 310B1 build

Source Model

Upstream 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/silero-vad@v6.2 β€” 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:

  • 17 of our 27 initializers are bit-identical to an upstream Constant;
  • the remaining ones match after removing a leading unit axis, except the two LSTM weight matrices and the bias;
  • each (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;
  • the (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

Validation

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:

  • Its input is outside the model's domain. 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.
  • The reported 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.

Full-scale / clipping retest, all three precision builds

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.

Usage

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.

Changelog

revision 2

  • Replaced the model card, which previously described ZipVoice-Distill.
  • Corrected the 310P artifact. The file published as 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.
  • Added 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.
  • Kept all three 310P1 builds in the repo, declared in 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.

License

Code and packaging: Apache-2.0. Silero VAD weights follow the upstream snakers4/silero-vad license (MIT).

Citation

@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}
}
Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support