在本文中,我将带领你经历构建一个助手的步骤,这个助手允许你与一个开源LLM进行语音互动。所有组件都在你的电脑上本地运行。
架构
架构涉及三个独立组件:
聊天服务
聊天服务运行一个名为HuggingFaceH4/zephyr-7b-alpha的开源大型语言模型(LLM)。该服务通过POST请求接收一个提示,经过LLM处理后,将输出作为请求响应返回。
在…/chat_service/server/目录下,将chat_server_config.xml.example重命名为chat_server_config.xml。
然后你可以使用以下命令启动聊天服务器:
python .\chat_server.py
当服务首次运行时,它需要几分钟才能启动,因为需要从HuggingFace网站下载大文件并存储在本地缓存目录中。
你将从终端获得一个确认,表明服务正在运行
将app_config.xml.example重命名为app_config.xml。启动网页聊天服务。
.\start_interface.sh
浏览到本地地址 localhost:8000
你应该能够通过文字界面与本地运行的LLM进行交互:
语音助手服务
语音助手服务是语音转文本和文本转语音转换发生的地方。
前往 …/voice_assistant/server/。
将 voice_assistant_service_config.xml.example 重命名为 voice_assistant_service_config.xml。
助手通过播放问候语开始,表明它正在听取用户的指令。问候语文本在 voice_assistant_config.xml 中配置,位于元素 <welcome_message> 下:
这个程序能够将文本转换为口语音频的文本转语音引擎是pyttsx3。根据我的经验,这个引擎用一种相当自然的语调说话,无论是英语还是法语。与依赖API调用的其他包不同,它在本地运行。
一个名为facebook/seamless-m4t-v2-large的模型执行语音到文本的推理。当第一次运行voice_assistant_service.py时,模型权重会被下载。
voice_assistant_service.main()中的主循环执行以下任务:
end_of_conversation = False
while not end_of_conversation:
transcription = get_sentence(
mic_stream, stt_processor, stt_model, device, config.sampling_rate,
config
)
if transcription.lower().replace('.', '').replace('!', '') == config.end_of_conversation_text.lower():
logging.info(f"voice_assistant_service.main(): End of conversation")
end_of_conversation = True
else:
sentence_is_gibberish = False
if transcription[0] == '[':
sentence_is_gibberish = True
for prefix in config.gibberish_prefix_list:
if transcription.lower().startswith(prefix):
sentence_is_gibberish = True
if len(transcription) > 15 and not sentence_is_gibberish:
response = send_request_to_chat_service(config, transcription)
logging.info(f"voice_assistant_service.main(): response = {response}")
play_message(response, engine, config)
goodbye(engine, config)
唤醒词服务
最后一个组件是一个持续监听用户麦克风的服务。当用户说出唤醒词时,系统调用会启动语音助手服务。唤醒词服务运行的模型比语音助手服务的模型小。因此,持续运行唤醒词服务是有意义的,而语音助手服务只在我们需要时才启动。
克隆项目后,移动到…/wakeword_service/server。
将 wakeword_service_gui_config.xml.example 重命名为 wakeword_service_gui_config.xml。
将 command.bat.example 重命名为 command.bat。你需要编辑 command.bat,使虚拟环境激活和调用 voice_assistant_service.py 与你的目录结构相对应。
你可以通过以下调用来启动服务:
python gui.py
唤醒词检测服务的核心是开源项目openwakeword。在几个唤醒词模型中,我选择了"hey jarvis"模型。我发现仅仅说"Jarvis?"就会触发检测。
每当唤醒词被检测到时,会根据配置文件中<command_on_wakeword>元素的指定调用一个命令文件。在我们的例子中,command.bat文件激活了虚拟环境并启动了语音助手服务。
如果你希望将唤醒词检测服务用于其他事物,你可以编辑 command.bat 文件以使其启动你想要的任何程序。
当检测到唤醒词时,唤醒词检测服务会发出两声哔哔的音频信号,以表明它已被触发。这种快速反馈告诉用户他们必须等待,因为文本到语音和语音到文本的模型加载到计算机的 GPU 中,这可能需要几秒钟。当两个模型都加载好后,语音助手服务播放问候语,对话就可以开始了。对话结束后,语音助手服务终止,唤醒词检测服务会发出另外两声哔哔信号。
当这三个组件安装并测试好之后,我们可以启动聊天和唤醒词检测服务。唤醒词检测服务将不断监听麦克风。当检测到唤醒词(“Jarvis?”)时,它会启动语音助手服务。你可以大声提问并收到口头答复。当检测到结束对话的短语(“谢谢再见”)时,语音助手服务结束。
与助手的互动示例
这是一个与语音助手互动的例子:
“Jarvis?” [哔-哔]
[加载语音助手模型时的几秒钟沉默]
“你好!我能帮你什么忙?”
“土星的环是由什么组成的?”
“土星的环主要由冰颗粒组成,大部分是由水冰制成。但是,环中还含有较少量的其他冰,如氨冰和岩石碎片。环的确切组成根据与土星的距离而有所不同,内环更加致密并且由较小颗粒组成,而外环更分散并包含较大的冰颗粒。”
“给我讲讲电影 '回到未来' 的情节。”
“电影‘回到未来’讲述了高中生马蒂·麦克弗莱的故事,他不小心被送回到1955年,乘坐着他那位古怪科学家朋友达克·布朗创造的时间旅行的德洛林汽车。马蒂必须在过去应对挑战,同时尝试修复对现在的损害,阻止他的青少年母亲爱上他的青少年父亲。一路上,马蒂交到了较年轻版本的达克·布朗,并帮他克服了一个个人悲剧。这部电影探索了命运、家庭以及改变过去的后果等主题。”
“谢谢再见”
“再见” [哔-哔]
结论
在这个项目中,我们实现了一个语音助手系统,包括唤醒词检测服务、语音助手服务和聊天服务。这些组件中的每一个都是可用于其他项目的独立构建块。