WeNet语音识别+Qwen-72B-Chat Bot+Sambert-Hifigan语音合成

WeNet语音识别+Qwen-72B-Chat Bot👾+Sambert-Hifigan语音合成

简介

利用 WeNet 进行语音识别,使用户能够通过语音输入与系统进行交互。接着,Qwen-72B-Chat Bot作为聊天机器人接收用户的语音输入或文本输入,提供响应并与用户进行对话。最后,系统利用 Sambert-Hifigan 进行语音合成,将机器人的响应转换为自然流畅的语音输出,使用户能够以语音方式接收机器人的回复。

特点

  1. 对话记忆功能: 该系统能够记忆和追踪用户和聊天机器人之间的对话历史。这使得用户能够在对话中随时回顾之前的交流内容,从而实现更连贯的对话和更好的交互体验。

  2. 多语音模型切换: 该系统支持多种语音模型的切换。用户可以根据需要选择不同的语音模型进行交互。这种多语音模型切换功能使得系统在不同语境下有更强的适用性和灵活性。

界面

体验一下

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

环境配置

在这里插入图片描述

完整代码

import os
os.system('pip install dashscope')
os.system('pip install modelscope')
import gradio as gr
from http import HTTPStatus
import dashscope
from dashscope import Generation
from dashscope.api_entities.dashscope_response import Role
from typing import List, Optional, Tuple, Dict
from urllib.error import HTTPError
import wenet
from modelscope.outputs import OutputKeys
from modelscope.pipelines import pipeline
from modelscope.utils.constant import Tasksdefault_system = 'You are a helpful assistant.'
chs_model = wenet.load_model('chinese')
YOUR_API_TOKEN = os.getenv('YOUR_API_TOKEN')
dashscope.api_key = YOUR_API_TOKEN
History = List[Tuple[str, str]]
Messages = List[Dict[str, str]]# 加载四个不同的语音合成模型
sambert_hifigan_zh_model_id = 'damo/speech_sambert-hifigan_tts_zh-cn_16k'
sambert_hifigan_zh = pipeline(task=Tasks.text_to_speech, model=sambert_hifigan_zh_model_id)sambert_hifigan_ch_model_id = 'speech_tts/speech_sambert-hifigan_tts_chuangirl_Sichuan_16k'
sambert_hifigan_ch = pipeline(task=Tasks.text_to_speech, model=sambert_hifigan_ch_model_id)sambert_hifigan_ca_model_id = 'speech_tts/speech_sambert-hifigan_tts_jiajia_Cantonese_16k'
sambert_hifigan_ca = pipeline(task=Tasks.text_to_speech, model=sambert_hifigan_ca_model_id)sambert_hifigan_ws_model_id = 'speech_tts/speech_sambert-hifigan_tts_xiaoda_WuuShanghai_16k'
sambert_hifigan_ws = pipeline(task=Tasks.text_to_speech, model=sambert_hifigan_ws_model_id)def clear_session() -> History:return []def modify_system_session(system: str) -> str:if system is None or len(system) == 0:system = default_systemreturn system, system, []def history_to_messages(history: History, system: str) -> Messages:messages = [{'role': Role.SYSTEM, 'content': system}]for h in history:messages.append({'role': Role.USER, 'content': h[0]})messages.append({'role': Role.ASSISTANT, 'content': h[1]})return messagesdef messages_to_history(messages: Messages) -> Tuple[str, History]:assert messages[0]['role'] == Role.SYSTEMsystem = messages[0]['content']history = []for q, r in zip(messages[1::2], messages[2::2]):history.append([q['content'], r['content']])return system, historydef model_chat(path:str, history: Optional[History], system: str,model:str,voice:str
) -> Tuple[str, str, History]:if path is not None:query = chs_model.transcribe(path)['text']if query is None:query = ''if history is None:history = []messages = history_to_messages(history, system)messages.append({'role': Role.USER, 'content': query})gen = Generation.call(model = "qwen-72b-chat",messages=messages,result_format='message',stream=True)for response in gen:if response.status_code == HTTPStatus.OK:role = response.output.choices[0].message.roleresponse = response.output.choices[0].message.contentsystem, history = messages_to_history(messages + [{'role': role, 'content': response}])else:raise HTTPError('Request id: %s, Status code: %s, error code: %s, error message: %s' % (response.request_id, response.status_code,response.code, response.message))output=None# 进行语音合成sambert_hifigan_tts_model = {'默认': sambert_hifigan_zh,'四川话': sambert_hifigan_ch,'粤语': sambert_hifigan_ca,'上海话': sambert_hifigan_ws}# 使用对应的语音合成模型进行合成sambert_hifigan_tts = sambert_hifigan_tts_model.get(model)if model == '默认':output = sambert_hifigan_tts(input=response, voice=voice)else:output = sambert_hifigan_tts(input=response)wav = output[OutputKeys.OUTPUT_WAV]path = 'output.wav'with open(path, 'wb') as f:f.write(wav)return history, system, pathdef update_dropdowns(model,voice):   if model == "默认":  voice=gr.Dropdown(choices=['zhitian_emo', 'zhiyan_emo', 'zhizhe_emo', 'zhibei_emo'], value='zhitian_emo',label="声音",visible=True) else: voice=gr.Dropdown(choices=['zhitian_emo', 'zhiyan_emo', 'zhizhe_emo', 'zhibei_emo'], value='zhitian_emo',label="声音",visible=False)return voice
with gr.Blocks() as demo:gr.Markdown("""<p align="center"><img src="https://modelscope.cn/api/v1/models/qwen/Qwen-VL-Chat/repo?Revision=master&FilePath=assets/logo.jpg&View=true" style="height: 80px"/><p>""")gr.Markdown("""<center><font size=4>WeNet语音识别+Qwen-72B-Chat Bot👾+Sambert-Hifigan语音合成</center>""")textbox = gr.Microphone(type="filepath",label='录音')with gr.Row():with gr.Column(scale=3):system_input = gr.Textbox(value=default_system, lines=1, label='System', visible=False)with gr.Column(scale=1):modify_system = gr.Button("🛠️ 设置system并清除历史对话", scale=2, visible=False)system_state = gr.Textbox(value=default_system, visible=False)chatbot = gr.Chatbot(label='Qwen-72B-Chat', visible=False)model=gr.Dropdown(choices=['默认', '四川话', '粤语', '上海话'], value='默认',label="声音模型")voice = gr.Dropdown(choices=['zhitian_emo', 'zhiyan_emo', 'zhizhe_emo', 'zhibei_emo'], value='zhitian_emo',label="声音")audio_output = gr.Audio(type="filepath",label='输出音频',autoPlay=True)with gr.Row():clear_history = gr.Button("🎲 清除记忆")sumbit = gr.Button("🚀 发送")model.change(update_dropdowns,inputs=[model,voice],outputs=[voice])sumbit.click(model_chat,inputs=[textbox, chatbot, system_state,model,voice],outputs=[chatbot, system_input,audio_output],concurrency_limit=10)clear_history.click(fn=clear_session,inputs=[],outputs=[chatbot],concurrency_limit=10)modify_system.click(fn=modify_system_session,inputs=[system_input],outputs=[system_state, system_input, chatbot],concurrency_limit=10)
demo.queue(api_open=False).launch(height=800, share=False)

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/602263.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RPC基础知识总结

RPC 是什么? RPC&#xff08;Remote Procedure Call&#xff09; 即远程过程调用&#xff0c;通过名字我们就能看出 RPC 关注的是远程调用而非本地调用。 为什么要 RPC &#xff1f; 因为&#xff0c;两个不同的服务器上的服务提供的方法不在一个内存空间&#xff0c;所以&am…

软件测试/测试开发丨Vuetify框架的使用

介绍 Vuetify 是一个基于 Vue.js 精心打造 UI 组件库&#xff0c;整套 UI 设计为 Material 风格。能够让没有任何设计技能的开发者创造出时尚的 Material 风格界面。 为什么要使用Vuetify框架 所有组件遵从 Material Design 设计规范&#xff0c;UI 体验非常优秀&#xff0c…

zookeeper经典应用场景之分布式锁

1. 什么是分布式锁 在单体的应用开发场景中涉及并发同步的时候&#xff0c;大家往往采用Synchronized&#xff08;同步&#xff09;或者其他同一个JVM内Lock机制来解决多线程间的同步问题。在分布式集群工作的开发场景中&#xff0c;就需要一种更加高级的锁机制来处理跨机器的进…

MiniTab的宏基础知识

什么是宏&#xff1f; 宏是包含一系列 Minitab 会话命令的文本文件。可以使用宏自动执行重复性任务&#xff08;例如&#xff0c;生成月度报表&#xff09;或扩展 Minitab 的功能&#xff08;例如&#xff0c;计算特殊检验统计量&#xff09;。 Minitab 提供以下类型的宏&…

MongoDB索引详解

概述 索引是一种用来快速查询数据的数据结构。BTree 就是一种常用的数据库索引数据结构&#xff0c;MongoDB 采用 BTree 做索引&#xff0c;索引创建 colletions 上。MongoDB 不使用索引的查询&#xff0c;先扫描所有的文档&#xff0c;再匹配符合条件的文档。使用索引的查询&…

Spring IOC的四种手动注入方法

手动注入 1.Set方法注入-五种类型的注入1.1 业务对象JavaBean第一步&#xff1a;创建dao包下的UserDao类第二步&#xff1a;属性字段提供set⽅法第三步&#xff1a;配置⽂件的bean标签设置property标签第四步&#xff1a;测试 1.2 常用对象String&#xff08;日期类型&#xff…

每日一题——LeetCode1089.复写0

方法一 splice&#xff1a; 通过数组的slice方法&#xff0c;碰到 0就在后面加一个0&#xff0c;最后截取原数组的长度&#xff0c;舍弃后面部分。 但这样做是违反了题目的要求&#xff0c;不要在超过该数组长度的位置写入元素。 var duplicateZeros function(arr) {var le…

软件测试|全面解析Docker Start/Stop/Restart命令:管理容器生命周期的必备工具

简介 Docker是一种流行的容器化平台&#xff0c;用于构建、分发和运行应用程序。在使用Docker时&#xff0c;经常需要管理容器的生命周期&#xff0c;包括启动、停止和重启容器。本文将详细介绍Docker中的docker start、docker stop和docker restart命令&#xff0c;帮助您全面…

计算机组成原理-进位计数制(进制表示 进制转换 真值和机器树)

文章目录 现代计算机的结构总览最古老的计数方法十进制计数法推广&#xff1a;r进制计数法任意进制->十进制二进制<--->八进制&#xff0c;十六进制 各种进制常见的书写方式十进制->任意进制整数部分小数部分 十进制->二进制&#xff08;拼凑法&#xff09;真值…

Oracle OCP怎么样线上考试呢

大家好&#xff01;今天咱们就来聊聊Oracle OCP这个让人又爱又恨的认证。为啥说又爱又恨呢&#xff1f;因为它既是IT界的“金字招牌”&#xff0c;又是一块硬骨头&#xff0c;不是那么容易啃下来的。好了&#xff0c;废话不多说&#xff0c;我们直奔主题&#xff0c;来看看关于…

解决vue3中watch 监听不到旧值的问题,亲测有效!

问题描述 这个问题是我在公司vue3项目的时候发现的一个问题&#xff0c;watch 在监听对象/数组变量的变化时&#xff0c;发现对象的数据变化时 旧数据 获取到的和新数据是一样的 类似于下面这样 const objref({a:我是原来的值,b:6, })obj.a改变值watch(obj,(nel,old)>{ c…

studio3T mongodb 根据查询条件更新字段 或 删除数据

1. mongodb 等于、不等于$ne、不包含 $nin 以及批量更新数据的使用。 业务场景&#xff1a; 在集合中&#xff0c;根据查询条件&#xff0c;更新数据状态。 实现代码&#xff1a; 1. 部门名称为XXX、状态不等于“完好”的、并且不包含这些编码的数据先查询出来2. 再把状态更…

rust sqlx包(数据库相关)使用方法+问题解决

可以操作pgsql、mysql、mssql、sqlite 异步的&#xff0c;性能应该不错&#xff0c;具体使用有几个坑 除了sqlx库&#xff0c;还有对于具体数据库的库&#xff0c;比如postgres库 演示以pgsql为例&#xff0c;更新时间2024.1.6 官方github: sqlx github rust官方文档&#xff1…

【Python学习】Python学习4-运算符

目录 【Python学习】Python学习4-运算符 前言算术运算符比较&#xff08;关系&#xff09;运算符赋值运算符逻辑运算符位运算符成员运算符身份运算符运算符优先级参考 文章所属专区 Python学习 前言 本章节主要说明Python的运算符。主要有 算术运算符 比较&#xff08;关系&…

强化学习3——马尔可夫性质、马尔科夫决策、状态转移矩阵和回报与策略(上)

与多臂老虎机问题不同&#xff0c;马尔可夫决策过程包含状态信息以及状态之间的转移机制。如果要用强化学习去解决一个实际问题&#xff0c;第一步要做的事情就是把这个实际问题抽象为一个马尔可夫决策过程。 马尔可夫决策过程描述 马尔可夫决策过程以智能体在与环境交互的过…

【linux笔记1】

目录 【linux笔记1】文件内容的理解用户管理用户管理命令添加用户切换用户修改用户信息删除用户 用户组 【linux笔记1】 文件内容的理解 etc文件夹&#xff1a;etc是拉丁语"et cetera"的缩写&#xff0c;意思是“和其他的”或“等等”。在linux系统中&#xff0c;“…

[嵌入式C][入门篇] 快速掌握基础2 (数据类型、常量、变量)

开发环境&#xff1a; 网页版&#xff1a;跳转本地开发(Vscode)&#xff1a;跳转 文章目录 一、基本变量大小和范围&#xff08;1&#xff09;在8位/32位单⽚机中&#xff1a;测试代码结果&#xff1a;64位机器结果&#xff1a;32位机器&#xff08;单片机&#xff09;无对齐限…

Geoserver扩展发布MySQL视图功能

Geoserver中并不自带mysql数据发布功能&#xff0c;需要扩展外部插件。 1、示例以geoserver-2.20.5版本进行演示&#xff0c;所以MySQL插件需要到该版本对应的“Extensions”标题下查找&#xff0c;下载地址&#xff1a;GeoServer&#xff0c;详见下图 2、选择MySQL进入下载页…

Linux第11步_解决“挂载后的U盘出现中文乱码”

学习完“通过终端挂载和卸载U盘”&#xff0c;我们发现U盘下的中文文件名会出现乱码&#xff0c;现在讲解怎么解决这个问题。其实就是复习一下“通过终端挂载和卸载U盘”&#xff0c;单独讲解&#xff0c;是为了解决问题&#xff0c;一次性搞好&#xff0c;我们会不长记性。 在…

数据在内存中的存储之大小端

今天也是努力学编程&#xff0c;敲代码的一天&#xff01; 1.什么是大小端 其实超过一个字节的数据在内存中存储的时候&#xff0c;就有存储顺序的问题&#xff0c;按照不同的存储顺序&#xff0c;我们分为大端字节序 存储和小端字节序存储&#xff0c;下面是具体的概念: &…