跳到正文
技术吧
返回

构建本地语音助手:Whisper + Ollama + Bark

更新于:

今天,我们更进一步,不仅实现了大型语言模型的对话功能,还添加了听力和口语功能。这个想法很简单:我们将创建一个语音助手,让人想起标志性钢铁侠电影中的贾维斯或星期五,它可以在你的计算机上离线运行。由于这是一个介绍性教程,我将用 Python 实现它,并使其对于初学者来说足够简单。最后,我将提供一些有关如何扩展应用程序的指导。

需要哪些技术?

首先,你应该设置一个虚拟 Python 环境。为此,你有多种选择,包括 pyenv、virtualenv、poetry 以及其他具有类似用途的选项。就我个人而言,由于我的个人喜好,我将在本教程中使用 Poetry。以下是你需要安装的几个重要库:

这里最关键的组件是大型语言模型 (LLM) 后端,我们将使用 Ollama。 成为 被广泛认为是离线运行和服务LLM的流行工具。

系统技术架构

好的,如果一切都已设置完毕,让我们继续下一步。下面是我们应用程序的整体架构,它基本上包含 3 个主要组件:

工作流程很简单:录制语音、转录为文本、使用 LLM 生成响应,并使用 Bark 发声响应。

Whisper、Ollama 和 Bark 语音助手的序列图。

如何实现

实施从制作一个 文字转语音服务 基于 Bark,结合了从文本合成语音并无缝处理较长文本输入的方法,如下所示:

 import nltk  
 import torch  
 import warnings  
 import numpy as np  
 from transformers import AutoProcessor, BarkModel  
 ​  
 warnings.filterwarnings(  
     "ignore",  
     message="torch.nn.utils.weight_norm is deprecated in favor of torch.nn.utils.parametrizations.weight_norm.",  
 )  
 ​  
 ​  
 class TextToSpeechService:  
     def __init__(self, device: str = "cuda" if torch.cuda.is_available() else "cpu"):  
         """  
         Initializes the TextToSpeechService class.  
 ​  
         Args:  
             device (str, optional): The device to be used for the model, either "cuda" if a GPU is available or "cpu".  
             Defaults to "cuda" if available, otherwise "cpu".  
         """  
         self.device = device  
         self.processor = AutoProcessor.from_pretrained("suno/bark-small")  
         self.model = BarkModel.from_pretrained("suno/bark-small")  
         self.model.to(self.device)  
 ​  
     def synthesize(self, text: str, voice_preset: str = "v2/en_speaker_1"):  
         """  
         Synthesizes audio from the given text using the specified voice preset.  
 ​  
         Args:  
             text (str): The input text to be synthesized.  
             voice_preset (str, optional): The voice preset to be used for the synthesis. Defaults to "v2/en_speaker_1".  
 ​  
         Returns:  
             tuple: A tuple containing the sample rate and the generated audio array.  
         """  
         inputs = self.processor(text, voice_preset=voice_preset, return_tensors="pt")  
         inputs = {k: v.to(self.device) for k, v in inputs.items()}  
 ​  
         with torch.no_grad():  
             audio_array = self.model.generate(**inputs, pad_token_id=10000)  
 ​  
         audio_array = audio_array.cpu().numpy().squeeze()  
         sample_rate = self.model.generation_config.sample_rate  
         return sample_rate, audio_array  
 ​  
     def long_form_synthesize(self, text: str, voice_preset: str = "v2/en_speaker_1"):  
         """  
         Synthesizes audio from the given long-form text using the specified voice preset.  
 ​  
         Args:  
             text (str): The input text to be synthesized.  
             voice_preset (str, optional): The voice preset to be used for the synthesis. Defaults to "v2/en_speaker_1".  
 ​  
         Returns:  
             tuple: A tuple containing the sample rate and the generated audio array.  
         """  
         pieces = []  
         sentences = nltk.sent_tokenize(text)  
         silence = np.zeros(int(0.25 * self.model.generation_config.sample_rate))  
 ​  
         for sent in sentences:  
             sample_rate, audio_array = self.synthesize(sent, voice_preset)  
             pieces += [audio_array, silence.copy()]  
 ​  
         return self.model.generation_config.sample_rate, np.concatenate(pieces)

现在我们有了 文字转语音服务 设置完毕后,我们需要准备 Ollama 服务器来提供大型语言模型 (LLM) 服务。为此,你需要执行以下步骤:

完成这些步骤后,你的应用程序将能够使用 Ollama 服务器和 Llama-2 模型生成对用户输入的响应。 接下来,我们将转向主要应用程序逻辑。首先,我们需要初始化以下组件:

现在,让我们定义必要的函数:

然后,我们定义主应用程序循环。主应用程序循环引导用户完成对话交互,如下所示:

  1. 系统会提示用户按 Enter 键开始记录其输入。
  2. 一旦用户按下 Enter 键, 录音音频 在单独的线程中调用该函数来捕获用户的音频输入。
  3. 当用户再次按 Enter 停止录音时,将使用以下命令转录音频数据: 录制 功能。
  4. 然后将转录的文本传递到 获取llm_响应 函数,它使用 Llama-2 语言模型生成响应。
  5. 生成的响应被打印到控制台并使用以下命令回放给用户 播放音频 功能。

结果

一旦所有东西都放在一起,我们就可以运行应用程序。该应用程序在我的 MacBook 上运行速度相当慢,因为 Bark 模型很大,即使是较小的版本也是如此。对于那些拥有支持 CUDA 的计算机的人来说,它可能运行得更快。以下是我们应用程序的主要功能:

对于那些想要将此应用程序提升到生产就绪状态的人,建议进行以下增强:

最后,我们完成了简单的语音助手应用程序。语音识别、语言建模和文本转语音技术的结合展示了我们如何构建听起来很困难,但实际上可以在计算机上运行的东西。让我们享受编码的乐趣,不要忘记订阅我的博客,这样你就不会错过最新的人工智能和编程文章。


分享本文:

上一篇
OpenAI 的 DevDay 为 AI 应用程序开发人员带来了实时 API
下一篇
AudioLDM:彻底改变文本到音频的生成质量