1. 流式处理
  2. 实时语音识别

实时语音识别

介绍

自动语音识别(ASR),即将口语转换为文本,是机器学习中一个非常重要且蓬勃发展的领域。ASR算法几乎在每部智能手机上运行,并且越来越多地嵌入到专业工作流程中,例如护士和医生的数字助手。由于ASR算法设计为直接由客户和最终用户使用,因此验证它们在面对各种语音模式(不同的口音、音调和背景音频条件)时是否按预期行为非常重要。

使用gradio,你可以轻松构建你的ASR模型的演示,并与测试团队分享,或者通过设备上的麦克风自己进行测试。

本教程将展示如何采用预训练的语音转文本模型并通过Gradio界面进行部署。我们将从一个全上下文模型开始,用户在此模型下在预测运行前说出整个音频。然后我们将调整演示以使其流式,这意味着音频模型将在您说话时转换语音。

先决条件

确保你已经安装gradio Python包。你还需要一个预训练的语音识别模型。在本教程中,我们将从两个ASR库构建演示:

  • Transformers(为此,pip install torch transformers torchaudio

确保您至少安装了其中一个,以便能够跟随教程。如果尚未安装,您还需要在系统上安装ffmpeg installed on your system,以便处理来自麦克风的文件。

以下是构建实时语音识别(ASR)应用程序的方法:

  1. 设置Transformers ASR模型
  2. 使用Transformers创建一个全上下文ASR演示
  3. 使用Transformers创建一个流式ASR演示

1. 设置Transformers ASR模型

首先,你需要有一个自己训练的ASR模型,或者你需要下载一个预训练模型。在本教程中,我们将从使用whisper模型中的预训练ASR模型开始。

这是从Hugging Face transformers加载whisper的代码。

from transformers import pipeline

p = pipeline("automatic-speech-recognition", model="openai/whisper-base.en")

就这样!

2. 使用Transformers创建一个全上下文ASR演示

我们将从创建一个全上下文的ASR演示开始,在这个演示中,用户在使用ASR模型进行推理之前会说出完整的音频。使用Gradio非常简单——我们只需在上面的pipeline对象周围创建一个函数。

我们将使用gradio内置的Audio组件,配置为从用户的麦克风获取输入并返回录制的音频文件路径。输出组件将是一个普通的Textbox

import gradio as gr
from transformers import pipeline
import numpy as np

transcriber = pipeline("automatic-speech-recognition", model="openai/whisper-base.en")

def transcribe(audio):
    sr, y = audio
    
    # Convert to mono if stereo
    if y.ndim > 1:
        y = y.mean(axis=1)
        
    y = y.astype(np.float32)
    y /= np.max(np.abs(y))

    return transcriber({"sampling_rate": sr, "raw": y})["text"]  

demo = gr.Interface(
    transcribe,
    gr.Audio(sources="microphone"),
    "text",
)

demo.launch()

transcribe 函数接受一个参数 audio,这是用户录制的音频的 numpy 数组。pipeline 对象期望它以 float32 格式输入,因此我们首先将其转换为 float32,然后提取转录的文本。

3. 使用Transformers创建一个流式ASR演示

为了使这成为一个流式演示,我们需要进行以下更改:

  1. Audio组件中设置streaming=True
  2. Interface中设置live=True
  3. 向界面添加一个state来存储用户的录音

    提示: 您也可以在界面中设置 `time_limit` 和 `stream_every` 参数。`time_limit` 限制了每个用户的流媒体可以占用的时间。默认是30秒,因此用户无法流式传输超过30秒的音频。`stream_every` 参数控制数据发送到您的函数的频率。默认情况下是0.5秒。

请看下面。

import gradio as gr
from transformers import pipeline
import numpy as np

transcriber = pipeline("automatic-speech-recognition", model="openai/whisper-base.en")

def transcribe(stream, new_chunk):
    sr, y = new_chunk
    
    # Convert to mono if stereo
    if y.ndim > 1:
        y = y.mean(axis=1)
        
    y = y.astype(np.float32)
    y /= np.max(np.abs(y))

    if stream is not None:
        stream = np.concatenate([stream, y])
    else:
        stream = y
    return stream, transcriber({"sampling_rate": sr, "raw": stream})["text"]  

demo = gr.Interface(
    transcribe,
    ["state", gr.Audio(sources=["microphone"], streaming=True)],
    ["state", "text"],
    live=True,
)

demo.launch()

注意,我们现在有一个状态变量,因为我们需要跟踪所有的音频历史。transcribe 每当有新的小段音频时就会被调用,但我们还需要在状态中跟踪到目前为止所说的所有音频。随着界面的运行,transcribe 函数会被调用,其中包含 stream 中所有先前说过的音频记录以及新的音频片段 new_chunk。我们返回新的完整音频以存储回其当前状态,并且我们还返回转录结果。在这里,我们天真地将音频拼接在一起,并在整个音频上调用 transcriber 对象。你可以想象更高效的处理方式,例如每当接收到新的音频片段时,只重新处理最后5秒的音频。

现在,ASR模型将在你说话时进行推理!