Phát hiện hoạt động giọng nói — Silero VAD v5
Có hai mô hình VAD: Pyannote segmentation để xử lý theo lô offline với độ chính xác cao, và Silero VAD v5 để phát hiện streaming với độ trễ thấp. Cả hai đều chạy hoàn toàn trên thiết bị.
Pyannote (offline)
Pyannote segmentation-3.0 cung cấp VAD độ chính xác cao bằng kiến trúc PyanNet. Mô hình xử lý âm thanh trong các cửa sổ trượt 10 giây với bước 1 giây, sau đó tổng hợp các dự đoán chồng lấn và áp dụng làm mượt theo độ trễ (hysteresis).
Kiến trúc
| Giai đoạn | Chi tiết |
|---|---|
| SincNet | 40 bộ lọc thông dải đã học (tổng 80: 40 cos + 40 sin) |
| BiLSTM | 4 lớp, hidden=128, hai chiều (đầu ra 256 chiều) |
| Linear | 2 lớp tuyến tính với LeakyReLU (negative_slope=0.01) |
| Đầu ra | Softmax 7 lớp với hậu xử lý theo hysteresis |
Kích thước mô hình: ~1.49M tham số, ~5.7 MB trên đĩa.
Ngưỡng mặc định
- Onset:
0.767— xác suất trên ngưỡng này coi như có giọng nói - Offset:
0.377— xác suất dưới ngưỡng này coi như giọng nói kết thúc
Cách dùng CLI
# Offline VAD
.build/release/speech vad recording.wav
# JSON output
.build/release/speech vad recording.wav --json
# Custom thresholds
.build/release/speech vad recording.wav --onset 0.6 --offset 0.3
Silero VAD v5 (streaming)
Silero VAD v5 là mô hình streaming nhẹ, xử lý các chunk 512 mẫu (32 ms ở 16 kHz). Mô hình chạy nhanh gấp 23 lần thời gian thực ở chế độ release, phù hợp cho các ứng dụng âm thanh trực tiếp.
Kiến trúc
| Giai đoạn | Chi tiết |
|---|---|
| STFT | Conv1d (1 đến 258 kênh), reflection pad bên phải 64 |
| Encoder | 4x Conv1d + ReLU |
| LSTM | Hidden size 128, trạng thái được duy trì giữa các chunk |
| Decoder | Conv1d (128 đến 1) trên trạng thái ẩn LSTM, đầu ra sigmoid |
Kích thước mô hình: ~309K tham số, ~1.2 MB trên đĩa.
Máy trạng thái streaming
Bộ xử lý VAD streaming dùng máy trạng thái 4 trạng thái để tạo ra các đoạn giọng nói sạch:
- silence — không phát hiện giọng nói
- pendingSpeech — đã vượt ngưỡng onset, chờ thời lượng giọng nói tối thiểu
- speech — đoạn giọng nói đã xác nhận đang diễn ra
- pendingSilence — đã vượt ngưỡng offset, chờ thời lượng im lặng tối thiểu
Ngưỡng mặc định
- Onset:
0.5 - Offset:
0.35 - Thời lượng giọng nói tối thiểu:
0.25s - Thời lượng im lặng tối thiểu:
0.1s
Cách dùng CLI
# Streaming VAD
.build/release/speech vad-stream recording.wav
# Custom thresholds
.build/release/speech vad-stream recording.wav --onset 0.6 --offset 0.3
# Minimum durations
.build/release/speech vad-stream recording.wav --min-speech 0.5 --min-silence 0.2
# Choose engine
.build/release/speech vad-stream recording.wav --engine coreml
Tùy chọn
| Tùy chọn | Áp dụng cho | Mô tả |
|---|---|---|
--onset | Cả hai | Ngưỡng xác suất bắt đầu giọng nói |
--offset | Cả hai | Ngưỡng xác suất kết thúc giọng nói |
--min-speech | Streaming | Thời lượng tối thiểu của đoạn giọng nói (giây) |
--min-silence | Streaming | Thời lượng im lặng tối thiểu để kết thúc đoạn (giây) |
--engine | Streaming | Engine suy luận: mlx hoặc coreml |
--json | Cả hai | Định dạng đầu ra JSON |
Với các ứng dụng thời gian thực, hãy dùng speech vad-stream với Silero VAD. Mô hình Pyannote yêu cầu toàn bộ tệp âm thanh và phù hợp hơn cho xử lý theo lô offline khi độ chính xác là ưu tiên.
Tải mô hình
| Mô hình | Backend | Kích thước | 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 PyannoteVADModel.fromPretrained()
let segments = pyannote.detectSpeech(audio: samples, sampleRate: 16000)
for segment in segments {
print("\(segment.startTime)s - \(segment.endTime)s")
}
// Streaming VAD (Silero)
let silero = try await SileroVADModel.fromPretrained()
let processor = StreamingVADProcessor(model: silero, config: .sileroDefault)
for event in processor.process(samples: audioBuffer) {
switch event {
case .speechStarted(let time):
print("Speech started at \(time)s")
case .speechEnded(let segment):
print("Speech: \(segment.startTime)s - \(segment.endTime)s")
}
}
Cũng có sẵn trên Android, Linux và Windows qua ONNX Runtime.