大语言模型应用构建指南-全-

大语言模型应用构建指南(全)

原文:Building LLM Apps: Create Intelligent Apps and Agents with Large Language Models

译者:飞龙

协议:CC BY-NC-SA 4.0

前言

通过本书,我们开始探索大型语言模型(LLMs)及其在人工智能(AI)领域所代表的变革范式。这本全面指南帮助您深入了解这些尖端技术的根本概念,从这些技术的坚实基础理论到 LLMs 提供的实际应用,最终聚焦于使用生成式 AI 解决方案时的伦理和责任考量。本书旨在为您提供对市场上新兴的 LLMs 如何影响个人、大型企业和社会的深刻理解。它侧重于如何构建由 LLMs 驱动的强大应用,利用新的 AI 编排器如 LangChain,并揭示现代应用开发中的新趋势。

在本书结束时,您将能够更轻松地导航快速发展的生成式 AI 解决方案生态系统;此外,您将拥有在日常工作以及商业中充分利用 LLMs 的工具。让我们开始吧!

本书面向对象

本书旨在主要吸引具有一定 Python 代码基础的技术受众。然而,理论章节和动手实践基于生成式 AI 基础和行业引领的用例,这也可能对非技术受众产生兴趣。

总体而言,本书面向那些希望全面了解大型语言模型(LLMs)的变革力量及其定义,并能够自信且前瞻性地在快速发展的 AI 领域中导航的个体。所有类型的读者都欢迎,但从中受益最大的读者包括:

  • 软件开发人员和工程师:本书为希望利用 LLMs 构建应用的开发者提供实用指导。它涵盖了将 LLMs 集成到应用后端、API、架构等方面的内容。

  • 数据科学家:对于有兴趣将 LLMs 部署到实际应用中的数据科学家,本书展示了如何将模型从研究阶段过渡到生产阶段。它涵盖了模型服务、监控和优化。

  • AI/ML 工程师:专注于 AI/ML 应用的工程师可以利用本书了解如何构建和部署 LLMs 作为智能系统和代理的一部分。

  • 技术创始人/CTO:初创公司创始人和技术总监可以使用本书评估在其应用和产品中是否以及如何使用 LLMs。它提供了技术概述,并考虑了商业因素。

  • 学生:攻读 AI、机器学习(ML)、自然语言处理(NLP)或计算机科学的研究生和高年级本科生可以通过本书了解 LLMs 在实际中的应用。

  • LLM 研究人员:致力于新型 LLM 架构、训练技术等工作的研究人员将获得对实际模型使用及其相关挑战的见解。

本书涵盖内容

第一章大型语言模型简介,介绍了 LLMs,这是生成 AI 领域中一套强大的深度学习神经网络。它介绍了 LLMs 的概念,它们与经典机器学习模型的区别,以及相关术语。它还讨论了最受欢迎的 LLMs 的架构,进而探讨 LLMs 的训练和消费方式,并将基础 LLMs 与微调 LLMs 进行比较。到本章结束时,你将了解 LLMs 是什么以及它们在 AI 领域的定位,为后续章节打下基础。

第二章LLMs 在 AI 应用中的运用,探讨了 LLMs 如何革命性地改变软件开发的世界,引领 AI 应用的新时代。到本章结束时,你将更清晰地了解 LLMs 如何嵌入不同的应用场景,借助目前 AI 开发市场中可用的新的 AI 编排框架。

第三章为你的应用选择 LLM,强调了不同的 LLM 可能具有不同的架构、大小、训练数据、能力和限制。为你的应用选择正确的 LLM 不是一个简单的决定,因为它可以显著影响解决方案的性能、质量和成本。在本章中,我们将指导你选择适合你应用的正确 LLM 的过程。我们将讨论市场上最有前途的 LLMs,比较 LLMs 时使用的最主要标准和工具,以及大小和性能之间的各种权衡。到本章结束时,你应该清楚地了解如何为你的应用选择正确的 LLM 以及如何有效地和负责任地使用它。

第四章提示工程,解释了为什么提示工程在设计 LLM 驱动的应用时是一项至关重要的活动,因为提示对 LLMs 的性能有巨大影响。实际上,有几种技术可以实现,不仅能够完善你的 LLM 的响应,还能降低与幻觉和偏见相关的风险。在本章中,我们将涵盖提示工程领域的最新技术,从基本方法到高级框架。到本章结束时,你将具备构建功能强大且稳固的提示的基础,这些提示对于即将到来的章节也将是相关的。

第五章在应用程序中嵌入 LLMs,讨论了随着使用 LLMs 开发应用程序的出现而引入软件开发领域的新组件集。为了使在应用程序流程中编排 LLMs 及其相关组件更加容易,出现了几个 AI 框架,其中 LangChain 是最广泛使用之一。在本章中,我们将深入研究 LangChain 及其使用方法,并学习如何通过 Hugging Face Hub 调用开源 LLM API,以及如何管理提示工程。到本章结束时,你将拥有使用 LangChain 和开源 Hugging Face 模型开始开发 LLM 驱动应用程序的技术基础。

第六章构建对话式应用程序,让我们通过第一个基于 LLMs 的应用程序的具体实现来开始本书的动手实践部分。在本章中,我们将逐步实现一个对话式应用程序,使用 LangChain 及其组件。我们将配置一个简单聊天机器人的架构,添加记忆组件、非参数化知识和使聊天机器人“有代理性”的工具。到本章结束时,你将能够仅用几行代码设置自己的对话式应用程序项目。

第七章使用 LLMs 的搜索和推荐引擎,探讨了 LLMs 如何通过嵌入和生成模型来增强推荐系统。我们将讨论推荐系统的定义和演变,了解生成式 AI 如何影响这一研究领域,并学习如何使用 LangChain 构建推荐系统。到本章结束时,你将能够创建自己的推荐应用程序,并利用 LangChain 作为框架来利用最先进的 LLMs。

第八章使用 LLMs 处理结构化数据,涵盖了 LLMs 的一个强大功能:处理结构化、表格数据的能力。我们将看到如何通过插件和有代理性的方法,我们可以将 LLMs 作为我们与结构化数据之间的自然语言界面,缩小业务用户与结构化信息之间的差距。为了演示这一点,我们将使用 LangChain 构建一个数据库助手。到本章结束时,你将能够为你的数据领域构建自己的自然语言界面,结合非结构化数据与结构化数据源。

第九章与代码一起工作,涵盖了 LLMs 的另一个重要能力:与编程语言一起工作。在前一章中,我们已经看到了这种能力的一瞥,当时我们要求我们的 LLM 生成针对 SQL 数据库的 SQL 查询。在本章中,我们将探讨 LLMs 可以用代码以哪些其他方式使用,从“简单”的代码理解和生成到构建表现得像算法的应用程序。到本章结束时,你将能够为你的编码项目构建由 LLM 驱动的应用程序,以及构建具有自然语言界面的 LLM 驱动的应用程序来处理代码。

第十章使用 LLMs 构建多模态应用程序,在构建代理的同时超越了 LLMs,引入了多模态的概念。我们将看到将不同 AI 领域的基座模型(语言、图像、音频)组合成一个单一代理的逻辑,该代理可以适应各种任务。你将学习如何使用 LangChain 构建一个多模态代理,使用单模态 LLMs。到本章结束时,你将能够构建自己的多模态代理,为其提供执行各种 AI 任务所需的工具和 LLMs。

第十一章微调大型语言模型,涵盖了微调 LLMs 的技术细节,从其背后的理论到使用 Python 和 Hugging Face 的动手实现。我们将深入探讨如何准备你的数据以微调基础模型,以及讨论你的微调模型的托管策略。到本章结束时,你将能够使用自己的数据微调 LLM,以便构建由该 LLM 驱动的特定领域应用。

第十二章负责任的 AI,介绍了减轻 LLMs(以及 AI 模型)潜在危害的学科基础——即负责任的 AI。这很重要,因为 LLMs 开启了新的风险和偏见的大门,这些风险和偏见在开发 LLM 驱动的应用程序时需要考虑。

然后,我们将转向与 LLMs 相关的风险以及如何使用适当的技术来预防或至少减轻它们。到本章结束时,你将更深入地了解如何防止 LLMs 使你的应用程序可能产生危害。

第十三章新兴趋势和创新,探讨了生成 AI 领域的最新进展和未来趋势。

为了充分利用本书

本书旨在提供 LLMs 是什么、它们的架构以及为什么它们正在革命化 AI 领域的坚实基础理论。它采用了一种动手方法,为你提供了一步一步的指南,用于实现特定任务的 LLMs 驱动的应用程序,并使用像 LangChain 这样的强大框架。此外,每个示例都将展示不同 LLM 的使用,以便你可以欣赏它们的差异化特点以及何时使用适当的模型来完成特定任务。

总体而言,本书将理论概念与实际应用相结合,对于想要在 LLMs 及其在 NLP 中的应用中获得坚实基础的人来说,是一本理想的资源。以下先决条件将帮助您最大限度地利用本书:

  • 对神经网络背后的数学(线性代数、神经元和参数以及损失函数)的基本理解

  • 对机器学习概念的基本理解,例如训练集和测试集、评估指标和自然语言处理

  • 对 Python 的基本理解

下载示例代码文件

本书代码包托管在 GitHub 上,网址为github.com/PacktPublishing/Building-LLM-Powered-Applications。我们还有其他来自我们丰富图书和视频目录的代码包,可在github.com/PacktPublishing/找到。查看它们吧!

下载彩色图像

我们还提供了一份包含本书中使用的截图/图表彩色图像的 PDF 文件。您可以从这里下载:packt.link/gbp/9781835462317

使用的约定

本书通篇使用了多种文本约定。

CodeInText:表示文本中的代码词汇、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟 URL、用户输入和 Twitter 昵称。例如:“我设置了两个变量system_messageinstructions。”

代码块设置为以下格式:

[default]
$pip install openai == 0.28
import os
import openai
openai.api_key = os.environment.get('OPENAI_API_KEY')
response = openai.ChatCompletion.create(
    model="gpt-35-turbo", # engine = "deployment_name".
    messages=[
        {"role": "system", "content": system_message},
        {"role": "user", "content": instructions},
    ]
) 

任何命令行输入或输出都按以下方式编写:

{'text': "Terrible movie. Nuff Said.[…]
 'label': 0} 

粗体:表示新术语、重要词汇或屏幕上看到的词汇。例如,菜单或对话框中的文字会像这样显示。例如:“[...]他发现重复提示末尾的主要指令可以帮助模型克服其内在的近期偏差。”

警告或重要提示如下所示。

技巧和窍门如下所示。

联系我们

我们欢迎读者的反馈。

一般反馈:请通过feedback@packtpub.com发送电子邮件,并在邮件主题中提及本书的标题。如果您对本书的任何方面有疑问,请通过questions@packtpub.com发送电子邮件给我们。

勘误表:尽管我们已经尽最大努力确保内容的准确性,但错误仍然可能发生。如果您在这本书中发现了错误,如果您能向我们报告,我们将不胜感激。请访问www.packtpub.com/submit-errata,点击提交勘误,并填写表格。

盗版:如果您在互联网上以任何形式遇到我们作品的非法副本,如果您能提供位置地址或网站名称,我们将不胜感激。请通过copyright@packtpub.com与我们联系,并附上材料的链接。

如果您有兴趣成为作者:如果您在某个领域有专业知识,并且您有兴趣撰写或为书籍做出贡献,请访问authors.packtpub.com

分享您的想法

一旦您阅读了《构建 LLM 驱动应用程序》,我们非常乐意听到您的想法!请点击此处直接访问该书的亚马逊评论页面并分享您的反馈。

您的评论对我们和科技社区非常重要,并将帮助我们确保我们提供高质量的内容。

下载本书的免费 PDF 副本

感谢您购买本书!

您喜欢在路上阅读,但无法携带您的印刷书籍到处走?

您选择的设备是否与您的电子书购买不兼容?

别担心,现在每购买一本 Packt 书籍,您都可以免费获得该书的 DRM 免费 PDF 版本。

在任何地方、任何设备上阅读。直接从您最喜欢的技术书籍中搜索、复制和粘贴代码到您的应用程序中。

优惠不止于此,您还可以获得独家折扣、时事通讯和丰富的免费内容,每天直接发送到您的邮箱。

按照以下简单步骤获取好处:

  1. 扫描下面的二维码或访问以下链接:

二维码图片

packt.link/free-ebook/9781835462317

  1. 提交您的购买证明。

  2. 就这些!我们将直接将免费 PDF 和其他好处发送到您的邮箱。

第一章:大型语言模型简介

亲爱的读者,欢迎来到构建大型语言模型应用!在这本书中,我们将探索一个新时代应用开发的迷人世界,其中大型语言模型LLMs)是主要角色。

在过去的一年里,我们都了解了 ChatGPT、Bing Chat、Bard 和 Dall-E 等生成式人工智能AI)工具的力量。最让我们印象深刻的是它们基于用户用自然语言提出的请求生成类似人类内容的能力。实际上,正是它们的对话能力使它们易于消费,因此一旦进入市场就变得流行。多亏了这个阶段,我们学会了承认生成式 AI 及其核心模型:LLM 的力量。然而,LLM 不仅仅是语言生成器。它们也可以被视为推理引擎,可以成为我们智能应用的头脑。

在本书中,我们将探讨如何构建由 LLM 驱动的应用的理论和实践,涵盖各种场景,并展示进入这个 AI 新时代软件开发领域的新组件和框架。本书将从第一部分开始,介绍 LLM 背后的理论,目前市场上最有前途的 LLM,以及为 LLM 驱动的应用而兴起的新框架。之后,我们将转向实践部分,使用各种 LLM 实现许多应用,解决不同的场景和现实世界问题。最后,我们将以第三部分结束本书,涵盖 LLM 领域的最新趋势,以及 AI 工具的风险以及如何通过负责任的 AI 实践来减轻这些风险。

那么,让我们深入探讨,并从我们所处环境的定义开始。本章提供了对 LLM 的介绍和深入研究,LLM 是一组强大的深度学习神经网络,它以生成 AI 领域为特征。

在本章中,我们将涵盖以下主题:

  • 理解 LLM,它们与经典机器学习模型的区别,以及相关的术语

  • 最受欢迎的 LLM 架构概述

  • LLM 的训练和消费方式

  • 基础型 LLM 与微调型 LLM

在本章结束时,你将掌握 LLM 的基本知识,了解它们是如何工作的,以及如何使它们更符合你的应用需求。这将为本书实践部分中 LLM 的具体应用铺平道路,在那里我们将看到如何在实践中将 LLM 嵌入到你的应用中。

什么是大型基础模型和 LLM?

LLM 是基于深度学习的模型,使用大量参数从大量未标记的文本中学习。它们可以执行各种自然语言处理任务,如识别、总结、翻译、预测和生成文本。

定义

深度学习是机器学习的一个分支,其特征是具有多层神经网络的神经网络,因此得名“深度”。这些深度神经网络可以自动学习层次化的数据表示,每一层从输入数据中提取越来越抽象的特征。这些网络的深度指的是它们所拥有的层数,这使得它们能够有效地模拟复杂数据集中的复杂关系和模式。

LLMs 属于一个更广泛的模型集合,这些模型具有人工智能子领域生成式人工智能的特征:大型基础模型(LFMs)。因此,在接下来的章节中,我们将探讨 LFMs 和 LLMs 的兴起和发展,以及它们的技术架构,这是理解它们的工作原理并在您的应用程序中正确采用这些技术的关键任务。

我们将首先了解为什么低秩因子分解(LFMs)和大型语言模型(LLMs)与传统人工智能模型不同,以及它们如何代表这一领域的范式转变。然后,我们将探讨 LLMs 的技术运作方式,它们是如何工作的,以及它们结果背后的机制。

人工智能范式转变——基础模型简介

基础模型是指一种预训练的生成式人工智能模型,通过适应各种特定任务而提供极大的灵活性。这些模型在大量且多样化的数据集上进行广泛的训练,使它们能够掌握数据中的通用模式和关系——不仅限于文本,还包括其他数据格式,如图像、音频和视频。这个初始的预训练阶段使模型在各个领域拥有强大的基础理解,为后续的微调奠定了基础。这种跨领域的功能将生成式人工智能模型与标准的自然语言理解(NLU)算法区分开来。

注意

生成式人工智能和 NLU 算法都与自然语言处理(NLP)相关,NLP 是处理人类语言的 AI 分支。然而,它们有不同的目标和应用。

生成式人工智能(Generative AI)与自然语言理解(NLU)算法之间的区别在于,生成式人工智能旨在创建新的自然语言内容,而 NLU 算法旨在理解现有的自然语言内容。生成式人工智能可用于文本摘要、文本生成、图像标题或风格迁移等任务。NLU 算法可用于聊天机器人、问答、情感分析或机器翻译等任务。

基础模型的设计考虑了迁移学习,这意味着它们可以有效地将预训练期间获得的知识应用于新的相关任务。这种知识迁移增强了它们的适应性,使它们能够以相对较少的额外训练快速掌握新任务。

基础模型的一个显著特点是它们的大型架构,包含数百万甚至数十亿个参数。这种广泛的规模使它们能够捕捉数据中的复杂模式和关系,从而有助于它们在各个任务上表现出令人印象深刻的表现。

由于它们具有全面的预训练和迁移学习能力,基础模型表现出强大的泛化能力。这意味着它们可以在各种任务上表现良好,并能够高效地适应新的、未见过的数据,从而消除了为单个任务训练单独模型的需要。

人工神经网络设计中的这种范式转变提供了相当多的优势,因为基础模型,凭借其多样化的训练数据集,可以根据用户的意图适应不同的任务,而不会损害性能或效率。在过去,为每个任务,如命名实体识别或情感分析,创建和训练不同的神经网络是必要的,但现在,基础模型为多个应用提供了一个统一且强大的解决方案。

图片

图 1.1:从特定任务模型到通用模型

现在,我们说 LFMs 是在不同格式的海量异构数据上训练的。每当这些数据是无结构化的自然语言数据时,我们将其输出的 LFM 称为 LLM,因为它专注于文本理解和生成。

一张白色卡的特写  自动生成的描述

图 1.2:LLMs 的特点

因此,我们可以认为 LLM 是一种专门为 NLP 任务设计的基础模型。这些模型,如 ChatGPT、BERT、Llama 以及许多其他模型,都是在大量文本数据上训练的,能够生成类似人类的文本,回答问题,执行翻译等。

尽管如此,LLMs 并不仅限于执行与文本相关的任务。正如我们将在整本书中看到的那样,这些独特的模型可以被视为推理引擎,在常识推理方面非常出色。这意味着它们可以帮助我们进行复杂任务、分析问题解决、增强信息片段之间的联系和洞察力。

事实上,正如我们将在下一节中看到的那样,LLMs 模仿我们大脑的构成方式,它们的架构以连接的神经元为特征。现在,人脑大约有 100 万亿个连接,远多于 LLM 内部的连接。尽管如此,LLMs 已被证明在将大量知识打包到那些较少的连接中方面比我们做得更好。

LLM 的内部结构

LLM 是一种特定类型的人工神经网络ANNs):受人类大脑结构和功能启发的计算模型。它们已被证明在解决复杂问题方面非常有效,尤其是在模式识别、分类、回归和决策任务等领域。

ANN 的基本构建块是人工神经元,也称为节点或单元。这些神经元被组织成层,神经元之间的连接被加权以表示它们之间关系的强度。这些权重代表了模型在训练过程中将要优化的参数

ANN 按定义是处理数值数据的数学模型。因此,当涉及到 LLMs 上下文中的非结构化文本数据时,有两个基本活动是必需的,以准备数据作为模型输入:

  • 分词:这是将文本片段(句子、段落或文档)分解成称为标记的更小单元的过程。这些标记可以是单词、子词,甚至字符,具体取决于选择的分词方案或算法。分词的目的是创建一个结构化的文本表示,以便机器学习模型能够轻松处理。

黑色矩形,黑色箭头指向黑色矩形,自动生成描述

图 1.3:分词的示例

  • 嵌入:一旦文本被分词,每个标记就被转换成一个称为嵌入的密集数值向量。嵌入是在语言模型训练期间学习到的,它捕捉了标记之间的语义关系。这种数值表示允许模型在标记上执行数学运算,并理解它们出现的上下文。

黑白图,自动生成描述

图 1.4:嵌入的示例

总结来说,分词将文本分解成称为标记的更小单元,而嵌入将这些标记转换成密集的数值向量。这种关系使得 LLMs 能够以有意义和上下文感知的方式处理和理解文本数据,从而能够以令人印象深刻的准确性执行广泛的 NLP 任务。

例如,让我们考虑一个二维嵌入空间,我们想要将单词 Man、King、Woman 和 Queen 向量化。想法是这些单词之间的数学距离应该代表它们的语义相似性。以下图表展示了这一点:

图 1.5:2D 空间中词语嵌入的示例

因此,如果我们正确地嵌入词语,则关系KingMan + WomanQueen应该成立。

一旦我们有了向量化的输入,我们就可以将其传递到多层神经网络中。主要有三种类型的层:

  • 输入层:神经网络的第一层接收输入数据。这一层的每个神经元对应于输入数据的一个特征或属性。

  • 隐藏层:在输入层和输出层之间,可以有一个或多个隐藏层。这些层通过一系列数学变换处理输入数据,并从数据中提取相关模式和表示。

  • 输出层:神经网络的最外层产生所需的输出,这可能是预测、分类或其他相关结果,具体取决于神经网络设计用于的任务。

图 1.6:通用人工神经网络的总体架构

训练人工神经网络的过程涉及根据训练数据和期望输出,通过迭代调整神经元之间连接的权重来进行的反向传播过程。

定义

反向传播 是一种在深度学习中用于训练神经网络的算法。它涉及两个阶段:正向传播,其中数据通过网络传递以计算输出,以及反向传播,其中错误被反向传播以更新网络的参数并提高其性能。这个迭代过程帮助网络从数据中学习并做出准确的预测。

在反向传播过程中,网络通过比较其预测与真实值以及最小化它们之间的错误或损失来学习。训练的目的是找到一组最优的权重,使神经网络能够对新、未见过的数据做出准确的预测。

人工神经网络的架构可以有所不同,包括层数、每层的神经元数量以及它们之间的连接。

当谈到生成式 AI 和大型语言模型时,它们根据我们的提示生成文本的非凡能力基于贝叶斯定理的统计概念。

定义

贝叶斯定理,以托马斯·贝叶斯牧师的名字命名,是概率论和统计学中的一个基本概念。它描述了如何根据新证据更新假设的概率。贝叶斯定理在我们想要在不确定性存在的情况下对未知参数或事件进行推理时特别有用。根据贝叶斯定理,给定两个事件 A 和 B,我们可以定义在给定 B 的条件下 A 的条件概率:

其中:

  • P(B|A) = 在给定 A 的情况下发生 B 的概率,也称为在固定的 BA 的似然性。

  • P(A|B) = 在给定 B 的情况下发生 A 的概率;也称为在给定 BA 的后验概率。

  • P(A) 和 P(B) = 在没有任何条件的情况下观察 AB 的概率。

贝叶斯定理将基于新证据的事件的条件概率与事件的事先概率相关联。在大型语言模型的背景下,我们说的是这样的模型通过预测用户提示的前一个单词后最有可能的下一个单词来工作。

但 LLM 如何知道下一个最有可能的词是什么呢?好吧,多亏了 LLM 在训练过程中所训练的巨大数据量(我们将在下一节中深入探讨 LLM 的训练过程)。基于训练文本语料库,模型将能够根据用户的提示识别出下一个最有可能的词,或者更普遍地说,是文本补全。

例如,让我们考虑以下提示:“猫在……上.”并且我们希望我们的 LLM 来完成这个句子。然而,LLM 可能会生成多个候选词,因此我们需要一种方法来评估哪个候选词最有可能。为此,我们可以使用贝叶斯定理来选择给定上下文中最可能的词。让我们看看所需的步骤:

  • 先验概率 P(A): 先验概率表示每个候选词在上下文中作为下一个词的概率,这是基于语言模型在训练期间学习到的知识。假设 LLM 有三个候选词:“table”,“chair”,和“roof”。

P(“table”), P(“chain”), 和 P(“roof”) 是每个候选词的先验概率,这些概率基于语言模型对训练数据中这些词频率的了解。

  • 似然 (P(B|A)): 似然表示每个候选词与上下文“猫在……上”的匹配程度。这是在给定每个候选词的情况下观察上下文的概率。LLM 根据训练数据和每个词在类似上下文中的出现频率来计算这个概率。

例如,如果 LLM 看到许多“猫在桌子上”的实例,它会给“table”作为给定上下文中的下一个词赋予高似然。同样,如果它看到许多“猫在椅子上”的实例,它会给“chair”作为下一个词赋予高似然。

P(“The cat is on the table”), P(“The cat is on the chair”), 和 P(“The cat is on the roof”) 是给定上下文中每个候选词的似然。

  • 后验概率 (P(A|B)): 使用贝叶斯定理,我们可以根据先验概率和似然计算每个候选词的后验概率:

图片

图片

图片

  • 选择最有可能的词。在计算每个候选词的后验概率后,我们选择后验概率最高的词作为最有可能的下一个词来完成句子。

LLM 使用贝叶斯定理和训练期间学习的概率来生成与上下文相关且有意义的内容,通过从训练数据中捕获模式和关联,以连贯的方式完成句子。

下面的图示说明了它如何转化为神经网络架构框架:

图片

图 1.7:预测 LLM 中的下一个最有可能的词

注意

ANN 的最后一层通常是一个非线性激活函数。在上面的图中,该函数是 Softmax,这是一个将实数向量转换为概率分布的数学函数。它在机器学习中常用于归一化神经网络或分类器的输出。Softmax 函数的定义如下:

图片

其中,z[i]是输入向量的第i个元素,K 是向量中的元素数量。Softmax 函数确保输出向量的每个元素都在 0 到 1 之间,并且所有元素的总和为 1。这使得输出向量适合表示不同类别或结果的概率。

总体而言,ANNs 是生成式 AI 模型发展的核心支柱:得益于它们的标记化、嵌入和多层隐藏机制,它们能够在最无结构的数据中捕捉复杂的模式,例如自然语言。

然而,我们今天所观察到的,是一系列展现出前所未有的惊人能力的模型,这要归功于近年来引入的特定的人工神经网络(ANNs)架构框架,它是 LLM 发展的主要推动者。这个框架被称为“转换器”,我们将在下一节中对其进行介绍。

最流行的基于 LLM 的转换器架构

正如我们在前面的章节中看到的,ANNs 是 LLMs 的核心。然而,为了成为生成式的,这些 ANNs 需要具备一些特殊的能力,例如并行处理文本句子或保持先前上下文的记忆。

这些特殊能力是过去几十年生成式 AI 研究的核心,从 20 世纪 80 年代和 90 年代开始。然而,直到最近几年,这些早期模型的主要缺点——如文本并行处理能力或内存管理——才被现代生成式 AI 框架所克服。这些框架就是所谓的转换器

在接下来的几节中,我们将探讨生成式 AI 模型架构的演变,从早期的发展到最先进的转换器。我们将从介绍为后续研究铺平道路的第一批生成式 AI 模型开始,突出它们的局限性以及克服这些局限性的方法。然后,我们将探讨基于转换器的架构的引入,涵盖它们的主要组件,并解释为什么它们代表了 LLMs 的当前最佳水平。

早期实验

第一个流行的生成式 AI ANN 架构可以追溯到 20 世纪 80 年代和 90 年代,包括:

  • 循环神经网络RNNs):RNNs 是一种用于处理序列数据的 ANN 类型。它们具有循环连接,允许信息在时间步之间持续存在,这使得它们适合语言建模、机器翻译和文本生成等任务。然而,由于梯度消失或爆炸问题,RNNs 在捕捉长距离依赖关系方面存在局限性。

    定义

    在 ANNs 中,梯度是衡量如果我们稍微调整模型的内部参数(权重),模型性能将提高多少的度量。在训练过程中,RNNs 通过根据损失函数的梯度调整其权重来最小化其预测与实际目标之间的差异。在训练过程中,当梯度变得极其小或大时,RNNs 会出现梯度消失或爆炸的问题。梯度消失问题发生在训练过程中梯度变得极其小的时候。结果,RNN 学习非常缓慢,难以捕捉数据中的长期模式。相反,梯度爆炸问题发生在梯度变得极其大的时候。这会导致训练不稳定,并阻止 RNN 收敛到良好的解决方案。

  • 长短期记忆LSTM):LSTMs 是一种解决梯度消失问题的 RNN 变体。它们引入了门控机制,使得在更长的序列中更好地保留重要信息。LSTMs 因其在文本生成、语音识别和情感分析等各种序列任务中的流行而变得流行。

这些架构在处理各种生成任务时都很受欢迎且有效,但在处理长距离依赖、可扩展性和整体效率方面存在局限性,尤其是在处理需要大量并行处理的大规模自然语言处理任务时。Transformer 框架的引入是为了克服这些局限性。在下一节中,我们将看到基于 Transformer 的架构如何克服上述局限性,并成为现代生成式 AI LLMs 的核心。

介绍 Transformer 架构

Transformer 架构是由 Vaswani 等人在 2017 年发表的论文“Attention Is All You Need”中引入的深度学习模型。它彻底改变了自然语言处理和其他序列到序列任务。

Transformer 完全摒弃了循环和卷积,完全依赖于注意力机制来编码和解码序列。

定义

在 Transformer 架构中,“注意力”是一种机制,它使模型能够在生成输出时关注输入序列的相关部分。它计算输入和输出位置之间的注意力分数,应用 Softmax 获取权重,并对输入序列进行加权求和以获得上下文向量。注意力对于捕捉数据中单词之间的长距离依赖关系和关系至关重要。

由于 transformer 在当前正在编码的相同序列上使用注意力,我们将其称为自注意力。自注意力层负责确定每个输入标记在生成输出中的重要性。它们回答了这样的问题:“我应该关注输入的哪个部分?

为了获得句子的自注意力向量,我们需要的是“值”、“查询”和“键”。这些矩阵用于计算输入序列中元素之间的注意力分数,并在训练过程中学习(通常用随机值初始化)。更具体地说,它们的作用如下:

  • 查询(Q)用于表示注意力机制的当前焦点

  • 键(K)用于确定输入的哪些部分应该给予注意力

  • 值(V)用于计算上下文向量

它们可以表示如下:

图片

图 1.8:输入矩阵分解为 Q、K 和 V 向量

这些矩阵随后相乘并通过非线性变换(归功于 Softmax 函数)。自注意力层的输出以转换后的、上下文感知的方式表示输入值,这使得 transformer 能够根据任务关注输入的不同部分。

图表,箱线图  描述自动生成

图 1.9:Q、K 和 V 矩阵乘积以获得上下文向量

数学公式如下:

图片

从架构角度来看,transformer 由两个主要组件组成,一个编码器和一个解码器:

  • 编码器接收输入序列并生成一系列隐藏状态,每个隐藏状态都是所有输入嵌入的加权求和。

  • 解码器接收输出序列(向右移动一个位置)并生成一系列预测,每个预测都是所有编码器隐藏状态和前一个解码器隐藏状态的加权求和。

注意

在解码器层中将输出序列向右移动一个位置的原因是为了防止模型在预测下一个标记时看到当前的标记。这是因为模型被训练为根据输入序列生成输出序列,输出序列不应依赖于自身。通过将输出序列向右移动,模型只能看到前一个标记作为输入,并学习根据输入序列和前一个输出标记来预测下一个标记。这样,模型可以学习生成连贯且有意义的话语,而不会作弊。

下面的插图来自原始论文,展示了 transformer 架构:

图  描述自动生成

图 1.10:简化的 transformer 架构

让我们逐一检查每个构建块,从编码部分开始:

  • 输入嵌入:这些是分词输入文本的向量表示。

  • 位置编码:由于变换器没有固有的词序感(与具有序列性质的 RNN 不同),因此将位置编码添加到输入嵌入中。这些编码提供了关于输入序列中单词位置的信息,使模型能够理解标记的顺序。

  • 多头注意力层:这是一种机制,其中多个自注意力机制并行地在输入数据的不同部分上操作,产生多个表示。这使得变换器模型能够并行地关注输入数据的不同部分,并从多个角度汇总信息。

  • 添加和归一化层:这结合了元素级加法和层归一化。它将层的输出添加到原始输入中,然后应用层归一化以稳定和加速训练。这项技术有助于减轻梯度相关的问题,并提高模型在序列数据上的性能。

  • 前馈层:这负责使用非线性激活函数(如之前提到的 Softmax)将注意力层的归一化输出转换为最终输出的合适表示。

变换器的解码部分从与编码部分类似的过程开始,其中目标序列(输出序列)经历输入嵌入和位置编码。让我们了解这些块:

  • 输出嵌入右移):对于解码器,目标序列被“右移”一个位置。这意味着在每个位置,模型试图预测原始目标序列中分析标记之后的标记。这是通过从目标序列中移除最后一个标记并用特殊的序列开始标记(开始符号)填充来实现的。这样,解码器通过在自回归解码期间根据先前的上下文生成正确的标记来学习。

定义

自回归解码是一种从预测每个输出标记的模型生成输出序列的技术,该模型基于先前输出的标记。它常用于自然语言处理任务,如机器翻译、文本摘要和文本生成。

自回归解码通过向模型提供一个初始标记(如序列开始符号)并使用模型的预测作为下一个输入标记来工作。这个过程重复进行,直到模型生成一个序列结束符号或达到最大长度。输出序列然后是所有预测标记的连接。

  • 解码器层:与编码器块类似,这里我们也有位置编码、多头注意力、添加和归一化以及前馈层,它们的作用与编码部分相同。

  • 线性与 Softmax:这些层分别对输出向量应用线性和非线性变换。非线性变换(Softmax)将输出向量转换为概率分布,对应于一组候选词。概率向量中最大元素对应的词将是整个过程的输出。

转换器架构为现代 LLM 铺平了道路,并且在其原始框架的基础上也出现了许多变化。

一些模型仅使用编码器部分,例如BERT双向编码器表示来自转换器),它被设计用于 NLU(自然语言理解)任务,如文本分类、问答和情感分析。

其他模型仅使用解码器部分,例如GPT-3生成预训练转换器 3),它被设计用于自然语言生成任务,如文本补全、摘要和对话。

最后,还有一些模型同时使用编码器和解码器部分,例如T5文本到文本转换转换器),它被设计用于各种可以表述为文本到文本转换的 NLP(自然语言处理)任务,如翻译、改写和文本简化。

不论是哪种变体,转换器的核心组件——注意力机制——在 LLM 架构中保持不变,这也代表了为什么这些框架在生成 AI 和 NLP 的背景下获得了如此多的关注。

然而,LLM 的架构变体并不是唯一影响该模型功能特性的元素。实际上,该模型的功能特性也由其训练数据集决定的“模型知道什么”以及根据其评估指标“模型如何根据用户请求应用其知识”来表征。

在下一节中,我们将介绍训练和评估 LLM 的过程,并提供区分不同 LLM 以及了解在您的应用程序中针对特定用例使用哪个 LLM 所需的指标。

训练和评估 LLM

在前面的章节中,我们看到了选择 LLM 架构是确定其功能的关键步骤。然而,输出文本的质量和多样性在很大程度上取决于两个因素:训练数据集和评估指标。

训练数据集决定了 LLM(大型语言模型)学习的数据类型以及它如何能够泛化到新的领域和语言。评估指标衡量 LLM 在特定任务和基准测试上的表现,以及它与其他模型和人类作者的比较。因此,选择合适的训练数据集和评估指标对于开发和评估 LLM 至关重要。

在本节中,我们将讨论在选择和使用不同训练数据集和评估指标时涉及的一些挑战和权衡,以及该领域的一些最新发展和未来方向。

训练 LLM

根据定义,LLM 从两个方面来看都是巨大的:

  • 参数数量:这是衡量 LLM 架构复杂度的指标,代表了神经元之间的连接数量。复杂的架构有数千层,每一层都有多个神经元,这意味着在层之间,我们将有多个带有相关参数(或权重)的连接。

  • 训练集:这指的是 LLM 学习和训练其参数的无标签文本语料库。为了说明 LLM 的文本语料库可能有多大,让我们考虑 OpenAI 的 GPT-3 训练集:

表格描述自动生成

图 1.11:GPT-3 知识库

考虑以下假设:

  • 1 个 token 约等于 4 个英语字符

  • 1 个 token 约等于 3/4 个单词

我们可以得出结论,GPT-3 大约训练了3740 亿个单词

所以一般来说,LLM 是通过在大量数据集上使用无监督学习进行训练的,这些数据集通常包含从互联网上不同来源收集的数十亿个句子。Transformer 架构,凭借其自注意力机制,使得模型能够高效地处理长序列的文本并捕捉词语之间的复杂依赖关系。训练此类模型需要大量的计算资源,通常采用具有多个图形处理单元(GPU)或张量处理单元(TPU)的分布式系统。

定义

张量是多维数组,在数学和计算机科学中使用。它包含数值数据,是机器学习等领域的基本元素。

TPU 是谷歌为深度学习任务创建的专用硬件加速器。TPU 针对张量操作进行了优化,使得它们在训练和运行神经网络时非常高效。它们提供快速处理的同时消耗更少的电力,使得数据中心中的模型训练和推理更快。

训练过程涉及对数据集的多次迭代,使用优化算法和反向传播微调模型的参数。通过这个过程,基于 Transformer 的语言模型获得了对语言模式、语义和上下文的深入理解,使它们能够在从文本生成到情感分析和机器翻译的广泛 NLP 任务中表现出色。

以下是在 LLM 训练过程中的主要步骤:

  1. 数据收集:这是一个从各种来源收集大量文本数据的过程,例如公开网络、书籍、新闻文章、社交媒体等。数据应该是多样化的、高质量的,并且能够代表 LLM 将遇到的自然语言。

  2. 数据预处理:这是清理、过滤和格式化数据以进行训练的过程。这可能包括删除重复项、噪声或敏感信息,将数据分割成句子或段落,将文本标记为子词或字符等。

  3. 模型架构:这是设计 LLM(大型语言模型)的结构和参数的过程。这可能包括选择神经网络的类型(例如 transformer)及其结构(例如仅解码器、仅编码器或编码器-解码器),层数和大小,注意力机制,激活函数等。

  4. 模型初始化:这是为 LLM 的权重和偏差分配初始值的过程。这可能通过随机分配或使用来自另一个模型的预训练权重来完成。

  5. 模型预训练:这是通过向 LLM 提供数据批次并计算损失函数来更新 LLM 的权重和偏差的过程。损失函数衡量 LLM 在给定前一个标记的情况下预测下一个标记的能力。LLM 通过使用优化算法(例如梯度下降)来调整权重和偏差,以减少损失并利用反向传播机制来最小化损失。模型训练可能需要多个 epoch(在整个数据集上的迭代)才能收敛到低损失值。

定义

在神经网络背景下,训练过程中的优化算法是用于找到最小化预测误差或最大化训练数据准确性的模型最佳权重集的方法。神经网络中最常见的优化算法是随机梯度下降SGD),它根据误差函数的梯度和当前输入-输出对以小步骤更新权重。SGD 通常与我们在本章中先前定义的反向传播相结合。

预训练阶段的输出被称为所谓的基模型。

  1. 微调:基模型通过使用由(提示,理想响应)元组组成的监督数据集进行监督训练。这一步骤是使基模型更符合 AI 助手(如 ChatGPT)所必需的。这一阶段的输出被称为监督微调SFT)模型。

  2. 基于人类反馈的强化学习RLHF):这一步骤包括通过更新其部分参数来迭代优化 SFT 模型(相对于奖励模型,通常是另一个结合人类偏好的 LLM 训练的模型)。

定义

强化学习RL)是机器学习的一个分支,专注于通过与环境交互来训练计算机做出最佳决策。计算机不是被给予明确的指令,而是通过试错来学习:通过探索环境和为其动作获得奖励或惩罚。强化学习的目标是找到最优行为或策略,以最大化给定模型的预期奖励或价值。为此,RL 过程涉及一个奖励模型RM),能够为计算机提供“偏好分数”。在 RLHF 的背景下,RM 被训练以结合人类偏好。

注意,RLHF(人类反馈强化学习)是实现人工智能系统与人类对齐的关键里程碑。由于生成人工智能领域的快速进展,持续赋予那些强大的 LLM(大型语言模型)以及更广泛的 LFM(语言模型)以典型的人类偏好和价值至关重要。

一旦我们有一个训练好的模型,下一步和最后一步就是评估其性能。

模型评估

评估传统的 AI 模型在某些方面是相当直观的。例如,让我们考虑一个图像分类模型,它必须确定输入图像代表的是狗还是猫。因此,我们在一组标记图像的训练数据集上训练我们的模型,一旦模型训练完成,我们就在未标记的图像上对其进行测试。评估指标仅仅是测试集中正确分类的图像占总图像数量的百分比。

当涉及到 LLM 时,情况略有不同。由于这些模型是在未标记的文本上训练的,并且不是针对特定任务的,而是根据用户的提示具有通用性和适应性,因此传统的评估指标不再适用。评估一个 LLM 意味着,在众多方面中,测量其语言流畅性、连贯性以及根据用户请求模仿不同风格的能力。

因此,需要引入一套新的评估框架。以下是最常用的用于评估 LLM 的框架:

  • 通用语言理解评估GLUE)和SuperGLUE:这个基准用于衡量 LLM 在多种自然语言理解(NLU)任务上的性能,例如情感分析、自然语言推理、问答等。在 GLUE 基准上的分数越高,LLM 在不同任务和领域中的泛化能力就越强。

它最近演变成一个以 GLUE 为风格的新的基准,称为SuperGLUE,它包含更困难的任务。它由八个需要比 GLUE 更高级推理技能的挑战性任务组成,例如自然语言推理、问答、指代消解等,一个广泛的覆盖诊断集,用于测试模型在多种语言能力和失败模式上的表现,以及一个根据模型在所有任务上的平均分数进行排名的排行榜。

GLUE 基准和 SuperGLUE 基准之间的区别在于,SuperGLUE 基准比 GLUE 基准更具挑战性和现实性,因为它涵盖了更复杂的任务和现象,要求模型处理多个领域和格式,并且具有更高的基准人类性能。SuperGLUE 基准旨在推动更通用和鲁棒的 NLU 系统开发的研究。

  • 大规模多任务语言理解MMLU):这个基准使用零样本和少样本设置来衡量 LLM 的知识。

定义

零样本评估的概念是一种在没有任何标记数据或微调的情况下评估语言模型的方法。它通过使用自然语言指令或示例作为提示,并计算给定输入的正确输出的可能性,来衡量语言模型执行新任务的能力。这是训练模型在没有需要标记的训练数据的情况下产生特定一组标记的概率。

这种设计增加了基准的复杂性,使其更接近于我们评估人类表现的方式。基准包括 14,000 个多项选择题,分为 57 组,涵盖 STEM、人文学科、社会科学和其他领域。它涵盖了从基础到高级专业水平的各种难度级别,评估了一般知识和解决问题的技能。主题包括传统领域,如数学和历史,以及法律和伦理等专门领域。广泛的主题范围和深度覆盖使这个基准对于揭示模型知识中的任何差距非常有价值。评分基于特定主题的准确性和所有主题的平均准确率。

  • HellaSwag:HellaSwag 评估框架是一种评估 LLM 在给定上下文中生成合理和常识性延续的能力的方法。它基于 HellaSwag 数据集,这是一个包含 70,000 个多项选择题的集合,涵盖了多样化的领域和类型,如书籍、电影、食谱等。每个问题由一个上下文(描述情况或事件的几个句子)和四个可能的结尾(一个正确和三个错误)组成。结尾被设计成对 LLM 来说难以区分,因为它们需要世界知识、常识推理和语言理解。

  • TruthfulQA:这个基准评估语言模型在生成问题回答的准确性。它包括 38 个类别(如健康、法律、金融和政治)中的 817 个问题。这些问题被设计成模仿人类可能由于错误信念或误解而回答错误的问题。

  • AI2 Reasoning ChallengeARC):这个基准用于衡量 LLM 的推理能力,并刺激能够执行复杂 NLU 任务的模型的发展。它由 7,787 个多项选择题的数据集组成,旨在鼓励高级问答研究。数据集分为简单集和挑战集,后者只包含需要复杂推理或额外知识才能正确回答的问题。基准还提供了一个超过 1400 万个科学句子的语料库,可以用作问题的支持证据。

需要注意的是,每个评估框架都专注于特定的功能。具体来说,GLUE 基准关注语法、释义和文本相似性,而 MMLU 关注各个领域和任务中的泛化语言理解。因此,在评估 LLM 时,重要的是要清楚了解最终目标,以便使用最相关的评估框架。或者,如果目标是任何任务中的最佳实践,关键不是只使用一个评估框架,而是多个框架的平均值。

此外,如果没有任何现有的 LLM 能够处理你的特定用例,你仍然有空间自定义这些模型,使它们更符合你的应用场景。在下一节中,我们将确实介绍 LLM 定制的现有技术,从最轻的(如提示工程)到从头开始训练整个 LLM。

基础模型与定制模型

LLM 的好处在于它们已经训练好并准备好使用。正如我们在上一节中看到的,训练 LLM 需要大量硬件投资(GPU 或 TPU),可能需要数月时间,这两个因素可能意味着对个人和小企业来说不可行。

幸运的是,预训练的 LLM 足够通用,可以应用于各种任务,因此可以直接通过它们的 REST API 进行消费,无需进一步调整(我们将在下一章深入探讨模型消费)。

尽管如此,可能存在一些场景,通用 LLM 不足以应对,因为它缺乏特定领域的知识或不符合特定的沟通风格和分类法。如果是这种情况,你可能想定制你的模型。

如何定制你的模型

定制你的模型主要有三种方法:

  • 扩展非参数化知识:这允许模型在响应用户查询时访问外部信息源,以整合其参数化知识。

定义

LLM 表现出两种类型的知识:参数化和非参数化。参数化知识是嵌入在 LLM 参数中的知识,来源于训练阶段的无标签文本语料库。另一方面,非参数化知识是我们可以通过嵌入文档“附加”到模型上的知识。非参数化知识不会改变模型的结构,而是允许它通过外部文档导航,用作回答用户查询的相关上下文。

这可能涉及将模型连接到网络资源(如维基百科)或具有特定领域知识的内部文档。将 LLM 连接到外部源的过程称为插件,我们将在本书的实践部分更深入地讨论它。

  • 少样本学习:在这种类型的模型定制中,LLM 被提供了一个包含少量示例(通常在 3 到 5 个之间)的元提示,这些示例是它被要求执行的新任务。模型必须使用其先验知识从这些示例中泛化以执行任务。

定义

元提示是一种可以用于通过几个示例提高 LLMs 在新任务上性能的消息或指令。

  • 微调:微调过程涉及使用较小、特定于任务的数据集来定制特定应用的基座模型。

这种方法与最初的方法不同,因为通过微调,预训练模型的参数被调整并优化以适应特定任务。这是通过在针对新任务的小型标记数据集上训练模型来完成的。微调背后的关键思想是利用从预训练模型中学到的知识,并将其微调以适应新任务,而不是从头开始训练一个模型。

数据处理流程图,描述自动生成

图 1.12:微调过程示意图

在前面的图中,你可以看到一个关于在 OpenAI 预建模型上如何进行微调的架构。其思想是,你有一个带有通用权重或参数的预训练模型可用。然后,你用自定义数据来喂养你的模型,通常是“键值”提示和完成的表单:

{"prompt": "<prompt text>", "completion": "<ideal generated text>"}
{"prompt": "<prompt text>", "completion": "<ideal generated text>"}
{"prompt": "<prompt text>", "completion": "<ideal generated text>"}
... 

一旦完成训练,你将有一个针对特定任务特别高效的定制模型,例如,你公司文档的分类。

微调的好处在于,你可以根据你的用例定制预建模型,而无需从头开始重新训练它们,同时利用较小的训练数据集,从而减少训练时间和计算。同时,模型保留了通过原始训练学到的生成能力和准确性,这是在大量数据集上发生的。

第十一章,“微调大型语言模型”中,我们将专注于在 Python 中微调你的模型,以便你可以测试它对你的任务。

在上述技术(你还可以将它们相互结合)之上,还有一个第四个技术,这是最“激进”的。它包括从头开始训练一个 LLM,你可能想自己构建或者从一个预建架构中初始化。我们将在最后一章中看到如何接近这种技术。

摘要

在本章中,我们探讨了大型语言模型(LLMs)的领域,对其架构、功能和训练过程进行了技术深入探讨。我们看到了最突出的架构,例如基于 transformer 的框架,训练过程是如何工作的,以及自定义你自己的 LLM 的不同方法。

我们现在有了理解什么是大型语言模型(LLMs)的基础。在下一章中,我们将看到如何使用它们,以及更具体地,如何使用它们构建智能应用。

参考文献

加入我们的 Discord 社区

加入我们社区的 Discord 空间,与作者和其他读者进行讨论:

packt.link/llm

第二章:LLMs 用于 AI 驱动应用程序

第一章大型语言模型简介中,我们将大型语言模型LLMs)介绍为具有生成能力和强大常识推理能力的强大基础模型。现在,下一个问题是:我应该用这些模型做什么?

在本章中,我们将看到 LLMs 如何彻底改变软件开发的世界,引领 AI 驱动应用程序的新时代。到本章结束时,你将更清楚地了解如何利用新的 AI 编排器框架将 LLMs 嵌入到不同的应用程序场景中,这些框架正在充斥着 AI 开发市场。

在本章中,我们将涵盖以下主题:

  • LLMs 如何改变软件开发

  • 代码伴侣系统

  • 介绍 AI 编排器以将 LLMs 嵌入到应用程序中

LLMs 如何改变软件开发

LLMs 已被证明具有非凡的能力:从自然语言理解任务(摘要、命名实体识别和分类)到文本生成,从常识推理到头脑风暴技能。然而,它们并不仅仅本身令人难以置信。正如第一章中讨论的,LLMs 以及一般而言的大型基础模型LFMs),通过作为构建强大应用程序的平台,正在彻底改变软件开发。

事实上,我们不必从头开始,今天的开发者可以通过调用 LLM 的托管版本来调用 API,并可以选择根据上一章中看到的方式进行定制。这种转变使得团队能够更轻松、更有效地将 AI 的力量整合到他们的应用程序中,类似于从专用计算到过去的时间共享的转变。

但在应用程序中具体如何整合 LLMs 呢?在整合 LLMs 时,有两个主要方面需要考虑:

  • 技术方面,涵盖了如何。将 LLMs 集成到应用程序中涉及通过 REST API 调用嵌入它们,并通过 AI 编排器管理它们。这意味着设置允许通过 API 调用无缝与 LLMs 通信的架构组件。此外,使用 AI 编排器有助于在应用程序中高效地管理和协调 LLMs 的功能,正如我们将在本章后面讨论的那样。

  • 概念方面,涵盖了什么。LLMs 带来了大量可以在应用程序中利用的新能力。这些能力将在本书的后续章节中详细探讨。一种看待 LLMs 影响的方式是将它们视为一种新的软件类别,通常被称为代码伴侣。这种分类突出了 LLMs 在增强应用程序功能方面提供的重大协助和协作。

我们将在本章后面深入探讨技术方面,而下一节将涵盖一个全新的软件类别——代码伴侣系统。

副驾驶系统

副驾驶系统是一种新的软件类别,它作为用户完成复杂任务的专家助手。这一概念由微软提出,并已应用于其应用程序中,例如 M365 副驾驶和新的 Bing,现在由 GPT-4 提供支持。使用这些产品相同的框架,开发者现在可以构建自己的副驾驶并将其嵌入到他们的应用程序中。

但副驾驶究竟是什么?

如其名所示,副驾驶旨在成为与用户并肩工作的 AI 助手,支持他们在各种活动中,从信息检索到博客写作和发布,从头脑风暴到代码审查和生成。

以下是副驾驶的一些独特特性:

  • 副驾驶由 LLM 驱动,或者更普遍地说,由 LFM 驱动,这意味着这些是使副驾驶“智能”的推理引擎。这个推理引擎是其组件之一,但不是唯一的。副驾驶还依赖于其他技术,如应用程序、数据源和用户界面,以向用户提供有用且引人入胜的体验。以下插图显示了这是如何工作的:

一个人物的卡通  描述自动生成

图 2.1:副驾驶由 LLM 驱动

  • 副驾驶被设计成具有会话式用户界面,允许用户使用自然语言与之交互。这减少了甚至消除了需要特定领域分类法(例如,查询表格数据需要了解编程语言如 T-SQL)的复杂系统与用户之间的知识差距。让我们看看这样一个对话的例子:

图 2.2:一个用于减少用户与数据库之间差距的对话式 UI 示例

  • 副驾驶有一个作用域。这意味着它被扎根于特定领域的数据,因此它只能在该应用程序或领域的范围内回答。

定义

扎根是通过使用 LLM 与特定用例的信息,这些信息是使用案例特定的、相关的,并且不是 LLM 训练知识的一部分。这对于确保输出质量、准确性和相关性至关重要。例如,假设你想要一个由 LLM 驱动的应用程序,在研究最新的论文(不包括在你的 LLM 训练数据集中)时帮助你。你还希望你的应用程序只有在答案包含在这些论文中时才做出回应。为此,你需要将你的 LLM 扎根于这些论文的集合,这样你的应用程序就只能在这个范围内做出回应。

通过一个名为检索增强生成(RAG)的架构框架实现扎根,这是一种通过在生成响应之前结合外部权威知识库的信息来增强 LLM 输出的技术。这个过程有助于确保生成的内容是相关、准确且最新的。

副驾驶和 RAG 之间的区别是什么?RAG 可以被看作是一种具有副驾驶特征的架构模式。每当我们要将副驾驶引导到特定领域的数据时,我们就使用 RAG 框架。请注意,RAG 不是唯一可以具有副驾驶特征的架构模式:还有其他框架,如函数调用或多智能体,我们将在本书中探讨。

例如,假设我们在公司内部开发了一个副驾驶,允许员工与企业知识库进行聊天。虽然这很有趣,但我们不能提供用户可以用来规划夏季旅行的副驾驶(那就像是在我们自己的托管成本下提供类似 ChatGPT 的工具!);相反,我们希望副驾驶仅限于我们的企业知识库,以便它只能对特定领域上下文相关的答案做出回应。

下图展示了引导副驾驶系统的示例:

图 2.3:引导副驾驶的示例

  • 副驾驶的能力可以通过技能进行扩展,这些技能可以是代码或对其他模型的调用。实际上,LLM(我们的推理引擎)可能存在两种类型的限制:

    • 参数知识有限。这是由于知识库截止日期,这是 LLM 的一个生理特征。实际上,它们的训练数据集总是会“过时”,不符合当前趋势。这可以通过添加非参数知识并通过引导来克服,如之前所见。

    • 缺乏执行权力。这意味着 LLM 本身没有执行动作的权限。以众所周知的 ChatGPT 为例:如果我们要求它生成一篇关于生产力技巧的领英帖子,我们随后需要将其复制粘贴到我们的领英个人资料上,因为 ChatGPT 本身无法完成这一操作。这就是我们需要插件的原因。插件是 LLM 连接外部世界的桥梁,不仅作为输入源来扩展 LLM 的非参数知识(例如,允许网络搜索),而且还作为输出源,以便副驾驶能够实际执行动作。例如,通过领英插件,我们由 LLM 驱动的副驾驶不仅能够生成帖子,还能够将其发布到网上。一个人指向插件的卡通  自动生成的描述

    图 2.4:维基百科和领英插件的示例

注意,用户在自然语言中的提示并非模型处理的唯一输入。实际上,它是我们基于 LLM 的应用程序的后端逻辑以及提供给模型的指令集的一个关键组成部分。这种元提示或系统消息是新学科提示工程的研究对象。

定义

提示工程是为各种应用程序和研究主题设计并优化 LLM 提示的过程。提示是用于引导 LLM 输出的简短文本。提示工程技能有助于更好地理解 LLM 的能力和局限性。

提示工程涉及选择合适的单词、短语、符号和格式,以从 LLM 中获得期望的响应。提示工程还涉及使用其他控制手段,如参数、示例或数据源,来影响 LLM 的行为。例如,如果我们想让我们的 LLM 驱动应用程序为 5 岁的孩子生成响应,我们可以在类似“扮演一个向 5 岁孩子解释复杂概念的教师”的系统消息中指定这一点。

实际上,安德烈·卡帕西(Andrej Karpathy),特斯拉前 AI 总监,于 2023 年 2 月重返 OpenAI,他在推特上表示:“英语是最新最热门的编程语言。”

我们将在第四章“提示工程”中更深入地探讨提示工程的概念。在下一节中,我们将关注新兴的 AI 编排器。

将 AI 编排器引入以将 LLM 嵌入到应用程序中

在本章的早期部分,我们看到了在将 LLM 整合到应用程序中时需要考虑的两个主要方面:技术方面和概念方面。虽然我们可以用名为 Copilot 的全新软件类别来解释概念方面,但在本节中,我们将进一步探讨如何在我们的应用程序中技术性地嵌入和编排 LLM。

AI 编排器的主要组件

从一方面来看,基础模型范式转变意味着在人工智能应用领域的大大简化:在生成模型之后,现在的趋势是消费模型。另一方面,在开发这种新型人工智能时可能会遇到许多障碍,因为其中有一些与大型语言模型(LLM)相关的组件是全新的,并且在应用生命周期中之前从未被管理过。例如,可能会有恶意行为者试图更改 LLM 指令(前面提到的系统消息),使得应用程序不遵循正确的指令。这是一个新的安全威胁集合的例子,这些威胁是 LLM 驱动应用程序的典型特征,需要用强大的反击或预防技术来解决。

下面的插图展示了此类应用程序的主要组件:

计算机程序图  自动生成描述

图 2.5:LLM 驱动应用程序的高级架构

让我们详细检查这些组件:

  • 模型:模型就是我们决定嵌入到我们的应用程序中的 LLM 类型。模型主要有两大类:

    • 专有 LLMs:由特定公司或组织拥有的模型。例如,由 OpenAI 开发的 GPT-3 和 GPT-4,或由 Google 开发的 Bard。由于它们的源代码和架构不可用,这些模型不能从头开始在自定义数据上重新训练,但在需要时可以进行微调。

    • 开源:代码和架构可以自由获取和分发的模型,因此它们也可以在自定义数据上从头开始训练。例如,由阿布扎比的技术创新研究所TII)开发的 Falcon LLM,或由 Meta 开发的 LLaMA。

我们将在第三章为您的应用程序选择一个 LLM中深入了解今天可用的主要 LLM 集。

  • 记忆:LLM 应用通常使用对话界面,这需要能够在对话中回溯到早期信息。这是通过一个“记忆”系统实现的,该系统允许应用程序存储和检索过去的交互。请注意,过去的交互也可能构成要添加到模型中的额外非参数知识。为了实现这一点,重要的是将所有过去的对话——适当嵌入——存储到 VectorDB 中,这是应用程序数据的核心。

定义

VectorDB 是一种基于向量嵌入存储和检索信息的数据库类型,这些嵌入是捕获文本意义和上下文的数值表示。通过使用 VectorDB,你可以根据意义的相似性而不是关键词进行语义搜索和检索。VectorDB 还可以通过提供上下文理解和丰富生成结果来帮助 LLMs 生成更相关和连贯的文本。VectorDB 的例子包括 Chroma、Elasticsearch、Milvus、Pinecone、Qdrant、Weaviate 以及Facebook AI Similarity SearchFAISS)。

FAISS 是由 Facebook(现在 Meta)于 2017 年开发的,是早期向量数据库之一。它旨在进行密集向量的高效相似性搜索和聚类,特别适用于多媒体文档和密集嵌入。最初,它是在 Facebook 的一个内部研究项目中。其主要目标是更好地利用 GPU 来识别与用户偏好相关的相似性。随着时间的推移,它发展成为可用的最快相似性搜索库,可以处理数十亿规模的数据集。FAISS 为推荐引擎和基于 AI 的助手系统开辟了可能性。

  • 插件:它们可以被视为可以集成到 LLM 中的附加模块或组件,以扩展其功能或使其适应特定任务和应用。这些插件作为附加组件,增强了 LLM 在核心语言生成或理解能力之外的特性。

插件背后的理念是使 LLMs 更加灵活和适应性强,允许开发者和用户根据他们的特定需求自定义语言模型的行为。可以创建执行各种任务的插件,并且它们可以无缝地集成到 LLM 的架构中。

  • 提示:这可能是 LLM 驱动的应用程序中最有趣和关键的部分。我们在上一节中已经引用了 Andrej Karpathy 的断言,“英语是最新最热门的编程语言”,你将在接下来的章节中理解原因。提示可以在两个不同的级别上定义:

    • “前端”,或用户所见:一个“提示”指的是模型输入。这是用户与应用程序交互的方式,以自然语言提问。

    • “后端”,或用户所见不到的:自然语言不仅是用户与前端交互的方式;它也是我们“编程”后端的方式。实际上,在用户的提示之上,有许多自然语言指令,或元提示,我们提供给模型,以便它能够正确地回答用户的查询。元提示的目的是指导模型按照预期的方式行动。例如,如果我们想限制我们的应用程序只回答与我们在 VectorDB 中提供的文档相关的问题,我们将在我们的元提示中指定以下内容:“只有当问题与提供的文档相关时才回答。

最后,我们来到了图 2.5所示的高级架构的核心,即AI 编排器。有了 AI 编排器,我们指的是那些使嵌入和编排 LLMs(大型语言模型)在应用程序中变得更加容易的轻量级库。

到了 2022 年底,随着 LLMs 的流行,市场上开始涌现出许多库。在接下来的几节中,我们将重点关注其中的三个:LangChain、Semantic Kernel 和 Haystack。

LangChain

LangChain 是由 Harrison Chase 在 2022 年 10 月作为开源项目推出的。它可以在 Python 和 JS/TS 中使用。它是一个用于开发由语言模型驱动的应用程序的框架,使它们具有数据感知性(具有扎根)和代理性——这意味着它们能够与外部环境交互。

让我们来看看 LangChain 的关键组件:

图片

图 2.6:LangChain 的组件

总体而言,LangChain 具有以下核心模块:

  • 模型:这些是将成为应用程序引擎的 LLMs 或 LFMs。LangChain 支持来自 OpenAI 和 Azure OpenAI 的专有模型,以及可以从Hugging Face Hub获取的开源模型。

定义

Hugging Face 是一家公司和一个社区,致力于构建和分享自然语言处理和其他机器学习领域的最先进模型和工具。它开发了 Hugging Face Hub,这是一个平台,人们可以在这里创建、发现和协作机器学习模型、LLMs、数据集和演示。Hugging Face Hub 在各个领域和任务中托管了超过 120k 个模型、20k 个数据集和 50k 个演示,例如音频、视觉和语言。

除了模型之外,LangChain 还提供了许多与提示相关的组件,这使得管理提示流程变得更加容易。

  • 数据连接器:这些是指构建所需的基本模块,用于检索我们希望提供给模型的额外外部知识(例如,在基于 RAG 的场景中)。数据连接器的例子包括文档加载器或文本嵌入模型。

  • 记忆:这允许应用程序在短期和长期内保持对用户交互的引用。它通常基于存储在 VectorDB 中的矢量化嵌入。

  • :这些是预定的一系列动作和对 LLM 的调用,这使得构建需要将 LLMs 链接在一起或与其他组件链接的复杂应用程序变得更加容易。链的一个例子可能是:获取用户查询,将其分成更小的部分,嵌入这些部分,在 VectorDB 中搜索相似的嵌入,使用 VectorDB 中最相似的三个部分作为上下文来提供答案,并生成答案。

  • 代理:代理是驱动 LLM 驱动的应用程序中决策的实体。它们可以访问一系列工具,并根据用户输入和上下文决定调用哪个工具。代理是动态和自适应的,这意味着它们可以根据情况或目标改变或调整其行为。

LangChain 提供以下好处:

  • LangChain 为我们之前提到的、与语言模型一起工作的必要组件提供了模块化抽象,例如提示、记忆和插件。

  • 除了这些组件之外,LangChain 还提供了预构建的 ,这是组件的结构化连接。这些链可以是针对特定用例预构建的,也可以是定制的。

在本书的 第二部分 中,我们将通过一系列基于 LangChain 的动手应用,从 第五章 开始,专注于将 LLMs 内置于您的应用程序中,我们将更深入地关注 LangChain 组件和整体框架。

Haystack

Haystack 是由 Deepset 开发的基于 Python 的框架,Deepset 是一家成立于 2018 年的柏林初创公司,由 Milos Rusic、Malte Pietsch 和 Timo Möller 创立。Deepset 为开发者提供构建基于自然语言处理(NLP)的应用程序的工具,随着 Haystack 的引入,他们将这些工具提升到了新的水平。

下面的插图显示了 Haystack 的核心组件:

图 2.7:Haystack 的组件

让我们详细看看这些组件:

  • 节点:这些是执行特定任务或功能的组件,例如检索器、阅读器、生成器、摘要器等。节点可以是 LLM 或其他与 LLM 或其他资源交互的实用工具。在 LLM 中,Haystack 支持专有模型,例如 OpenAI 和 Azure OpenAI 中可用的模型,以及来自 Hugging Face Hub 的开源模型。

  • 管道:这些是调用执行自然语言任务或与其他资源交互的节点的序列。管道可以是查询管道或索引管道,这取决于它们是否在文档集上执行搜索或为搜索准备文档。管道是预先确定和硬编码的,这意味着它们不会根据用户输入或上下文进行更改或适应。

  • 代理:这是一个使用 LLM 生成对复杂查询的准确响应的实体。代理可以访问一组工具,这些工具可以是管道或节点,并且可以根据用户输入和上下文决定调用哪个工具。代理是动态和自适应的,这意味着它可以根据情况或目标改变或调整其行为。

  • 工具:代理可以调用的函数来执行自然语言任务或与其他资源交互。工具可以是代理可用的管道或节点,它们可以被分组成工具包,这些工具包是一系列可以完成特定目标的工具。

  • DocumentStores:这些是存储和检索用于搜索的文档的后端。DocumentStores 可以基于不同的技术,包括 VectorDB(例如 FAISS、Milvus 或 Elasticsearch)。

Haystack 提供的一些好处包括:

  • 易用性:Haystack 易于使用且直观。它通常用于轻量级任务和快速原型。

  • 文档质量:Haystack 的文档被认为是高质量的,有助于开发者构建搜索系统、问答、摘要和对话式 AI。

  • 端到端框架:Haystack 覆盖了整个 LLM 项目生命周期,从数据预处理到部署。它非常适合大规模搜索系统和信息检索。

  • 关于 Haystack 的另一个优点是,你可以将其作为 REST API 部署,并且可以直接消费它。

语义内核

语义内核是我们将在本章中探索的第三个开源 SDK。它最初由微软开发,最初是用 C# 编写的,现在也支持 Python。

这个框架的名字来源于“内核”的概念,一般而言,内核指的是系统的核心或本质。在这个框架的上下文中,内核是指通过将一系列组件链接和连接成管道来处理用户输入的引擎,鼓励函数组合

定义

在数学中,函数组合是将两个函数组合起来创建一个新函数的方法。想法是使用一个函数的输出作为另一个函数的输入,形成一个函数链。两个函数 f 和 g 的组合表示为(f img/circle.png g),其中函数 g 首先应用,然后是函数 f img/arrow.png(f img/circle.png g)(x) = f(g(x))。

计算机科学中的函数组合是一个强大的概念,它通过将较小的函数组合成较大的函数来创建更复杂和可重用的代码。它增强了模块化和代码组织,使程序更容易阅读和维护。

以下是对语义内核解剖结构的说明:

图 2.8:语义内核的解剖结构

语义内核有以下主要组件:

  • 模型:这些是将成为应用程序引擎的 LLM 或 LFM。语义内核支持专有模型,例如 OpenAI 和 Azure OpenAI 中可用的模型,以及可以从 Hugging Face Hub 获取的开源模型。

  • 内存:它允许应用程序在短期和长期内保持对用户交互的引用。在语义内核的框架内,可以通过三种方式访问记忆:

    • 键值对:这包括保存存储简单信息的环境变量,例如名称或日期。

    • 本地存储:这包括将信息保存到可以通过其文件名检索的文件中,例如 CSV 或 JSON 文件。

    • 语义记忆搜索:这与 LangChain 和 Haystack 的记忆类似,因为它使用嵌入来表示和基于其意义搜索文本信息。

  • 函数:函数可以被视为混合 LLM 提示和代码的技能,目的是使用户的请求可解释和可操作。有两种类型的函数:

    • 语义函数:这是一种模板化提示,是一种自然语言查询,它指定了 LLM 的输入和输出格式,同时也结合了提示配置,该配置设置了 LLM 的参数。

    • 本地函数:这些指的是可以路由语义函数捕获的意图并执行相关任务的本地计算机代码。

为了举例说明,一个语义函数可以要求 LLM 写一段关于 AI 的短段落,而一个本地函数实际上可以在 LinkedIn 等社交媒体上发布。

  • 插件:这些是连接到外部来源或系统的连接器,旨在提供额外信息或执行自主操作的能力。语义内核提供了一些现成的插件,例如 Microsoft Graph 连接器套件,但你也可以通过利用函数(本地和语义,或两者的组合)来构建自定义插件。

  • 规划器: 由于 LLM 可以被视为推理引擎,它们也可以被用来自动创建链或管道以满足新用户的需求。这个目标是通过规划器实现的,它是一个接受用户任务作为输入并生成实现目标所需的一组动作、插件和函数的功能。

语义内核的一些好处包括:

  • 轻量级和 C#支持: 语义内核更轻量级,并包含 C#支持。对于 C#开发者或使用.NET 框架的开发者来说,它是一个极佳的选择。

  • 广泛的应用场景: 语义内核功能多样,支持各种与 LLM 相关的任务。

  • 行业引领: 语义内核是由微软开发的,它是公司构建自身协同飞行员框架所使用的框架。因此,它主要受行业需求和询问的驱动,使其成为企业级应用的稳固工具。

如何选择框架

总体而言,这三个框架提供,或多或少,类似的核心组件,有时被称为不同的分类法,但涵盖了协同飞行员系统概念中所示的所有模块。因此,一个自然的问题可能是:“我应该使用哪一个来构建我的 LLM 驱动应用程序?” 好吧,没有正确或错误答案!三者都非常有效。然而,有些特性可能对特定用例或开发者的偏好更为相关。以下是一些您可能想要考虑的标准:

  • 您熟悉或偏好的编程语言: 不同的框架可能支持不同的编程语言,或者与它们的兼容性或集成程度不同。例如,语义内核支持 C#、Python 和 Java,而 LangChain 和 Haystack 主要基于 Python(尽管 LangChain 也引入了对 JS/TS 的支持)。您可能希望选择一个与您现有技能或偏好相匹配的框架,或者允许您使用最适合您的应用程序领域或环境的语言。

  • 您想要执行或支持的自然语言任务类型和复杂性: 不同的框架可能具有不同的能力或特性来处理各种自然语言任务,例如摘要、生成、翻译、推理等。例如,LangChain 和 Haystack 提供了编排和执行自然语言任务的实用工具和组件,而语义内核允许您使用自然语言语义函数调用 LLM 和服务。您可能希望选择一个提供您为应用程序目标或场景所需的功能和灵活性的框架。

  • 您需要或希望对 LLM 及其参数或选项进行定制和控制的程度:不同的框架可能有不同的方式来访问、配置和微调 LLM 及其参数或选项,例如模型选择、提示设计、推理速度、输出格式等。例如,Semantic Kernel 提供了连接器,使得向您的 AI 应用中添加记忆和模型变得容易,而 LangChain 和 Haystack 允许您为文档存储、检索器、阅读器、生成器、摘要器和评估器插入不同的组件。您可能希望选择一个框架,它能够提供您对 LLM 及其参数或选项所需或希望达到的定制和控制的程度。

  • 框架的文档、教程、示例和社区支持的可获得性和质量:不同的框架可能有不同水平的文档、教程、示例和社区支持,这些可以帮助您学习、使用和调试框架。例如,Semantic Kernel 有一个包含文档、教程、示例和 Discord 社区的网站;LangChain 有一个包含文档、示例和问题的 GitHub 仓库;Haystack 有一个包含文档、教程、演示、博客文章和 Slack 社区的网站。您可能希望选择一个具有文档、教程、示例和社区支持的可获得性和质量,这可以帮助您开始使用框架并解决与框架相关的问题。

让我们简要总结一下这些编排器之间的差异:

| 功能 | LangChain | Haystack | Semantic Kernel |

| --- | --- | --- | --- |

| LLM 支持 | 专有和开源 | 专有和开源 | 专有和开源 |

| 支持的语言 | Python 和 JS/TS | Python | C#、Java 和 Python |

| 流程编排 | 链 | 节点管道 | 函数管道 |

| 部署 | 无 REST API | REST API | 无 REST API |

| 功能 | LangChain | Haystack | Semantic Kernel |

表 2.1:三种 AI 编排器的比较

总体而言,这三个框架都提供了一系列的工具和集成,以构建您的 LLM 驱动应用程序,并且一个明智的方法可能是使用与您当前技能或公司整体方法最一致的框架。

摘要

在本章中,我们深入探讨了 LLM(大型语言模型)正在铺就的新应用开发方式,正如我们介绍了协同驾驶员的概念并讨论了新 AI 编排器的出现。在这些中,我们重点关注了三个项目——LangChain、Haystack 和 Semantic Kernel——并检查了它们的功能、主要组件以及一些选择哪一个的标准。

一旦我们确定了人工智能编排器,另一个关键步骤就是决定我们想要嵌入到我们的应用程序中的 LLM(大型语言模型)。在第三章为您的应用程序选择一个 LLM,我们将了解市场上最突出的 LLM——既有专有也有开源的——并了解一些决策标准,以便根据应用程序用例选择合适的模型。

参考文献

加入我们的 Discord 社区

加入我们的社区 Discord 空间,与作者和其他读者进行讨论:

packt.link/llm

二维码

第三章:为您的应用选择 LLM

在上一章中,我们看到了在应用中正确编排大型语言模型LLM)及其组件是多么关键。事实上,我们看到了并非所有 LLM 都是相同的。下一个关键决策是实际使用哪些 LLM。不同的 LLM 可能具有不同的架构、大小、训练数据、能力和局限性。为您的应用选择正确的 LLM 不是一个简单的决定,因为它可能会对您解决方案的性能、质量和成本产生重大影响。

在本章中,我们将指导你通过选择适合您应用的正确 LLM 的过程。我们将涵盖以下主题:

  • 市场上最有前景的 LLM 概述

  • 比较 LLM 时使用的主要标准和工具

  • 大小与性能之间的权衡

到本章结束时,你应该清楚地了解如何选择适合您应用的正确 LLM,以及如何有效地和负责任地使用它。

市场上最有前景的 LLM

过去一年见证了 LLM 研究和开发的空前激增。不同组织发布了或宣布了几个新模型,每个模型都有其独特的特性和功能。其中一些模型是迄今为止最大、最先进的,其性能远远超过了之前的最先进水平SOTA)。其他模型则更轻量,但在特定任务上更加专业化。

在本章中,我们将回顾截至 2024 年市场上一些最有前景的 LLM(大型语言模型)。我们将介绍它们的背景、关键发现和主要技术。我们还将比较它们在各种基准和任务上的性能、优势和局限性。我们还将讨论它们在人工智能和社会未来的潜在应用、挑战和影响。

专有模型

专有 LLM 是由私人公司开发和拥有的,它们不公开代码。它们通常也需付费才能使用。

专有模型提供一系列优势,包括更好的支持和维护,以及安全性和一致性。由于它们的复杂性和训练数据集,它们在泛化方面通常优于开源模型。另一方面,它们充当一个“黑盒”,这意味着所有者不会向开发者公开源代码。

在接下来的几节中,我们将介绍截至 2023 年 8 月市场上最受欢迎的三种专有 LLM。

GPT-4

于 2023 年 3 月发布,GPT-4 与其新发布的“堂兄弟”GPT-4 Turbo 一起,是OpenAI开发的最新模型之一,在撰写本书时(根据其首席执行官山姆·奥特曼的确认,OpenAI 已经在开发 GPT-5),是市场上表现最好的模型之一。

它属于生成预训练转换器GPT)模型类别,这是一种由 OpenAI 引入的仅包含解码器的转换器架构。以下图表展示了基本架构:

图片

图 3.1:仅解码器转换器的高级架构

如前图所示,仅解码器架构仍然包括我们在第一章中介绍过的转换器架构的主要元素,包括位置嵌入多头注意力前馈层。然而,在这个架构中,模型仅由一个解码器组成,该解码器被训练根据前面的标记来预测序列中的下一个标记。与编码器-解码器架构不同,仅解码器设计缺少一个用于总结输入信息的显式编码器。相反,信息隐含地编码在解码器的隐藏状态中,该状态在生成过程的每一步都会更新。

现在,我们将探讨 GPT-4 相较于先前版本的一些改进。

GPT-4 与 GPT 系列中的先前模型一样,是在公开可用的和 OpenAI 许可的数据集上训练的(OpenAI 没有披露训练集的确切组成)。

此外,为了使模型更符合用户的意图,训练过程还涉及了基于人类反馈的强化学习RLHF)训练。

定义

RLHF 是一种旨在使用人类反馈作为评估 LLM 生成输出的指标,然后使用该反馈进一步优化模型的技术。实现该目标主要有两个步骤:

  1. 基于人类偏好训练奖励模型。

  2. 优化 LLM 以适应奖励模型。这一步骤是通过强化学习完成的,它是一种机器学习范式,其中代理通过与环境的交互来学习做出决策。代理根据其行为获得奖励或惩罚的反馈,其目标是通过对行为进行试错来不断调整其行为,以最大化累积奖励。

通过 RLHF(强化学习与人类反馈),得益于奖励模型,LLM 能够从人类偏好中学习,并更符合用户的意图。

以 ChatGPT 为例。该模型集成了各种训练方法,包括无监督预训练、监督微调、指令调整和 RLHF。RLHF 组件涉及通过使用来自人类训练师的反馈来训练模型预测人类偏好。这些训练师审查模型的响应并提供评分或更正,指导模型生成更有帮助、更准确和更符合预期的响应。

例如,如果一个语言模型最初生成的输出不太有帮助或不准确,人类训练师可以提供反馈,表明首选的输出。然后,该模型使用这些反馈来调整其参数并改进未来的响应。这个过程迭代地进行,模型从一系列人类判断中学习,以更好地符合人类标准认为的有用或适当的内容。

GPT-4 在常识推理和分析技能方面表现出卓越的能力。它已经与包括我们在第一章中提到的大规模多任务语言理解(MMLU)在内的 SOTA 系统进行了基准测试。在 MMLU 上,GPT-4 不仅在英语上,而且在其他语言上也优于之前的模型。

下面的插图显示了 GPT-4 在 MMLU 上的表现:

带有绿色和蓝色条的图表  自动生成的描述

图 3.2:GPT-4 在 MMLU 上的 3 次射击准确率(来源:openai.com/research/gpt-4

除了 MMLU 之外,GPT-4 在各种最先进(SOTA)系统和学术考试上进行了基准测试,正如您可以从以下图表中看到:

性能图表  自动生成的描述

图 3.3:GPT 在学术和专业考试中的表现(来源:arxiv.org/pdf/2303.08774.pdf

注意:在前面的图表中,您可以看到两个版本的 GPT-4,有视觉和无视觉(以及 GPT-3.5 用于基准测试)。这是因为 GPT-4 是一个多模态模型,意味着它可以接受图像作为输入,除了文本。然而,在本章中,我们将仅对其文本能力进行基准测试。

与其前辈(GPT-3.5 和 GPT-3)相比,GPT-4 的一个显著改进是幻觉风险的明显降低。

定义

幻觉是一个描述 LLMs 生成不正确、无意义或不真实的文本,但看起来似乎合理或连贯的现象。例如,一个 LLM 可能会虚构一个与来源或常识相矛盾的事实,一个不存在的名字,或者一个没有意义的句子。

幻觉可能发生,因为大型语言模型(LLMs)并非存储或检索事实信息的数据库或搜索引擎。相反,它们是统计模型,从大量文本数据中学习并基于它们学到的模式和概率生成输出。然而,这些模式和概率可能并不反映真相或现实,因为数据可能是不完整、嘈杂或存在偏见的。此外,LLMs 的上下文理解和记忆有限,因为它们一次只能处理一定数量的标记并将它们抽象为潜在表示。因此,LLMs 可能会生成不支持任何数据或逻辑的文本,但这些文本是最可能或与提示最相关的。

事实上,尽管它仍然不是 100%可靠的,但 GPT-4 在 TruthfulQA 基准测试中取得了很大的进步,这些基准测试测试了模型区分事实和错误陈述的能力(我们在第一章模型评估部分介绍了 TruthfulQA 基准测试)。

在这里,你可以看到一幅插图,比较了 GPT-4 在 TruthfulQA 基准测试中的结果与 GPT-3.5(OpenAI 的 ChatGPT 背后的模型)和 Anthropic-LM(我们将在下一节中介绍这个模型)的结果。

不同颜色方块的图表,描述由系统自动生成

图 3.4:在 TruthfulQA 基准测试中的模型比较(来源:openai.com/research/gpt-4

最后,随着 GPT-4 的推出,OpenAI 做出了额外的努力使其更安全、更对齐,从一开始就组建了一个由 50 多位专家组成的团队,这些专家在 AI 对齐风险、隐私和网络安全等领域,目标是了解这样一个强大模型的风险程度以及如何预防这些风险。

定义

对齐是指 LLM(大型语言模型)在多大程度上以对人类用户有用且无害的方式行事。例如,如果一个 LLM 生成的文本是准确、相关、连贯且尊重的,那么它可以被认为是对齐的。如果一个 LLM 生成的文本是虚假的、误导性的、有害的或冒犯性的,那么它可以被认为是未对齐的。

多亏了这次分析,在训练 GPT-4 时收集并使用了更多数据,以减轻其潜在风险,从而使其风险比其前身 GPT-3.5 有所降低。

Gemini 1.5

Gemini 1.5 是由谷歌开发并于 2023 年 12 月发布的 SOTA(最先进的技术)生成式 AI 模型。与 GPT-4 一样,Gemini 被设计成多模态,这意味着它可以处理和生成各种模态的内容,包括文本、图像、音频、视频和代码。它基于一个专家混合MoE)的 transformer。

定义

在 transformer 架构的背景下,MoE 指的是在其层中包含多个专门子模型(称为“专家”)的模型。每个专家都是一个神经网络,旨在更有效地处理不同类型的数据或任务。MoE 模型使用门控机制或路由器来确定哪个专家应该处理给定的输入,这使得模型能够动态分配资源并专门处理某些类型的信息。这种方法可以导致更高效的训练和推理,因为它使得模型在规模和复杂性上可以扩展,而不会导致计算成本的成比例增加。

Gemini 有多种尺寸,包括 Ultra、Pro 和 Nano,以满足从数据中心到移动设备的不同计算需求。要使用 Gemini,开发者可以通过为不同模型变体提供的 API 访问它,从而将其功能集成到应用程序中。

与其前一代版本 Gemini 1.0 相比,当前模型在文本、视觉和音频任务上表现更优,如下面的截图所示:

图 3.5:Gemini 1.5 Pro 和 Ultra 与其前一代版本 1.0 的比较(来源:storage.googleapis.com/deepmind-media/gemini/gemini_v1_5_report.pdf

类似地,它在数学、科学、推理以及编码和多元语言等领域也展现了卓越的能力:

图 3.6:Gemini 1.5 Pro 与 Gemini 1.0 Pro 和 Ultra 在不同基准测试中的比较(来源:storage.googleapis.com/deepmind-media/gemini/gemini_v1_5_report.pdf

注意,Gemini 1.5 Pro 在多个领域的许多基准测试中表现优于 Gemini 1.0 Ultra(后者体积显著更大)。截至今天,您可以通过 gemini.google.com 的网页应用程序免费试用 Gemini Pro,而 Gemini Ultra 则可通过带有月费的付费订阅获得。另一方面,专为移动设备定制的 Gemini Nano 可以通过 Google AI Edge SDK for Android 在具备能力的 Android 设备上运行。请注意,截至 2024 年 4 月,此 SDK 仍处于早期访问预览阶段,您可以在 docs.google.com/forms/d/e/1FAIpQLSdDvg0eEzcUY_-CmtiMZLd68KD3F0usCnRzKKzWb4sAYwhFJg/viewform 申请早期访问计划。最后,开发人员也可以通过 Google AI Studio 的 REST API 使用 Gemini Pro 和 Ultra。

Claude 2

Claude 2,代表通过用户数据和专业知识进行宪法规模对齐,是由前 OpenAI 研究员创立的研究公司 Anthropic 开发的 LLM。它于 2023 年 7 月宣布。

Claude 2 是一个基于 transformer 的 LLM,它通过无监督学习、RLHF 和 宪法 AICAI)在互联网上公开可用的信息和专有数据混合训练而成。

CAI 是 Claude 的一个真正独特之处。事实上,Anthropic 对 Claude 2 的安全原则对齐给予了极大的关注。更具体地说,Anthropic 开发了这种独特的 CAI 技术,该技术在 2022 年 12 月发表的论文 宪法 AI:从 AI 反馈中无害 中被披露。

CAI 旨在通过防止产生有害或歧视性输出,不帮助人类参与非法或不道德的活动,以及广泛创建一个有益、诚实且无害的 AI 系统,来使模型更安全并与其人类价值观和意图保持一致。为了实现这一点,它使用一系列原则来指导模型的行为和输出,而不是仅仅依赖于人类反馈或数据。这些原则来自各种来源,例如联合国人权宣言、信任和安全最佳实践、其他 AI 研究实验室提出的原则、非西方观点和实证研究。

CAI 在训练过程的两个阶段使用这些原则:

  • 首先,该模型被训练使用原则和一些示例来批评和修改自己的响应。

  • 第二,该模型通过强化学习进行训练,但不是使用人类反馈,而是使用基于原则生成的 AI 反馈来选择更无害的输出。

以下插图展示了根据 CAI 技术进行的训练过程:

流程图示意图  自动生成描述

图 3.7:根据 CAI 技术进行的 Claude 的训练过程(来源:arxiv.org/abs/2212.08073)

Claude 2 的另一个特点是上下文长度,其限制为 100,000 个标记。这意味着用户可以输入更长的提示,例如页面的技术文档或甚至一本书,无需嵌入。此外,与其他 LLM 相比,该模型还可以生成更长的输出。

最后,Claude 2 在处理代码时也展示了相关能力,在 HumanEval 基准测试中得分 71.2%。

定义

HumanEval 是评估 LLM 代码生成能力的基准。它由 164 个由人类编写的 Python 编码问题组成,每个问题都有一个提示、一个解决方案和一个测试套件。这些问题涵盖了各种主题,如数据结构、算法、逻辑、数学和字符串操作。该基准可以用来衡量 LLM 输出的功能性正确性、语法有效性和语义一致性。

总体而言,Claude 2 是一个非常有趣的模型,也是 GPT-4 的竞争对手,值得关注。它可以通过 REST API 或直接通过 Anthropic 的 beta 聊天体验(截至 2023 年 8 月仅限美国和英国用户)进行消费。

以下比较表展示了三个模型之间的主要区别:

| | GPT-4 | Gemini | Claude 2 |

| --- | --- | --- | --- |

| 公司或机构 | OpenAI | Google | Anthropic |

| 首次发布 | 2023 年 3 月 | 2023 年 12 月 | 2023 年 7 月 |

| 架构 | 基于 Transformer,仅解码器 | 基于 Transformer | 基于 Transformer |

| 大小和变体 | 参数未正式公布两种上下文长度变体:GPT-4 8K 标记 GPT-4 32K 标记 | 从最小到最大有三个尺寸:Nano、Pro 和 Ultra | 参数未正式公布 |

| 如何使用 | OpenAI 开发者平台上的 REST API 使用 OpenAI Playground 在platform.openai.com/playground | Google AI Studio 上的 REST API 使用 Gemini 在gemini.google.com/ | 在www.anthropic.com/claude编译表单后的 REST API |

表 3.1:GPT-4、PaLM 2 和 Claude 2 的比较表

除了专有模型之外,目前市场上还有大量开源的 LLM(大型语言模型)。让我们在下一节中讨论其中的一些。

开源模型

开源模型的优势在于,根据定义,开发者可以完全看到并访问源代码。在 LLM 的背景下,这意味着以下内容:

  • 你对架构有主要控制权,这意味着你还可以修改你将在项目中使用的本地版本。这也意味着它们不太可能受到模型所有者对源代码进行的潜在更新的影响。

  • 有可能从头开始训练你的模型,除了对专有模型也适用的经典微调之外。

  • 免费使用,这意味着在使用这些 LLM 时,你不会产生任何费用,与那些按使用付费的专有模型形成对比。

为了比较开源模型,在这本书中,我们将参考独立的 Hugging Face Open LLM 排行榜(你可以在huggingface.co/spaces/HuggingFaceH4/open_llm_leaderboard找到),这是一个旨在评估和比较 LLM 在各种自然语言理解NLU)任务上性能的项目。该项目托管在 Hugging Face Spaces 上,这是一个用于创建和分享机器学习应用的平台。

Open LLM 排行榜使用四个主要的评估基准,我们在第一章模型评估部分进行了介绍:

  • AI2 推理挑战ARC):小学科学问题和复杂的 NLU 任务。

  • HellaSwag:常识推理。

  • MMLU:包括数学、计算机科学和法律等多个领域的任务。

  • TruthfulQA:评估模型在生成答案时的真实性。

尽管这些只是众多 LLM 基准测试中的一部分,但我们将坚持使用这个排行榜作为参考评估框架,因为它被广泛采用。

LLaMA-2

大型语言模型 Meta AI 2LLaMA-2)是 Meta 开发的新一代模型,于 2023 年 7 月 18 日向公众公布,开源且免费(其首个版本最初仅限于研究人员)。

它是一个自回归模型,具有优化且仅包含解码器的 transformer 架构。

定义

在 Transformer 的上下文中,自回归的概念指的是模型在给定所有先前标记的条件下预测序列中的下一个标记。这是通过在输入中屏蔽未来标记来完成的,这样模型就只能关注过去标记。例如,如果输入序列是“The sky is blue”,模型将首先预测“The”,然后是“sky”,接着是“is”,最后是“blue”,使用掩码隐藏每个预测之后的标记。

LLaMA-2 模型有三种大小:70 亿、130 亿和 700 亿参数。所有版本都在 2000 万亿标记上训练,上下文长度为 4092 个标记。

此外,所有模型大小都附带一个“聊天”版本,称为 LLaMA-2-chat,与基础模型 LLama-2 相比,它在通用对话场景中更加灵活。

注意

在 LLM 的背景下,基础模型与“聊天”或助手模型之间的区别主要在于它们的训练和预期用途:

  • 基础模型:这些模型在大量的文本数据上训练,通常来自互联网,其主要功能是在给定上下文中预测下一个单词,这使得它们在理解和生成语言方面非常出色。然而,它们可能并不总是精确或专注于特定指令。

  • 助手模型:这些模型最初是基础 LLM,但通过包含指令和模型尝试遵循这些指令的输入输出对进行进一步微调。它们通常使用 RLHF 来细化模型,使其更擅长提供帮助、诚实和无害。因此,它们不太可能生成有问题的文本,更适合聊天机器人内容和内容生成等实际应用。例如,助手模型 GPT-3.5 Turbo(ChatGPT 背后的模型)是完成模型 GPT-3 的微调版本。

从本质上讲,虽然基础模型提供了对语言的广泛理解,但助手模型经过优化以遵循指令并提供更准确和上下文相关的响应。

LLaMA-2-chat 是通过一个包含两个主要步骤的微调过程开发的:

  1. 监督微调:这一步骤涉及在公开可用的指令数据集和超过 100 万人的标注上进行模型微调,使其在对话用例中更有帮助和安全。微调过程使用所选提示列表来引导模型输出,并使用一个鼓励多样性和相关性的损失函数(这就是为什么它被称为“监督”)。

  2. RLHF:正如我们在介绍 GPT-4 时所看到的,RLHF 是一种旨在使用人类反馈作为评估 LLM 生成输出的指标的技术,然后使用该反馈进一步优化模型。

以下是如何进行 LLaMA 训练过程的说明:

图片

图 3.8:两步微调以获得 LLaMa-2 聊天(来源:ai.meta.com/resources/models-and-libraries/llama/)

要访问该模型,您需要在 Meta 的网站上提交一个请求(表格可在 ai.meta.com/resources/models-and-libraries/llama-downloads/ 找到)。一旦提交请求,您将收到一封电子邮件,其中包含您将能够下载以下资产的 GitHub 仓库:

  • 模型代码

  • 模型权重

  • README(用户指南)

  • 负责任的使用指南

  • 许可证

  • 可接受的使用政策

  • 模型卡

Falcon LLM

Falcon LLM 是 LLM 的一种新趋势的表示,包括构建更轻的模型(参数更少)并专注于训练数据集的质量。事实上,这是一个事实,即像 GPT-4 这样具有万亿参数的复杂模型在训练阶段和推理阶段都非常沉重。这暗示了需要高且昂贵的计算能力(GPU 和 TPU 驱动)以及漫长的训练时间。

Falcon LLM 是阿布扎比的 技术创新研究所TII)于 2023 年 5 月推出的开源模型。它是一个自回归的、仅解码器的变压器,在 1 万亿个标记上训练,拥有 40 亿个参数(尽管它也以 70 亿参数的轻量版本发布)。与 LlaMA 类似,Falcon LLM 还附带了一个经过微调的变体,称为“Instruct”,该变体旨在遵循用户的指令。

定义

Instruct 模型专门用于遵循短格式指令。指令遵循是一个任务,其中模型必须执行一个自然语言命令或查询,例如“写一首关于猫的俳句”或“告诉我巴黎的天气。”Instruct 微调模型是在一个包含指令及其相应输出的大型数据集上训练的,例如斯坦福 Alpaca 数据集。

根据开放 LLM 排行榜,自发布以来,Falcon LLM 一直位居全球前列,仅次于一些 LlaMA 的版本。

所以,问题可能就是:一个“仅有”40 亿参数的模型是如何表现得如此出色的?实际上,答案在于数据集的质量。Falcon 是使用专用工具开发的,并集成了独特的数据管道,能够从网络数据中提取有价值的内容。该管道通过采用广泛的过滤和去重技术来设计,以提取高质量的内容。由此产生的数据集,称为 RefinedWeb,已由 TII 在 Apache-2.0 许可下发布,可在 huggingface.co/datasets/tiiuae/falcon-refinedweb 找到。

通过结合优质数据与这些优化,Falcon 在利用大约 75%和 80%的 GPT-3 和 PaLM-62B 的训练计算预算的同时,实现了显著的性能。

Mistral

我们将要介绍的第三个也是最后一个开源模型系列是 Mistral,由 Mistral AI 开发,该公司成立于 2023 年 4 月,由一支曾在 Meta Platforms 和 Google DeepMind 工作的 AI 科学家团队创立。总部位于法国,该公司通过筹集大量资金和发布开源 LLM,迅速在 AI 开发领域树立了声誉,强调透明性和可访问性的重要性。

Mistral 模型,特别是 Mistral-7B-v0.1,是一个仅具有解码器的 Transformer,拥有 73 亿参数,专为生成文本任务设计。它以其创新的架构选择而闻名,如分组查询注意力GQA)和滑动窗口注意力SWA),这些选择使它在基准测试中优于其他模型。

定义

GQA 和 SWA 是旨在提高 LLM 效率和性能的机制。

GQA 是一种技术,与标准全注意力机制相比,它允许更快的推理时间。它是通过将注意力机制的查询头部分成组,每组共享一个单一的关键头和价值头来实现的。

SWA 用于高效地处理较长的文本序列。它将模型的注意力扩展到固定窗口大小之外,允许每一层引用前一层的多个位置。这意味着某一层的隐藏状态可以关注前一层特定范围内的隐藏状态,从而使得模型能够访问更远距离的标记,并以降低推理成本的方式管理不同长度的序列。

该模型还提供了一个针对通用能力进行了微调的变体。这个变体被称为 Mistral-7B-instruct,它在 MT-Bench(一个使用 LLM 作为评判标准的评估框架)上优于市场上所有其他 70 亿参数的 LLM(截至 2024 年 4 月)。

与许多其他开源模型一样,Mistral 可以通过 Hugging Face Hub 进行消费和下载。

注意

2024 年 2 月,Mistral AI 和微软签署了一项多年合作协议,以加速 AI 创新。这次合作将利用微软的 Azure AI 超级计算基础设施来支持 Mistral AI 的 LLM 的开发和部署。Mistral AI 的模型,包括其高级模型 Mistral Large,将通过 Azure AI Studio 和 Azure 机器学习模型目录提供给客户。该合作的目标是扩大 Mistral AI 在全球市场的影响力,并促进持续的研究合作。

下面的比较表提供了三个模型之间的主要区别:

| | LlaMA | Falcon LLM | Mistral |

| --- | --- | --- | --- |

| 公司或机构 | Meta | 技术创新研究所TII) | Mistral AI |

| 首次发布 | 2023 年 7 月 | 2023 年 5 月 | 2023 年 9 月 |

| 架构 | 自回归变换器,仅解码器 | 自回归变换器,仅解码器 | 变换器,仅解码器 |

| 大小和变体 | 三种大小:7B、13B 和 70B,以及微调版本(聊天) | 两种大小:7B 和 40B,以及微调版本(指令) | 7B 大小以及微调版本(指令) |

| 许可证 | 可在ai.meta.com/resources/models-and-libraries/llama-downloads/获取定制商业许可证 | 商业 Apache 2.0 许可证 | 商业 Apache 2.0 许可证 |

| 如何使用 | 在ai.meta.com/resources/models-and-libraries/llama-downloads/提交请求表单并下载 GitHub 仓库,也可在 Hugging Face Hub 使用 | 下载或使用 Hugging Face Hub 推理 API/端点 | 下载或使用 Hugging Face Hub 推理 API/端点或 Azure AI Studio |

表 3.2:LLM 比较表

超越语言模型

到目前为止,我们只介绍了语言特定的基础模型,因为这是本书的重点。然而,在 AI 驱动应用的环境中,值得提及的是,还有一些可以处理不同于文本的数据的基础模型,这些数据可以被嵌入和编排。

在这里,你可以找到一些市场上大型基础模型LFMs)的例子:

  • Whisper:这是一个由 OpenAI 开发的多语言通用语音识别模型,能够将多种语言的语音进行转录和翻译。它在一个包含多种音频的大型数据集上进行了训练,并且还是一个多任务模型,能够执行多语言语音识别、语音翻译、口语语言识别和语音活动检测。

  • Midjourney:由同名独立研究实验室开发,Midjourney 基于一个序列到序列的变换器模型,它接受文本提示并输出一组与提示相匹配的四张图像。Midjourney 被设计成艺术家和创意专业人士的工具,他们可以使用它进行艺术概念的快速原型设计、灵感或实验。

  • DALL-E:与之前的类似,DALL-E 是由 OpenAI 开发的,它使用 GPT-3 的 120 亿参数版本,在文本-图像对的数据集上训练,从自然语言描述生成图像。

想法是我们可以在我们的应用程序中将多个 LFMs 组合和编排,以实现非凡的结果。例如,假设我们想要写一篇关于年轻厨师访谈的评论并发布在 Instagram 上。可能涉及的模型可能如下:

  • Whisper会将访谈音频转换为文本。

  • 一个带有网络插件的LLM,例如 Falcon-7B-instruct,将推断年轻厨师的名字并在互联网上搜索以检索其传记。

  • 另一个LLM,例如 LlaMA,将处理转录并生成一个具有 Instagram 帖子风格的评论。我们也可以要求同一个模型生成一个提示,让下一个模型根据帖子内容生成图片。

  • Dall-E将根据 LLM 生成的提示生成图像。

我们将为我们的 LFMs 流程添加一个 Instagram 插件,以便应用程序能够在我们个人资料上发布整个评论,包括插图。

最后,有一些新兴的 LFMs 旨在实现多模态,这意味着它们可以用一个架构处理多种数据格式。GPT-4 本身就是一个例子。

下面的截图显示了 OpenAI 早期与 GPT-4 视觉实验的一个示例,展示了它对图像中幽默方面的理解:

手机插上充电线  自动生成的描述

图 3.9:GPT-4 视觉的早期实验(来源:openai.com/research/gpt-4

下面的截图显示了 GPT-4 的早期版本的一个示例,展示了它如何能够详细理解和解释图表:

图表截图  自动生成的描述

图 3.10:GPT-4 视觉的早期实验(来源:openai.com/research/gpt-4

下面的示例显示了 GPT-4 的早期版本如何理解和解决复杂的数学问题,同时提供其响应的相应理由:

计算机截图  自动生成的描述

图 3.11:GPT-4 视觉的早期实验(来源:openai.com/research/gpt-4

GPT-4 只是大型多模态模型(LMM)的一个例子,它代表了我们在未来几年可能会见证的趋势。

选择合适的 LLM 的决策框架

在前面的段落中,我们介绍了一些目前市场上最有前途的 LLM。现在的问题是:在我的应用程序中我应该使用哪一个?事实是,这个问题没有直接的答案。

考虑事项

在选择适用于您的应用程序的 LLM 时,有许多因素需要考虑。这些因素还需要在两种情况下进行说明:专有和开源 LLM。以下是一些在选择 LLM 时您可能想要考虑的因素和权衡:

  • 大小和性能:我们注意到,更复杂的模型(这意味着具有高参数数量)往往具有更好的性能,特别是在参数知识和泛化能力方面。然而,模型越大,处理输入和生成输出所需的计算和内存就越多,这可能导致更高的延迟,正如我们将看到的,还有更高的成本。

  • 成本和托管策略:在我们将 LLM 整合到我们的应用程序中时,我们必须考虑两种类型的成本:

    • 模型消费成本:这指的是我们为消费模型所支付的费用。像 GPT-4 或 Claude 2 这样的专有模型需要支付费用,这通常与处理的令牌数量成比例。另一方面,像 LlaMA 或 Falcon LLM 这样的开源模型是免费使用的。

    • 模型托管成本:这指的是您的托管策略。通常,专有模型托管在私有或公共超大规模计算器中,以便通过 REST API 进行消费,您无需担心底层基础设施(例如,GPT-4 托管在微软 Azure 云中构建的超计算机)。对于开源模型,我们通常需要提供自己的基础设施,因为那些模型可以本地下载。当然,模型越大,所需的计算能力就越强。

      注意

      在开源模型的背景下,另一种消费这些模型的方式是使用 Hugging Face 推理 API。免费版本允许您以有限的速率在 Hugging Face 上托管的共享基础设施上测试和评估所有可用的 LLM。对于生产用例,Hugging Face 还提供推理端点,这样您就可以轻松地将 LLM 部署在专用且完全管理的基础设施上,并有可能配置区域、计算能力和安全级别等参数,以满足您在延迟、吞吐量和合规性方面的限制。

      推理端点的定价信息可在huggingface.co/docs/inference-endpoints/pricing公开获取。

  • 定制:这可能是在决定采用哪种模型之前想要评估的要求。实际上,并非所有模型在定制方面都同样灵活。当我们谈论定制时,我们指的是两种活动:

    • 微调:这是略微调整 LLM 参数以更好地适应特定领域的过程。所有开源模型都可以进行微调。当涉及到专有模型时,并非所有 LLM 都可以进行微调:例如,OpenAI 的 GPT-3.5 可以进行微调,而 GPT-4-0613 的微调过程仍然是实验性的,并且需要根据 OpenAI 的要求进行(截至 2023 年 12 月)。

    从此以后,了解您是否需要在应用程序中进行微调,并据此做出决定是很重要的。

    • 从头开始训练:如果您真的需要一个对您的领域知识非常具体的 LLM,您可能需要从头开始重新训练模型。要从头开始训练一个 LLM,而无需重新发明架构,您可以下载开源 LLM,并在自定义数据集上简单地重新训练它们。当然,这隐含着我们有权访问源代码,而我们与专有 LLM 合作时并非如此。
  • 特定领域的能力:我们注意到评估 LLM 性能最流行的方式是跨领域平均不同的基准测试。然而,也有一些基准测试是针对特定能力量身定制的:如果 MMLU 衡量 LLM 的泛化文化和常识推理,那么 TruthfulQA 更关注 LLM 的对齐,而 HumanEval 则针对 LLM 的编码能力。

从此以后,如果您有一个特定的用例在心中,您可能希望使用在特定基准测试中表现最佳的模型,而不是在所有基准测试中平均表现最佳的模型。也就是说,如果您在寻找卓越的编码能力,可能会选择 Claude 2;如果您在寻找分析推理能力,可能会选择 PaLM 2。另一方面,如果您需要一个包含所有这些能力的模型,GPT-4 可能是您的正确选择。

选择特定领域的模型也是节省模型复杂度的一种方式。问题是,如果您需要将其用于特定用例,可能只需要一个相对较小的模型(例如,LlaMA-7B-instruct),这样就可以带来成本和性能方面的所有好处。

注意

如果您正在寻找极其具体的 LLM,有许多模型是在特定领域的技术文档上训练的。例如,2023 年初,斯坦福大学基础模型研究中心CRFM)和 MosaicML 宣布发布了 BioMedLM,这是一个仅具有解码器功能的基于 Transformer 的 2.7 亿参数 LLM,它在生物医学摘要和论文上进行了训练。

另一个例子是 BloombergGPT,这是一个由彭博社开发的针对金融领域的 50 亿参数大型语言模型(LLM),它基于彭博社广泛的数据源,在包含 3630 亿个标记的数据集上进行训练,这可能是迄今为止最大的特定领域数据集,并额外增加了来自通用数据集的 3450 亿个标记。

为了使这个决策框架更加实用,让我们考虑以下关于 TechGen 公司的假设案例研究。

案例研究

TechGen Solutions,一家领先的 AI 驱动分析服务提供商,在为下一代客户交互系统选择两个高级语言模型(GPT-4 和 LLaMa-2)之间面临抉择。他们需要一个能够处理各种客户查询、提供准确技术信息并能与他们的专有软件集成的强大语言模型。以下是他们可选的方案:

  • GPT-4:由 OpenAI 开发,GPT-4 以其庞大的参数数量和能够处理文本和图像输入的能力而闻名。

  • LLama 2:由 Meta AI 创建,LLama 2 是一个开源模型,因其易用性和在小数据集上的性能而受到赞誉。

以下是他们做出决策时考虑的因素:

  • 性能:TechGen 评估了这些模型的表现,特别是在生成技术内容和代码方面,GPT-4 表现出了更高的准确性。

  • 集成:与 TechGen 系统的集成简便性至关重要,GPT-4 由于其广泛采用,可能提供更无缝的兼容性。

  • 成本:虽然 LLama 2 在特定条件下对商业用途免费,但 GPT-4 是有成本的,TechGen 必须将其纳入他们的决策考量。

  • 未来保障:TechGen 考虑了每个模型的长期可行性,包括更新和改进的潜力。

基于这些考虑,TechGen 选择了 GPT-4,受其生成复杂、技术性回应的优越性能和其多语言能力所吸引,这些能力与他们的国际扩张计划相吻合。这一决定还受到 GPT-4 图像处理功能的影响,TechGen 预计随着他们将其更多的多媒体内容融入客户服务,这一功能将变得越来越重要。

TechGen 选择 GPT-4 而非 LLama 2,是由其对一个高性能、多功能的语言模型的需求所驱动,该模型能够随着其日益增长的全球影响力和多样化的客户需求而扩展。虽然 LLama 2 的开源特性和成本效益颇具吸引力,但 GPT-4 的高级功能和未来保障特性为 TechGen 的雄心勃勃目标提供了更有说服力的理由。

注意,这些决策因素并非旨在成为决定在应用中嵌入哪些模型的详尽指南。尽管如此,这些因素在设置你的应用流程时仍是有用的反思元素,这样你可以确定你的需求,然后筛选出那些更适合你目标的 LLM。

摘要

本章涵盖了市场上一些最有前景的 LLM。它首先区分了专有模型和开源模型,并详细讨论了所有相关的优缺点。接着深入探讨了 GPT-4、PaLM-2、Claude 2、LLaMa-2、Falcon LLM 和 MPT 的架构和技术特性,并增加了一个关于一些 LMM 的章节。最后,提供了一个框架,帮助开发者决定在构建 AI 应用时选择哪些 LLM。鉴于你的行业特定场景,这对于从你的应用中获得最大影响至关重要。

从下一章开始,我们将开始在实际应用中与 LLM 进行动手操作。

参考文献

加入我们的 Discord 社区

加入我们的 Discord 空间,与作者和其他读者进行讨论:

packt.link/llm

第四章:提示工程

第二章 中,我们介绍了提示工程的概念,即设计并优化用于指导 大型语言模型LLM)行为的文本输入——提示——的过程,以适用于广泛的 LLM 应用和研究主题。由于提示对 LLM 性能有巨大影响,提示工程在设计基于 LLM 的应用程序时是一项关键活动。实际上,有一些技术不仅可以完善你的 LLM 的响应,还可以减少与幻觉和偏差相关的风险。

在本章中,我们将探讨提示工程领域的新兴技术,从基本方法到高级框架。到本章结束时,你将具备构建功能强大且稳固的提示的基础,这些提示对于你的基于 LLM 的应用程序也将在后续章节中适用。

我们将探讨以下主题:

  • 提示工程简介

  • 提示工程的原理

  • 提示工程的先进技术

技术要求

要完成本章的任务,你需要以下条件:

  • OpenAI 账户和 API

  • Python 3.7.1 或更高版本

你可以在本书的 GitHub 仓库中找到所有代码和示例:github.com/PacktPublishing/Building-LLM-Powered-Applications

什么是提示工程?

提示是一种文本输入,它指导大型语言模型(LLM)生成文本输出。

提示工程是一个设计有效提示的过程,这些提示可以从 LLM 中激发出高质量和相关的输出。提示工程需要创造力、对 LLM 的理解以及精确性。

以下图展示了如何通过一个精心编写的提示来指导同一个模型执行三个不同的任务:

图 4.1:提示工程示例,用于专门化大型语言模型(LLM)

如你所想,提示成为了一个基于 LLM 的应用程序成功的关键要素之一。因此,投入时间和资源在这一步至关重要,我们需要遵循一些最佳实践和原则,这些将在接下来的章节中介绍。

提示工程的原理

通常来说,没有固定的规则可以获得“完美”的提示,因为需要考虑的变量太多(使用的模型类型、应用程序的目标、支持的基础设施等)。尽管如此,有一些明确的原理,如果融入提示中,已被证明会产生积极的效果。让我们考察其中的一些。

清晰的指令

明确指令的原则是向模型提供足够的信息和指导,以便正确且高效地完成任务。清晰的指令应包括以下要素:

  • 任务的目标或目的,例如“写一首诗”或“总结一篇文章”

  • 预期输出的格式或结构,例如“使用四行押韵的词”或“使用每项不超过 10 个单词的项目符号”

  • 任务的约束或限制,例如“不要使用任何粗俗的语言”或“不要复制任何来自源文本的文本”

  • 任务的上下文或背景,例如“这首诗是关于秋天的”或“这篇文章来自科学期刊”

假设,例如,我们希望我们的模型从文本中提取任何类型的指令,并以项目符号列表的形式返回教程。此外,如果提供的文本中没有指令,模型应通知我们。以下是步骤:

  1. 首先,我们需要初始化我们的模型。为此,我们将利用 OpenAI 的 GPT-3.5-turbo 模型。我们首先安装openai库:

    $pip install openai == 0.28 
    
  2. 要初始化模型,我使用了openai Python 库,并将 OpenAI API 密钥设置为环境变量:

    import os
    import openai
    openai.api_key = os.environment.get('OPENAI_API_KEY')
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo", # engine = "deployment_name".
        messages=[
            {"role": "system", "content": system_message},
            {"role": "user", "content": instructions},
        ]
    ) 
    

如您所见,聊天模型包含两个变量占位符:system message(或元提示),其中我们定义了模型应该如何表现,以及instructions(或查询),用户将向模型提问。

  1. 然后,它接受用户的查询(在这种情况下,文本指令)。对于这个场景,我将两个变量system_messageinstructions设置如下:

    system_message = """
    You are an AI assistant that helps humans by generating tutorials given a text.
    You will be provided with a text. If the text contains any kind of istructions on how to proceed with something, generate a tutorial in a bullet list.
    Otherwise, inform the user that the text does not contain any instructions.
    Text:
    """
    instructions = """
    To prepare the known sauce from Genova, Italy, you can start by toasting the pine nuts to then coarsely
    chop them in a kitchen mortar together with basil and garlic. Then, add half of the oil in the kitchen mortar and season with salt and pepper.
    Finally, transfer the pesto to a bowl and stir in the grated Parmesan cheese.
    """ 
    
  2. 现在让我们测试我们的模型:

    print(response['choices'][0]['message']['content']) 
    

我们得到了以下输出:

Sure, I can generate a tutorial based on the given text. Here's a bullet list on how to prepare the Genovese pesto sauce:
- Toast the pine nuts on a pan until they are slightly browned.
- Coarsely chop the toasted pine nuts, along with basil leaves and garlic cloves, using a kitchen mortar.
- Add half of the olive oil into the kitchen mortar, and season the mixture with salt and pepper.
- Grind the mixture until it becomes a smooth paste.
- Transfer the pesto to a bowl, and stir in the grated Parmesan cheese.
- You can add more olive oil to achieve the desired consistency for the sauce.
- Your Genovese pesto sauce is now ready. It can be served with pasta, vegetables, or as a dip for bread. Enjoy! 
  1. 注意,如果我们向模型传递不包含任何指令的另一个文本,它将能够按照我们的指示回答:

    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo", # engine = "deployment_name".
        messages=[
            {"role": "system", "content": system_message},
            {"role": "user", "content": 'the sun is shining and dogs are running on the beach.'},
        ]
    )
    #print(response)
    print(response['choices'][0]['message']['content']) 
    

以下是对应的输出:

As there are no instructions provided in the text you have given me, it is not possible to create a tutorial. May I have a different text to work with? 

通过给出清晰的指令,你可以帮助模型理解你想要它做什么以及你想要它如何做。这可以提高模型输出的质量和相关性,并减少进一步修订或校正的需求。

然而,有时,清晰度不足以解决问题。我们可能需要推断我们的 LLM 的思维方式,使其在任务上更加稳健。在下一节中,我们将检查这些技术之一,这在完成复杂任务时将非常有用。

将复杂任务分解为子任务

如前所述,提示工程是一种技术,涉及为 LLM 设计有效的输入以执行各种任务。有时,任务过于复杂或含糊不清,以至于单个提示无法处理,最好将它们分解为更简单的子任务,这些子任务可以通过不同的提示来解决。

这里有一些将复杂任务分解为子任务的示例:

  • 文本摘要:这是一个复杂的任务,涉及生成长文本的简洁和准确的摘要。这个任务可以分解为以下子任务:

    • 从文本中提取主要观点或关键词

    • 以连贯和流畅的方式重写主要观点或关键词

    • 将摘要裁剪到期望的长度或格式

  • 机器翻译:这是一个复杂的任务,涉及将文本从一种语言翻译成另一种语言。这个任务可以分解为以下子任务:

    • 识别文本的源语言

    • 将文本转换为中间表示,以保留原始文本的意义和结构

    • 从中间表示生成目标语言的文本

  • 诗歌生成:一项涉及创作遵循特定风格、主题或情绪的诗歌的创造性任务。这项任务可以分解为以下子任务:

    • 为诗歌选择一种诗歌形式(如十四行诗、俳句、五言绝句等)和韵律模式(如 ABAB、AABB、ABCB 等)

    • 根据用户的输入或偏好为诗歌生成标题和主题

    • 生成符合所选形式、韵律模式和主题的诗句或诗节

    • 精炼和润色诗歌,以确保连贯性、流畅性和原创性

  • 代码生成:一项涉及生成执行特定功能或任务的代码片段的技术性任务。这项任务可以分解为以下子任务:

    • 选择一种编程语言(如 Python、Java、C++ 等)以及一个框架或库(如 TensorFlow、PyTorch、React 等)

    • 根据用户的输入或规格为代码生成函数名、参数列表和返回值

    • 生成实现代码逻辑和功能的函数体

    • 添加注释和文档来解释代码及其用法

让我们考虑以下 Python 中的示例,我们将要求我们的模型生成一篇文章的摘要:

  1. 我们将类似于本章前面讨论的示例,利用 OpenAI 的 GPT-3.5-turbo 模型:

    import os
    import openai
    openai.api_key = os.environ.get("OPENAI_API_KEY")
    response = openai.ChatCompletion.create(
        model="gpt-35-turbo", # engine = "deployment_name".
        messages=[
            {"role": "system", "content": system_message},
            {"role": "user", "content": article},
        ]
    ) 
    
  2. 让我们将 system_messagearticle 变量设置如下(你可以在书的 GitHub 仓库中找到完整的脚本):

    system_message = """
    You are an AI assistant that summarizes articles.
    To complete this task, do the following subtasks:
    Read the provided article context comprehensively and identify the main topic and key points
    Generate a paragraph summary of the current article context that captures the essential information and conveys the main idea
    Print each step of the process.
    Article:
    """
    article = """
    Recurrent neural networks, long short-term memory, and gated recurrent neural networks
    in particular, […]
    """ 
    
  3. 要查看输出,你可以运行以下代码:

    print(response['choices'][0]['message']['content']) 
    

这里是获得的结果:

Summary:
The article discusses the use of recurrent neural networks, specifically long short-term memory and gated recurrent neural networks, in sequence modeling and transduction problems. These models have achieved great success but are limited by their inherently sequential nature. Attention mechanisms have become popular in addressing this issue but are usually used in conjunction with recurrent networks. The authors propose the Transformer, an architecture that relies solely on attention mechanisms instead of recurrence. The Transformer allows for greater parallelization and can achieve state-of-the-art results in machine translation after only twelve hours of training on eight GPUs.
Steps:
1\. The article discusses the success and limitations of recurrent neural networks in sequence modeling and transduction problems.
2\. Attention mechanisms have become popular in addressing the limitations of recurrence but are usually used alongside recurrent networks.
3\. The authors propose the Transformer, a model architecture that relies solely on attention mechanisms and allows for greater parallelization.
4\. The Transformer can achieve state-of-the-art results in machine translation after only twelve hours of training on eight GPUs. 

如您所见,该模型能够根据从给定文章中提取(并显示)的关键主题生成高质量的摘要。我们提示模型将任务拆分为子任务“强制”它降低每个子任务的复杂性,从而提高了最终结果的质量。这种方法在处理诸如数学问题等场景时也能带来明显的效果,因为它增强了模型的推理能力。

注意

在众多不同的 LLM 中,了解以下事实至关重要:同一个系统消息可能不是在所有模型上都同样有效。例如,与 GPT-4 完美配合的系统消息在应用于 Llama 2 时可能效率不高。因此,根据你为应用程序选择的 LLM 类型来设计提示至关重要。

将复杂任务分解为更简单的子任务是一种强大的技术;然而,它并没有解决 LLM 生成内容的主要风险之一,即输出错误。在接下来的两个部分中,我们将看到一些主要旨在解决这一风险的技术。

请求证明

LLM 是以这样的方式构建的,它们根据前面的标记预测下一个标记,而不回顾它们的生成。这可能会导致模型以非常令人信服的方式向用户输出错误的内容。如果 LLM 驱动的应用程序没有提供对该响应的具体参考,那么验证其背后的真实情况可能很困难。因此,在提示中指定用一些反思和证明来支持 LLM 的答案,可能会促使模型从其行为中恢复过来。此外,在答案正确但我们不知道 LLM 背后的推理时,请求证明也可能很有用。例如,假设我们想让我们的 LLM 解决谜题。为此,我们可以这样指示它:

system_message = """
You are an AI assistant specialized in solving riddles.
Given a riddle, solve it the best you can.
Provide a clear justification of your answer and the reasoning behind it.
Riddle:
""" 

如您所见,我在元提示中指定了让 LLM 证明其答案并提供其推理。让我们看看它是如何工作的:

riddle = """
What has a face and two hands, but no arms or legs?
"""
response = openai.ChatCompletion.create(
    model="gpt-3.5-turbo",
    messages=[
        {"role": "system", "content": system_message},
        {"role": "user", "content": riddle},
    ]
)
#print(response)
print(response['choices'][0]['message']['content']) 

以下是我们获得的结果:

The answer to this riddle is a clock.
A clock has a face with numbers and two hands (the hour and minute hand), which rotate around the center of the clock to show the time. Although it doesn't have any arms or legs like humans do, it still has the ability to measure time, which is important in our daily lives.
Hence, a clock is the correct answer to this riddle. 

证明是使你的模型更加可靠和健壮的强大工具,因为它迫使模型“重新思考”其输出,同时也为我们提供了如何设置推理来解决问题的视角。

以类似的方式,我们也可以在不同的提示级别上进行干预,以改善我们 LLM 的性能。例如,我们可能会发现模型在系统地以错误的方式解决数学问题;因此,我们可能希望在元提示级别上直接建议正确的方法。另一个例子可能是要求模型生成多个输出——以及它们的证明——以评估不同的推理技术,并在元提示中提示最佳的一个。

在下一节中,我们将重点关注这些例子中的一个,更具体地说,是生成多个输出然后选择最可能的一个的可能性。

生成许多输出,然后使用模型选择最佳的一个

如前所述,LLM 是以这样的方式构建的,它们根据前面的标记预测下一个标记,而不回顾它们的生成。如果这种情况发生,如果采样的标记是错误的(换句话说,如果模型运气不好),LLM 将继续生成错误的标记,从而生成错误的内容。现在,坏消息是,与人类不同,LLM 不能自行从错误中恢复。这意味着,如果我们要求它们,它们会承认错误,但我们需要明确提示它们去思考。

克服这种限制的一种方法是通过扩展选择正确标记的概率空间。我们不仅生成一个响应,还可以提示模型生成多个响应,然后选择最适合用户查询的那个。这把我们的 LLM 的工作分成两个子任务:

  1. 对用户的查询生成多个响应

  2. 比较这些响应并选择最佳的一个,根据我们可以在元提示中指定的某些标准

让我们看看一个例子,继续探讨上一节中讨论的谜题:

system_message = """
You are an AI assistant specialized in solving riddles.
Given a riddle, you have to generate three answers to the riddle.
For each answer, be specific about the reasoning you made.
Then, among the three answers, select the one that is most plausible given the riddle.
Riddle:
"""
riddle = """
What has a face and two hands, but no arms or legs?
""" 

在这种情况下,我提示模型生成三个谜题的答案,然后给我最可能的答案,并说明理由。让我们看看结果:

response = openai.ChatCompletion.create(
    model="gpt-3.5-turbo", # engine = "deployment_name".
    messages=[
        {"role": "system", "content": system_message},
        {"role": "user", "content": riddle},
    ]
)
#print(response)
print(response['choices'][0]['message']['content']) 

我们随后得到以下输出:

Answer 1: A clock. A clock has a face with numbers and two hands to show minutes and hours. It does not have arms or legs because it is an object, and it does not have intrinsic limbs.
Answer 2: A watch. Similar to a clock, a watch also has a face with numbers and two hands to indicate the time. Although it is usually worn on a person's wrist, it does not have arms or legs.
Answer 3: A wall. While this answer may be less obvious, a wall does, in a way, have a face and two hands. The face is its outer surface, and the hands are the clock that usually hangs on the wall.
Among the three answers, the most plausible one is answer 1: a clock. The riddle distinctly mentions "two hands" and it's logical to associate hands with those that are found in clocks to indicate time. 

如您所见,模型选择了最可能的答案,并对其选择进行了说明。值得注意的是,“时钟”和“手表”可能看起来是相似的回答;然而,模型明确指出“手表”通常戴在人的手腕上,尽管这并不意味着它有手臂或腿,但这个元素可能降低了它是正确答案的概率。

你会选择什么?

如前所述,迫使模型以不同的方法处理问题是一种收集多个推理样本的方法,这些样本可能作为元提示中的进一步指令。例如,如果我们想让模型始终提出不是问题最直接解决方案的东西——换句话说,如果我们想让它“思考不同”的话——我们可能迫使它以 N 种方式解决问题,然后使用最富有创意的推理作为元提示的框架。

我们将要检查的最后一个元素是我们想要给予我们的元提示的整体结构。实际上,在之前的例子中,我们看到了一个包含一些声明和指令的示例系统消息。在下一节中,我们将看到那些声明和指令的顺序和“强度”并不是不变的。

在末尾重复指令

LLMs 往往不会以相同的权重或重要性处理元提示的所有部分。实际上,在 John Stewart(微软的一名软件工程师)的博客文章《大型语言模型复杂摘要的提示工程》中,他发现了一些有趣的成果,这些成果来自于对提示部分的排列(devblogs.microsoft.com/ise/gpt-summary-prompt-engineering/)。更具体地说,经过几次实验,他发现重复提示末尾的主要指令可以帮助模型克服其内在的近期偏差

定义

近期偏差是指大型语言模型(LLMs)倾向于给予靠近提示末尾的信息更多权重,而忽略或忘记之前出现的信息。这可能导致不准确或不一致的响应,没有考虑到整个任务的上下文。例如,如果提示是两个人之间的长对话,模型可能只会关注最后几条消息,而忽略之前的消息。

让我们看看一些克服近期偏差的方法:

  • 一种克服近期偏差的可能方法是将任务分解成更小的步骤或子任务,并在过程中提供反馈或指导。这可以帮助模型专注于每个步骤,避免陷入无关紧要的细节。我们在“将复杂任务分解为子任务”部分讨论了这项技术。

  • 另一种使用提示工程技术克服近期偏差的方法是在提示的末尾重复指令或任务的主要目标。这可以帮助提醒模型它应该做什么以及它应该生成什么样的响应。

例如,假设我们想让我们的模型输出 AI 代理和用户之间整个聊天历史的情感。我们想确保模型将输出小写字母且不带标点的情感。

让我们考虑以下示例(对话被截断,但您可以在书籍的 GitHub 仓库中找到完整的代码)。在这种情况下,关键指令是只输出小写字母且不带标点的情感:

system_message = """
You are a sentiment analyzer. You classify conversations into three categories: positive, negative, or neutral.
Return only the sentiment, in lowercase and without punctuation.
Conversation:
"""
conversation = """
Customer: Hi, I need some help with my order.
AI agent: Hello, welcome to our online store. I'm an AI agent and I'm here to assist you.
Customer: I ordered a pair of shoes yesterday, but I haven't received a confirmation email yet. Can you check the status of my order?
[…]
""" 

在这个场景中,我们在对话之前有关键指令,所以让我们初始化我们的模型,并用两个变量system_messageconversation给它提供数据:

response = openai.ChatCompletion.create(
    model="gpt-3.5-turbo", # engine = "deployment_name".
    messages=[
        {"role": "system", "content": system_message},
        {"role": "user", "content": conversation},
    ]
)
#print(response)
print(response['choices'][0]['message']['content']) 

这里是我们收到的输出:

Neutral 

模型没有遵循只输出小写字母的指令。让我们尝试在提示的末尾也重复这个指令:

system_message = f"""
You are a sentiment analyzer. You classify conversations into three categories: positive, negative, or neutral.
Return only the sentiment, in lowercase and without punctuation.
Conversation:
{conversation}
Remember to return only the sentiment, in lowercase and without punctuation
""" 

再次,让我们用更新的system_message调用我们的模型:

response = openai.ChatCompletion.create(
    model="gpt-3.5-turbo", # engine = "deployment_name".
    messages=[
        {"role": "user", "content": system_message},
    ]
)
#print(response)
print(response['choices'][0]['message']['content']) 

这里是相应的输出:

neutral 

如您所见,现在模型能够提供我们想要的精确输出。这种方法特别有用,当我们有需要持续存储在上下文窗口中的对话历史时。如果这种情况发生,将主要指令放在开头可能会让模型在经过整个历史后不再考虑这些指令,从而减弱它们的影响力。

使用分隔符

要讨论的最后一个原则与我们想要给我们的元提示的格式有关。这有助于我们的 LLM 更好地理解其意图,以及将不同的部分和段落联系起来。

要实现这一点,我们可以在提示中使用分隔符。分隔符可以是任何字符或符号的序列,它清楚地映射一个模式而不是一个概念。例如,我们可以考虑以下序列作为分隔符:

posted @ 2026-07-27 16:25  绝不原创的飞龙  阅读(11)  评论(0)    收藏  举报