大模型UI:Gradio全解11——Chatbot:融合大模型的聊天机器人(4)
- 前言
- 本篇摘要
- 11. Chatbot:融合大模型的多模态聊天机器人
- 11.4 使用Blocks创建自定义聊天机器人
- 11.4.1 简单聊天机器人演示
- 11.4.2 流式传输Chatbot
- 11.4.3 添加Markdown、Images、Audio或Videos
- 参考文献
前言
本系列文章主要介绍WEB界面工具Gradio。Gradio是Hugging Face发布的简易webui开发框架,它基于FastAPI和svelte,便于开发多功能界面和部署人工智能模型,是当前热门的非常易于开发和展示机器学习大语言模型LLM及扩散模型DM的UI框架。本系列文章分为前置概念和实战演练两部分。前置概念先介绍Gradio的详细技术架构、历史、应用场景、与其他框架Gradio/NiceGui/StreamLit/Dash/PyWebIO的区别,然后详细介绍了著名的资源网站Hugging Face,因为Gradio演示中经常用到Hugging Face的models及某些场景需要部署在spaces,这里包括三类资源models/datasets/spaces的使用、六类工具库transformers/diffusers/datasets/PEFT/accelerate/optimum实战。实战演练部分先讲解了多种不同的安装、运行和部署方式,安装包括Linux/Win/Mac三类系统安装,运行包括普通方式和热重载方式,部署包括本地部署、HuggingFace托管、FastAPI挂载和Gradio-Lite浏览器集成;然后按照先整体再细节的逻辑,讲解Gradio的多种高级特性,包括三种Gradio Clients(python/javascript/curl)、Gradio Tools、Gradio的模块架构和环境变量等,方便读者对Gradio整体把握;最后深入细节,也是本系列文章的核心,先实践基础功能Interface、Blocks和Additional Features,再详解高级功能Chatbots、Data Science And Plots和Streaming。本系列文章讲解细致,涵盖Gradio大部分组件和功能,代码均可运行并附有大量运行截图,方便读者理解,Gradio一定会成为每个技术人员实现奇思妙想的最称手工具。
本系列文章目录如下:
- 《Gradio全解1——Gradio简介》
- 《Gradio全解1——Gradio的安装与运行》
- 《Gradio全解2——剖析Hugging Face:详解三类资源models/datasets/spaces》
- 《Gradio全解3——剖析Hugging Face:实战六类工具库transformers/diffusers/datasets/PEFT/accelerate/optimum》
- 《Gradio全解4——Gradio的3+1种部署方式实践》
- 《Gradio全解4——浏览器集成Gradio-Lite》
- 《Gradio全解5——Gradio Client:python客户端》
- 《Gradio全解5——Gradio Client:javascript客户端》
- 《Gradio全解5——Gradio Client:curl客户端》
- 《Gradio全解6——Gradio Tools:将Gradio用于LLM Agents》
- 《Gradio全解7——Gradio库的模块架构和环境变量》
- 《Gradio全解8——Interface:高级抽象界面类(上)》
- 《Gradio全解8——Interface:高级抽象界面类(下)》
- 《Gradio全解9——Blocks:底层区块类(上)》
- 《Gradio全解9——Blocks:底层区块类(下)》
- 《Gradio全解10——Additional Features:补充特性(上)》
- 《Gradio全解10——Additional Features:补充特性(下)》
- 《Gradio全解11——Chatbot:融合大模型的多模态聊天机器人(1)》
- 《Gradio全解11——Chatbot:融合大模型的多模态聊天机器人(2)》
- 《Gradio全解11——Chatbot:融合大模型的多模态聊天机器人(3)》
- 《Gradio全解11——Chatbot:融合大模型的多模态聊天机器人(4)》
- 《Gradio全解系列12——Data Science And Plots:数据科学与绘图》
- 《Gradio全解13——Streaming:数据流(上)》
- 《Gradio全解13——Streaming:数据流(下)》
本篇摘要
本篇介绍如何使用Gradio创建聊天机器人,主要内容包括gr.ChatInterface快速创建Chatbot、与流行LLM库及API结合、使用Agents和Tools智能代理工具、使用Blocks创建Chatbot、Chatbot的特殊Events、通过Gradio应用创建Discord Bot/Slack Bot/Website Widget。
11. Chatbot:融合大模型的多模态聊天机器人
本章介绍如何使用Gradio创建聊天机器人。聊天机器人是大型语言模型(LLMs)的一个流行应用,通过Gradio,我们可以轻松构建LLM演示并与其它用户分享,或者自己使用直观的聊天机器人界面进行开发尝试。本章主要内容包括gr.ChatInterface快速创建Chatbot、与流行LLM库及API结合、组件Chatbot及消息格式ChatMessage、使用Blocks创建Chatbot、Chatbot的特殊Events、使用Agents和Tools智能代理工具、通过Gradio应用创建Discord Bot/Slack Bot/Website Widget。
11.4 使用Blocks创建自定义聊天机器人
重要提示:如果是初学者,建议使用gr.ChatInterface来创建聊天机器人——这是一个高级抽象,通常只需一行代码,就可以快速创建漂亮的聊天机器人应用程序,请读者参照本章第一节和第二节内容。
有了上一节的知识储备后,本节就可以展示如何使用Gradio的底层Blocks API从头开始构建聊天机器人用户界面,这将使你能够完全控制聊天机器人UI。我们将首先创建一个简单的聊天机器人来显示文本,然后创建一个可以流式传输文本响应的聊天机器人,最后创建一个能够处理媒体文件的聊天机器人。
前提条件:我们将使用gradio.Blocks类来构建我们的聊天机器人演示。如果读者还不熟悉它,可以先阅读《Blocks:底层区块类》。此外,请确保使用最新版本Gradio:pip install --upgrade gradio。
11.4.1 简单聊天机器人演示
让我们从创建简单演示开始,机器人只是随机响应"How are you?"、"Today is a great day"或 “I’m very hungry” 来回应任何输入。以下是使用Gradio创建此功能的代码:
import gradio as gr
import random
import time
with gr.Blocks() as demo:
chatbot = gr.Chatbot(type="messages")
msg = gr.Textbox()
clear = gr.ClearButton([msg, chatbot])
def respond(message, chat_history):
bot_message = random.choice(["How are you?", "Today is a great day", "I'm very hungry"])
chat_history.append({"role": "user", "content": message})
chat_history.append({"role": "assistant", "content": bot_message})
time.sleep(2)
return "", chat_history
msg.submit(respond, [msg, chatbot], [msg, chatbot])
demo.launch()
运行界面如下:
这里使用了三个Gradio组件:
- Chatbot:它的值存储了整个对话的历史记录,作为用户和机器人之间响应对的列表;
- Textbox:用户可以在其中输入消息,然后按回车/提交以触发聊天机器人的响应;
- ClearButton:用于清除文本框和整个聊天机器人历史记录的按钮。
我们有一个函数respond(),它接收聊天机器人的整个历史记录,附加一条随机消息,等待2秒钟后返回更新后的聊天历史记录。respond()函数在返回时还会清除文本框。当然在实际应用中,可以将respond()替换为自己的更复杂的函数,该函数可能会调用预训练模型或API来生成响应。
11.4.2 流式传输Chatbot
我们可以通过几种方式改进上述聊天机器人的用户体验:首先,我们可以使用流式传输响应,这样用户在生成消息时不必等待太长时间;其次,我们可以在生成聊天机器人的响应时,让用户的消息立即显示在聊天历史记录中。以下是实现此功能的代码:
import gradio as gr
import random
import time
with gr.Blocks() as demo:
chatbot = gr.Chatbot(type="messages")
msg = gr.Textbox()
clear = gr.Button("Clear")
def user(user_message, history: list):
return "", history + [{"role": "user", "content": user_message}]
def bot(history: list):
bot_message = random.choice(["How are you?", "I love you", "I'm very hungry"])
history.append({"role": "assistant", "content": ""})
for character in bot_message:
history[-1]['content'] += character
time.sleep(0.05)
yield history
msg.submit(user, [msg, chatbot], [msg, chatbot], queue=False).then(
bot, chatbot, chatbot
)
clear.click(lambda: None, None, chatbot, queue=False)
demo.launch()
运行界面如下:
请注意,此时的消息是流式输出的。另外,当用户提交消息时,通过.then()链式调用两个事件:
- 第一个方法user():使用用户消息更新聊天机器人并清空输入框。因为我们希望立即执行此操作,所以设置queue=False,这将跳过任何已启用的队列,聊天机器人的历史记录会附加 {“role”: “user”, “content”: user_message}。
- 第二个方法bot():用机器人的响应更新聊天历史记录。最后我们逐字符构建消息,并在构建过程中生成中间输出。Gradio会自动将任何带有yield关键字的函数转换为流式输出界面。
当然在实际应用中,我们可以将bot()替换为自己更复杂的函数,该函数可能会调用预训练模型或API来生成响应。
11.4.3 添加Markdown、Images、Audio或Videos
gr.Chatbot组件支持部分Markdown 语法,包括加粗、斜体和代码。例如,我们可以编写一个函数,用加粗的That’s cool! 来响应用户的消息,如下所示:
def bot(history):
response = {"role": "assistant", "content": "**That's cool!**"}
history.append(response)
return history
此外,它还可以处理媒体文件,例如图片、音频和视频。我们可以使用MultimodalTextbox组件轻松上传所有类型的媒体文件到chatbot,还可以通过传递sources参数进一步自定义MultimodalTextbox,该参数是一个启用的来源列表。要传递媒体文件,我们必须将文件作为字典传递,其中path键指向本地文件,alt_text键是可选的,因此可以只传递一个包含单个元素的元组{“path”: “filepath”},如下所示:
def add_message(history, message):
for x in message["files"]:
history.append({"role": "user", "content": {"path": x}})
if message["text"] is not None:
history.append({"role": "user", "content": message["text"]})
return history, gr.MultimodalTextbox(value=None, interactive=False, file_types=["image"], sources=["upload", "microphone"])
将这些结合起来,我们可以创建一个多模态聊天机器人,使用多模态文本框让用户提交文本和媒体文件。其余的代码看起来与之前几乎相同:
import gradio as gr
import time
# Chatbot demo with multimodal input (text, markdown, LaTeX, code blocks, image, audio, & video). Plus shows support for streaming text.
def print_like_dislike(x: gr.LikeData):
print(x.index, x.value, x.liked)
def add_message(history, message):
for x in message["files"]:
history.append({"role": "user", "content": {"path": x}})
if message["text"] is not None:
history.append({"role": "user", "content": message["text"]})
return history, gr.MultimodalTextbox(value=None, interactive=False)
def bot(history: list):
response = "**That's cool!**"
history.append({"role": "assistant", "content": ""})
for character in response:
history[-1]["content"] += character
time.sleep(0.05)
yield history
with gr.Blocks() as demo:
chatbot = gr.Chatbot(elem_id="chatbot", bubble_full_width=False, type="messages")
chat_input = gr.MultimodalTextbox(
interactive=True,
file_count="multiple",
placeholder="Enter message or upload file...",
show_label=False,
sources=["microphone", "upload"],
)
chat_msg = chat_input.submit(
add_message, [chatbot, chat_input], [chatbot, chat_input]
)
bot_msg = chat_msg.then(bot, chatbot, chatbot, api_name="bot_response")
bot_msg.then(lambda: gr.MultimodalTextbox(interactive=True), None, [chat_input])
chatbot.like(print_like_dislike, None, None, like_user_message=True)
demo.launch()
上传文件并输入一段信息后,运行界面如下:
在后台通过命令运行:python XXX.py,在点赞和点踩之后,会在后台输出以下信息:
0 [{'component': 'file', 'value': {'path': '/tmp/gradio/439c333fbe1cde660c82dd81000e1e59b08121367a652b85efdd6e2e22ebb2d8/DeepSeek_V3.pdf', 'url': 'http://127.0.0.1:7862/gradio_api/file=/tmp/gradio/439c333fbe1cde660c82dd81000e1e59b08121367a652b85efdd6e2e22ebb2d8/DeepSeek_V3.pdf', 'size': None, 'orig_name': None, 'mime_type': 'application/pdf', 'is_stream': False, 'meta': {'_type': 'gradio.FileData'}}, 'alt_text': None, 'constructor_args': {}, 'props': {}}, 'test multimodal textbox.'] True
2 ["**That's cool!**"] False
以上就是为聊天机器人模型构建界面所需的全部代码。最后,我们将在指南的结尾提供一些运行在Spaces上的聊天机器人链接,以便你了解其他可能的功能:
- project-baize/Baize-7B:一个风格化的聊天机器人,可以停止生成或重新生成响应;
- MAGAer13/mPLUG-Owl:一个多模态聊天机器人,可以对响应进行点赞和点踩。
参考文献
- Gradio - guides - Chatbots