自动语音识别(ASR)是将口语语音转换为文本的过程,是机器学习领域一个非常重要且蓬勃发展的领域。ASR 算法在几乎所有智能手机上运行,并且越来越多地嵌入到专业工作流程中,例如用于护士和医生的数字助理。由于 ASR 算法旨在供客户和最终用户直接使用,因此在面对各种语音模式(不同口音、音高和背景音频条件)时,验证它们的行为是否符合预期非常重要。
使用 gradio,您可以轻松构建 ASR 模型的演示,并将其分享给测试团队,或者通过设备上的麦克风自行测试。
本教程将展示如何获取一个预训练的语音转文本模型,并使用 Gradio 界面部署它。我们将从一个**_全上下文_**模型开始,其中用户在预测运行之前说出整个音频。然后我们将修改这个演示,使其变为**_流式_**的,这意味着音频模型将在您说话时实时转换语音。
确保您已经[安装](/getting_started)了 gradio Python 包。您还需要一个预训练的语音识别模型。在本教程中,我们将使用 2 个 ASR 库来构建演示:
pip install torch transformers torchaudio)确保您至少安装了其中一个,以便能够跟着本教程进行操作。您还需要在系统上安装 ffmpeg(如果您尚未安装),以便处理来自麦克风的文件。
以下是如何构建实时语音识别(ASR)应用程序的方法:
首先,您需要有一个 ASR 模型,要么是您自己训练的,要么是下载的预训练模型。在本教程中,我们将首先使用来自模型 whisper 的预训练 ASR 模型。
这是从 Hugging Face transformers 加载 whisper 的代码。
from transformers import pipeline
p = pipeline("automatic-speech-recognition", model="openai/whisper-base.en")就是这样!
我们将首先创建一个*全上下文* 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",
api_name="predict",
)
demo.launch()
transcribe 函数接受一个参数 audio,它是一个用户录制的音频的 numpy 数组。pipeline 对象期望这是 float32 格式,所以我们首先将其转换为 float32,然后提取转录的文本。
要使其成为*流式*演示,我们需要进行以下更改:
Audio 组件中设置 streaming=TrueInterface 中设置 live=Truestate 以存储用户的录制音频您还可以在界面中设置 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,
api_name="predict"
)
demo.launch()
请注意,我们现在有一个状态变量,因为我们需要跟踪所有的音频历史记录。每次有新的小块音频时,transcribe 都会被调用,但我们还需要在状态中跟踪到目前为止所说的所有音频。当界面运行时,transcribe 函数被调用,其中包含 stream 中所有先前说过的音频记录,以及作为 new_chunk 的新音频块。我们返回新的完整音频以存储回其当前状态,并且还返回转录文本。在这里,我们天真地将音频附加在一起,并对整个音频调用 transcriber 对象。您可以想象更有效的处理方式,例如在接收到新的音频块时仅重新处理最后 5 秒的音频。
现在 ASR 模型将在您说话时运行推理!