RUNLOCALAIv38
->Will it run?Best GPUCompareTroubleshootStartLearnPulseModelsHardwareToolsBench
Run check
RUNLOCALAI

Independently operated catalog for local-AI hardware and software. Hand-written verdicts. Source-cited claims. Reproducible commands when we have them.

OP·Eruo Fredoline
DIR
  • Models
  • Hardware
  • Tools
  • Benchmarks
TOOLS
  • Will it run?
  • Compare hardware
  • Cost vs cloud
  • Choose my GPU
  • Prompting kits
  • Quick answers
REF
  • All buyer guides
  • Learn local AI
  • Methodology
  • Glossary
  • Errors KB
  • Trust
  • Suggest a feature
EDITOR
  • About
  • Author
  • How we make money
  • Editorial policy
  • Contact
LEGAL
  • Privacy
  • Terms
  • Sitemap
MAIL · MONTHLY DIGEST
Get monthly local AI changes
Monthly recap. No spam.
DISCLOSURE

Some links on this site are affiliate links (Amazon Associates and other first-class retailers). When you buy through them, we earn a small commission at no extra cost to you. Affiliate links do not influence our verdicts — there are cards we rate highly that we don't have affiliate relationships with, and cards that sell well that we refuse to recommend. Read more →

© 2026 runlocalai.coIndependently operated
RUNLOCALAI · v38
  1. >
  2. Home
  3. /Learn
  4. /Courses
  5. /Voice AI with Local Models
  6. /Ch. 5
Voice AI with Local Models

05. Voice Activity Detection

Chapter 5 of 22 · 15 min
KEY INSIGHT

VAD aggressiveness settings must match deployment environment noise characteristics; office settings differ from manufacturing floors.

Voice Activity Detection identifies segments containing human speech within audio streams. Streaming voice AI requires VAD to trigger processing only when someone speaks, avoiding continuous analysis.

Silero VAD provides high accuracy with minimal computational overhead. The model operates on short audio chunks and produces speech probability scores. A threshold parameter controls sensitivity.

Create a VAD-enabled audio streamer:

import torch
import numpy as np
import pyaudio
from queue import Queue

class VADAudio:
    def __init__(self, aggressiveness=3):
        self.model, utils = torch.hub.load(
            "snakers4/silero-vad",
            "silero_vad"
        )
        self.get_speech_timestamps = utils[0]
        
        self.sample_rate = 16000
        self.frame_duration = 1536  # ~96ms at 16kHz
        self.aggressiveness = aggressiveness
        self.audio_queue = Queue()
        self.buffer = np.zeros(int(self.sample_rate * 0.5))
    
    def start(self):
        self.stream = pyaudio.PyAudio().open(
            format=pyaudio.paInt16,
            channels=1,
            rate=self.sample_rate,
            input=True,
            frames_per_buffer=512,
            stream_callback=self._callback
        )
        self.stream.start_stream()
    
    def _callback(self, input_data, frame_count, time_info, status):
        audio = np.frombuffer(input_data, dtype=np.int16)
        audio = audio.astype(np.float32) / 32768.0
        
        speech_prob = self.model(
            torch.from_numpy(audio).unsqueeze(0),
            self.sample_rate
        ).item()
        
        self.buffer = np.append(self.buffer, audio)
        if len(self.buffer) > self.sample_rate * 5:
            self.buffer = self.buffer[-self.sample_rate * 5:]
        
        return (input_data, pyaudio.paContinue)
    
    def stop(self):
        self.stream.stop_stream()
        self.stream.close()

vad = VADAudio(aggressiveness=3)
vad.start()

The aggressiveness parameter (0-3) controls per-frame suppression. Higher values reject more non-speech frames. Experiment to find the setting matching background noise levels.

Chunk-based processing introduces latency. Longer chunks improve accuracy but increase response time to speech onset. The 1536-sample frame provides reasonable balance for conversational applications.

Local verification checkpoint

Run the smallest example from this chapter in a local workspace and record the package version, runtime, data path, and observed output. If the result depends on model size, vector count, CPU/GPU backend, or available memory, note that constraint beside the exercise so the lesson remains reproducible.

Local verification checkpoint

Run the smallest example from this chapter in a local workspace and record the package version, runtime, data path, and observed output. If the result depends on model size, vector count, CPU/GPU backend, or available memory, note that constraint beside the exercise so the lesson remains reproducible.

EXERCISE

Implement logging to record speech probability scores and visualize them over time while speaking and remaining silent. Identify optimal threshold cutoff. (15 minutes)

← Chapter 4
STT Accuracy Tuning
Chapter 6 →
TTS Options: Kokoro