Gradio 月活用户达到 100 万的旅程!

阅读更多
Gradio logo
  1. 流式传输
  2. 实时语音识别

实时语音识别

简介

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

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

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

先决条件

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

  • Transformers(为此,pip install torch transformers torchaudio

请确保您至少安装了其中一个,以便您可以按照本教程进行操作。如果您还没有 ffmpeg,您还需要 在您的系统上安装 它,以处理来自麦克风的文件。

以下是如何构建实时语音识别 (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 模型将运行推理了!