大模型0基础开发入门与实践:第10章 实战:搭建你的第一个对话机器人

第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 我们的"巨人":技术选型

要快速搭建应用,关键在于选择正确的工具。我们的策略是:复杂的工作交给"巨人",我们只做聪明的"指挥家"。

  1. 模型 (The Brain) : 我们将使用来自 Hugging Face Hub 的开源预训练模型。Hugging Face (🤗) 是目前全球最大、最活跃的AI社区和平台。你可以把它想象成"AI界的GitHub"。全世界的研究者和公司都会把他们训练好的模型(有大有小)上传到这里供大家使用。我们无需从头训练,可以直接下载一个已经很聪明的"大脑"来用。

  2. 模型调用库 (The Nerves) : 我们将使用Hugging Face官方出品的 transformers 库。这个库将加载、运行大模型的复杂过程,封装成了非常简洁的Python接口。特别是其 pipeline 功能,可以让你用一行代码就创建一个特定任务的完整调用流程(例如,文本生成、对话)。

  3. 用户界面 (The Face) : 我们将使用 Gradio 库。Gradio是一个神奇的工具,它可以自动为你的Python函数生成一个简洁、美观、可交互的Web UI。你只需要定义好输入和输出,Gradio会帮你处理所有前端的杂事。

graph TD subgraph 我们的技术栈 A[Hugging Face Hub
(提供开源模型)] --> 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行 : 导入我们需要的库,gradiotransformerspipeline
  • 第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 运行与体验

  1. 保存代码 :确保你已经将上面的代码保存为 app.py 文件。

  2. 运行脚本 :在你的终端中,cdapp.py所在的目录,然后运行:

    bash 复制代码
    python app.py
  3. 等待与观察

    • 如果你是第一次运行,终端会显示下载模型的进度条。请耐心等待它完成。

    • 下载并加载完毕后,你会看到类似下面的输出:

      复制代码
      模型加载完毕!
      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.
  4. 开始聊天

    • 在你的浏览器中打开那个本地网址 (local URL) http://127.0.0.1:7860
    • 你将看到一个设计精美的聊天界面。在底部的输入框中输入"你好!",然后按回车。片刻之后,机器人就会给你回复。
    • 尝试和它进行多轮对话,比如:
      • 你: "我喜欢看科幻电影"
      • 机器人: "我也是!你最喜欢哪一部?"
      • 你: "我最喜欢《星际穿越》"
      • 机器人: "那是一部伟大的电影!我也很喜欢它的配乐。"

恭喜你!你已经成功构建并运行了你的第一个对话机器人!

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"。但请注意,更强大的模型通常也更大,需要更多的下载时间和内存/显存。

3. 总结与预告

在本章,我们完成了一次从理论到实践的伟大飞跃。我们不再只是纸上谈兵,而是真正地动手创造了一个可交互的AI应用。

本章核心要点

  • 我们认识了Hugging Face 这个强大的AI军火库,并学会了如何利用**transformers库**的pipeline来轻松调用一个预训练好的对话模型。
  • 我们掌握了**Gradio**这个神奇的工具,它让我们只用几行Python代码就能生成一个功能完善的Web聊天界面。
  • 通过将二者结合,我们成功地构建并运行了第一个属于自己的对话机器人,直观地感受到了将理论知识转化为实际应用的过程。

现在,我们的机器人虽然能聊天,但它像一个被关在"小黑屋"里的天才,它所知道的一切都来自于它的训练数据。它无法获取最新的信息(比如今天的天气),也无法执行外部动作(比如帮你搜索资料或订一张机票)。

如何打破这个"次元壁",让大模型能够与外部世界私有数据 进行交互,甚至调用其他的API和工具?这将是我们下一章要探索的核心主题:《进阶:LangChain与外部工具调用》 。我们将学习一个强大的框架LangChain,它会像一个"超级胶水",将我们的大模型与各种外部能力粘合在一起,释放出远超对话本身的、更加强大的潜力。


4. 课后练习

  1. 更换模型 :请尝试将代码中的模型更换为"microsoft/DialoGPT-small"。观察并比较它与medium版本在回复速度和回复质量上有什么不同。
  2. 自定义UI :阅读Gradio ChatInterface的官方文档,尝试修改代码,为你的聊天机器人添加一个"主题(Theme)",或者在界面上增加一个你自己的头像。
  3. 思想实验:目前我们的机器人是"无状态"的,也就是说,每次你关闭程序再重新打开,它就忘记了之前的对话。如果想让它拥有长期记忆(例如,记住你的名字和偏好),请你从工程的角度,设想一下可以如何实现这个功能?(提示:可以考虑将对话历史保存到文件中。)