Skip to content

VAD 语音活动检测 ​

VAD(Voice Activity Detection)判断连续音频中的哪些时间段包含语音。它通常输出逐帧语音概率或若干组起止时间,供录音切片、流式识别、唤醒后监听、通话检测和功耗控制使用。

VAD 不负责识别说了什么,也不等同于对话结束判断。工程上的关键工作不是得到一个概率,而是把概率、连续帧、前后缓存和业务超时组合成稳定的语音片段。

VAD 状态与数据流

概念边界 ​

模块回答的问题典型输出
降噪如何减少回声、稳态噪声和增益波动增强后的 PCM
VAD当前音频是否包含语音概率、开始和结束时间
唤醒词检测是否说出了指定短语唤醒事件、置信度
ASR说话内容是什么文本、时间戳、识别状态
端点检测本轮输入是否可以提交识别或理解句段完成事件
轮次检测用户是否已经表达完、系统能否接话交互轮次状态

VAD 可以为端点检测提供声学依据,但两者不能直接画等号。例如用户说“帮我查一下……明天的天气”,中间停顿可能已经超过 VAD 的静音阈值,端点策略仍应结合 ASR 状态、语义完整性和最大等待时间决定是否结束本轮。

从概率到语音片段 ​

神经网络 VAD 通常按固定帧读取 PCM,并为每帧输出 0~1 的语音概率。生产系统还需要一层分段器,把抖动的帧级结果变成稳定事件:

  1. 保留一段环形前置缓存,避免检测确认期间吞掉字头。
  2. 概率连续达到起始条件后进入说话状态,并回补前置音频。
  3. 说话期间持续输出或缓存音频,不因单帧低概率立即截断。
  4. 低概率持续达到结束条件后关闭片段,并保留尾部音频。
  5. 丢弃过短片段;过长片段则在可接受的静音处切开,或按最大时长强制切分。

起始阈值和结束阈值最好分开设置。起始条件严格一些可以降低噪声误触发,结束条件宽松一些可以避免音节间短暂停顿导致频繁切段。这种滞回策略比单一阈值稳定。

text
未说话 --连续高概率--> 候选语音 --满足最短语音--> 说话中
说话中 --连续低概率--> 候选结束 --满足最短静音--> 未说话
候选语音 --概率回落--> 未说话
候选结束 --概率恢复--> 说话中

主要参数 ​

参数控制的行为过小的表现过大的表现
start_threshold进入语音状态的概率门槛噪声、音乐容易触发轻声和远场语音漏检
end_threshold判断语音结束的概率门槛片段容易拖尾音节间停顿容易被截断
min_speech_duration_ms接受片段所需的最短语音时长咳嗽、敲击声成为片段“嗯”“对”等短词被丢弃
min_silence_duration_ms结束前要求的连续静音一句话被切成多段提交延迟增加、两句话粘连
speech_pad_ms片段前后保留的音频字头、尾音被切掉相邻片段重叠、附带噪声增多
max_speech_duration_s单片段允许的最长时长长句被频繁切分缓存、识别延迟和内存增长

参数之间会互相影响。起点丢字不一定需要降低模型阈值,先检查前置缓存通常更安全;句尾拖延也不一定要缩短静音时长,还要确认 ASR 是否需要更多上下文。

放在语音链路的什么位置 ​

常见链路是:

text
Mic -> AEC -> 波束形成 / NS -> AGC -> VAD -> KWS / ASR / 录音切片

这个顺序不是固定模板,但有几个约束:

  • 有设备播放声时,先让 AEC 去掉扬声器回采,否则播放内容会持续触发 VAD。
  • 强降噪可能破坏轻声和辅音,VAD 应同时在原始音频与增强音频上做对比验证。
  • AGC 在非语音阶段抬升底噪会增加误触发,应限制静音增益或让 AGC 使用 VAD 状态。
  • VAD 若运行在 16 kHz,而采集链路是 48 kHz,应明确使用哪一路重采样结果,不能只改采样率参数。

长录音转写 ​

长录音可以先经 VAD 切成语音片段,再交给非流式 ASR。这样能跳过大段静音并控制单次识别长度,但切分边界必须保留上下文,过度切碎会让标点、说话人和语言模型上下文变差。

流式语音交互 ​

流式系统通常持续把音频送给 VAD。检测到开始后创建或激活 ASR 流,检测到结束后等待端点策略确认,再提交最终结果。相关运行模式见 sherpa-onnx 识别运行模式。

唤醒后监听 ​

设备被唤醒后,VAD 可以判断用户是否开始说话以及何时停止。如果唤醒词和命令紧邻,应保留唤醒前后的共享缓冲,不能在唤醒事件发生时清空整段音频。

流式实现要点 ​

每路会话需要独立维护模型状态、当前分段状态和环形缓存:

text
Session
├── model_state       # 神经网络的历史状态
├── segment_state     # idle / speech / ending
├── pre_roll_buffer   # 字头保护
├── current_segment   # 当前语音片段
└── sample_counter    # 计算准确时间戳

以下情况必须重置状态:新文件、新通话、新设备流、采样率改变、时间戳跳变或中间音频丢失。不能把不同用户的音频交错送入同一个有状态实例,也不能为了并行推理打乱同一会话的帧顺序。

时间戳应以累计采样点为基准,而不是按回调次数估算。设备回调的块大小可能变化,网络抖动也可能造成空洞;只有采样点计数能稳定映射回原音频。

如何评估 ​

帧级准确率不能完整反映工程体验。背景静音帧通常远多于语音帧,即使模型总是输出静音,也可能得到看似较高的准确率。评估至少分三层:

层级指标说明
帧级Precision、Recall、F1、ROC判断语音与非语音的基础能力
片段级漏检率、误检率、碎片数、起止点偏差判断切片是否完整稳定
系统级首字丢失率、句尾截断率、误触发次数/小时、提交延迟、WER判断 VAD 对真实业务的影响

测试集要覆盖安静近场、远场轻声、车噪、风噪、键盘声、音乐和电视人声、设备播放、双讲、儿童声、短词、长停顿以及不同麦克风增益。训练集上的阈值不能直接视为设备量产参数。

排错闭环 ​

现象优先检查调整顺序
第一个字缺失前置缓存、回调延迟、起始确认时长先增大前置缓存,再调整起始阈值
句尾被截断尾部缓存、最短静音、降噪失真先补尾部,再延长静音确认
一句话被切碎结束阈值、最短静音、丢帧先排除丢帧,再增加静音确认
音乐或电视持续触发AEC、数据集覆盖、阈值先确认回声路径,再评估模型或融合策略
轻声漏检输入幅度、AGC、模型概率分布先检查采集幅度,再降低阈值或补数据
结束很慢最短静音、尾部 padding、业务端点策略分清 VAD 延迟和语义端点等待
多路并发结果串线状态实例、缓冲归属、重置时机每会话独立状态并补充隔离测试

排错时同时保存原始 PCM、前处理后 PCM、逐帧概率、状态变化和最终时间戳。只看最终切片无法区分是模型判断错误、平滑策略错误,还是音频链路丢帧。

方案选择 ​

能量阈值适合按键录音、安静近场或资源极紧张的设备,但对非平稳噪声和背景人声较敏感。WebRTC VAD 等传统方案体积小、依赖少,适合先建立低成本基线。神经网络 VAD 对复杂场景通常更稳,但需要模型运行时、状态管理和目标设备基准测试。

如果需要一个可离线运行、支持流式状态并已有多语言预训练模型的方案,可以继续阅读 Silero VAD。如果系统已经使用 sherpa-onnx,应同时检查其模型包版本、接口参数和 ASR 端点配置,不能只替换模型文件。

总结 ​

VAD 的输出只是语音概率,稳定的工程结果来自模型、分段状态机、前后缓存和业务端点策略的组合。调优时先固定音频链路和状态管理,再看概率分布,最后按起点、终点、碎片、误触发和系统延迟逐项收敛。

别急,先让缓存热一下。