基于Ernie-Bot打造语音对话功能
大模型场景实战培训,提示词效果调优,大模型应用定制开发,点击咨询
咨询热线:400-920-8999转2
GPT-4的语音对话功能前段时间在网上火了一把,许多人被其强大的自然语言处理能力和流畅的语音交互所吸引。现在,让我们来看看如何使用类似的技术,即基于百度的ERNIE-Bot,来打造自己的语音对话功能。ERNIE-Bot是一种先进的语言理解模型,可以处理复杂的语言任务,包括语音到文本的转换和自然语言理解。
视频演示:
shequ.mov
涉及技术:
- langchain Memory、Chain
- Ernie-bot
- 百度智能云语音识别: https://ai.baidu.com/ai-doc/SPEECH/0lbxfnc9b
- 百度智能云语音合成: https://ai.baidu.com/ai-doc/SPEECH/plbxhh4be
依赖:
- ffmpeg
langchain调用Ernie-bot并实现记忆
值得一提的是,在langchain构建ernie-bot多轮对话能力上,社区中已有成员对此进行了深入研究和实践: https://cloud.baidu.com/qianfandev/topic/267682
from langchain.chat_models import ErnieBotChat
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
from langchain.memory import ConversationBufferMemory
# 定义一个大语言模型对象
llm = ErnieBotChat(ernie_client_id="xxxxx", ernie_client_secret="xxxxxx",model_name='ERNIE-Bot',temperature=0.01) # 定义prompt template
template = """You are a chatbot having a conversation with a human. Please answer as briefly as possible.{chat_history}
Human: {human_input}
Chatbot:
"""prompt = PromptTemplate(input_variables=["chat_history", "human_input"], template=template
)
# memory
memory = ConversationBufferMemory(llm=llm,memory_key="chat_history",return_messages=True)
# chain
conversation = LLMChain(llm=llm, memory=memory,prompt=prompt)
# 推理
response = conversation.predict(human_input=input)
语音识别部分
目前,百度语音识别服务支持固定的采样率:16000Hz 和 8000Hz。为了确保您的音频文件与这些标准兼容,可能需要对原始音频的采样率进行适当调整。这意味着,如果您的音频文件采样率与上述两个固定值不符,您将需要通过音频处理软件或编程方法,将其转换为这两种支持的采样率之一。这个步骤是确保音频识别准确性的关键,可以显著提高语音识别的效果和准确度。
详情参考: https://ai.baidu.com/ai-doc/SPEECH/0lbxfnc9b
from aip import AipSpeech
import tempfile
import os, uuid
from pydub import AudioSegmentAPP_ID = 'xxx'
API_KEY = 'xxxxx'
SECRET_KEY = 'xxxxxxxxx'client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)def transcribe(audio):with tempfile.TemporaryDirectory() as tempdir:print(f"Temporary directory created at {tempdir}")audio = AudioSegment.from_file(audio)new_frame_rate = 16000new_audio = audio.set_frame_rate(new_frame_rate)random_code = uuid.uuid4()temp_audio_path = f"{tempdir}/output_audio_16000_{random_code}.wav"new_audio.export(temp_audio_path, format="wav")def get_file_content(filePath):with open(filePath, 'rb') as fp:return fp.read()ret = client.asr(get_file_content(temp_audio_path), 'wav', 16000, {'dev_pid': 1537})# 注意:退出 with 块后,tempdir 及其内容会被自动删除return ret.get('result')[0]
语音合成部分
将大型语言模型生成的文本内容转换成语音输出是一个引人入胜的过程。通过这种转换,我们可以将模型的文字回应转化为更加生动、直观的语音形式。这不仅提升了用户体验,还增加了交互的可访问性和便利性。无论是为视觉受限用户提供更加友好的界面,还是为智能助理增添自然的交流方式,这一过程都显得至关重要。
参考语音合成SDK: https://ai.baidu.com/ai-doc/SPEECH/plbxhh4be
from pydub import AudioSegment
from pydub.playback import playdef play_voice(text):result = client.synthesis(text, 'zh', 1, {'vol': 5})# 识别正确返回语音二进制 错误则返回dict 参照下面错误码if not isinstance(result, dict):with tempfile.NamedTemporaryFile(delete=True, suffix='.mp3', mode='wb') as temp_audio_file:temp_audio_file.write(result)temp_audio_file.seek(0) # 回到文件开头# print(temp_audio_file.name)# 使用 pydub 播放音频audio = AudioSegment.from_file(temp_audio_file.name, format="mp3")play(audio)
gradio交互逻辑
gradio的核心代码框架如下:
def clear_history():# 返回一个空列表来清空聊天记录return [], []with gr.Blocks(css="#chatbot{height:800px} .overflow-y-auto{height:800px}") as demo:chatbot = gr.Chatbot(elem_id="chatbot")state = gr.State([])with gr.Row():txt = gr.Textbox(show_label=False, placeholder="Enter text and press enter")# 录音功能with gr.Row(): # 得到音频文件地址audio = gr.Audio(sources="microphone", type="filepath")with gr.Row(): clear_button = gr.Button("清空聊天记录")# 重要逻辑 txt.submit(predict, [txt, state], [chatbot, txt, state]) audio.change(process_audio, [audio, state], [chatbot, audio, state])clear_button.click(clear_history, [], [chatbot, state])
# 启动gradio
demo.launch(share=False)
代码18/19行重点介绍下
-
txt.submit(predict, [txt, state], [chatbot, txt, state])
txt.submit
: 这是Gradio中Textbox
组件的一个方法,用于绑定一个函数(在本例中是predict
函数)到文本框的输入动作上。当用户在文本框中输入文本并提交(通常是按下回车键)时,绑定的predict
函数会被触发。predict
: 这是绑定到文本框提交动作的函数。这个函数会在用户提交文本后执行。[txt, state]
: 这是传递给predict
函数的参数列表。在这里,txt
代表文本框的内容,state
是一个State
组件,用于在Gradio界面中维持状态。[chatbot, txt, state]
: 这是predict
函数执行后,其输出将被传递的组件列表。在此,函数的输出将被用来更新Chatbot
组件(显示对话内容)、清空Textbox
组件的文本,以及更新State
组件的状态。
-
audio.change(process_audio, [audio, state], [chatbot, audio, state])
audio.change
: 这是Gradio中Audio
组件的一个方法,用于将一个函数(在这个例子中是process_audio
函数)绑定到音频输入的变化上。当用户通过音频组件提供新的音频输入时,绑定的process_audio
函数会被触发。process_audio
: 这是绑定到音频组件变化的函数。当音频输入改变时,这个函数会执行。[audio, state]
: 这是传递给process_audio
函数的参数列表。在这里,audio
代表音频组件的输入,state
仍然是用于维持状态的State
组件。[chatbot, audio, state]
: 这是process_audio
函数执行后,其输出将被传递的组件列表。这意味着函数的输出将用于更新Chatbot
组件、重置Audio
组件的输入,以及更新State
组件的状态。
总的来说,这两行代码将用户界面的交互(文本输入和音频输入)与相应的处理函数(predict
和process_audio
)关联起来,并定义了这些函数执行后如何更新界面组件。
两个函数的实现逻辑:
def play_voice(text):result = client.synthesis(text, 'zh', 1, {'vol': 5})# 识别正确返回语音二进制 错误则返回dict 参照下面错误码if not isinstance(result, dict):with tempfile.NamedTemporaryFile(delete=True, suffix='.mp3', mode='wb') as temp_audio_file:temp_audio_file.write(result)temp_audio_file.seek(0) # 回到文件开头# print(temp_audio_file.name)# 使用 pydub 播放音频audio = AudioSegment.from_file(temp_audio_file.name, format="mp3")play(audio)# 录音文件转文本的过程
def process_audio(audio, history=[]):if audio:text = transcribe(audio) # print(text)if text is None:text="你好"responses, clear, updated_history = predict(text, history)# print(f"====={responses}")# print(f"++++{updated_history}")# 返回处理结果和 None 来清空音频输入return responses, None, updated_history else: # print(f"------{history}")return [(u,b) for u,b in zip(history[::2], history[1::2])], None, history# 调用ernie-bot对话功能
def predict(input, history=[]): history.append(input) response = conversation.predict(human_input=input)history.append(response)# history[::2] 切片语法,每隔两个元素提取一个元素,即提取出所有的输入,# history[1::2]表示从历史记录中每隔2个元素提取一个元素,即提取出所有的输出# zip函数把两个列表元素打包为元组的列表的方式play_voice(response)responses = [(u,b) for u,b in zip(history[::2], history[1::2])]print("==取出输入:",history[::2])print("==取出输出:",history[1::2])print("组合元组:",responses)return responses, "", history
通过本文的介绍,我们探索了如何利用ERNIE-Bot来打造一个高效的语音对话功能。从设置开发环境、处理音频文件,到利用ERNIE-Bot进行语言理解和生成语音回应,每一步都是构建这一创新交互体验的关键部分。
相关文章:
基于Ernie-Bot打造语音对话功能
大模型场景实战培训,提示词效果调优,大模型应用定制开发,点击咨询 咨询热线:400-920-8999转2 GPT-4的语音对话功能前段时间在网上火了一把,许多人被其强大的自然语言处理能力和流畅的语音交互所吸引。现在,…...
动手学深度学习(李沐)PyTorch 第 3 章 线性神经网络
3.1 线性回归 线性回归是对n维输入的加权,外加偏差 线性回归可以看作是单层神经网络 回归问题中最常用的损失函数是平方误差函数。 平方误差可以定义为以下公式: 常数1/2不会带来本质的差别,但这样在形式上稍微简单一些 (因为当…...
ROS理论与实践学习笔记——2 ROS通信机制之服务通信
服务通信也是ROS中一种极其常用的通信模式,服务通信是基于请求响应模式的,是一种应答机制。也即: 一个节点A向另一个节点B发送请求,B接收处理请求并产生响应结果返回给A,用于偶然的、对时时性有要求、有一定逻辑处理需求的数据传输…...
技术成神之路:设计模式(十八)适配器模式
介绍 适配器模式(Adapter Pattern)是一种结构型设计模式,它允许接口不兼容的类可以协同工作,通过将一个类的接口转换成客户端所期望的另一个接口,使得原本由于接口不兼容而不能一起工作的类可以一起工作。 1.定义 适配…...
图神经网络:处理复杂关系结构与图分类任务的强大工具
创作不易,您的打赏、关注、点赞、收藏和转发是我坚持下去的动力! 图神经网络(Graph Neural Network, GNN)是针对图数据的一类神经网络模型。图数据具有节点(节点代表实体)和边(边代表节点之间的…...
LeetCode: 1971. 寻找图中是否存在路径
寻找图中是否存在路径 原题 有一个具有 n 个顶点的 双向 图,其中每个顶点标记从 0 到 n - 1(包含 0 和 n - 1)。图中的边用一个二维整数数组 edges 表示,其中 edges[i] [ui, vi] 表示顶点 ui 和顶点 vi 之间的双向边。 每个顶点…...
mysql 查询表所有数据,分页的语句
在 MySQL 中,若要从表中查询所有数据并实现分页,你可以使用 SELECT 语句结合 LIMIT 和 OFFSET 子句。LIMIT 用于指定返回的记录数,而 OFFSET 则用于指定从哪一条记录开始返回(即跳过的记录数)。 以下是一个基本的分页…...
TI DSP TMS320F280025 Note13:CPUtimer定时器原理分析与使用
TMS320F280025 CPUtimer定时器原理分析与使用 ` 文章目录 TMS320F280025 CPUtimer定时器原理分析与使用框图分析定时器中断定时器使用CPUtimers.cCPUtimers.h框图分析 定时器框图如图所示 定时器有一个预分频模块和一个定时/计数模块, 其中预分频模块包括一个 16 位的定时器分…...
Australis 相機率定軟體說明
概要 課堂中使用Australis這套軟體,順帶記錄操作過程 內容以老師口述及我測試的經過 照片為老師課堂提供之 說明 執行 Step1. 匯入照片 注意!!如果是Mac的作業系統,將資料夾移到Windows上的時候,建議創一個新的資料…...
C++入门(有C语言基础)
string类 string类初始化的方式大概有以下几种: string str1;string str2 "hello str2";string str3("hello str3");string str4(5, B);string str5[3] {"Xiaomi", "BYD", "XPeng"};string str6 str5[2];str…...
第四届高性能计算与通信工程国际学术会议(HPCCE 2024)
目录 大会简介 主办单位,承办单位 征稿主题 会议议程 参会方式 大会官网:www.hpcce.net 大会简介 第四届高性能计算与通信工程国际学术会议(HPCCE 2024)将于2024年11月22-24日在苏州召开。HPCCE 2024将围绕“高性能计算与通信工…...
负载均衡架构解说
负载均衡架构是一种设计模式,用于在多个服务器之间分配网络或应用流量,以提高资源利用率、最大化吞吐量、减少响应时间,并确保高可用性。 负载均衡架构的关键组件和概念: 关键组件 1.负载均衡器(Load Balancer&…...
【异常数据检测】孤立森林算法异常数据检测算法(数据可视化 Matlab语言)
摘要 本文研究了基于孤立森林算法的异常数据检测方法,并在MATLAB中实现了该算法的可视化。孤立森林是一种无监督的异常检测算法,主要通过构建决策树来区分正常数据和异常数据。本文使用真实数据集,通过二维可视化展示了检测结果。实验结果表…...
MKV转MP4丨FFmpeg的简单命令使用——视频格式转换
MKV是一种视频封装格式,很好用,也是OBS的默认推荐录制格式,因为不会突然断电关机而导致整个视频录制文件丢失。 但是MKV无法直接导入PR中剪辑,最直接的方法是将MKV转换为MP4格式,最方便且安全无损的转换方法便是用FFmp…...
git使用“保姆级”教程4——版本回退及分支讲解
一、版本回退 1、历史回退(版本回退)——命令行git reset --hard 版本编号 注意:当前命令会让工作区的内容发生改变,可以理解成历史区(master分支)直接回到工作区比如:从版本4回到版本3,则工作区只会显示版本3的代码内容 1.1、指…...
spring cache,Spring data redis
本项目使用Redis存储缓存数据,如何通过Java去访问Redis? 常用的有Jedis和Lettuce两个访问redis的客户端类库 ,Jedis和Lettuce都是redis提供的。其中Lettuce的性能和并发性要好一些,Spring Boot 默认使用的是 Lettuce 作为 Redis …...
10.数据结构与算法-线性表的应用(线性表与有序表的合并)
线性表的合并 有序表的合并 顺序表 链表...
GAN|对抗| 生成器更新|判别器更新过程
如上图所示,生成对抗网络存在上述内容: 真实数据集;生成器;生成器损失函数;判别器;判别器损失函数;生成器、判别器更新(生成器和判别器就是小偷和警察的关系,他们共用的…...
day01——登录功能
逻辑: 前端将登录信息通过报文的形式,发送给后端。后端进行登陆验证 2.1 根据接受的用户名,查询数据表。 若不存在该用户的记录,返回用户不存在。 若用户存在,判断数据库中的密码和接收的是否一致,不一致则…...
Flutter中使用FFI的方式链接C/C++的so库(harmonyos)
Flutter中使用FFI的方式链接C/C库(harmonyos) FFI plugin创建和so的配置FFI插件对so库的使用 FFI plugin创建和so的配置 首先我们可以根据下面的链接生成FFI plugin插件:开发FFI plugin插件 然后在主项目中pubspec.yaml 添加插件的依赖路径&…...
【C++】二义性
在C中,二义性(ambiguity)通常指的是编译器无法确定使用哪个函数、变量或类成员的情况。这种不确定性通常是由于继承和多态特性导致的。下面是一些常见的产生二义性的场景以及如何解决它们的方法: 1. 多重继承中的二义性 当一个类…...
高并发内存池(五):ThreadCache、CentralCache和PageCache的内存回收机制、阶段性代码展示和释放内存过程的调试
目录 ThreadCache的内存回收机制 补充内容1 补充内容2 补充内容3 补充内容4 ListTooLong函数的实现 CentralCache的内存回收机制 MapObjectToSpan函数的实现 ReleaseListToSpans函数的实现 PageCache的内存回收机制 补充内容1 补充内容2 ReleaseSpanToPageCache函…...
STL之stackqueue篇(上)探索C++ STL中的Queue与Stack——构建数据处理的基础框架
文章目录 前言一、stack1.1 定义与基本概念1.2 底层容器1.3 成员函数1.4 使用示例1.5 注意事项1.6 应用场景 二、queue2.1 定义与基本概念2.2 底层容器2.3 成员函数2.4 使用示例2.5 注意事项2.6 应用场景 前言 本文旨在深入探讨C STL中的queue与stack容器,从它们的…...
代码随想录算法训练营Day13
110.平衡二叉树 力扣题目链接:. - 力扣(LeetCode) 后序迭代 class Solution {public boolean isBalanced(TreeNode root) {return getHeight(root)!-1;}public int getHeight(TreeNode root){if(rootnull){return 0;}int leftheightgetHei…...
基于STM32的智能门禁系统
目录 引言项目背景环境准备 硬件准备软件安装与配置系统设计 系统架构关键技术代码示例 RFID数据采集与处理门禁控制实现显示与报警功能应用场景结论 1. 引言 智能门禁系统在现代安防中占据重要地位,通常用于控制进入和离开特定区域的权限。通过基于STM32微控制器…...
[EBPF] 实时捕获DM数据库是否存在SQL阻塞
1. 介绍 eBPF(extened Berkeley Packet Filter)是一种内核技术,它允许开发人员在不修改内核代码的情况下运行特定的功能。eBPF 的概念源自于 Berkeley Packet Filter(BPF),后者是由贝尔实验室开发的一种网…...
秋招内推--招联金融2025
【投递方式】 直接扫下方二维码,或点击内推官网https://wecruit.hotjob.cn/SU61025e262f9d247b98e0a2c2/mc/position/campus,使用内推码 igcefb 投递) 【招聘岗位】 后台开发 前端开发 数据开发 数据运营 算法开发 技术运维 软件测试 产品策…...
Unity2022.3.x各个版本bug集合及推荐稳定版本
最近升级到Unity2022,发现以下问题,仅作参考 2022.3.0f1 - 2022.3.6f1 粒子渲染到RenderTexture闪屏 https://issuetracker.unity3d.com/issues/android-vulkan-visualisation-corruption-occurs-when-rendering-particles-to-render-texture 2022.3.…...
SparkSQL-性能调优
祝福 在这个举国同庆的时刻,我们首先献上对祖国的祝福: 第一,我们感谢您给我们和平的环境,让我们能快乐生活 第二,祝福我们国家未来的路越走越宽广,科技更发达,人民更幸福 第三,…...
leetcode-链表篇
leetcode-707 你可以选择使用单链表或者双链表,设计并实现自己的链表。 单链表中的节点应该具备两个属性:val 和 next 。val 是当前节点的值,next 是指向下一个节点的指针/引用。 如果是双向链表,则还需要属性 prev 以指示链表中的…...
网站页面组成部分/企业培训师
1.CtrlALTF1 进入控制台 2.输入用户名和密码进入系统 3.输入以下命令: cd /etc/X11 sudo cp xorg.conf.failsafe xorg.conf sudo reboot 进入系统后感觉到明显的卡顿,查看分辨率很低,而且在vm下无法全屏 解决办法: sudo apt-get updata…...
网站建设发展情况/最近实时热点事件
回城传送–》《JAVA筑基100例》 文章目录 零、前言一、题目描述二、解题思路三、代码详解四、推荐专栏五、示例源码下载零、前言 今天是学习 JAVA语言 打卡的第47天,每天我会提供一篇文章供群成员阅读( 不需要订阅付钱 ),读完文章之后,按解题思路,自己再实现一遍。在…...
html5+css3网站/百度网址大全
ng-zorro-antd 是 Ant Design 的 Angular 实现,主要用于研发企业级中后台产品。全部代码开源并遵循 MIT 协议,任何企业、组织及个人均可免费使用。ng-zorro-antd 13.2.0 现已发布,更新内容如下: Bug Fixes carousel: 修复 nzAft…...
徐州市制作网站的公司/网络营销专业如何
为什么80%的码农都做不了架构师?>>> 结论: 1、不管有木有出现异常,finally块中代码都会执行; 2、当try和catch中有return时,finally仍然会执行; 3、finally是在return后面的表达式运算后执行的…...
门户网站界面设计/seo是什么地方
题目表述 泰波那契序列 Tn 定义如下: T0 0, T1 1, T2 1, 且在 n > 0 的条件下 Tn3 Tn Tn1 Tn2 给你整数 n,请返回第 n 个泰波那契数 Tn 的值。示例 1: 输入:n 4 输出:4 解释: T_3 0 1 1 2 T…...
织梦wordpress帝国对比/市场调研流程
大浪淘沙的AI创业圈,触景无限正在这个技术浪潮中不断找寻自己的位置。 有人说,AI创业的大门已经慢慢关闭,场内的玩家也已基本定型,未来的战争将聚焦在头部几家,马太效应的收紧会使得一大波竞逐者生存艰难,…...