pipecat- VAD

2 阅读1分钟

pipecat- VAD

前言

pipecat的VAD算法用了两个主要的类,分别是silero VAD类,一个是pipecat框架的适配器类。其中文的意思就是语音活动检测,VAD(Voice Activity Detection)。

SileroOnnxModel

采用了 Silero VAD 这个算法,我用netron 看了一下网络结构图(silero_vad.onnx)。如下图所示,我会重点关注一下输入输出。

image

如模型结构图所示,输入分为三部分,分别是input、state 、 sr。

  • input 是输入的音频块,维度为[batch_size, n],根据sr这个采样频率分为,如果是16KHZ,则是512,如果是8Khz则是256。float格式,在[-1,1]之间。其实最终还要加上上次尾巴,因此最终是512+64或者256+32
  • state 上下文状态,[2,batch_size,128], 保存之前的上下文状态信息。这里的2是指2层LSTM网络。
  • sr 是采样率,要么是16KHZ,要么是8KHZ。

输出分为两部分。

  • 人声置信度,判断这一小块频率是人声的概率
  • state,新的状态,也就是输入中提到的之前的上下文状态。

关键概念理解:采样频率是每秒中采集16000个数值。也就是每32ms做一次判断。

SileroVADAnalyzer​&TransportParams

这里其实在把传过来的音频数据转换成silero 推理模型需要的格式。

此外:vad_analyzer=SileroVADAnalyzer(params=VADParams(stop_secs=0.2))​,通过连续0.2s没有检测人声的情况会结束。

配置文件设置音频、视频等参数

判断语句停止

模型输入大语言模型之前会再次对VAD的是否结束做个判断,这里采用的是语义是否完整的方式。


    messages = [
        {
            "role": "system",
            "content": "You are a helpful LLM in a WebRTC call. Your goal is to demonstrate your capabilities in a succinct way. Your output will be spoken aloud, so avoid special characters that can't easily be spoken, such as emojis or bullet points. Respond to what the user said in a creative and helpful way. You are also able to describe images.",
        },
    ]

    context = LLMContext(messages)
    user_aggregator, assistant_aggregator = LLMContextAggregatorPair(
        context,
        user_params=LLMUserAggregatorParams(
            user_turn_strategies=UserTurnStrategies(
                stop=[TurnAnalyzerUserTurnStopStrategy(turn_analyzer=LocalSmartTurnAnalyzerV3())]
            ),
        ),
    )

smart-turn-v3.2-cpu.onnx​ 这个模型作文文本语句完整性判断。

VAD算法只是静音检测判断,所以无法区分我说完了和我只是喘口气的区别。所以需要smart-turn-v3.2-cpu​ 这种模型做判断

这个模型只接受输入是8s的音频

  • 太长:只取最后 8 秒。因为判断“是不是刚说完”,只要听刚才那几秒就够了,很久以前的话不重要。
  • 太短:在前面补静音(Pad zeros)。保持时间轴的对齐。

通过WhisperFeatureExtractor​ 提取听觉特征。这是Hugging Face Transformers库中的Whisper 模型进行特征提取。

        # Process audio using Whisper's feature extractor
        inputs = self._feature_extractor(
            audio_array,  #原始的数字信号
            sampling_rate=16000, # 每秒是16000个数据
            return_tensors="np", #返回numpy格式
            padding="max_length",# 填充为最大尺寸
            max_length=8 * 16000,,# 输出长度为8×16000
            truncation=True, #超出部分截断
            do_normalize=True,# 标准化
        )

所以是一个 input_features是log-mel 声谱图。80行 x 800列 的大矩阵。

参考文档:huggingface.co/pipecat-ai/…

总结

这篇文章主要帮助自己梳理一下VAD功能,通过这篇文章可以知道VAD算法一般需要两个模型进行联合判断,第一个是判断是否存在人声,第二个判断是停顿期间是因为卡断还是确实是话已经说完。