Deteccao de atividade de voz
Dois modelos VAD estao disponiveis: Pyannote segmentation para processamento batch offline com alta precisao e Silero VAD v5 para deteccao em streaming de baixa latencia. Ambos rodam totalmente no dispositivo.
Pyannote (offline)
Pyannote segmentation-3.0 fornece VAD de alta precisao usando uma arquitetura PyanNet. Processa audio em janelas deslizantes de 10 segundos com passo de 1 segundo, depois agrega predicoes sobrepostas e aplica suavizacao por histerese.
Arquitetura
| Estagio | Detalhes |
|---|---|
| SincNet | 40 filtros bandpass aprendidos (80 no total: 40 cos + 40 sin) |
| BiLSTM | 4 camadas, hidden=128, bidirecional (saida de 256 dim) |
| Linear | 2 camadas lineares com LeakyReLU (negative_slope=0.01) |
| Saida | Softmax de 7 classes com pos-processamento por histerese |
Tamanho do modelo: ~1.49M parametros, ~5.7 MB em disco.
Limiares padrao
- Onset:
0.767— probabilidade acima da qual fala e detectada - Offset:
0.377— probabilidade abaixo da qual fala termina
Uso do CLI
# Offline VAD
.build/release/audio vad recording.wav
# JSON output
.build/release/audio vad recording.wav --json
# Custom thresholds
.build/release/audio vad recording.wav --onset 0.6 --offset 0.3
Silero VAD v5 (streaming)
Silero VAD v5 e um modelo de streaming leve que processa chunks de 512 amostras (32 ms a 16 kHz). Roda a 23x tempo real em modo release, tornando-o adequado para aplicacoes de audio ao vivo.
Arquitetura
| Estagio | Detalhes |
|---|---|
| STFT | Conv1d (1 para 258 canais), pad de reflexao somente a direita de 64 |
| Codificador | 4x Conv1d + ReLU |
| LSTM | Tamanho hidden 128, estado carregado entre chunks |
| Decodificador | Conv1d (128 para 1) no estado hidden do LSTM, saida sigmoid |
Tamanho do modelo: ~309K parametros, ~1.2 MB em disco.
Maquina de estados de streaming
O processador de VAD em streaming usa uma maquina de 4 estados para produzir segmentos de fala limpos:
- silence — nenhuma fala detectada
- pendingSpeech — limiar de onset ultrapassado, aguardando duracao minima de fala
- speech — segmento de fala confirmado em andamento
- pendingSilence — limiar de offset ultrapassado, aguardando duracao minima de silencio
Limiares padrao
- Onset:
0.5 - Offset:
0.35 - Duracao minima de fala:
0.25s - Duracao minima de silencio:
0.1s
Uso do CLI
# Streaming VAD
.build/release/audio vad-stream recording.wav
# Custom thresholds
.build/release/audio vad-stream recording.wav --onset 0.6 --offset 0.3
# Minimum durations
.build/release/audio vad-stream recording.wav --min-speech 0.5 --min-silence 0.2
# Choose engine
.build/release/audio vad-stream recording.wav --engine coreml
Opcoes
| Opcao | Aplica-se a | Descricao |
|---|---|---|
--onset | Ambos | Limiar de probabilidade de onset de fala |
--offset | Ambos | Limiar de probabilidade de offset de fala |
--min-speech | Streaming | Duracao minima de segmento de fala (segundos) |
--min-silence | Streaming | Duracao minima de silencio para encerrar segmento (segundos) |
--engine | Streaming | Engine de inferencia: mlx ou coreml |
--json | Ambos | Formato de saida JSON |
Para aplicacoes em tempo real, use audio vad-stream com Silero VAD. O modelo Pyannote requer o arquivo de audio completo e e mais adequado para processamento batch offline onde a precisao e a prioridade.
Downloads de modelos
| Modelo | Backend | Tamanho | 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 |
API Swift
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")
}
}
Tambem disponivel em Android e Linux via ONNX Runtime.