Sprachaktivitätserkennung
Zwei VAD-Modelle sind verfügbar: Pyannote-Segmentierung für Offline-Batch-Verarbeitung mit hoher Genauigkeit und Silero VAD v5 für Streaming mit niedriger Latenz. Beide laufen vollständig auf dem Gerät.
Pyannote (Offline)
Pyannote segmentation-3.0 bietet hochgenaue VAD über eine PyanNet-Architektur. Sie verarbeitet Audio in 10-Sekunden-Gleitfenstern mit einem Schritt von 1 Sekunde, aggregiert dann überlappende Vorhersagen und wendet Hysterese-Glättung an.
Architektur
| Stufe | Details |
|---|---|
| SincNet | 40 gelernte Bandpass-Filter (insgesamt 80: 40 cos + 40 sin) |
| BiLSTM | 4 Schichten, hidden=128, bidirektional (256-dim-Ausgabe) |
| Linear | 2 lineare Schichten mit LeakyReLU (negative_slope=0,01) |
| Ausgabe | 7-Klassen-Softmax mit Hysterese-Nachbearbeitung |
Modellgröße: ~1,49M Parameter, ~5,7 MB auf Disk.
Standard-Schwellenwerte
- Onset:
0,767— Wahrscheinlichkeit, oberhalb derer Sprache erkannt wird - Offset:
0,377— Wahrscheinlichkeit, unterhalb derer Sprache endet
CLI-Verwendung
# Offline-VAD
.build/release/audio vad recording.wav
# JSON-Ausgabe
.build/release/audio vad recording.wav --json
# Benutzerdefinierte Schwellenwerte
.build/release/audio vad recording.wav --onset 0.6 --offset 0.3
Silero VAD v5 (Streaming)
Silero VAD v5 ist ein leichtgewichtiges Streaming-Modell, das 512-Sample-Chunks (32 ms bei 16 kHz) verarbeitet. Es läuft im Release-Modus mit 23-facher Echtzeit und eignet sich damit für Live-Audio-Anwendungen.
Architektur
| Stufe | Details |
|---|---|
| STFT | Conv1d (1 auf 258 Kanäle), Reflection-Pad nur rechts von 64 |
| Encoder | 4x Conv1d + ReLU |
| LSTM | Hidden-Size 128, Zustand wird über Chunks hinweg fortgeführt |
| Decoder | Conv1d (128 auf 1) auf LSTM-Hidden-State, Sigmoid-Ausgabe |
Modellgröße: ~309K Parameter, ~1,2 MB auf Disk.
Streaming-Zustandsmaschine
Der Streaming-VAD-Prozessor verwendet eine 4-Zustands-Maschine, um saubere Sprachsegmente zu erzeugen:
- silence — keine Sprache erkannt
- pendingSpeech — Onset-Schwellenwert überschritten, warten auf minimale Sprachdauer
- speech — bestätigtes Sprachsegment läuft
- pendingSilence — Offset-Schwellenwert unterschritten, warten auf minimale Stillezeit
Standard-Schwellenwerte
- Onset:
0,5 - Offset:
0,35 - Minimale Sprachdauer:
0,25 s - Minimale Stillezeit:
0,1 s
CLI-Verwendung
# Streaming-VAD
.build/release/audio vad-stream recording.wav
# Benutzerdefinierte Schwellenwerte
.build/release/audio vad-stream recording.wav --onset 0.6 --offset 0.3
# Mindestdauern
.build/release/audio vad-stream recording.wav --min-speech 0.5 --min-silence 0.2
# Engine wählen
.build/release/audio vad-stream recording.wav --engine coreml
Optionen
| Option | Gilt für | Beschreibung |
|---|---|---|
--onset | Beide | Wahrscheinlichkeitsschwelle für Sprachbeginn |
--offset | Beide | Wahrscheinlichkeitsschwelle für Sprachende |
--min-speech | Streaming | Minimale Sprachsegmentdauer (Sekunden) |
--min-silence | Streaming | Minimale Stillezeit zum Beenden des Segments (Sekunden) |
--engine | Streaming | Inferenz-Engine: mlx oder coreml |
--json | Beide | JSON-Ausgabeformat |
Für Echtzeit-Anwendungen verwende audio vad-stream mit Silero VAD. Das Pyannote-Modell benötigt die vollständige Audiodatei und eignet sich besser für Offline-Batch-Verarbeitung, bei der Genauigkeit Vorrang hat.
Modell-Downloads
| Modell | Backend | Größe | HuggingFace |
|---|---|---|---|
| Silero-VAD-v5 | MLX | ~1,2 MB | aufklarer/Silero-VAD-v5-MLX |
| Silero-VAD-v5 | CoreML | ~1,2 MB | aufklarer/Silero-VAD-v5-CoreML |
| Pyannote-Segmentation-3.0 | MLX | ~5,7 MB | aufklarer/Pyannote-Segmentation-MLX |
Swift-API
import SpeechVAD
// Offline-VAD (Pyannote)
let pyannote = try await PyannoteVAD.loadFromHub()
let segments = try await pyannote.detectSpeech(audioFile: "recording.wav")
for segment in segments {
print("\(segment.start)s - \(segment.end)s")
}
// Streaming-VAD (Silero)
let silero = try await SileroVAD.loadFromHub()
let processor = StreamingVADProcessor(model: silero, config: .sileroDefault)
for chunk in audioChunks {
if let segment = try processor.process(chunk: chunk) {
print("Speech: \(segment.start)s - \(segment.end)s")
}
}
Auch verfügbar auf Android & Linux über ONNX Runtime.