Understand the workflow

Voice activity detection (VAD) classifies short audio frames as speech or silence. VAD is useful for voice assistants, transcription pipelines, and other systems that should avoid processing silent audio.

You’ll deploy the 16 kHz Silero VAD model with ExecuTorch. The workflow quantizes the model, lowers supported operations to the Arm Ethos-U backend, builds a bare-metal application, and runs it on a Corstone-320 Fixed Virtual Platform (FVP). You don’t need a physical development board.

The application processes 512 audio samples every 32 ms. It keeps the long short-term memory (LSTM) hidden and cell state inside the ExecuTorch program between frames, then produces one speech probability for each frame.

The host uses the validation clip to generate reference probabilities. The bare-metal application processes the same clip on the FVP. The final comparison verifies that both paths produce the same speech decisions.

Image Alt Text:Three-lane workflow showing host preparation from the Silero model and source audio to a stateful PTE, virtual target execution from the embedded PTE and validation audio to an FVP log, and host verification that compares reference probabilities with the FVP result.Silero VAD workflow separated into prepare, run, and verify lanes

Use the FVP for functional validation. The FVP’s Ethos-U model is cycle accurate, but don’t use its Cortex-M CPU model for CPU performance measurements.

Check your development machine

Run the following preflight check before downloading the source:

    

        
        
case "$(uname -s)/$(uname -m)" in
  Linux/x86_64|Linux/aarch64|Linux/arm64|Darwin/arm64)
    echo "Supported host: $(uname -s)/$(uname -m)"
    ;;
  *)
    echo "Unsupported host: $(uname -s)/$(uname -m)" >&2
    exit 1
    ;;
esac

for tool in python3 git cmake c++ curl; do
  command -v "$tool" >/dev/null || {
    echo "Missing required tool: $tool" >&2
    exit 1
  }
done

if ! command -v ninja >/dev/null && ! command -v make >/dev/null; then
  echo "Install Ninja or Make before continuing." >&2
  exit 1
fi

printf 'int main() { return 0; }\n' | \
  c++ -std=c++17 -x c++ -fsyntax-only -

python3 - <<'PY'
import re
import subprocess
import sys

if not (3, 10) <= sys.version_info[:2] <= (3, 13):
    raise SystemExit("Python 3.10 through 3.13 is required")

output = subprocess.check_output(["cmake", "--version"], text=True)
version = tuple(map(int, re.search(r"\d+(?:\.\d+)+", output).group().split(".")[:2]))
if version < (3, 24):
    raise SystemExit("CMake 3.24 or later is required")

print(f"Python {sys.version.split()[0]}")
print(output.splitlines()[0])
PY

    

Create an isolated ExecuTorch environment

The Silero VAD Ethos-U example is available in the upstream ExecuTorch repository. Use the tested main-branch commit so that the commands and generated artifacts match the Learning Path.

Clone ExecuTorch and check out the tested revision:

    

        
        
git clone https://github.com/pytorch/executorch.git
cd executorch
git checkout 4fd161058ebe2b9d80d11242a9d21811c0e92dac
git submodule sync --recursive
git submodule update --init --recursive

    

Confirm the checked-out revision:

    

        
        
git rev-parse --short=12 HEAD

    

The expected output is:

    

        
        4fd161058ebe

        
    

Create and activate a Python virtual environment:

    

        
        
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip

    

Install ExecuTorch and its Python dependencies:

    

        
        
CMAKE_ARGS="-DEXECUTORCH_BUILD_MLX=OFF" \
  env -u DEBUG ./install_executorch.sh \
  --minimal --optional-dependency ethos_u

python - <<'PY'
import executorch.codegen.tools.selective_build
from executorch.backends.arm.ethosu import EthosUPartitioner
from executorch.backends.arm.quantizer import EthosUQuantizer

print("ExecuTorch installation verified")
PY

    

The installation script initializes the Git submodules that are needed by the build. The script also installs the matching PyTorch and ExecuTorch packages. The command omits the unrelated MLX backend and optional packages used by other examples.

Install the Arm backend tools

The Arm setup script downloads the Arm GNU Toolchain, Ethos-U Vela compiler, and supporting Python packages. On Linux, the script also installs the Corstone FVPs. Review the license terms presented by the script before using its EULA acceptance option.

macOS

Before you run the Arm setup command on macOS, install Docker Desktop and follow the AVH FVPs on macOS install guide . Add the FVPs-on-Mac bin directory to PATH. Confirm that Docker is running and that FVP_Corstone_SSE-320 resolves to the wrapper:

    

        
        
docker info >/dev/null
command -v FVP_Corstone_SSE-320

    

Run the setup script from the ExecuTorch repository root:

    

        
        
./examples/arm/setup.sh --i-agree-to-the-contained-eula
source examples/arm/arm-scratch/setup_path.sh

    

The second command adds the downloaded cross-compiler and, on Linux, FVP binaries to the current shell environment. If you start a new shell, you’ll need to run the command again.

Check that the two target tools are available:

    

        
        
command -v arm-none-eabi-g++
command -v FVP_Corstone_SSE-320

    

The compiler resolves under examples/arm/arm-scratch/. On Linux, the FVP also resolves under this directory. On macOS, the FVP resolves under the FVPs-on-Mac wrapper directory. If the compiler is missing, source examples/arm/arm-scratch/setup_path.sh again. If the FVP is missing on macOS, add the wrapper directory to PATH.

Download the model and sample audio

Create one workspace for the files generated in this Learning Path:

    

        
        
mkdir -p silero-vad-work/{assets,export}

    

Download the model and sample audio from the tested Silero VAD revision:

    

        
        
curl --fail --location \
  --output silero-vad-work/assets/silero_vad.jit \
  https://raw.githubusercontent.com/snakers4/silero-vad/dbacf536adadf42210f37ae50fbaf75f6235b3cf/src/silero_vad/data/silero_vad.jit

curl --fail --location \
  --output silero-vad-work/assets/test.wav \
  https://raw.githubusercontent.com/snakers4/silero-vad/dbacf536adadf42210f37ae50fbaf75f6235b3cf/tests/data/test.wav

    

Create two audio clips

The target processes 2.5 seconds of audio. Copy the following snippet once to create a calibration clip and a separate validation clip:

    

        
        
python3 - <<'PY'
import wave
from pathlib import Path

source_path = Path("silero-vad-work/assets/test.wav")
clips = (("calibration.wav", 0.0), ("validation.wav", 2.5))

with wave.open(str(source_path), "rb") as source:
    parameters = source.getparams()
    if (
        parameters.nchannels,
        parameters.sampwidth,
        parameters.framerate,
        parameters.comptype,
    ) != (1, 2, 16000, "NONE"):
        raise SystemExit("test.wav must be mono, 16 kHz, 16-bit PCM")
    if source.getnframes() < 5 * parameters.framerate:
        raise SystemExit("test.wav does not contain five seconds of audio")
    for name, start_seconds in clips:
        source.setpos(int(start_seconds * parameters.framerate))
        frames = source.readframes(int(2.5 * parameters.framerate))
        if len(frames) != 40000 * parameters.sampwidth:
            raise SystemExit(f"Could not create a 2.5-second {name} clip")
        with wave.open(str(source_path.with_name(name)), "wb") as target:
            target.setparams(parameters)
            target.writeframes(frames)
PY

    

Use calibration.wav to calibrate quantization. The FVP will process the separate validation.wav clip.

What you’ve accomplished and what’s next

You’ve installed the pinned ExecuTorch source, prepared the Arm tools, and created the model inputs.

Next, you’ll export the model as a quantized ExecuTorch program for Ethos-U85.

Back
Next