Voice Activity Detection (VAD):用 Python 检测「有没有人在说话」

语音应用的第一道关卡,做好它能省一大半识别成本

返回教程列表
进阶9 分钟

Voice Activity Detection (VAD):用 Python 检测「有没有人在说话」

语音应用的第一道关卡,做好它能省一大半识别成本

Voice Activity Detection(VAD,语音活动检测)判断音频里哪段是人声、哪段是静音/噪声。它是语音应用的基础环节,做好能大幅降低后续 ASR 的成本和延迟。本文用 Python 实战 webrtcvad 和 Silero VAD。

Voice Activity Detection:用 Python 检测人声

做语音应用,第一个该解决的不是「识别说了什么」,而是「这段音频里到底有没有人在说话」。这就是 VAD(Voice Activity Detection,语音活动检测)干的事。

为什么重要?因为把静音和噪声段也丢给语音识别(ASR),既费钱又费时还容易出错。 VAD 先把人声段切出来,后面才高效。

它解决什么

一段录音里通常混着:人说话、停顿静音、背景噪声。VAD 的任务是给每一小段打标签——「这是语音」还是「这不是语音」。

典型用途:

  • 实时语音助手:检测到用户开始说话才唤醒、说完了才提交识别。
  • 降低 ASR 成本:只把人声段送去识别,静音不送。
  • 语音分段:长录音按说话/停顿切成片段。
  • 方案一:webrtcvad(轻量、快)

    Google WebRTC 项目里的 VAD,极轻量,纯靠信号特征判断,不用模型,速度飞快。

    python
    import webrtcvad
    vad = webrtcvad.Vad(2)  # 0-3,数字越大越激进(越容易判为非语音)

    音频需是 16kHz/8kHz、16-bit 单声道,按 10/20/30ms 分帧

    is_speech = vad.is_speech(frame_bytes, sample_rate=16000)

    优点:快、零依赖模型、适合实时和资源受限场景。 缺点:吵的环境里容易误判——它分不清「人声」和「像人声的噪声」。

    方案二:Silero VAD(准、抗噪)

    基于神经网络的 VAD,准确率明显更高,尤其抗噪声。模型也很小,CPU 上就能实时跑。

    python
    import torch
    model, utils = torch.hub.load('snakers4/silero-vad', 'silero_vad')
    (get_speech_timestamps, _, read_audio, _, _) = utils

    wav = read_audio('audio.wav', sampling_rate=16000) speech_ts = get_speech_timestamps(wav, model, sampling_rate=16000)

    speech_ts: [{'start': 12000, 'end': 35000}, ...] 人声段的采样点区间

    优点:准、抗噪、多语言通用、还轻。 缺点:比 webrtcvad 重一点(要加载模型),但绝大多数场景这点开销值得。

    怎么选

    场景推荐

    资源极受限 / 嵌入式webrtcvad 环境安静、要极致快webrtcvad 有噪声 / 要准Silero VAD 大多数应用Silero VAD

    实话说,除非你跑在很弱的设备上,默认选 Silero VAD,省心又准。

    实战中的坑

    采样率和格式要对。 webrtcvad 对输入格式很挑(16/8kHz、16-bit、单声道、固定帧长),不对就报错或乱判。先把音频转成它要的格式。

    别指望 VAD 解决一切。 强噪声、多人同时说话这些复杂场景,VAD 也会犯错。它是「第一道粗筛」,不是完美分离器。

    加一点缓冲。 人声段前后留一点余量(padding),别把刚要说的第一个字或尾音切掉了。

    接下来

    VAD 切出人声段后,下一步就是送去 ASR 做识别。如果要做多语种识别,可以接着看 多语种语音识别,或用 OpenAI Whisper API

    小结

    VAD 是语音流水线里最容易被跳过、又最不该跳过的一环。做好它,后面的识别又快又省。新项目无脑选 Silero VAD 起步基本不会错。

    相关工具

    Silero VADwebrtcvadWhisperPyTorch