基于Ernie-Bot打造语音对话功能

news2024/9/30 3:30:50

大模型场景实战培训,提示词效果调优,大模型应用定制开发,点击咨询
咨询热线: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 AudioSegment

APP_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 = 16000
        new_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 play

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)

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行重点介绍下

  1. 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组件的状态。
  2. 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组件的状态。

总的来说,这两行代码将用户界面的交互(文本输入和音频输入)与相应的处理函数(predictprocess_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进行语言理解和生成语音回应,每一步都是构建这一创新交互体验的关键部分。

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

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

相关文章

Python酷玩之旅_如何连接MySQL(mysql-connector-python)

前言 Python作为数据科学、机器学习等领域的必选武器,备受各界人士的喜爱。当你面对不同类型、存储于各类介质的数据时,第一时间是不是要让它亮个相?做个统计,画个图表,搞个报表… 等等。 正如Java中的JdbcDriver一样…

以“棋”启智,乐在其中:二近制AI智能棋盘内含9种经典玩法让老人小孩爱不释手

近年来,人工智能算法被广泛地应用到生活的各个领域,棋类游戏亦是如此。各种搭载 A 智能算法的棋盘层出不穷,以“棋”启智,乐在其中成为了当下较流行地全民益智游戏之一。 棋类游戏为何屡受欢迎? 棋类游戏是一种能够激发民族智慧…

济南奇牛科技移动办公手机安全管理平台功能说明

济南奇牛信息科技有限公司自主研发的企业移动安全管理平台为企业提供一整移动终端安全解决方案,为解决企业在实施移动终端应用系统中会遇到的安全、应用管理和资产管理方面的问题,建立统一安全策略,解决企业数字化资产安全和员工隐私保护问题…

【教学类-23-02】20240929《不会写学号的中班幼儿的学号描字贴》(中2班描字)

背景需求: 今天给孩子们做中班操作材料包《练眼力》,希望他们在操作纸左上角写学号,结果有不少孩子嚷:“我不会写学号!” “不会写的孩子举手,老师给你们做个字帖” 结果有不少孩子都举手了,我…

opencv学习:Harris角点检测和SIFT(尺度不变特征变换)算法完整代码实现

Harris角点检测 概念 Harris角点检测是一种在图像处理和计算机视觉领域广泛使用的技术,用于检测图像中的角点。角点是图像中两条边缘交点的位置,它们在图像分析、目标识别和图像配准等任务中非常重要。 角点:图像中的角点是指图像局部区域…

GDB :代码调试工具

文章目录 一、启动GDB二、GDB的基本命令1. 显示代码2. 运行程序3. 设置断点4. 单步执行5. 查看变量和内存6. 查看函数调用堆栈7. 修改变量值8. 退出GDB 一、启动GDB 在终端中,使用以下命令启动GDB并加载你的可执行文件: gdb ./your_program会进入以下界…

应用性能管理工具-SkyWalking

前言 随着微服务架构的流行,一次请求往往需要涉及到多个服务,因此服务性能监控和排查就变得更复杂,因此,就需要一些可以帮助理解系统行为、用于分析性能问题的工具,以便发生故障的时候,能够快速定位和解决…

关于大模型的10个思考

9月28日,第四届“青年科学家50论坛”在南方科技大学举行,美国国家工程院外籍院士沈向洋做了《通用人工智能时代,我们应该怎样思考大模型》的主题演讲,并给出了他对大模型的10个思考。 以下是他10个思考的具体内容: 1…

STM32移植RT-Thread实现DAC功能

在进行DAC的学习中,发现RT-Thread中没有该外设的驱动,因此需要自己进行相关配置 1.配置RT-Thread Setting中的DAC组件 2.在HAL库中完成DAC的配置(HAL库起到时钟的作用) 不懂HAL库配置的最好学一下HAL库的编程思想 3.在board.h中添加宏定义 我的RT-T…

关于分箱的一些介绍

在这篇文章中,我将介绍一种数据预处理的技术——分箱,然会将会从概念、步骤、分类、应用场景、注意事项与实际操作等方面去介绍它。 一、概念 分箱(Binning)是一种数据预处理技术,在数据分析和机器学习中经常使用。它…

Java8 用流收集数据之归约汇总

目录 规约汇总最大值 (max)・最小值 (min)统计总数 (count)统计求和 (summingInt・summingLong・summingDouble・sum)平均值 (averagingInt・averagingLong・averagingInt・average)统计梗概 (summarizingInt・summarizingLong・summarizingDouble・summ…

AI周报(9.22-9.28)

AI应用-Siipet宠物沟通师 Siipet是一款由SiiPet公司推出的创新宠物行为分析相机,旨在通过尖端技术加深宠物与主人之间的情感联系。这款相机利用先进的AI算法,能够自动识别和分析家中宠物的行为,并提供定制化的护理建议。 SiiPet相机的核心功…

益而益集团荣获2024年江苏省智能制造车间称号

近日,江苏省工信厅公示2024年江苏省智能制造车间名单,苏州益而益电器制造有限公司以其卓越的智能化转型成果,荣获2024年度江苏省级智能制造车间称号。 此次获评,是江苏省政府对益而益集团智能化高质量转型发展的认可及肯定&#…

活动在线报名小程序源码系统 自主提交表单+创建表单 带完整的安装代码包以及搭建部署教程

系统概述 随着各类活动的日益丰富和多样化,传统的报名方式逐渐显现出其局限性。纸质报名表格繁琐易错、人工统计费时费力,难以满足现代活动管理的需求。因此,开发一款集自主提交表单和创建表单功能于一体的活动在线报名小程序源码系统成为必…

mit6824-01-MapReduce详解

文章目录 MapReduce简述编程模型执行流程执行流程排序保证Combiner函数Master数据结构 容错性Worker故障Master故障 性能提升定制分区函数局部性执行缓慢的worker(slow workers) 常见问题总结回顾参考链接 MapReduce简述 MapReduce是一个在多台机器上并行计算大规模数据的软件架…

C++进阶知识2 多态

多态 1. 多态的概念2. 多态的定义及实现2.1 多态的构成条件2.1.2 虚函数2.1.3 虚函数的重写/覆盖2.1.5 虚函数重写的⼀些其他问题2.1.6 override和final关键字2.1.7 重载/重写/隐藏的对⽐ 3. 多态的原理3.2 多态的原理3.2.1 多态是如何实现的3.2.2 动态绑定与静态绑定3.2.3 虚函…

828华为云征文|部署在线文档应用程序 CodeX Docs

828华为云征文|部署在线文档应用程序 CodeX Docs 一、Flexus云服务器X实例介绍二、Flexus云服务器X实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置2.4 Docker 环境搭建 三、Flexus云服务器X实例部署 CodeX Docs3.1 CodeX Docs 介绍3.2 CodeX Docs 部署3.3 CodeX…

SpringBoot整合JPA 基础使用

一、什么是JPA ‌‌1.JPA的定义和基本概念‌‌ ‌JPA(Java Persistence API)‌是Java中用于进行持久化操作的一种规范,它定义了一系列用于操作关系型数据库的API接口。通过这些接口,开发人员可以方便地进行数据库的增删改查等操…

ArcgisEngine开发中,Ifeatureclass.Addfield 报错0x80040655处理方法

1、ArcgisEngine开发中,Ifeatureclass.Addfield 报错0x80040655。如下图所示。 2、经分析,这是由于字段类型错误,经检查,是由于字段名为中文名,超出shp格式的最大字段长度量,看资料说是5个中文字符&#xf…

fastadmin 搜索提交重置按钮文本修改

默认 修改require-backend.min.js文件 效果 当然最好还是去需修改lang文件 效果 如果修改没生效记得清楚一下缓存,再刷新 完结 赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,你…