rnvad:把 VAD 压到 15KB 能用吗?与 Silero、TEN VAD 的实测对比
rnvad 是一个 12,897 参数的语音活动检测模型,通过知识蒸馏从 Silero VAD v4 训练而来。
核心数据:
- 体积是 Silero 的1/12,TEN VAD 的1/6
- 中文对话帧级 F1:0.892(Silero 0.908,TEN VAD 0.909)——差距 2%
- 噪声 -5dB 下准确率:90.7%(Silero 84.8%,TEN VAD 83.2%)——反超 6~7 个百分点
- 纯 C99 实现,零依赖,INT8 量化后仅 15.3 KB
它不是在所有场景下都更好。干净语音和低噪声下它不如大模型。但当你需要一个能塞进 MCU、不依赖 ONNX Runtime、在嘈杂环境下还能用的 VAD——这个体积精度比值得考虑。
为什么做这个
嵌入式 VAD 的需求很明确:体积小、延迟低、不依赖 GPU。现有方案要么太大(Silero 628KB ONNX),要么需要复杂的前端(TEN VAD 依赖 FBank + LSTM)。我想验证一个假设:DSP 手工特征 + 极小 GRU 能否通过蒸馏达到接近大模型的判别能力?
16kHz 音频 → 34维 DSP 特征(Bark 能量 + F0 + 非平稳度)→ 2层 GRU(h=32) → sigmoid三方对比
模型规格
| rnvad | Silero VAD v4 | TEN VAD | |
|---|---|---|---|
| 架构 | GRU (h=32, l=2) | STFT+Conv+LSTM | SepConv2D+2×LSTM |
| 参数量 | 12,897 | 155,908 (12×) | 75,516 (6×) |
| 文件体积 | 52.8 KB | 628.8 KB | 308.1 KB |
| 帧移 | 32 ms | 32 ms | 10 ms |
| 输入 | 34维 DSP 特征 | 512 raw PCM | 3×41 FBank |
| 依赖 | 无(纯 C99) | ONNX Runtime | ONNX Runtime |
| 实时倍率 | 323× | 586× | 254× |
三个模型都快到不是瓶颈(RTF < 4‰),但 rnvad 的优势在于零依赖部署——不需要 ONNX Runtime,交叉编译到 MCU 只需一个 C 编译器。
英文测试集:帧级精度(vs 教师标签)
在 LibriSpeech test-clean 200 条音频上,以 Silero 输出为参考标签:
| 帧级准确率 | MAE | |
|---|---|---|
| rnvad | 97.6% | 0.033 |
| Silero VAD | 100%(参考) | 0.000 |
| TEN VAD | 94.3% | 0.150 |
rnvad 作为学生,在干净语音上与教师的一致性达到 97.6%。TEN VAD 因为架构和训练数据不同,偏差更大。
中文对话测试集:帧级 F1
在 MDT2021S003 双人对话数据集上(20 clips × 5min,人工标注),测帧级 F1:
| 帧级 F1 | 标准差 | |
|---|---|---|
| rnvad | 0.892 | ±0.017 |
| Silero VAD | 0.908 | ±0.026 |
| TEN VAD | 0.909 | ±0.016 |
三者差距在 2% 以内。考虑到 rnvad 只用英文朗读数据训练,从未见过中文,这个结果说明 DSP 前端的语种无关性确实有效——Bark 频带能量和基频不依赖具体语种的频谱分布。
噪声鲁棒性:低 SNR 下的真正差距
这是最有意思的结果。在 LibriSpeech + MUSAN 噪声混合测试中:
| SNR | rnvad | Silero VAD | TEN VAD |
|---|---|---|---|
| Clean | 97.6% | 100.0% | 94.2% |
| 20 dB | 97.4% | 97.4% | 91.9% |
| 10 dB | 95.8% | 95.1% | 89.1% |
| 5 dB | 96.2% | 93.7% | 87.3% |
| 0 dB | 93.6% | 91.9% | 87.4% |
| -5 dB | 90.7% | 84.8% | 83.2% |
在 5dB 及以下,rnvad 全面超越两个更大的模型。-5dB 时领先 Silero 近 6 个百分点,领先 TEN VAD 7.5 个百分点。
为什么?两个可能的原因:
- DSP 特征的天然抗噪性:Bark 频带能量本质上是一种平滑的频谱表示,对窄带噪声不敏感。非平稳度特征(spectral flux)关注的是变化而非绝对能量,稳态噪声对它影响很小。
- 训练时的噪声增强:蒸馏数据在 SNR [-5, 25] dB 范围内做了增强,模型被迫在噪声中学会跟随教师的判断——相当于做了隐式的噪声归一化。
TEN VAD 官方测试集:PR 曲线
在 TEN VAD 官方发布的 30 个带人工标注测试文件上,三个模型的 Precision-Recall 曲线高度重叠。在 threshold=0.5 时:
| Precision | Recall | F1 | |
|---|---|---|---|
| rnvad | 0.894 | 0.944 | 0.919 |
| Silero VAD | 0.928 | 0.856 | 0.890 |
| TEN VAD | 0.886 | 0.935 | 0.910 |
rnvad 在高 recall 区间表现更好(得益于 DSP 前端对弱语音的敏感性),Silero 在高 precision 区间更优。
训练细节
| 项目 | 内容 |
|---|---|
| 教师 | Silero VAD v4(~6000h 多语种训练) |
| 语音 | LibriSpeech train-clean-100(英文有声书,~100h) |
| 噪声 | MUSAN(环境噪声、音乐,~1600 文件) |
| 增强 | SNR [-5, 25] dB,增益 [-12, 12] dB |
| 损失 | BCE(学生 vs 教师逐帧概率) |
| 优化 | Adam, lr=1e-3, batch=32, ~50 epochs |
只用了 100 小时英文数据。没有中文、没有多说话人、没有对话场景。模型在这些场景上的表现完全来自蒸馏迁移和 DSP 前端的泛化能力。
INT8 量化
对称 per-channel 量化,权重压缩至 int8,bias 保持 float32:
| F32 | INT8 | |
|---|---|---|
| 体积 | 50.4 KB | 15.3 KB |
| max Δprob | — | 0.003 |
15KB 的模型,概率偏差不超过 0.003。推理代码自动检测格式,无需修改调用方式。
段级评估与后处理
在中文对话测试集上,加入滞回后处理后的段级指标:
| rnvad + 滞回 | Silero VAD(原始) | |
|---|---|---|
| Seg Recall | 0.816 | 0.684 |
| Seg Precision | 0.744 | 0.572 |
| Seg F1 | 0.757 | 0.571 |
| 过分割(pred/GT) | 1.1× | 1.4× |
注意这里 Silero 用的是简单阈值(threshold=0.5),没有加滞回。滞回参数(onset=0.4, offset=0.3, hangover=8帧=256ms)对对话场景的提升非常显著:
| 后处理方式 | Seg F1 | Offset 延迟 |
|---|---|---|
| 简单阈值 0.5 | 0.591 | -1473 ms |
| 滞回后处理 | 0.757 | -393 ms |
256ms 的 hangover 恰好覆盖了对话中常见的句间停顿(呼吸、犹豫),避免了过度切割。
局限性
- Offset 精度:滞回使 offset 延迟约 393ms(教师只有 80ms)。对实时转录场景偏高。
- 极低 SNR:虽然 -5dB 下仍有 90.7%,但已经开始出现 false positive 上升。
- 单帧分辨率:32ms 帧移限制了对极短音节(<100ms)的检测精度。TEN VAD 的 10ms 帧移在这方面有天然优势。
- 训练数据单一:只用了英文朗读,对音乐人声、低语、远场拾音等场景未验证。
结论
这个实验回答了开头的问题:15KB 的 VAD 能用吗?要看场景。
- 干净、安静的环境:能用,但不如 Silero/TEN VAD,差 2-3 个百分点
- 噪声环境(SNR ≤ 5dB):不仅能用,而且比大模型更稳定
- 嵌入式部署:零依赖、15KB、纯 C99,这是它真正的差异化优势
模型本身并不比大模型"聪明"。噪声下的优势来自两个工程选择:DSP 手工特征天然抗稳态噪声,训练时的噪声增强让模型学会了在恶劣条件下跟随教师。这些选择在干净场景下没有回报,在噪声场景下才显现价值。
适合的场景:嵌入式设备、边缘计算、嘈杂环境(工厂、车载、户外)的低功耗唤醒。不适合的场景:对边界精度要求极高的语音转录前端。
下一步
- 换 Silero v6 做教师:当前用的是 v4,Silero 已经迭代到 v6,边界精度和多语种表现都有提升。用更强的教师重新蒸馏,上限也会涨。
- 多语种训练数据:目前只用了英文朗读,跨语种靠 DSP 前端硬扛。加入中文、日语、西班牙语等语种的数据做蒸馏。
- 更多场景覆盖:远场拾音、耳语、带背景音乐的播客、电话信道。这些声学条件和朗读差别大,目前没测试,不确定表现如何。
- 自适应 hangover:固定 256ms 对快节奏对话偏长,对演讲偏短。可以试根据模型输出的置信度动态调整。
测试数据:LibriSpeech test-clean (200 clips), MDT2021S003 中文对话 (20×5min), TEN VAD 官方测试集 (30 files), MUSAN 噪声库。所有评测脚本开源。