第10章 实战:搭建你的第一个对话机器人
1. 引言
欢迎来到我们这趟旅程中最令人兴奋的站点!在过去的九章里,我们如同在脑海中建造了一座宏伟的宫殿, meticulously 学习了从基础的神经元到复杂的Transformer架构,从"野蛮"的预训练到"文明"的对齊。我们知道了大模型"是什么"以及"为什么"如此强大。
现在,我们要做的,就是为这座宫殿打开大门,邀请所有人进来参观互动。理论的深度最终需要通过应用的广度来体现。是时候停止谈论,开始创造了!
本章,我们将完成一次激动人心的身份转变:从一个大模型知识的"学习者 ",转变为一个大模型应用的"创造者 "和"工程师"。我们将亲自动手,利用强大的开源工具和模型,只用几十行Python代码,就搭建起一个完全属于你、运行在你本地电脑上的对话机器人。
这不再是关于万亿参数的遥远想象,而是你指尖下实实在在的交互和创造。你会看到,那些复杂的理论,是如何被封装成简洁的接口,让我们能站在巨人的肩膀上,快速构建出有趣的应用。
本章学习目标:
- 熟悉Hugging Face生态:认识并学会使用业界领先的AI开源社区Hugging Face,了解其作为"AI界的GitHub"的核心价值。
- 掌握
transformers
库 :学会使用transformers
库中便捷的pipeline
(管道)功能,轻松加载和调用预训练好的大模型。 - 学会使用
Gradio
构建UI :掌握一个极其简单的Python库Gradio
,只需几行代码,就能为你的AI模型创建一个可交互的Web用户界面。 - 整合与实践:将模型、逻辑和界面三者结合,构建并运行你的第一个完整的对话机器人应用。
本章核心问题:
- 我们没有千亿参数的模型和成千上万的GPU,如何进行大模型开发?(利用开源模型)
- 如何用最简单的方式调用一个复杂的预训练模型,而无需关心其内部细节?(Hugging Face
pipeline
) - 我不是前端工程师,如何为我的Python程序创建一个好看的、可以分享的网页界面?(Gradio)
准备好你的"扳手"(Python环境),我们要把之前学到的所有零件,组装成第一台属于你的"AI引擎"了!
2. 正文
2.1 我们的"巨人":技术选型
要快速搭建应用,关键在于选择正确的工具。我们的策略是:复杂的工作交给"巨人",我们只做聪明的"指挥家"。
-
模型 (The Brain) : 我们将使用来自 Hugging Face Hub 的开源预训练模型。Hugging Face (🤗) 是目前全球最大、最活跃的AI社区和平台。你可以把它想象成"AI界的GitHub"。全世界的研究者和公司都会把他们训练好的模型(有大有小)上传到这里供大家使用。我们无需从头训练,可以直接下载一个已经很聪明的"大脑"来用。
-
模型调用库 (The Nerves) : 我们将使用Hugging Face官方出品的
transformers
库。这个库将加载、运行大模型的复杂过程,封装成了非常简洁的Python接口。特别是其pipeline
功能,可以让你用一行代码就创建一个特定任务的完整调用流程(例如,文本生成、对话)。 -
用户界面 (The Face) : 我们将使用
Gradio
库。Gradio是一个神奇的工具,它可以自动为你的Python函数生成一个简洁、美观、可交互的Web UI。你只需要定义好输入和输出,Gradio会帮你处理所有前端的杂事。
(提供开源模型)] --> B{我们的Python代码}; C[Transformers Library
(用于调用模型)] --> B; D[Gradio Library
(用于构建UI)] --> B; B -- 整合 --> E[对话机器人App!]; end
2.2 环境准备:安装必要的"零件"
在开始编码前,我们需要通过pip
来安装这三个核心库。打开你的终端或命令行,输入以下命令:
bash
pip install transformers torch gradio
transformers
: 我们刚刚介绍的模型调用库。torch
: PyTorch库。transformers
在底层依赖它来进行神经网络的计算。gradio
: 我们的UI构建库。
安装过程可能需要一些时间,因为它会下载好几个依赖包。请耐心等待其完成。
2.3 代码实战:构建一个多轮对话机器人
好了,环境已经就绪。现在,让我们看看用代码实现这一切有多么简单。
场景定义
我们要构建一个具有记忆能力的多轮对话机器人。你不仅可以问它一个问题,还可以基于之前的对话和它继续交流。
完整Python代码
创建一个名为 app.py
的文件,并将以下代码完整地复制进去。
python
# 1. 导入必要的库
import gradio as gr
from transformers import pipeline
# 2. 加载预训练的对话模型
# 我们使用Hugging Face上的'microsoft/DialoGPT-medium'模型
# 'pipeline'会自动处理模型的下载、加载和预处理
print("正在加载模型,请稍候...")
chatbot_pipeline = pipeline("conversational", model="microsoft/DialoGPT-medium")
print("模型加载完毕!")
# 3. 定义核心的对话函数
def chat_function(message, history):
"""
处理单次用户输入的函数。
:param message: 用户当前输入的一句话(字符串)。
:param history: Gradio自动维护的对话历史记录。
它是一个列表,每个元素是[用户输入, 机器人回复]的列表。
例如: [["你好", "你好!有什么可以帮你的吗?"], ["今天天气怎么样", "我是一个AI,无法感知天气。"]]
:return: 机器人生成的回复(字符串)。
"""
# transformers的对话pipeline需要一个特殊的输入格式,
# 我们需要将Gradio的history格式转换为pipeline需要的Conversation对象。
# 不过,一个更简单的方式是每次都将历史拼接成一个长文本(虽然这不是最高效的)。
# 这里我们为了简单起见,仅使用pipeline的内置记忆。
# 注意:'conversational' pipeline在内部会维护一个对话历史。
# 当我们反复调用同一个pipeline实例时,它能记住上下文。
# 但Gradio的ChatInterface每次调用函数都是独立的,所以我们需要手动管理历史。
# 一个简单的方式是每次都重新构建对话。
# Gradio的history是[[user1, bot1], [user2, bot2], ...],
# 我们需要把它传给pipeline。
# pipeline的调用方式是 `chatbot(Conversation("新消息", past_user_inputs=[], generated_responses=[]))`
# 我们来手动构建这个历史
past_user_inputs = []
generated_responses = []
for user_msg, bot_msg in history:
past_user_inputs.append(user_msg)
generated_responses.append(bot_msg)
# 调用pipeline获取回复
from transformers import Conversation
conversation = Conversation(message, past_user_inputs=past_user_inputs, generated_responses=generated_responses)
conversation = chatbot_pipeline(conversation)
# conversation.generated_responses[-1] 就是最新的机器人回复
return conversation.generated_responses[-1]
# 4. 使用Gradio创建聊天界面
# gr.ChatInterface会自动处理UI的渲染、输入输出的展示以及历史记录的管理
# 我们只需要将我们上面定义的 `chat_function` 作为核心逻辑传入即可
demo = gr.ChatInterface(
fn=chat_function,
title="我的第一个对话机器人",
description="这是一个使用Hugging Face和Gradio搭建的简单聊天机器人。",
chatbot=gr.Chatbot(height=300), # 自定义聊天框高度
textbox=gr.Textbox(placeholder="请输入你的问题...", container=False, scale=7), # 自定义输入框
retry_btn=None, # 去掉"重试"按钮
undo_btn="删除上一条", # 修改"撤销"按钮文字
clear_btn="清空聊天记录", # 修改"清空"按钮文字
)
# 5. 启动Web服务
if __name__ == "__main__":
# `share=True` 会生成一个公网可以访问的链接,方便你分享给朋友体验
demo.launch(share=True)
代码逐行讲解
- 第1-3行 : 导入我们需要的库,
gradio
和transformers
的pipeline
。 - 第6-10行 : 这是我们程序的核心。我们调用
pipeline("conversational", ...)
来创建一个对话任务管道。我们指定了模型为"microsoft/DialoGPT-medium"
,这是一个由微软发布的中等规模的对话模型,效果不错且对硬件要求不高。第一次运行时,pipeline
会自动从Hugging Face Hub下载模型文件(大概几GB),所以需要耐心等待。 - 第13-41行 : 这是我们定义的核心逻辑函数
chat_function
。Gradio的ChatInterface
在用户每次发送消息时,都会调用这个函数。它会自动传入两个参数:用户最新的消息message
和完整的对话历史history
。我们的函数需要做的,就是根据这两个输入,调用模型,并返回一个字符串作为机器人的回复。 - 第30-38行 : 我们将Gradio维护的
history
列表,转换成transformers
对话管道需要的格式,并调用chatbot_pipeline
来获得模型的回复。 - 第44-55行 : 见证奇迹的时刻 。我们只用一行核心代码
gr.ChatInterface(fn=chat_function, ...)
就创建了一个完整、漂亮的聊天机器人界面!我们把我们的逻辑函数chat_function
传给它,它就知道了如何处理用户的输入。其他参数都是为了让界面更好看的一些自定义选项。 - 第58-60行 :
demo.launch()
会启动一个本地的Web服务器。你可以在终端看到一个本地网址(通常是http://127.0.0.1:7860
)。
2.4 运行与体验
-
保存代码 :确保你已经将上面的代码保存为
app.py
文件。 -
运行脚本 :在你的终端中,
cd
到app.py
所在的目录,然后运行:bashpython app.py
-
等待与观察 :
-
如果你是第一次运行,终端会显示下载模型的进度条。请耐心等待它完成。
-
下载并加载完毕后,你会看到类似下面的输出:
模型加载完毕! Running on local URL: http://127.0.0.1:7860 Running on public URL: https://xxxxxxxxxx.gradio.live This share link expires in 72 hours. For free permanent hosting and GPU upgrades, run `gradio deploy` from Terminal.
-
-
开始聊天 :
- 在你的浏览器中打开那个本地网址 (local URL)
http://127.0.0.1:7860
。 - 你将看到一个设计精美的聊天界面。在底部的输入框中输入"你好!",然后按回车。片刻之后,机器人就会给你回复。
- 尝试和它进行多轮对话,比如:
- 你:
"我喜欢看科幻电影"
- 机器人:
"我也是!你最喜欢哪一部?"
- 你:
"我最喜欢《星际穿越》"
- 机器人:
"那是一部伟大的电影!我也很喜欢它的配乐。"
- 你:
- 在你的浏览器中打开那个本地网址 (local URL)
恭喜你!你已经成功构建并运行了你的第一个对话机器人!
2.5 Q&A: 你可能会问...
-
问:为什么第一次运行这么慢,而且占用了好多内存?
- 答 :第一次运行时,
transformers
库需要从网上下载模型的权重文件,DialoGPT-medium
模型大约有1.5GB,所以会比较慢。下载完成后,它会把模型加载到你的内存(或显存)中,这也会占用几个GB的空间。之后的运行就不需要再下载了,会快很多。
- 答 :第一次运行时,
-
问:为什么这个机器人的回答有时候看起来有点傻,或者会重复自己说过的话?
- 答 :这是一个非常好的问题!因为它只是一个经过预训练的基础对话模型,并没有经过我们第九章所学的、复杂的**对齐(Alignment)**过程(如RLHF)。它学会了如何"对话",但没有被精细地调教"如何进行高质量的对话"。这让你能更直观地感受到"对齐"的价值所在。像ChatGPT那样的流畅体验,是经过了大量对齐工作的成果。
-
问:我可以换一个更强大的模型吗?
- 答 :当然可以!这就是Hugging Face生态的魅力。你只需要在代码的第10行,把
model="microsoft/DialoGPT-medium"
换成Hugging Face Hub上的另一个对话模型的名字即可,例如"microsoft/DialoGPT-large"
。但请注意,更强大的模型通常也更大,需要更多的下载时间和内存/显存。
- 答 :当然可以!这就是Hugging Face生态的魅力。你只需要在代码的第10行,把
3. 总结与预告
在本章,我们完成了一次从理论到实践的伟大飞跃。我们不再只是纸上谈兵,而是真正地动手创造了一个可交互的AI应用。
本章核心要点:
- 我们认识了Hugging Face 这个强大的AI军火库,并学会了如何利用**
transformers
库**的pipeline
来轻松调用一个预训练好的对话模型。 - 我们掌握了**
Gradio
**这个神奇的工具,它让我们只用几行Python代码就能生成一个功能完善的Web聊天界面。 - 通过将二者结合,我们成功地构建并运行了第一个属于自己的对话机器人,直观地感受到了将理论知识转化为实际应用的过程。
现在,我们的机器人虽然能聊天,但它像一个被关在"小黑屋"里的天才,它所知道的一切都来自于它的训练数据。它无法获取最新的信息(比如今天的天气),也无法执行外部动作(比如帮你搜索资料或订一张机票)。
如何打破这个"次元壁",让大模型能够与外部世界 和私有数据 进行交互,甚至调用其他的API和工具?这将是我们下一章要探索的核心主题:《进阶:LangChain与外部工具调用》 。我们将学习一个强大的框架LangChain
,它会像一个"超级胶水",将我们的大模型与各种外部能力粘合在一起,释放出远超对话本身的、更加强大的潜力。
4. 课后练习
- 更换模型 :请尝试将代码中的模型更换为
"microsoft/DialoGPT-small"
。观察并比较它与medium
版本在回复速度和回复质量上有什么不同。 - 自定义UI :阅读Gradio
ChatInterface
的官方文档,尝试修改代码,为你的聊天机器人添加一个"主题(Theme)",或者在界面上增加一个你自己的头像。 - 思想实验:目前我们的机器人是"无状态"的,也就是说,每次你关闭程序再重新打开,它就忘记了之前的对话。如果想让它拥有长期记忆(例如,记住你的名字和偏好),请你从工程的角度,设想一下可以如何实现这个功能?(提示:可以考虑将对话历史保存到文件中。)