第一部分 生成式 AI 的基础

本节介绍了支撑生成式 AI 的基本概念和技术。我们首先概述了生成式 AI 能做什么,它是如何工作的,以及如何在各种企业环境中应用。然后我们详细探讨了大型语言模型(LLMs)的细节,例如它们的结构、类别和主要概念。本节最后几章涵盖了通过 API 生成文本、图像和类似内容,提供了访问和利用这些技术的实用指南。

第一章介绍了生成式 AI 的概念,并解释了其创建新内容(如文本、图像和代码)的能力。它讨论了各种企业应用案例,比较了生成式 AI 与传统 AI,并为考虑采用这项技术的组织提供指导。

第二章深入探讨大型语言模型,解释其基础概念和架构,特别是关注 Transformer 模型。它还涵盖了不同类型的 LLM 以及诸如提示、令牌和嵌入等基本概念。

第三章探讨了如何使用 API 生成文本,从基本实现开始,逐步过渡到更高级的选项。它解释了模型类别和依赖关系,并提供了文本生成应用的实用示例。

第四章专注于生成图像和其他媒体类型。它概述了图像生成模型,并解释了如何使用 API 创建各种类型的媒体内容。

最后,第五章扩展到生成其他媒体类型,如视频和音频。它涵盖了媒体生成的技术和方法,提供了实际案例和 API 使用说明。本章还涵盖了使用各种模型进行代码生成。

第一章:生成式人工智能简介

本章涵盖

  • 生成式人工智能简介

  • 使用生成式人工智能可以生成的示例

  • 采用生成式人工智能时组织的指导

  • 生成式人工智能的关键用例

  • 生成式人工智能与其他人工智能类型的比较

人工智能(AI)熟悉且已经存在多年。我们都在使用搜索引擎、阅读产品推荐、收听定制播放列表或在我们用手机打字时使用建议的单词时使用它——所有这些动作都是由 AI 驱动的。然而,在 AI 领域,一切似乎都焕然一新,全世界都在热烈地讨论它,特别是关于生成式人工智能。

生成式人工智能,人工智能技术中一个迷人且独特的进步,已经引起了公众的兴趣并激发了全球的热情。OpenAI 的 ChatGPT 显著提升了其知名度,两个月内吸引了 1 亿用户——这是人类历史上任何技术最快的用户采用率。许多企业认为这项技术是下一波数字化转型和自动化的关键驱动力。生成式人工智能可以创建新的内容和流程,从而增强各种业务运营。它已经被用于生成各种内容,从图像、文本和音乐到更复杂的结果,如设计模式和代码。其潜力巨大且令人兴奋,能够生成几乎任何东西——从新的游戏关卡到新颖的食谱等等。

随着人工智能技术的飞速进步,实现人类水平性能的旅程显著加速。图 1.1 生动地展示了图像和语言识别能力如何迅速超越人类水平,标志着人工智能的一个重大里程碑。

图 1.1 人工智能系统能力 [1]

本书探讨了这一新兴技术的各个方面。我们将讨论实际的应用案例以及企业如何将生成式人工智能集成到现有框架中。此外,我们还将探讨其技术基础、关键组件以及应用架构中必要的修改。此外,我们还将研究在生产环境中实施人工智能的最有效实践以及如何最优地管理其运营。

生成式人工智能与其他类型的 AI 根本不同,因为它涉及创造全新的东西,而不是修改或复制其训练数据。而传统人工智能基于输入数据进行预测,生成模型通过预测下一组单词来创造新事物,这些单词基于其生成和理解现实世界语义的能力。这些新事物涵盖了广泛的文本、图像、音乐和 3D 模型。我们将看到企业如何适应使用这些新技术。生成式人工智能,就像富有想象力的艺术家或富有创造力的小说家一样,从信息碎片中描绘出生动的画面,写出触动灵魂的诗歌,并从无中创造出整个宇宙。欢迎,亲爱的读者,来到令人敬畏的生成式人工智能世界——一个机器学习理解、分析和创造的世界。

1.1 这本书是关于什么的?

阅读此书后,您将全面了解生成式人工智能及其在企业中的应用。本书涵盖了生成式人工智能的基本技术和原理,包括基础模型、大型语言模型、嵌入以及相关的算法和架构。它将提供所需的知识,以识别和实施将生成式人工智能融入您组织的人工智能战略和项目中的步骤。此外,本书还展示了生成式人工智能在企业环境中开发和部署的实际案例和指南。它还探讨了架构模式、最佳实践和与现有系统和企业工作流程的集成模式的新兴应用。本书突出了企业应了解的新兴工具和趋势,包括提示工程、可解释人工智能、迁移学习和强化学习(特别是从人类反馈中学习的强化学习,或 RLHF)。

本书面向多元化的受众,包括开发者、软件架构师、数据科学家、企业决策者以及在各行各业企业中工作的高级用户。本书中现实世界企业场景的例子主要关注技术方面,并展示了生成式人工智能如何解决许多企业面临的独特挑战。这里讨论的基本原理同样适用于较小的组织和初创企业。此外,我们将探讨与生成式人工智能相关的挑战和风险,例如使用企业和个人数据、伦理考量、数据隐私、安全和安全考量,以便在将这些技术融入组织时做出明智的决策。

LLM 模型和平台

本书主要使用 Azure OpenAI 和 OpenAI,这是顶级的大型语言模型和发布平台。它们已经投入生产近两年(截至撰写时),是最稳定、经过测试且适用于云规模企业使用的。成千上万家企业依赖并使用这些平台。

目标是帮助您理解生成式 AI 以及如何利用新技术为您的企业服务。即使您使用不同的 LLM,这些概念和原语也是相同的。在本书中,我们还将看到其他 LLM 和提供商的示例,了解这些概念是如何相同的,以及 API 和 SDK 是如何类似于 OpenAI 的。我们还深入探讨了各种开源模型。

最后,许多这些模型仅适用于企业账户,并不对所有人开放。因此,我无法访问所有这些模型,但我可以访问 Microsoft 堆栈,这也是我们在这里使用它的另一个原因。

1.2 什么是生成式 AI?

生成式 AI 并非 AI 领域的新兴领域,但最近它获得了更多的普及和关注。它可以在各种输出中生成新的内容——从逼真的人类面孔和有说服力的文本,到创作音乐和开发新型药物化合物。这种新的 AI 技术涉及复制现有模式、想象新的模式、构建新的场景以及创造新的知识。

图 1.2 生成式 AI 概述

如图 1.2 所示,生成式 AI 是 AI 的一个子领域,它通过大量数据训练来学习底层模式和分布。其神奇之处在于它能够生成新颖和原创的内容,这是以前被认为仅是人类独创性的专属领域。

机器学习和深度学习为我们理解生成式 AI 提供了必要的根本技术。它们为我们提供了导航 AI 领域和了解数据工程、模型训练和推理背后的过程的工具箱。随着我们通过本书的进展,我们将应用这些原则,但不会深入细节。已有多本书籍专门讨论这两个主题,对于细节,读者更明智的做法是查阅那些书籍。

在最简单的层面上,机器学习(ML)是关注计算机如何从数据中学习的科学学科。在机器学习中,我们不是明确编程计算机执行任务,而是开发能够从数据中学习并基于数据做出预测或决策的算法。这种数据驱动的决策适用于众多现实世界场景,从电子邮件中的垃圾邮件过滤到电子商务平台上的推荐系统。

深度学习(DL),作为机器学习的一个子集,进一步发展了这一概念。它使用具有多个层的人工神经网络。这些网络试图模拟人类大脑的行为——尽管是简化的形式——以从大量数据中学习。虽然单层神经网络仍然可以做出近似预测,但额外的隐藏层可以帮助优化其准确性。深度学习推动了今天许多 AI 应用,并有助于以改进的效率、速度和规模执行任务。

人工智能模型是一种复杂的算法结构,在大量数据集上训练以自主执行特定任务,如文本生成、翻译和决策。这些模型通过学习数据模式来模仿人类的认知能力,这使得它们能够理解和生成自然语言。一旦训练完成,开发者应认识到这些模型可以独立地使用机器学习和深度学习技术处理和分析数据。机器学习模型将数学框架应用于数据以进行预测,而深度学习模型则使用神经网络处理涉及非结构化数据的复杂任务。本质上,人工智能模型是一个自给自足的工具,在训练后可以根据学习到的数据模式执行智能任务,这对于创建智能应用至关重要。

生成式人工智能是深度学习的一个分支。许多人错误地认为 ChatGPT 是生成式人工智能。ChatGPT 是一个使用生成式人工智能最简单形式的网络应用程序。ChatGPT 的兴起和流行让许多人接触到了生成式人工智能,而被称为大型语言模型(LLM)的其他生成模型的力量,正如其名称所暗示的,与语言相关。OpenAI 在多样化的互联网文本上训练 ChatGPT 以产生类似人类的对话。除了 ChatGPT 之外,表 1.1 概述了今天使用的某些关键生成式人工智能模型;这些模型根据生成式人工智能领域类型分组:语言、图像和代码生成。

表 1.1 流行的人工智能生成模型
名称描述领域
生成式预训练转换器(GPT)OpenAI 开发的一个大型语言模型,在大量文本和代码数据集上训练,可以生成文本、翻译语言、编写各种类型的创意内容,并能够提供信息丰富的回答。GPT4-Omni(更常被称为 GPT-4o)是一个多模态模型。在撰写本文时,它是最新版本,是 GPT-4 的重大升级,提供了速度、成本和功能上的改进。语言/多模态
Llama 3Meta 最近发布了自然大型语言模型的第三个版本,在特殊许可证下开源。这些模型有多种大小和不同的功能。语言
Claude 3Anthropic 公司推出了 Claude 3 模型系列,包括 Claude 3 Haiku、Claude 3 Sonnet 和 Claude 3 Opus。这些模型提供了一系列功能,其中 Opus 是最智能的。它能够执行复杂任务,展现出接近人类的理解和流畅度。与 OpenAI 的 ChatGPT 类似,Claude 可以根据提示生成文本、编写代码、总结和推理等。语言
Cohere CommandCohere 提供了其 Command 系列中的两个模型(Command R 和 Command R+)。虽然这些 LLMMS 优化了各种用例,但 Cohere 的新大型语言模型 Command R+ 优化了对话交互和长上下文任务。它旨在对复杂的检索增强生成(RAG)工作流程和多步骤工具使用提供高性能。语言/多模态
MistralMistral 大型语言模型是专为文本生成和其他语言任务设计的先进人工智能模型。它们拥有不同尺寸的模型,从一系列开源模型(Mistral-7B、8x7B 和 8x22B)到优化的商业模型(Mistral 小型、中型和大型),每个模型都针对不同的推理复杂度和工作负载进行了定制。语言
GeminiGemini 是谷歌的新多模态模型,能够理解文本、图像、视频和音频。它将提供不同尺寸(超大型、专业型和纳米型),每个尺寸都有不同的功能。语言/多模态
DALL-EOpenAI 开发的视觉人工智能模型,可以从文本提示创建逼真的图像。图像
Stable Diffusion这是一个开源的图像生成模型,可以从提示输入生成图像。它主要用于根据文本描述生成详细图像,也可以应用于其他任务,如修复、扩展和生成图像到图像的翻译。图像
MidjourneyMidjourney 是一家名为 Midjourney, Inc. 的初创公司使用自然语言提示进行图像生成的模型,类似于 OpenAI 的 DALL-E 和 Stable Diffusion。图像
CodeWhispererCodeWhisperer 是一个 AWS 代码生成模型,可以在多种编程语言中生成代码,包括 Python、Java、JavaScript 和 TypeScript。代码
CodeLlamaCodeLlama 是基于 Llama 2 构建的大型语言模型,专门针对代码进行训练。它提供多种尺寸,并支持多种流行的编程语言。代码
CodexCodex 是一个专门针对代码进行训练的大型语言模型,用于帮助代码生成。它支持超过十种编程语言,包括一些常用的,如 C#、Java、Python、JavaScript、SQL、Go、PHP 和 Shell 等。代码

以下列表描述了今天生成式人工智能应用的一些领域。随着生成式人工智能技术的发展,我们预计将看到更多创新和创造性的应用。

  • 图像——这项技术可以创建现实中不存在的真实人物、物体和场景的图像。它被用于各种目的,例如为游戏和娱乐创建虚拟世界,为电子商务生成逼真的产品图像,以及为其他人工智能模型提供训练数据。

  • 视频—创建现实中不存在的内容的视频。这项技术用于多种目的,例如为电影和电视剧制作特效、为其他 AI 模型生成训练数据以及为营销和广告创建个性化视频内容。

  • 文本(语言)—这项技术创建逼真的文本,例如新闻文章、博客文章和创意写作。它用于多种目的,例如为网站和社交媒体生成内容、创建个性化营销材料和创建合成数据。

  • 文本(代码)—生成式 AI 模型在开发者编写代码时提供增强和辅助。GitHub 的研究发现,使用其 Copilot 功能的开发者感觉生产力提高了 88%,在重复性任务上的速度提高了 96%。

  • 音乐—生成式 AI 模型正被用于创作原创和富有创意的新音乐。这项技术服务于多种目的,例如为电影和电视剧创作音乐、生成个性化播放列表以及为其他 AI 模型创建训练数据。

我们将在下一章深入探讨生成式 AI 是如何工作的,但就目前而言,让我们讨论一下可以使用这项技术生成的内容以及它如何帮助您的企业。

1.3 我们可以生成什么?

当涉及到使用生成式 AI 生成事物时,天空才是极限。正如之前所讨论的,我们可以生成文本、图像、音乐、代码、声音甚至设计。在我们查看可以生成的示例之前,值得注意的是,生成式 AI 并不像人类那样理解内容。它使用数据中的模式(其训练集的一部分)来生成新的、类似的数据——生成内容的品质和相关性直接关联到训练数据的品质和相关性。

1.3.1 实体提取

我们可以使用生成式 AI,特别是大型语言模型(LLM),从文本中提取实体。实体是我们感兴趣的信息片段。在过去,我们需要使用命名实体识别(NER)模型进行实体提取;此外,该模型需要看到数据,并作为其数据集的一部分进行训练。有了 LLM 模型,我们无需任何训练即可完成这项工作,并且它们更加准确。虽然传统的 NER 方法有效,但它们通常需要人工努力和特定领域的定制。LLMs 显著减轻了这一负担,为各个领域提供了更高效且通常更准确的 NER 方法。一个关键原因是 Transformer 架构,我们将在接下来的几章中介绍。这是一个传统 AI 比生成式 AI 更加僵化和缺乏灵活性的绝佳例子。

在这里,我们将使用 OpenAI 的 GPT-4 模型从文本中提取姓名、公司名称、地点、电子邮件和电话号码:

你好。我叫 Amit Bahree。我来自华盛顿州西雅图的 Acme 保险公司。我的同事提到你对了解我们的全面福利政策感兴趣。你方便的时候能给我回个电话(555)111-2222,我们可以一起讨论福利?我可以在周一至周五的正常工作时间联系到。如果你愿意,你也可以通过 aweomseinsrance@acme.com 邮箱联系我。谢谢,Amit。

我们可以在图 1.3 的输出中看到模型提取的实体。

图 1.3 实体提取

1.3.2 生成文本

以多种方式生成文本是生成式 AI 的基本功。我们可以生成各种内容,如诗歌、笑话和个性化内容。在这个例子中,我们将使用 GPT-4 为一本关于生成式 AI 的新书生成图书发行邮件。我们向模型提供一个包含我们要求和一些背景信息的提示,以便构建。我们设定场景,概述要求,并添加额外的背景信息,如文本的语气,这将为我们生成邮件。

由于底层模型(称为基础模型,将在下一章中介绍)的广泛性质,它也擅长理解语法和拼写错误。例如,我们拼写错了“pracrtices”和“architectes”,但它都理解了:

**https://github.com/OpenDocCN/ibooker-dl-zh/raw/master/docs/genai-act/img/Prompt.png** 为即将在所有书店上市的全新生成式 AI 书籍撰写一封简短的图书发行邮件。本书涵盖了生成式 AI 的介绍、不同类型和应用场景,以及企业最佳实践,包括它们如何将这项新的 AI 技术融入其业务流程。本书由 Manning 出版,作者为 Amit Bahree。本书名为《生成式 AI 在行动:企业 AI 的实际应用与案例研究》,目标读者为开发人员和企业架构师,语气友好且令人兴奋。

  1. 邮件的标题应该是什么?

  2. 邮件正文应该是什么?

我们得到了以下相当不错的回答:

  1. **https://github.com/OpenDocCN/ibooker-dl-zh/raw/master/docs/genai-act/img/Response.png** 1. 主题行:“探索我们的新书《Amit Bahree 的“生成式 AI 在行动”》中生成式 AI 的力量!”

    1. 邮件正文:

亲爱的 [收件人姓名],

我很高兴地宣布,由 Amit Bahree 撰写并由 Manning 出版的引人注目的新书《生成式 AI 在行动:企业 AI 的实际应用与案例研究》已发布。

我们动态的商业环境需要尖端解决方案,生成式 AI 正是如此。它是科技行业最令人兴奋的进步之一,并且可能成为您业务的变革者。无论您是开发者还是企业架构师,这本书都是您利用生成式 AI 力量的入场券。

“生成式人工智能实战”揭示了生成式人工智能的复杂性。它提供了一个易于理解的介绍,深入探讨了其不同类型、用例以及它如何能够革新业务流程。此外,它还提供了企业将这一前沿技术融入运营的最佳实践。

这是您可以从这次启发性的阅读中期待的内容:

  • 生成式人工智能的全面介绍。

  • 探索各种类型的生成式人工智能及其现实世界的应用。

  • 通过案例研究展示了企业如何利用生成式人工智能。

  • 关于在您的企业中实施生成式人工智能的最佳实践的宝贵指导。

我们精心挑选了这本书,使生成式人工智能对任何渴望理解和使用它的人都能触手可及。因此,无论你是 AI 的新手还是寻求保持在技术进步前沿的资深专业人士,“生成式人工智能实战”正是你一直在等待的资源。

我们很高兴地分享,“生成式人工智能实战”现在在所有主要书店都有售。今天抓起你的副本,开始你的用生成式人工智能改变业务的旅程。

感谢您的持续支持,祝您阅读愉快!

最好的祝愿,

[您的姓名]

[您的职位]

[您的联系信息]

1.3.3 生成图像

我们不仅限于仅生成文本——我们可以使用提示生成图像。为了明确,模型不会找到满足这些属性的可比图像;相反,它会生成一些全新的东西,这些东西在现实中并不存在。如果我们要求一些在现实世界中不可能存在的奇异事物,比如一只狗坐在桌子旁,戴着眼镜,在泰姬陵的背景下写书,这都没有关系。AI 可以分解并理解每个方面,然后利用这些信息创造新的东西,就像艺术家一样。在图 1.4 中,我们使用 OpenAI 的 DALL-E 3 模型根据提示生成图像。

**https://github.com/OpenDocCN/ibooker-dl-zh/raw/master/docs/genai-act/img/Prompt.png**生成一张狗戴着眼镜坐在桌子旁,用电脑编写关于人工智能的书籍的图像。让它成为一张积极的图像,背景是远处窗户中金色的泰姬陵。

图 1.4 使用 DALL-E 3 进行图像生成

1.3.4 生成代码

当思考生成代码时,将 AI 视为能够创建一些函数和例程,而不是能够创建完全功能的应用程序是有帮助的。大量的代码是关于不同运行时和框架的脚手架,而不是关于精确的业务逻辑。在这些场景中,代码生成可以帮助提高开发者的生产力。在以下示例中,我们使用 GPT-3.5 为经典的“Hello, World!”函数生成代码。我们可以给出以下提示,它将为我们生成代码。

**https://github.com/OpenDocCN/ibooker-dl-zh/raw/master/docs/genai-act/img/Prompt.png**为一位新手开发者编写一个使用 OpenAI API 的 Python“Hello World”等效代码,并将输出翻译成法语。

你会得到类似于列表 1.1 的答案,包括启动所需的步骤,这令人印象深刻。当然,这只是一个说明性的例子,用来展示模型的力量——理解请求的上下文和规则,包括编程语言、软件开发工具包(SDK)、要使用的包,最后生成代码。此代码不遵循既定的最佳实践(例如,不应该在代码中包含 API 密钥)。

列表 1.1 “Hello, World!”调用 OpenAI 服务
import os
from openai import OpenAI

gpt_model = "gpt-3.5-turbo"

# Replace with your actual OpenAI API key
client = OpenAI(api_key='your-api-key')

# Generate English text
response_english = client.chat.completions.create(
    model="gpt-3.5-turbo",
    messages=[
      {
        "role": "user",
        "content": "Hello, World!"
      }
    ],
    max_tokens=50
)
english_text = response_english.choices[0].message.content.strip()
print(english_text)

# Translate English text to French
response_french = client.chat.completions.create(
    model="gpt-3.5-turbo",

    messages=[
      {
        "role": "user",
        "content": "Translate the following English 
          ↪text to French: " + english_text
      }
    ],
    max_tokens=100
)

# This prints the translation to French
print(response_french.choices[0].message.content.strip())

运行脚本:

python helloworld.py

输出如图 1.5 所示。请注意,由于 AI 的非确定性本质,每次运行时我们都会得到略微不同的响应。在第三章中,我们将看到如何使用不同的选项来控制一些这些行为,并引导模型变得更加确定。这些选项中的一些是大型语言模型(LLMs),这是一种生成式 AI 模型。我们将在下一章中探讨 LLMs。

图 1.5 生成的代码

当我们概述代码生成时,大型语言模型(LLMs)可以在与代码相关的其他方面提供帮助,例如可解释性、优化和可读性。我们将在第五章中更详细地介绍代码。

1.3.5 解决逻辑问题的能力

生成式 AI 推理能力令人印象深刻。由于这些 AI 技术的涌现行为,如果我们可以通过提示表达问题域,我们就可以得到一个答案,以及逐步的思考过程。这类似于人类思考、分解和解决问题的方法。

例如,我们可以要求模型解决一个简单的数学方程,解释步骤,并给出答案。

如果 x = 80 且 y = 60

当 y = 30 时,x 是多少?

这里是模型逐步工作并通过其步骤以及它所经历的精确思维过程的响应。使用传统 AI 实现这一点,在更广泛的领域空间中实现泛化,将是困难的,如果不是不可能的:

**https://github.com/OpenDocCN/ibooker-dl-zh/raw/master/docs/genai-act/img/Response.png**鉴于当 y = 60 时 x = 80,我们可以建立一个比例来求解当 y = 30 时的 x。

在这个例子中,我们假设 x 和 y 之间存在线性关系,即 x 与 y 成正比。因此,当 y 减半时,x 也会减半。

使用给定的值:

x1/y1 = x2/y2

其中:

x1 = 80

y1 = 60

y2 = 30

我们正在尝试找到 x2。

我们可以设置方程:

80/60 = x2/30

解 x2,我们得到:

x2 = (80/60) * 30

这简化为:

x2 = (4/3) * 30

x2 = 40

因此,如果 y = 30,那么 x = 40。

传统人工智能无法解决这个问题,因为它对世界的理解很狭窄。它不能理解问题的意图来概述一个逐步的过程,因为传统人工智能不是生成性的。它只能遵循明确编程进它的指令。

然而,生成性人工智能可以理解问题的意图,因为它对世界的理解更广泛,并且可以生成逐步的过程。这还允许生成性人工智能模型的涌现行为。这种行为是概述逐步过程的能力。它不是模型任何单个组件中存在的,而是从组件的交互中产生的。下一章将在介绍大型语言模型时更详细地介绍涌现行为。

1.3.6 生成音乐

与我们使用提示生成图像的方式类似,我们也可以用音乐来做同样的事情。与文本相比,音乐生成仍然是一个新兴领域,但底层模型和技术正在快速发展。我们可以使用生成性人工智能音乐模型,如来自 Google 的 MusicLM 或 Meta 及其他公司的 MusicGen,来生成音乐。例如,如图 1.6 所示,我们可以使用一个提示,如“创建一首冥想曲,用长笛和吉他营造出平静和舒缓的感觉。音乐应该节奏缓慢,专注于营造平和与宁静的感觉。”这会生成几个 30 秒的剪辑。

图 1.6 MusicLM 的截图

1.3.7 生成视频

Sora 是来自 OpenAI 的新人工智能模型,可以生成文本到视频场景。它可以根据用户的文本描述(提示)创建逼真和富有创意的场景。这些提示可以决定从艺术风格到想象中的图像或现实世界的情况。Sora 创建短视频剪辑,同时保持视觉质量并遵循用户的指令。

除了 Sora,还有一些其他模型可以生成视频。一个例子是 Runway 的 Gen-2,它具有与 Sora 相同的能力。Pika 是另一个由人工智能驱动的视频生成器,可以从提示生成视频和 3D 动画。Hotshot 是 Sora 的开源选项。最后,还有来自 StabilityAI 的 Stable Video Diffusion。与其它模型相比,Sora 似乎更先进,可以创建长达一分钟的剪辑,具有连贯的角色和动作。

1.4 企业用例

生成式 AI 领域正处于陡峭的上升轨迹上,市场价值估计从 2022 年的 17.5 亿美元飙升至到 2027 年的预计 330 亿美元,复合年增长率(CAGR)达到 80% [2]。彭博情报的行业专家预测,在十年内市场将扩大到 1.3 万亿美元,从 2022 年记录的 400 亿美元跃升 [3]。GenAI 的广泛应用在各个行业中都很明显,包括金融服务和客户关系管理,这得益于其增强洞察力和生产力的能力。考虑到 Gartner 预测到 2027 年 90%的服务提供商将采用 GenAI 进行软件开发 [4],很明显,生成式 AI 不仅正在重塑现有的商业格局,而且也在为新的市场前景铺平道路。企业迅速将 GenAI 整合到其产品中,将自己置于这场技术革命的前沿和它带来的众多机会的前沿。

生成式 AI 是一种强大的技术,可以从现有内容或数据中创建新的内容或数据。许多企业在其组织内外使用它来满足不同的用例。其中一些是为了提高他们的工作流程或效率,而另一些则向客户提供更好的服务或产品。根据目的的不同,使用生成式 AI 的挑战也各不相同。例如,一个常见的挑战是当 AI 系统产生一些没有意义的东西时(即,它编造了东西——也称为幻觉)。这通常比外部处理更容易处理,因为客户可能对 AI 系统有更高的期望或更低的信任度。

有许多原因导致 AI 系统倾向于产生幻觉,但通常是因为底层模型无法在其训练数据中区分事实和虚构。大型语言模型(LLMs)被训练生成连贯、上下文感知的文本,而不是事实准确性的回应。当提示或上下文不准确但与任务相关时,它们往往会产生幻觉。我们将在本书的后面部分介绍幻觉以及可以用来减少它们的技巧。

表 1.2 概述了一些企业用例。这些用例是通用的,因为它们是更横向的例子,适用于多个行业。表 1.3 概述了一些特定行业的用例。

表 1.2:生成式 AI 的企业横向用例
横向用例描述
内容生成GPT-4 可以生成内容,如博客、报告、电子邮件和社交媒体帖子,这有助于企业扩大其内容营销的努力。
个性化营销生成式 AI 可以创建个性化的营销内容,如电子邮件、着陆页和社交媒体帖子。这可以帮助企业更有效地接触目标受众并提高转化率。
客户服务生成式 AI 可用于创建能够回答客户问题并解决问题的聊天机器人。这可以使人工客服代表有更多时间专注于更复杂的工作。许多这些聊天机器人都是通过类似企业 ChatGPT 的范式实现的。
风险管理生成式 AI 可以识别和预测风险,如欺诈、网络攻击和供应链中断。这可以帮助企业降低风险并保护其资产。
合规性生成式 AI 可以生成合规的文件,例如合同、报告和披露。这可以帮助企业节省时间和金钱,并降低违规风险。
软件开发在软件开发中,生成式 AI 可以生成新代码、提供代码片段,甚至编写简单的软件,可能节省时间并减少错误。它还帮助文档化代码、重构、生成测试用例和优化现有代码。
数据增强在数据科学和机器学习领域,当用于模型训练的真实数据不足时,生成式 AI 可以创建合成数据。
合同管理生成式 AI 的关键应用案例是合同生成和合同理解——既创建法律文件的草案,又理解包含特定监管和区域法律要求的企业和特定公司政策的法律合同。这种方法减少了人为错误,并帮助企业做出明智的决策。
表 1.3 生成式 AI 的行业特定应用案例
行业应用案例描述
金融在金融领域,生成式 AI 可以模拟不同场景以帮助决策、风险评估以及新金融产品和服务的开发。客户运营以增强服务和针对每位客户的解决方案基于交易和历史记录。
医疗保健生成式 AI 用于开发新药和治疗,设计医疗设备,创建个性化患者治疗方案,并生成有关说明、风险和药物相互作用的病人文档。
制造业生成式 AI 用于设计新产品、优化制造流程和改进质量控制。
零售和消费品生成式 AI 用于个性化购物体验、推荐产品、管理库存、加速消费者研究、增强供应链等。
品牌和销售市场营销和销售已经广泛使用 AI。生成式 AI 正在帮助提升行业的某些方面——特别是帮助我们理解实时客户趋势、嵌入到虚拟助手中的个性化接触以及动态的客户旅程。

这些只是生成式 AI 在企业的几个应用案例。随着技术的不断发展,我们可以期待看到更多创新和有影响力的应用。

1.5 不宜使用生成式 AI 的情况

在企业环境中使用生成式 AI 与个人出于个人原因使用它有很大不同。组织必须遵循适用于其行业的某些法规和期望,其中一些可能因地区而异。此外,还有其他财务、法律、技术和道德方面的考虑。如果 AI 生成的内容不正确、充满偏见,或者只是简单的不礼貌——这会引发什么问题?例如,如果 AI 聊天机器人搞砸了一个食谱,那没什么大不了的,但如果它给修理复杂机械的人提供了错误的指示,那就完全是另一回事了。

如果企业没有为生成式 AI 制定适当的道德准则,可能会导致意想不到的后果。生成式 AI 可以创造虚假信息和虚假内容,包括虚假新闻文章、虚假图像、敏感内容和恶意内容。图片不再值千言万语;有些图片做得太好,以至于越来越难以区分虚假和真实图像。在某些情况下,生成的输出也可能侵犯第三方版权材料。增加人工监督和贡献可以帮助解决这些挑战。

生成式 AI 模型也可能无意中放大训练数据中存在的偏见,导致产生具有问题性的输出,这些输出会持续传播刻板印象和有害意识形态。它们还可以生成虚构或不合逻辑的回应,这些回应没有基于事实(即,幻觉)。

公司需要有一个明确的计划来使用生成式 AI,并确保它与业务目标一致,例如它将如何影响销售、营销、商业、服务和 IT 工作。在生死攸关的决策中,确保有人参与其中,由人类作为最终决策者,AI 作为副驾驶协助。

1.6 生成式 AI 与传统 AI 有何不同?

传统 AI,现在有些人称之为窄 AI,是我们今天遇到的主要 AI 形式。它使用经典数据科学和系统方法,通过使用各种方法和技术从数据中提取洞察和知识。它通常包括以下步骤:数据收集、数据准备、数据分析、特征工程、训练和数据验证。传统 AI 在预定义的边界内预测事物,这些边界是编码在模型中的规则和指令。它只能根据预定义的条件、约束和潜在结果行事。因此,结果是确定性的且相对可预测的。例如,传统 AI 可以被编程来自动化客户服务,通过聊天机器人生成基于预定义脚本的响应。虽然这些系统在其规定的领域内非常有效,但它们仍然在自己的轨道上,不能学习并适应其编程知识之外的情况——这就是所谓的窄 AI。到目前为止,企业所做的大多数 AI 实现都是传统 AI。

相比之下,生成式 AI 倾向于概率方法,其结果是基于受输入数据和学习模式影响的概率计算得出的。这使得这些 AI 系统能够创建既没有硬编码也没有明确教授给系统的输出。生成式 AI 需要经典的数据科学流程,它在许多方面都增强了并补充了这一流程。生成式 AI 可以帮助处理新的数据类型和内容,评估生成输出的质量和有效性,并确保生成式 AI 的道德和负责任的使用。经典数据科学和生成式 AI 必须共同工作,从数据中创造价值和影响。

一个显著的区别是,与这些较新的生成式 AI 模型交流的方式是通过使用提示词,正如我们在示例中看到的那样。更正式地说,提示词是一组指令,告诉生成式 AI 系统我们想要创建哪种内容。提示词越好,结果越好。提示词应该根据你想要收到的响应类型以及你所使用的生成式 AI 的具体情况来定制。我们将在稍后更详细地介绍提示词工程。

提示词让我们能够更加表达自己,不仅概述要求和意图,还能通过语言捕捉同情和情感。提示词工程是开发者和企业的一个新兴领域,它更像是艺术而非科学。

AI 生成的文本:

通过提示词我们工程化得更多——

笑声连连,再来一次!

表 1.4 概述了广泛的类别,以展示生成式和传统 AI 架构之间的差异。同时,值得注意的是,不同类型的 AI 之间存在很多重叠。例如,聊天机器人可能会同时使用生成式和预测模型,根据对语言的学习理解生成响应,并预测用户可能认为最有帮助的响应类型。

表 1.4 生成式 AI 与传统 AI 的区别
领域区别
创建与预测传统 AI 专注于预测或分类任务,基于现有数据识别某个事物或预测接下来会发生什么。生成式 AI 创建新的内容和输出,这些在原始数据中并不存在。

| 部署和推理 | 相比于生成式 AI,传统 AI 模型更简单,需要的计算资源更少,这使得它们可以在各种硬件上运行,从小型边缘设备到大型云集群,无所不在。这种云到边缘的灵活性对企业来说是一个巨大的优势。生成式模型庞大且复杂;大部分情况下,它们只能通过 API 在大型云计算节点上获得,这也有其他优势,例如,这些基础模型中编码的世界知识对每个人都是可用的。然而,还有其他需要考虑的约束。

注意:存在越来越多的较小开源模型可以在本地运行,但今天,它们仍然更多是实验性和初级的。许多人声称自己是 AI 质量(AIQ),类似于 OpenAI 的模型。鉴于生成式 AI 覆盖的广泛范围,出现了一套新的基准,例如斯坦福大学的语言模型全面评估(HELM),以及 Hugging Face 最近发布的开放 LLM 排行榜。我们将在本书后面关于评估和基准的部分深入探讨这些内容。

|

训练方法生成式模型需要不同的训练方法(自监督和多任务学习),由于需要大量数据、模型大小和计算资源,因此这种方法更长且成本更高。管理和这些相关的成本和复杂性是巨大的,我们将在本章后面讨论这些问题。
训练数据集生成式 AI 模型通常在大量现有内容的数据集上进行训练,而传统 AI 模型通常在较小标记数据集上进行训练。例如,用于图像生成的生成式 AI 模型可能是在数百万张图像的数据集上训练的。相比之下,用于图像分类的判别式 AI 模型可能是在几千个标记图像数据集上训练的。
模型复杂性生成式 AI 模型通常比其他类型的模型更复杂,因为它们需要学习数据中的模式和关系,以生成与现有内容相似的新内容。
适应方法传统 AI 除了标注更多数据和完成完整的机器学习循环(包括训练、部署和评估)之外,没有其他适应技术。相比之下,生成式 AI 拥有广泛的世界知识。有时,需要根据特定需求和任务对其进行定制,或者提炼内部私有和专有知识;这是通过适应来实现的。根据需要,可以使用各种技术。

1.7 企业应采取什么方法?

生成式 AI 可以弥补传统数据驱动 AI 系统的局限性,并提供一个非凡的工具包来构建更智能的应用和系统;对企业来说,可能性是广阔且令人兴奋的。想象一下设计能够随着时间的推移自我优化的系统,或者开发能够撰写电子邮件和报告、生成代码片段等的人工智能助手(Copilots),从而提高生产力和缩短上市时间。

许多组织可能会被生成式 AI 的兴奋和错失良机的恐惧所吸引,它看起来像是魔法。然而,事实是,拥有像 GPT-4 这样的基础模型,一个大型语言模型,本身并不会带来任何区别。这些高级 AI 系统必须像任何其他外部软件一样实施并连接到企业的业务线和流程。我们将在后续章节中看到如何实现这一点的例子。

在整体方法上,应该很少有变化;企业在整合生成式 AI 时仍应采取深思熟虑和战略性的方法。以下是一些关键考虑因素——这些涵盖了大多数企业需要考虑的各个方面,从战略到业务再到技术:

  • 循序渐进。从小处着手,不要急于求成。从一个小的试点项目开始,以评估、学习和适应。这是一个复杂的技术,开发和部署有效的生成式 AI 应用需要时间。不要期望一夜之间看到结果。

  • 明确目标和合适的使用场景。对企业来说,仔细评估潜在的使用场景并选择那些最有可能带来价值的使用场景非常重要。所选的使用场景将指导 AI 模型的选择、数据准备和资源分配。一些生成式 AI 应用已经比较成熟,并有着成功的记录,而其他应用仍处于早期阶段。

  • 建立治理政策。生成式 AI 可以生成数据,其中一些可能敏感或有害。企业必须建立治理政策,以确保这些数据被负责任和安全地使用。这些政策应解决数据所有权、隐私和安全等问题。

  • 建立负责任的 AI 和伦理治理*。 考虑使用生成式 AI 的伦理影响是很重要的。建立一个独立的负责任的 AI 和伦理政策集,这些政策反映了公司的价值观,并且对于管理其声誉和品牌非常重要。这包括 AI 输出中的偏见、生成内容的潜在滥用、生成内容中的幻觉和错误细节,以及自动化人类以前执行的任务的影响。一个强大的 AI 治理和伦理框架可以帮助管理这些风险。

  • 实验和迭代*。 与计算机科学不同,AI,尤其是生成式 AI,是非确定性的,并且根据模型参数和设置,输出可能相当不同。与任何 AI 应用一样,在实施生成式 AI 时采取迭代方法是至关重要的。从小项目开始,从结果中学习,并逐步扩大规模。这种方法有助于管理风险并获得实践经验。

  • 为失败设计*。 目前大多数生成式 AI 模型作为云 API 商业上可用。因此,它们比更传统的 API 复杂,并且具有相当大的延迟。企业应遵循云最佳实践并为失败设计。他们还应考虑重试机制的最佳实践,包括指数退避策略、缓存、安全等。

  • 扩展现有架构*。 这些新的生成式 AI 端点是整个系统中的额外部分。因此,大多数组织将希望保持其现有的架构指导和实践,并扩展其现有的架构和最佳实践,而不是从头开始。需要纳入新的结构,如上下文窗口、令牌和嵌入等。

  • 带来你的数据*。 企业区别于其他企业的主要不同之处在于它们的专有数据和相关的提示;因此,确定在使用由 GenAI 驱动的应用程序时如何利用它们的专有内部数据至关重要。这需要基于手头的用例,如果不妥善管理,可能会迅速变得复杂,这将在后续章节中讨论,当我们谈到 RAG 时。

  • 管理成本*。 生成式 AI 复杂且成本高昂。成本通常以不同的方式衡量(例如,以令牌计),而不是以 API 调用计。对于企业来说,这许多都是新的和不同的,成本很容易失控。

  • 补充传统 AI*。 在大多数情况下,生成式 AI 将有助于协助企业现有的传统 AI 投资。这两套技术不是相互排斥的,而是相互支持的。

  • 开源模型与商业模型*.* 一些模型是商业可用的,例如 Azure OpenAI 的 GPT 模型,而一些是开源的,例如 Stable Diffusion。根据用例,验证要使用哪些模型、许可允许什么以及已经覆盖了哪些法律和监管方面非常重要。

1.8 架构考虑因素

假设您是一位看到所有关于生成式 AI 的新闻以及主要科技公司各种产品公告的企业开发者。在这种情况下,您可能会认为对于 AI 来说,一切都已经改变。然而,在现实中,并没有什么改变。

从企业角度来看,需要考虑生成式 AI 的新方面—大多数,如果不是全部,这些都会是添加到现有架构最佳实践和指南中的内容,而不是完全摒弃。我们将在本书的后续章节中详细说明,但新的架构模式必须在高层次上得到考虑。我们已经涉及了许多这些方面,但关键的是

  • 提示词—我们将看到如何评估围绕提示词的工程和管理方面,包括令牌和上下文窗口。

  • 模型适应性—目标是使输出更适合特定任务。

  • 将生成式 AI 集成到现有的企业业务系统中—这些新的 AI 模型本身并不能解决商业问题。

  • 设计容错—在构建关键任务系统时,这个方面本身并不是什么新事物,但许多人仍然走捷径。

  • 成本和投资回报率*—*这些生成式 AI 系统非常昂贵,因为其背后的计算成本也非常高。随着时间的推移,成本将会下降,但它们必须在前瞻性地规划和设计。例如,OpenAI 的 GPT-3.5 Turbo 的成本下降了 90%,而其质量与 GPT-3 相比也提高了 90% [5]。

  • 开源(OSS)与商业模式的政策和方法*—*每周都会有新的模型为 AI 系统提供动力并发布。有些是商业的,有些是开源的,具有不同的许可结构。

  • 供应商*—*目前有少数供应商的企业可以使用,但很快就会有更多。今天,最成熟的两个是 OpenAI 和 Azure OpenAI。前者针对小型公司和初创企业,而后者针对企业。谷歌也在 Google Cloud 上发布其生成式 AI 套件,亚马逊也有类似的公告。此外,许多资金充足的初创公司也宣布了类似的产品,如 Anthropic 和 Mistral。企业需要将它们视为供应商,并确定他们希望利用和依赖哪一个。

1.9 因此,您的企业希望使用生成式 AI。接下来该怎么做?

您的企业已经迈出了使用生成式 AI 推动创新和效率的关键一步。然而,了解接下来会发生什么对于最大化这种先进技术的利益和减轻风险至关重要。

要开始,我们将使用实施企业 ChatGPT 的例子,并概述在高级别上所需的步骤。在接下来的几章中,我们将深入探讨更多技术细节,包括实施指导和最佳实践。图 1.7 展示了企业中典型工作流程的高级概述。

图 1.7 实施生成式 AI 的高级概述

您应该从为您的聊天机器人设定明确的目标开始。您希望通过生成式 AI 解决哪些挑战?它如何能帮助您最多?这可以是任何事情,从为营销创建内容到通过聊天机器人增强客户服务,预测商业计划,甚至创新新产品或服务。在我们的例子中,我们正在构建一个企业 ChatGPT,例如 OpenAI 的 ChatGPT,但它是部署并在企业环境中运行,使用内部和专有数据,并且只有授权用户可以访问。

接下来,我们需要确保我们有必要的资源可用,即具有正确能力的人员、合适的软硬件框架、定义成功指标,以及适当的治理和伦理原则。

然后,考虑数据。在我们的例子中,企业聊天机器人需要访问相关的高质量企业数据,用户可以加以利用。这些数据需要被摄取和索引以帮助回答专有问题。在此之前,数据必须得到妥善管理,确保隐私和遵守法律。记住,输入数据的质量将影响输出质量。

接下来,我们需要将企业聊天机器人集成到解决我们试图解决的问题和用例的业务应用程序中。作为一家企业,我们还将希望解决与生成式 AI 相关的风险,并实施关于安全和负责任 AI 的企业指导。

最后,尽管我们可能已经准备好在生产中部署,但实施生成式 AI 不是一个一次性的事件,而是一个旅程。它需要持续的监控、测试和微调,以确保其最优和负责任地运行。从较小的、可管理的项目开始,随着您在处理这项强大技术方面获得更多信心和专业知识,逐步扩大规模是个好主意。

采用生成式 AI 是一项重大的承诺,可能会改变您的企业,但它需要周密的规划、适当的资源、持续的监控和对伦理考量的坚定不移的关注。有了这些,您的企业可以享受到生成式 AI 的众多好处。

摘要

  • 生成式 AI 可用于多个用例,例如实体提取;生成特定和个性化的文本、图像、代码和音乐;解释文本;以及解决逻辑问题。

  • 生成人工智能的应用案例可以横跨大多数行业(如客户服务和个性化营销)或特定行业(如金融中的欺诈检测或医疗保健中的个性化治疗方案)。

  • 传统人工智能主要在预定义的狭窄通道中运行,只能在那些维度上行动,与更广泛且更具灵活性的生成人工智能不同。

  • 本章概述了企业在采用和实施生成人工智能时需要考虑的方法和架构。

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

本章涵盖

  • LLMs 概述

  • 由 LLMs 驱动的关键用例

  • 基础模型及其对 AI 发展的影响

  • LLMs(大型语言模型)的新架构概念,例如提示(prompts)、提示工程(prompt engineering)、嵌入(embeddings)、标记(tokens)、模型参数(model parameters)、上下文窗口(context window)和涌现行为(emergent behavior)

  • 小型语言模型概述

  • 开源和商业 LLMs 的比较

大型语言模型(LLMs)是基于给定输入能够理解和生成类似人类文本的生成式 AI 模型。LLMs 是许多自然语言处理(NLP)任务的基础,如搜索、语音转文本、情感分析、文本摘要等。此外,它们是通用语言模型,经过预训练,可以针对特定任务和目的进行微调。

本章探讨了 LLMs 的迷人世界及其对人工智能(AI)的变革性影响。作为 AI 领域的一项重大进步,LLMs 在理解和生成类似人类文本方面表现出惊人的能力,从而使得 LLMs 在各个行业得到广泛应用。在这里,我们深入探讨 LLMs 的关键用例、不同类型的 LLMs 以及颠覆了 AI 发展的基础模型概念。

本章讨论了 LLMs 的基本概念,如提示、提示工程、嵌入、标记、模型参数、上下文窗口、Transformer 架构和涌现行为。最后,我们比较了开源和商业 LLMs,突出了它们的优缺点。在本章结束时,您将全面了解 LLMs 及其对 AI 应用和研究的影响。LLMs 建立在基础模型之上;因此,在更深入地讨论 LLMs 之前,我们将首先概述这些模型是什么。

2.1 基础模型概述

由斯坦福研究人员于 2021 年提出的基础模型在很大程度上改变了 AI 系统的构建方式。它们不同于特定任务的模型,转向了更广泛、更适应性的模型,这些模型在大数据量上训练。这些模型在多种自然语言任务上表现出色,如机器翻译和问答,因为它们从大量的文本和代码数据集中学习通用的语言表示。这些表示可以用于执行各种任务,甚至包括它们没有明确训练过的任务,如图 2.1 所示。

在更技术性的术语中,基础模型利用了已建立的机器学习技术,如自监督学习和迁移学习,使它们能够将获得的知识应用于各种任务。通过深度学习开发,这些模型采用多层人工神经网络来理解复杂的数据模式;因此,它们在处理非结构化数据方面的能力,如图像、音频和文本。这也扩展到 3D 信号——代表 3D 属性的数据,如捕获空间维度和深度的激光雷达传感器的 3D 点云、3D 医学成像(如 CT 扫描)或用于计算机图形和模拟的 3D 模型。这些可以用于基于 3D 数据进行预测,例如物体识别、场景理解和机器人以及自动驾驶车辆的导航。

注意:迁移学习是一种机器学习技术,其中为某一任务开发的模型被重新用作类似任务的起点。我们不是从头开始,而是使用先前任务的知识来在新任务上表现更好。这就像使用以前工作的知识来在新但相关的岗位上表现出色。

生成式 AI 和基础模型紧密相连。如前所述,在大量数据集上训练的基础模型可以适应执行各种任务;这种特性使它们特别适合于生成式 AI,并允许创建新内容。这些模型广泛的知识库允许有效的迁移学习,这可以用于在多个领域生成新的、上下文适当的内容。它们代表了一种统一的方法,其中单个模型可以生成各种输出,由于广泛的训练,它们提供了最先进的性能。如果没有基础模型作为骨干,就不会有生成式 AI 模型。

图 2.1 基础模型概述

这里有一些常见的基础模型示例:

  • GPT(生成预训练转换器)家族是由 OpenAI 开发的 NLP 模型家族。它是一个在大量文本和代码数据集上训练的大型语言模型,这使得它能够生成文本、翻译语言、创作内容以及提供信息性的回答。GPT-4,在撰写本文时的最新版本,也是一个多模态模型——它既能处理语言也能处理图像。

  • Codex 是一个专门针对代码进行训练的大型语言模型,用于帮助代码生成。它支持超过十种编程语言,包括一些常用的,如 C#、Java、Python、JavaScript、SQL、Go、PHP 和 Shell 等。

  • Claude 是由一家名为 Anthropic 的初创公司构建的 LLM。与 OpenAI 的 ChatGPT 类似,当给出一定的提示时,它可以预测序列中的下一个标记,并可以生成文本、编写代码、总结和推理。

  • BERT(来自 Transformer 的双向编码器表示)是由谷歌开发的一种自然语言处理模型。它是一个双向模型,这意味着它可以从左到右和从右到左处理文本。这一特性使得它更擅长理解单词和短语的上下文。

  • PaLM(路径语言模型)及其继任者 PaLM2 是由谷歌开发的大型多模态语言模型。多模态模型可以同时处理文本、代码和图像,使其能够在这些模态中执行比仅在一个模态中操作的传统语言模型更广泛的任务。

  • Gemini 是谷歌最新的 AI 模型,能够理解文本、图像、视频和音频。它是一个多模态模型,描述为能够在数学、物理和其他领域完成复杂任务,以及理解和生成各种编程语言中的高质量代码。Gemini 是从头开始构建的多模态模型,这意味着它可以泛化并无缝地理解、操作和结合不同类型的信息。它也是谷歌所有 AI 工具的新总称,取代了 Google Bard 和 Duet AI,并被认为是对 PaLM 模型的继承。

一旦训练了基础模型,就可以通过微调其参数来将其适应广泛的下游任务。微调涉及调整模型的参数以优化模型以特定任务。这可以使用少量标记数据进行。通过为特定任务或领域微调这些模型,我们利用它们对语言的普遍理解,并补充以特定任务的知识。这种方法的好处包括时间和资源效率,以及显著的灵活性。我们还可以通过提示工程来调整模型,我们将在本章后面讨论。现在我们更了解基础模型,让我们来探索 LLMs。

2.2 LLMs 概述

LLMs 代表了人工智能的重大进步。它们在大量文本数据上接受训练,如书籍、文章和网站,以学习人类语言的模式。它们也难以开发和维护,因为它们需要大量的数据、计算和工程资源。OpenAI 的 ChatGPT 是 LLM 的一个例子——它通过预测文本中已使用的单词的概率来生成类似人类的文本。

该模型通过调整其内部参数以最小化预测与训练数据中实际结果之间的差异,从而学会生成连贯且与上下文相关的句子。在生成文本时,模型会选择概率最高的单词作为其后续输出,然后对下一个单词重复此过程。

大型语言模型(LLMs)是为自然语言处理和语言生成任务而改编的基础模型。这些 LLMs 是通用的,可以处理没有特定任务训练数据的任务。正如前一章简要描述的,给定正确的提示,它们可以回答问题、撰写文章、总结文本、翻译语言,甚至生成代码。LLMs 可以应用于不同行业中的许多应用,如第一章概述的——从摘要到分类、问答聊天机器人、内容生成、数据分析、实体提取等。在我们深入了解 LLMs 之前,让我们看看 Transformer 架构,这是这些基础模型成为可能的原因。

2.3 Transformer 架构

变压器是基础模型的基础,并负责其卓越的语言理解能力。Transformer 模型首次在 2017 年由 Vaswani 等人撰写的论文“Attention Is All You Need”中提出[1]。从那时起,基于 Transformer 的模型在许多任务中已成为最先进的模型。GPT 和 BERT 是基于 Transformer 的模型的例子,GPT 中的“T”代表 Transformer。

在其核心,Transformer 使用一种称为注意力(特别是自注意力)的机制,这使得模型能够考虑句子的整个上下文,同时考虑所有单词,而不是逐词处理句子。这种方法更高效,可以提高许多 NLP 任务的结果。

这种方法的优点是它捕捉了无论它们在文本中的位置如何的依赖关系,这是语言理解中的一个关键因素。这对于机器翻译和文本摘要等任务至关重要,在这些任务中,一个句子的意义可能取决于相隔几个单词的术语。

变压器可以并行化其计算,这使得它们比其他类型的神经网络训练得更快。这种机制使得模型能够关注任务输入中最相关的部分。

在生成式 AI 的背景下,一个 Transformer 模型会通过权衡输入的每个部分在生成输出中的重要性,接收一个输入(例如一个提示)并生成一个输出(例如下一个单词或句子的完成)。例如,在句子“The cat sat on the…”中,一个 Transformer 模型在确定可能的下一个单词可能是“mat”时,可能会给单词“cat”赋予很大的权重。这些模型通过预测序列中的下一个项目——句子中的下一个单词或旋律中的下一个音符——来展示其生成特性。我们将在下一章中进一步探讨这一点。

变压器模型通常非常大,需要大量的计算资源来训练和使用。用汽车类比,可以将变压器模型视为超级引擎,需要大量能量来运行,但能做惊人的事情。可以将其视为在 ResNET 50 等模型之后的下一步,ResNET 50 用于识别图像。ResNET 50 像一辆有 50 个档位的汽车,而 OpenAI 的 GPT-3 像一辆有 96 个档位和额外功能的重型卡车。由于它们的先进能力,这些模型是创建智能 AI 输出的首选。

LLMs 使用变压器,它由编码器和解码器组成。编码器处理输入文本(即提示),并生成一系列表示输入文本意义的隐藏状态。解码器使用这些隐藏状态来生成输出文本。这些编码器和解码器形成一层,类似于一个小型大脑。可以将多层堆叠在一起。如前所述,GPT3 是一个仅包含解码器的模型,有 96 层。

2.4 训练截止点

在基础模型的情况下,训练截止点指的是模型训练结束的点,即收集用于训练模型的数据的时间。在 OpenAI 开发的 AI 模型(如 GPT-3 或 GPT-4)的情况下,训练截止点是模型最后一次在新数据上训练的时间。

这个截止点很重要,因为在此之后,模型不会意识到任何事件、进步、新概念或语言使用的变化。例如,GPT-3.5 Turbo 的训练数据截止日期是 2021 年 9 月,GPT-4 Turbo 是 2023 年 4 月,GPT-4o 是 2023 年 10 月,这意味着模型不知道在此点之后的现实世界事件或各个领域的进步。

马士兵 MCA 架构师课程笔记(七十六)

关键点在于,尽管这些模型可以根据它们训练的数据生成文本,但在训练截止点之后,它们不会学习或更新它们的知识。它们无法访问或从互联网或任何外部数据库检索实时信息。它们的响应完全是基于它们在训练期间学到的模式生成的。

注意:最近宣布 ChatGPT 的付费版本将通过 Bing 插件访问互联网,并不意味着模型有更准确的信息。这使用了一种称为 RAG(检索增强生成)的模式,将在第七章中介绍。

2.5 LLMs 类型

如表 2.1 所示,存在三种 LLMs 类别。当我们谈论 LLMs 时,拥有上下文至关重要,在某些情况下可能并不明显。这非常重要,因为我们使用模型时可以走的路径不是可以互换的,选择正确的类型取决于试图解决的问题的使用案例。此外,还依赖于一个人如何有效地将模型适应特定的使用案例。

表 2.1 LLMs 类型
LLM 类型描述
基础大型语言模型这些是原始模型,在大量文本数据语料库上预训练,可以根据在训练期间学习到的模式生成文本。有些人也把这些原始语言模型称为基础模型,甚至称其为基础模型;它们可以直接用于生成文本。它们学习到强大且通用的表示,但在特定任务上缺乏专业知识。GPT-3 的 DaVinci 模型就是一个基础大型语言模型的例子。
基于指令的大型语言模型这涉及使用基础大型语言模型,并在提示输入中提供明确的指令。在前一章中我们看到的许多示例中,我们指示模型遵循指令,例如“将以下文本翻译成法语:”或“总结这篇文章:”。有时,这些模型也被称为指令调整的大型语言模型。
微调的大型语言模型微调涉及在基础大型语言模型上进一步训练,通常是在它在特定领域表现不佳的任务上。一个例子是,如果我们想让它理解医学主题,就在医学文献上训练模型;如果我们想让它对特定行业的客户咨询做出回应,就在客户服务互动上训练模型。微调可以帮助使模型更准确或对特定任务或领域更有帮助,但它需要额外的数据和训练时间。

值得注意的是,所有这些方法都有其优缺点:

  • 基础大型语言模型具有多功能性,可以在不进行额外训练的情况下处理许多任务。然而,它们可能不如您期望的那样准确或可靠,尤其是在特定任务或领域,尤其是在企业环境中。

  • 对于某些任务,基于指令的使用可能非常有效,但它需要仔细的提示制作,并且并不从根本上改变模型的能力。这正是许多提示工程技术和最佳实践适用的地方。

  • 微调对于特定任务或领域可以产生出色的结果。然而,它需要额外的资源,并伴随着过度拟合训练数据的危险,这可能会限制模型泛化到新示例的能力。

此外,可以采取(零样本、少样本和迁移学习)等方法来进一步调整大型语言模型以适应特定任务,使其在这些特定领域表现更好且更稳健。在某种程度上,所实施的大型语言模型类型也决定了哪种方法更适合需求。每种方法都有其优点和缺点,最佳选择取决于具体任务、可用数据和现有资源:

  • 零样本学习——模型可以在训练过程中没有看到该任务的示例的情况下泛化到该任务。例如,我们可以要求一个仅在英语上训练的模型将英语翻译成德语,即使它在训练期间没有看到任何特定的德语语言示例。它可以通过语义相似性、词嵌入和机器学习来实现零样本翻译。使用这些技术,我们可以测量即使在不同的语言中,两个单词的相似程度。

  • 少样本学习——这涉及到向模型展示我们想要执行的任务的示例,然后要求模型用新的示例执行相同的任务。因此,如果我们想让一个模型识别推文的情感,我们可能会向它展示一些推文及其相关情感的示例,然后要求它预测新推文的情感。

  • 迁移学习——这涉及到在一个任务上训练一个模型,然后使用它在不同但相关的任务上应用学到的知识。例如,尽管 LLMs 是在语言上而不是在特定的客户支持票据上训练的,但它们可以被用来将客户支持票据分类到不同的类别,如账单、技术问题或一般咨询。这有助于简化客户支持流程并确保快速解决,提高客户满意度。

2.6 小型语言模型

小型语言模型(SLMs)是一种新兴趋势,它激发了众多企业的兴趣。它们是较大语言模型的缩小版,旨在提供较大模型的许多好处,同时更加资源高效和易于访问。它们在多个方面与 LLMs(例如,GPT-4)不同,主要在于规模和复杂性、计算资源、训练和运营成本以及性能质量。知识蒸馏和迁移学习等技术使小型模型能够在分析、翻译和摘要方面表现出色,且训练速度更快。在某些情况下,它们甚至可以匹配或超越较大的 LLMs,从而成为游戏规则的改变者。

在规模和复杂性方面,SLMs 比 GPT-4 等大型模型明显更小,参数也更少。这种规模差异是显著的:一个小型模型可能有数百万到数十亿个参数,而大型模型可能有数十亿或数百亿个参数。这种规模和复杂性的减少使得 SLMs 在处理和生成语言的方式上与大型模型有根本性的不同。

从计算资源的角度来看,SLMs 较小的规模需要更少的计算能力。这种减少的需求使它们更适合于处理能力有限的应用或实时响应至关重要的场合。对计算资源的需求减少也意味着 SLMs 可以在更广泛的环境中部署,包括边缘设备或处理能力较低的系统中。

关于培训和运营成本,SLMs 通常培训成本和运营成本较低。这种成本效益源于其简化了的结构和更少的数据量需求。因此,SLMs 对预算有限的个人和组织来说更加可负担,从而实现了高级语言处理技术的民主化。

然而,在性能和质量方面,尽管能够有效地处理广泛的语言任务,SLMs 通常无法达到大型模型的性能水平。这在需要广泛理解上下文或专业知识的更复杂任务中尤为明显。大型模型凭借其更深入和广泛的数据和理解,更能应对这种复杂性。相比之下,SLMs 可能由于自身在规模和训练方面的内在限制而难以应对这些挑战。

战略性数据选择和新的创新培训方法是 Phi 系列等 SLMs 之所以如此成功的关键原因。战略性数据选择优先考虑质量而非数量,并涉及使用教科书质量的数据,包括合成数据集和精心挑选的网页数据 [2]。数据的选择旨在提供坚实的常识推理和一般知识基础。这种数据选择战略对于模型在一系列任务中的卓越性能至关重要。

相比之下,创新的培训方法包括从小型模型如 Phi-1.5 扩展到 Phi-2 [3],并将知识嵌入其中。这种方法加速了训练收敛并提高了基准分数,挑战了传统的扩展定律,并证明了即使是小型语言模型也能实现显著的性能。

SLMs 目前仍处于生命周期早期,但越来越多的企业开始考虑将其用于生产环境。然而,它们的准备情况很大程度上取决于具体需求和应用环境。以下是一些需要考虑的因素:

  • 任务复杂性—SLMs 适合更简单、更明确的任务。然而,如果企业应用涉及复杂语言理解或生成,可能需要更大的模型以实现最佳性能。

  • 资源限制—SLMs 是计算资源有限或需要将模型部署到边缘设备的企业的一个优秀选择,因为它们对资源的需求较低。

  • 成本效益—运营 SLMs 在计算资源和能源消耗方面通常比运营大型模型更具成本效益。这对于希望最小化运营成本的企业来说可能是一个重大优势。

  • 速度和响应性—SLMs 可以提供更快的响应时间,这对于需要实时交互的应用程序至关重要,例如客户服务聊天机器人。

  • 本地化——对于由于监管或政策原因无法部署或连接到云的应用,SLM 可以是一个选择,因为它们可以更容易地在本地或私有云中部署。

现在可用的 SLM 的一些例子包括

  • Phi-3——微软最近推出的 Phi-2 后继者,一个小型语言模型系列,在各种基准测试中优于其他类似甚至更大的模型,有三种尺寸:mini(3.8B)、small(7B)和 medium(14B)。

  • Phi-2——微软的一个 27 亿参数模型,在推理和语言理解任务上展示了最先进的性能,其性能可以超过其 25 倍大小的模型。

  • Orca 2——微软的一个 7 亿或 13 亿参数模型,从更强大的教师模型中学习各种推理技术和解决方案策略 5。

  • Gemini Nano——谷歌的一个 1.22 亿参数模型,是 Gemini 系列的一部分,专为在边缘设备上进行高效推理和部署而设计。

  • DistilBERT——BERT 的一个更小的版本,在保持 97%的语言理解能力的同时,体积缩小了 40%,速度提高了 60%。

  • GPT-Neo——GPT 架构的一个更小的版本(125M 和 1.3B),是 EleutherAI 创建的 GPT-Neo 系列的一部分。

当由于成本、速度或计算需求而无法部署大型模型时,这些 SLM 特别有用。它们平衡性能和效率,使高级 NLP 能力更加易于访问。

尽管 SLM 可能不适合每个企业应用,尤其是那些需要深度理解或复杂语言生成的应用,但在许多场景中,它们已经准备好投入生产,尤其是在效率、速度和成本是关键考虑因素的情况下。企业应评估其具体需求和限制,以确定 SLM 是否适合其应用。

2.7 开源 LLM 与商业 LLM

今天的商业模型在 AI 质量和广泛能力方面提供了顶级性能。然而,自从 ChatGPT 发布以来,开源模型的方向发生了显著转变。许多这些开源项目专注于开发更小的基础模型,声称它们可以在不造成重大损失的情况下达到几乎相同的质量水平。图 2.2 [4]展示了这些谱系以及它们如何迅速爆炸。

图 2.2:拥有 10+B 参数的 LLM 时间线:LLM 综述

2.7.1 商业 LLM

目前,有几种商业 LLM,它们已经开始印刷并开始产生影响。几乎所有的 LLM 都遵循 OpenAI 模式,并通过我们使用的 API 公开。尽管它们仍然是初创公司,但许多都有严重的资金,并且它们的创始人有深厚的科研背景:

  • OpenAI 是一个 AI 研究实验室,开发和发布前沿 AI 模型,如 GPT 系列。它无疑是今天最具影响力的。它有几个基础模型,如 GPT-4、DALL.E 和 ChatGPT,在这个群体中最为成熟,得到了微软的全力支持和拥有。

  • Azure OpenAI 和 OpenAI 提供了对强大语言模型的访问,但它们的性质和实现方式不同。主要区别在于 Azure OpenAI 是一种托管服务,而 OpenAI 则不是。微软负责 Azure OpenAI 的底层基础设施和维护,使其成为资源不足的企业管理 OpenAI 部署的有价值选择。此外,Azure OpenAI 将原始 OpenAI 模型打包成开发者友好的服务,开发者可以无缝地将这些服务集成到他们的应用程序中。这些服务运行在 Azure 上,确保了高可扩展性、可靠性和全球可用性。

  • Anthropic 是由前 OpenAI 工程师创立的初创公司,发布了 Claude,这是一个可以生成文本和代码的 LLM。他们的关键区别在于使用宪法 AI [5] 实现了 LLM。宪法 AI 使用强化学习(RL)和传统的监督学习,并声称可以产生更少的危害性输出。截至本文发表时,Anthropic 获得了谷歌和亚马逊的支持。Claude 3,最新一代的模型,有三个版本:Haiku(小型)、Sonnet(中型)和 Opus(大型)模型。

  • Gemini 是谷歌最新的 GenAI 模型,作为最近推出的 Google AI Studio 产品的一部分,可在 Google Cloud 提供的服务中使用。在撰写本文时,谷歌正在对模型进行私人预览,开放 API 访问。

  • Cohere AI,一家起源于 Transformer 论文(《注意力即一切所需》)的初创公司,拥有 LLM 以及其他产品,如 Neural Search 和 Embed。

2.7.2 开源 LLMs

新一代的开源 LLM 正在涌现,其中一些将与 ChatGPT 竞争。如图 2.1 所示,数量太多,难以一一列举,但表中列出了几个值得注意的例子。

表 2.2 开源 LLMs
公司开源 LLM参数大小
MetaMeta 的 Llama LLM 是许多其他 OSS 模型受到启发的模型之一。它有多种大小(7B、13B、33B 和 65B),虽然比 GPT-3 小,但在许多任务上可以匹敌。Meta 与研究人员分享了这些模型(并且它们也被单独泄露到网络上),激励了许多其他人以此作为起点。各种(7B–65B)
DatabricksDatabricks 最近发布了 Dolly 的 v2 版本,他们将其称为“世界上第一个真正开放的指令调整 LLM”。它是在 CCA 3.0 许可证下发布的,允许任何人使用、扩展和修改它,包括商业用途。12B
Alpaca斯坦福大学的 Alpaca,基于 Llama 的指令模型,声称在某些任务上可以匹配 GPT-3.5 Turbo 的性能。7B
FreedomGPT这是一个基于 Alpaca 的开源对话代理。他们声称提供 100% 无审查和私密的对话。未公开
Vicuna来自多个机构(加州大学伯克利分校、卡内基梅隆大学、斯坦福大学、加州大学圣地亚哥分校和 MBZUAI)的学术研究人员发布了 Vicuna,这是 Llama 的一个微调版本,在许多任务上与 GPT4 的性能相匹配。13B
Koala伯克利人工智能研究实验室发布了 Koala,这是使用互联网对话微调的 Llama 版本。13B
ChatLLaMa从技术上来说,它不是一个模型,而是为模型提供的工具。Nebuly AI 发布了 ChatLLaMa,这是一个库,可以使用您的数据创建类似 ChatGPT 的对话助手。7B
ColossalChat加州大学伯克利分校的 ColossalAI 项目发布了 ColossalChat,这是一个类似于 ChatGPT 的模型,包括基于 Llama 的完整强化学习与人类反馈(RLHF)管道。7B
Falcon阿联酋的技术创新研究所(TII)发布了一系列名为 Falcon LLM 模型的 LLM。当时,Falcon 是有史以来发布的最大开源 LLM,并在开源 LLM 排行榜上位居榜首。最近,一个更强大的 180B 参数模型再次位居排行榜首位。各种(1B–180B)
Mistral法国初创公司 Mistral AI 开发了一系列模型。其中一些是开源模型,根据 Apache 2.0 许可证发布,这是一个允许在任何环境下无限制使用的宽松许可。如前一章所述,他们也有商业模型。各种(7B – 141B)
OpenAI 与 Azure OpenAI

Azure OpenAI 和 OpenAI 都是提供访问 OpenAI 强大语言模型的服务,但它们有一些关键区别。OpenAI 更适合小型和中型企业的个人开发者和新创公司。相比之下,Azure OpenAI 旨在满足需要在不同地区提供额外安全和可用性的企业,以及有监管需求的企业。

Azure OpenAI 提供了额外的企业级功能,例如数据隐私、客户管理的密钥、静态加密、私有网络、区域可用性和负责任的 AI 内容过滤。这些功能对于需要遵守特定安全或监管要求的企业来说可能很重要。

因此,这两个服务之间的 API 相似但不完全相同。然而,底层模型是相同的,Azure OpenAI 有一个包含这些大多数企业所需额外功能的部署。

2.8 LLM 的关键概念

本节描述了典型大型语言模型(LLM)实现的架构。图 2.3 展示了在高级别上常见 LLM 实现的抽象结构;每次我们使用 LLM,如 OpenAI 的 GPT,都会遵循此过程。

图 2.3 LLM 的概念架构

模型从输入文本——提示开始。首先,使用标记化将其转换为一系列标记。然后,每个标记通过称为嵌入的过程转换为数值向量,这作为编码器的输入。

编码器处理输入序列并生成一系列隐藏状态。然后,这些隐藏状态被输入到解码器中,并带有起始标记。解码器通过预测下一个标记(基于前一个标记和隐藏状态)一次生成一个输出序列。

一旦所有层都处理了信息,模型就会预测学习序列中的下一个标记。这个结果被转换回文本,我们看到响应。这个过程在一个迭代循环中运行,并且对每个新生成的标记都会发生,从而创建出一个连贯的文本输出。模型生成的最终文本是这个分层、迭代过程的涌现属性。最终的输出序列也被称为完成。

让我们更详细地检查这些大型语言模型(LLM)的各个方面。

2.8.1 提示

提示是我们与这些模型“交谈”的方式。提示只是用自然语言描述我们试图通过自然语言完成的任务的文本。这些模型的输出也是文本。以这种方式(自然语言)表达我们的意图(而不是遵守机器的输入限制)的能力使提示变得强大。在提示中构建或设计文本类似于编程模型,并创建一个称为提示工程的新范式,这将在本书的后面部分介绍。

提示允许我们使用相同的范式捕捉更广泛的意图和情感。在以下两个由 AI 生成的示例中,一个提示要求写一首俳句来概述 LLM 是多么伟大:一首俳句是快乐的,另一首是悲伤的。在同一个任务上获得这种程度情感和表现力是不可能的。

LLMs 很棒

它们可以聊天并生成

创造性和智能

LLMs 很棒

但它们无法感受或爱

只能模拟

注意:LLM 并不像人类那样理解文本。它们是统计模型,通过学习数据中的模式并使用这些模式来生成输出。尽管它们的输出令人印象深刻,但这些模型并不像我们那样理解生成的内容——包括信念、欲望、意识、对与错。它们只是极其擅长根据他们看到的数百万次模式预测文本序列中的下一个单词。

2.8.2 标记

标记是 LLM 用于处理请求和响应(即理解和生成文本)的基本文本单位。分词是将文本转换为称为标记的较小单元序列的过程。在使用 LLM 时,我们使用标记与这些模型进行对话,这是理解 LLM 的最基本要素之一。

当将 LLM 集成到您的应用程序或解决方案中时,标记是新的货币。它们直接关联到运行模型的成本,无论是金钱还是延迟和吞吐量的体验。标记越多,模型必须进行的处理就越多。这意味着模型需要更多的计算资源,这意味着性能降低和延迟增加。

LLM 在处理文本之前将其转换为标记。根据分词算法的不同,它们可以是单个字符、单词、子词,甚至是更大的语言单位。一个粗略的规则是,一个标记大约是四个字符或 0.75 个单词的英文文本。对于今天的大多数 LLM,它们支持的标记大小包括输入提示和响应。

让我们通过一个例子来说明这一点。图 2.4 展示了句子“我有一只名叫 Champ 的白色狗”是如何被分词的(在此例中使用的是 OpenAI 的分词器)。每个块代表一个不同的标记。在这个例子中,我们使用了八个标记。

图 2.4 分词器示例

LLM 通过预测给定序列(即输入提示)中最有可能跟随的下一个单词或符号(标记)来生成文本。我们在图 2.5 中展示了这一过程的视觉表示,其中右侧的标记列表显示了跟随提示“The dog sat on.”的标记的最高概率。我们可以通过本章后面将要看到的几个参数来影响其中一些标记的概率。

图 2.5 LLM—下一个标记预测器

假设我们有一个长度为 n 的标记序列。利用这些 n 个标记作为上下文,我们生成随后的标记,即 n + 1。这个新预测的标记随后被添加到原始的标记序列中,从而扩展了上下文。因此,生成标记 n + 2 的扩展上下文窗口变为 n + (n + 1)。这个过程在达到预定的停止条件(如特定的序列或标记的大小限制)时重复进行。

例如,如果我们有一个句子,“夏威夷披萨是我的最爱”,我们看到下一个单词的概率分布如图 2.6 所示。最可能的单词是“类型”,完成句子“夏威夷披萨是我的最爱类型”。

图 2.6 下一个标记概率分布

如果你再次运行这个示例,你将得到一个与这里显示不同的概率。这是因为大多数 AI 是非确定性的,特别是在 LLMs 的情况下。同时,它可能预测一个标记,并且很可能在模型在训练阶段学习到的所有可能的标记中进行观察。

我们还使用了两个示例,说明了单个标记如何极大地改变分布(将一个单词从“the”改为“a”)。图 2.7 显示,最可能的下一个标记是“mat”,概率为 41%。我们还看到了其他标记及其概率分布的列表。

图 2.7 示例 1

然而,将一个标记从“the”改为“a”会极大地改变下一个分布集,使得“mat”的概率从 30 点上升到近 75%,如图 2.8 所示。

图 2.8 示例 2

一些与 LLMs 相关的设置很重要,并且可以改变模型的行为和文本生成方式。这些设置是模型配置,可以通过 API、GUI 或两者来更改。我们将在本章后面更详细地介绍模型配置。

2.8.3 计数标记

许多开发者在使用 LLM 时可能对跟踪标记不太熟悉,尤其是在企业环境中。然而,计数标记有多个重要原因:

  • 内存限制—LLMs 在一次遍历中可以处理的最大标记数量。这是由于它们架构的内存限制,通常由它们的上下文窗口定义(我们将在本章后面讨论的另一个概念)。例如,OpenAI 最新的 GPT-4o 模型有一个 128K 的内容窗口,而 Google 最新的 Gemini 1.5 Pro 有一个 1M 标记的内容窗口。另一个 OpenAI 模型 GPT3.5-Turbo 有两个模型支持 8K 和 16K 标记长度。正在进行研究以解决这一问题,例如微软研究机构的 LongNet [6],它展示了如何扩展到 1B 上下文窗口。重要的是指出,这仍然是一个活跃的研究领域,尚未产品化。

  • 成本—在考虑成本时,有两个维度:从延迟、内存和整体体验的角度来看的计算成本,以及实际成本。对于每次调用,处理标记所需的计算资源与标记的长度直接相关。随着标记长度的增加,它需要更多的时间来处理,导致更高的计算需求(特别是内存和 GPU)和更高的延迟。这也意味着使用 LLMs 的成本增加。

  • AI 质量—模型输出的质量取决于它被要求生成或处理的标记数量。如果文本太短,模型可能没有足够的上下文来提供好的答案。相反,如果文本太长,模型可能在回答中失去连贯性。我们将在第六章的后续部分讨论提示工程中关于好与坏的概念。

对于许多企业来说,成本和性能是决定是否使用标记的关键因素。一般来说,较小的模型比较大的模型更经济高效。

tiktokenpip install tiktokentiktoken
列表 2.1 GPT 的标记计数
import tiktoken as tk

def count_tokens(string: str, encoding_name: str) -> int:
    # Get the encoding
    encoding = tk.get_encoding(encoding_name)  #1

    # Encode the string
    encoded_string = encoding.encode(string)

    # Count the number of tokens
    num_tokens = len(encoded_string)
    return num_tokens

# Define the input string
prompt = “I have a white dog named Champ”

# Display the number of tokens in the String
print(“Number of tokens:” , count_tokens(prompt, “cl100k_base”))

#1 编码指定了文本如何转换为标记。

运行此代码,正如预期的那样,给出了以下输出:

$ python countingtokens.py
Number of tokens: 7

注意:字节对编码(BPE)是一种在 NLP 任务中广泛使用的压缩算法,如文本分类、文本生成和机器翻译。BPE 的一个优点是它是可逆的且无损的,因此我们可以获取原始文本。BPE 可以在标记化器训练数据未见过的任何文本上工作,并压缩文本,从而产生比原始文本更短的标记序列。BPE 还有助于泛化语言中的重复模式,并提供对语法的更好理解。例如,现在分词(-ing 形式)在英语中相当常见(swimming, running, debugging 等)。BPE 会将其分割成不同的标记,所以“swim”和“-ing”在 swimming 中变成了两个标记,并且泛化得更好。

get_encoding()encoding_for_model()encoding = tiktoken.encoding_for_model('gpt-4').
表格 2.3 OpenAI 编码
cl100k_basep50k_baser50k_base

列表 2.2 展示了如何使用不同的编码以及如何从标记中获取原始文本。我们现在应该将其视为一个基本结构,但对于更高级的使用案例,如缓存和文本分块——这些内容我们将在本书的后续章节中介绍。

列表 2.2 标记
import tiktoken as tk

def get_tokens(string: str, encoding_name: str) -> str:
    # Get the encoding
    encoding = tk.get_encoding(encoding_name)

    # Encode the string
    return encoding.encode(string)

def get_string(tokens: str, encoding_name: str) -> str:
    # Get the encoding
    encoding = tk.get_encoding(encoding_name)

    # Decode the tokens
    return encoding.decode(tokens)

# Define the input string
prompt = “I have a white dog named Champ.”

# Display the tokens
print(“cl100k_base Tokens:” , get_tokens(prompt, “cl100k_base”))
print(“  p50k_base Tokens:” , get_tokens(prompt, “p50k_base”))
print(“  r50k_base Tokens:” , get_tokens(prompt, “r50k_base”))

print(“Original String:” , get_string([40, 617, 264, 4251, 5679, 7086, 56690, 13], “cl100k_base”))

$ python encodings.py
cl100k_base Tokens: [40, 617, 264, 4251, 5679, 7086, 56690, 13]
  p50k_base Tokens: [40, 423, 257, 2330, 3290, 3706, 29260, 13]
  r50k_base Tokens: [40, 423, 257, 2330, 3290, 3706, 29260, 13]
Original String: I have a white dog named Champ.
tiktoken
  • WordPiece——由谷歌的 BERT 模型使用,它根据最频繁的词片段将文本分割成更小的单元,允许高效地表示罕见或不在词汇表中的单词。

  • SentencePiece——Meta 的 RoBERTa 模型(鲁棒优化 BERT)使用该模型。它将 WordPiece 和 BPE 方法结合到一个单一的语言无关框架中,从而提供了更多的灵活性。

  • T5 分词器——基于 SentencePiece,它被 Google 的 T5 模型(文本到文本迁移转换器)所使用。

  • XLM 分词器——它在 Meta 的 XLM(跨语言语言模型)中使用,并实现了一个带有学习嵌入的 BPE 方法(BPEmb)。它旨在处理多语言文本并支持跨语言迁移学习。

2.8.4 嵌入

嵌入是强大的机器学习工具,用于表示单词的大输入。它们在向量空间中捕捉语义相似性(即如图 2.9 所示的一组向量),使我们能够确定两个文本片段是否代表相同的意义。通过提供相似度分数,嵌入可以帮助我们更好地理解不同文本片段之间的关系。

嵌入背后的理念是,含义相似的单词应该有相似的向量表示,这是通过它们的距离来衡量的。它们之间距离较小的向量表明它们高度相关,而距离较长的向量表明相关性较低。有几种方法可以衡量相似性;我们将在第七章中介绍这些方法。

这些向量是在训练过程中学习的,用于捕捉单词或短语的含义。AI 算法可以轻松地利用这些浮点数向量。

图 2.9 嵌入

例如,单词“猫”可能由一个向量表示为[0.2, 0.3, -0.1],而单词“狗”可能表示为[0.4, 0.1, 0.2]。这些向量然后可以被用作机器学习模型的输入,用于诸如文本分类、情感分析和机器翻译等任务。

当模型在大量的文本数据语料库上训练时,会学习到嵌入。其理念是基于训练数据中单词或短语的上下文来捕捉它们的含义。

根据任务的不同,有几种创建嵌入的算法:

  • 相似度嵌入擅长捕捉两篇或多篇文本之间的语义相似性。

  • 文本搜索嵌入衡量长文档是否与短查询相关。

  • 代码搜索嵌入对于嵌入代码片段和自然语言搜索查询是有用的。

注意:由一种方法创建的嵌入不能被另一种方法理解。换句话说,如果你使用 OpenAI 的 API 创建嵌入,其他提供商的嵌入将无法理解你创建的向量,反之亦然。

get_embedding()text-embedding-ada-002
列表 2.3 在 OpenAI 中获取嵌入
import os
from openai import OpenAI

client = OpenAI(api_key=’your-API-key’)

def get_embedding(text):
    response = client.embeddings.create(
        model="text-embedding-ada-002",
        input=text)
    return response.data[0].embedding

embeddings = get_embedding("I have a white dog named Champ.")
print("Embedding Length:", len(embeddings))
print("Embedding:", embeddings[:5])

从嵌入产生的向量空间不是一对一映射到标记,但可以更多。以下展示了前几个示例的输出。为了简洁,我们只显示了列表中的前五项:

print("Embedding Length:", len(embeddings))
print("Embedding:", embeddings[:5])

2.8.5 模型配置

top_p
最大响应

被称为最大响应的参数实际上定义了模型生成的文本长度的上限。这意味着一旦模型达到这个预定的长度,无论它是否在单词或句子中间,它都会停止文本生成。理解这个配置非常重要,因为大多数模型可以处理的标记大小有限。增加这个大小对应着更高的计算需求,导致延迟和成本的增加。

温度

在生成文本时,与任何基础模型一样,固有的随机性导致每次调用模型时都会产生不同的输出。温度是控制模型随机程度最重要的设置之一。通常,这是一个从 0 到 1 的值,其中 0 代表更准确和可预测的输出。相反,将值设置为 1 会使输出更加多样化和随机,如图 2.10 所示。

图 2.10 温度设置及其对概率的影响
顶概率(top_p)
top_ptop_p
top_ptop_p
图 2.11 展示了 top-p 的工作原理示例
一个示例
max_tokenstemperature
client = OpenAI(api_key=’your-API-key’)
response = client.completions.create(
  model="text-davinci-003",
  prompt="...",
  temperature=1,
  max_tokens=256,
  top_p=1,
  frequency_penalty=0,
  presence_penalty=0
)

由于 API 是无状态的,这些设置可以在不同实例和同一实例的 API 调用之间有所不同,具体取决于试图实现的业务场景。此外,这些设置的全球最优值并不存在,它们取决于任务。一般来说,如果您想要一个平衡的输出并且不希望模型产生过多的幻觉,温度设置为 0.7 或 0.8 是好的。表 2.4 概述了控制行为的配置设置。

表 2.4 LLM 配置设置
top_ptop_ptop_ptop_ptop_p

2.8.6 上下文窗口

上下文窗口是一个相对较新且非常重要的概念。它指的是 LLM 在做出预测时考虑的特定单词或标记周围的标记或词语的范围。上下文窗口帮助模型理解词语之间的依赖关系和关系,使其能够生成更准确和连贯的预测。

例如,在预测句子中的下一个单词时,上下文窗口可能包括几个在目标单词之前出现的单词。上下文窗口的大小可能因模型及其架构而异。在 LLM 中,上下文窗口可以相当大,允许模型捕捉到词语之间的长距离依赖关系和复杂的语义关系。这些较长的上下文窗口可以帮助在文本生成、翻译和摘要等任务上获得更好的输出。

当前的 LLM 架构将上下文窗口大小限制在几千个标记。尽管一些较新的模型支持高达一百万个标记,但上下文窗口仍然是一个关键的关注点,主要是因为注意力机制的全球性质导致计算成本与上下文长度呈二次方关系。换句话说,上下文窗口越大,计算成本与输入数据大小的平方成正比。虽然拥有更大的上下文窗口可能看起来很好,但重要的是要理解它既有积极的一面,也有消极的一面。拥有更大的上下文窗口,模型的性能在理解和生成方面都会变得较慢,并且具有更高的延迟。虽然我们可能觉得更长的上下文会更好,但通常情况下,如果小窗口足以完成当前任务,则使用较小的窗口会更好——它的性能会比大窗口更好。其中一些优点是

  • 提高对上下文的理解—更长的上下文窗口允许模型捕捉到长距离依赖关系和词语之间复杂的语义关系,从而实现更好的预测和更连贯的文本生成。然而,这需要付出相当大的代价,并且应该谨慎使用。

  • 在复杂任务中的更好表现—拥有更广泛的上下文窗口,语言模型在需要更好理解更广泛上下文的任务上表现更佳,例如机器翻译、摘要和情感分析。

这里有一些缺点:

  • 增加的计算需求—更长的上下文窗口需要更多的内存和计算能力来处理和存储额外的信息,这可能导致更长的训练和推理时间,并需要更强大的硬件或分布式计算解决方案。

  • 过拟合的潜力—随着上下文窗口的增加,模型变得更加复杂,更容易过拟合,尤其是在训练数据有限的情况下。过拟合发生在模型学会在训练数据上表现出色,但在处理新的和未见过的数据时遇到困难。

  • 处理非常长序列的困难—尽管较长的上下文窗口可以提高性能,但它们在处理极长序列时也可能带来挑战。一些模型可能难以在如此长的距离上保持必要的信息,从而导致性能下降。

  • 收益递减—虽然增加上下文窗口大小可以提高性能,但可能存在一个收益递减的点,进一步增加只会带来微小的改进。在达到最佳性能时,平衡上下文窗口大小、计算成本和模型复杂性是至关重要的。

上下文窗口作为一个概念,对于几个原因来说非常重要:

  • 捕捉依赖关系—上下文窗口允许模型理解文本中单词、短语或句子之间的关系。这有助于模型掌握输入的整体意义和上下文。

  • 提高预测准确性—这可能是我们使用 LLMs 时看到的大部分情况,其中上下文窗口使模型能够根据前面的文本生成更准确和连贯的建议。

  • 提供更好的理解背景—通过考虑上下文窗口,大型语言模型(LLMs)可以更好地理解正在发挥作用的上下文,从而在文本中理解句法和语义关系;这有助于更准确的语言理解和生成。

2.8.7 提示工程

提示工程是一个相对较新的领域,涉及整理或设计提示以从机器学习模型(尤其是 LLMs)中引发期望的响应或行为。这是一种强大的技术,可以提高语言模型在各种任务上的性能。提示工程是一个新兴领域,需要创造力和对细节的关注。

提示工程可以被视为一种艺术和科学。它涉及仔细选择和措辞输入命令,以帮助引导 AI 产生期望的输出。这些输入命令可以简单到选择正确的单词、短语和格式,以引导模型为特定任务生成高质量和相关的文本。

例如,为了得到详细的答案,你可能使用这样的提示:“详细解释……”,或者为了得到快速总结,你可能使用“用几个要点总结……”。同样,为了使 AI 以特定作者的风格写作,你可能使用这样的提示:“以 P. G. Wodehouse 的笔触写一段文字。”

提示工程需要理解 AI 模型的能力、底层训练数据和它对不同类型输入的反应方式。有效的提示工程可以显著提高 AI 模型在各种任务中的实用性。请注意,本节只是对提示工程作为一个基本概念进行介绍;我们将在第六章中更深入地探讨提示工程。

2.8.8 模型适应性

LLMs 是预训练和通用的,有时它们必须进行微调。它们在大量文本数据集上训练,可以作为在较小数据集上训练特定任务的起点。在较小数据集上微调基础 LLM 可以提高其在该特定任务上的表现。

微调是将预训练模型进一步训练在新任务或数据集上。预训练模型被用作起点,并在训练过程中调整模型的权重以提高其在新任务上的表现。微调常用于迁移学习,其中在一个任务上训练的模型被适应到另一个相关任务。

微调 LLMs 的一些例子包括以下内容:

  • 文本分类——在特定的文本分类任务上微调 LLM,例如情感分析或垃圾邮件检测

  • 问答——在特定的问答任务上微调 LLM,例如回答关于特定主题的问题

  • 语言生成——在特定的语言生成任务上微调 LLM,例如生成摘要或翻译

微调 LLM,如 GPT-3.5 Turbo,可以是一种强大的方式来为特定任务定制模型,但它也可能非常昂贵,应该是最后的选项之一。在某些情况下,微调也可能导致灾难性遗忘。这发生在模型在新数据集上微调时,导致它忘记从原始训练数据中学到的知识,从而导致微调模型失去推理能力。我们将在第九章更详细地介绍模型适应,包括微调的任何陷阱。

2.8.9 演化行为

演化行为的概念定义了基础模型和大型语言模型(LLMs)的重要性。演化行为指的是 LLMs 在与环境交互时表现出的意外行为,特别是在用大量数据进行训练时。LLMs 并非明确训练以具备这些能力,而是通过观察自然语言来学习它们。行为的出现是隐式诱导的,而不是显式构建的;它既是科学兴奋的源泉,也是对未预见到后果的焦虑。

如图 2.12 所示,一个模型在多个自然语言基准测试(例如,问答)上的表现并不比随机机会好,直到它们达到一定的规模,在本例中是通过训练计算量(以 FLOPs 衡量)。在这个点上,模型的表现急剧上升,这是演化能力的例子。这有助于我们理解 LLMs 的演化属性并不存在于较小的模型中。此外,这些能力只在模型规模达到一定阈值时才会出现。演化属性不能通过外推较小模型的表现来预测。

图 2.12 模型规模按训练计算需求(FLOP)衡量

让我们通过代码示例来看看,因为代码的确切逻辑和性质无法预先确定或为 LLM 编程。它需要依赖基础模型的涌现行为特性来理解、分析和理解代码。

假设我们有如下所示的反转字符串的 C 代码。这使用了 C 的一些更高级的特性,如指针、XOR 运算符和宏。在我们的例子中,我们使用 GPT-4 将这个 C 函数转换为 Python。

列表 2.4 用于反转字符串的 C 语言函数
#include <String.h> // for strlen()

// reverse the given null-terminated String in place
void inplace_reverse(char * str)
{
  if (str)
  {
    char * end = str + strlen(str) - 1;

    // swap the values in the two given variables
    // XXX: fails when a and b refer to same memory location
#   define XOR_SWAP(a,b) do\
    {\
      a ^= b;\
      b ^= a;\
      a ^= b;\
    } while (0)

    // walk inwards from both ends of the String, 
    // swapping until we get to the middle
    while (str < end)
    {
      XOR_SWAP(*str, *end);
      str++;
      end--;
    }
#   undef XOR_SWAP
  }
}

第一步将是要求我们的语言模型使用类似于下一个提示的提示将此代码转换为 Python。为了简洁起见,我们再次省略了 C 函数(列表 2.4)。代码是提示的一部分。

#include <string.h> // for strlen()

// reverse the given null-terminated String in place
void inplace_reverse(char * str)
{
...
}

while
inplace_reversereverse_string
列表 2.5 转换为 Python 的字符串反转函数
def inplace_reverse(str):
    if str:
        # Convert the String to a list since strings are immutable in Python
        lst = list(str)

        # Initialize two pointers at the start and end of the list
        start = 0
        end = len(lst) - 1

        # Reverse the list in place
        while start < end:
            # XOR_SWAP equivalent in Python
            lst[start], lst[end] = lst[end], lst[start]

            # Move the pointers towards the center of the list
            start += 1
            end -= 1

        # Convert the list back into a string
        return ''.join(lst)
    return str

我们可以通过询问模型以下内容来进一步简化它:

**https://github.com/OpenDocCN/ibooker-dl-zh/raw/master/docs/genai-act/img/Response.png**当然可以!在 Python 中反转字符串最简单的方法之一是使用切片。以下是一个返回字符串反转的函数:

def reverse_string(s):
    return s[::-1]

[::-1]

然而,如果你想模拟 C 程序中的相同逻辑,即使用两个指针就地反转字符串,这里有一个更 Pythonic 的实现方式:

def reverse_string(s):
    lst = list(s)
    lst.reverse()
    return ''.join(lst)

reversereverse

响应中指出的类似两个指针方法展示了涌现特性的强大。我们从未在对话的任何地方明确指出这一点。

在本章中,我们探讨了使 LLMs 工作核心概念,以及在我们将新的生成式 AI 技术在企业中实施时需要注意的事项。我们涵盖了新的概念,如提示、提示工程、嵌入、标记、模型参数、上下文窗口、Transformer 架构和涌现行为。现在,我们已经对 LLMs 及其在下一章中的影响有了广泛的理解,让我们将其付诸实践,通过 API 生成文本,包括通过提示提供指令的补全和可以进行对话的聊天,并在对话的上下文中生成文本。

摘要

  • 大型语言模型(LLMs)代表了人工智能领域的一项重大进步。它们通过在大量文本数据上训练来学习人类语言的模式。

  • LLMs 是通用型的,可以处理不需要特定任务训练数据的任务,例如回答问题、撰写文章、总结文本、翻译语言和生成代码。

  • 关键的 LLM 应用案例包括摘要、分类、问答/聊天机器人、内容生成、数据分析、翻译和本地化、流程自动化、研发、情感分析和实体提取。

  • LLMs 的类型包括基础型、基于指令的和微调型 LLM。每种类型都有其优缺点,并由基础模型驱动。

  • 基础模型是在大规模数据上训练的大型 AI 模型,这使得模型能够适应广泛的下游任务。

  • 一些关键的 LLM 概念包括提示、提示工程、嵌入、标记、模型参数、上下文窗口、Transformer 架构和涌现行为。

  • 开源和商业 LLMs 各有优缺点,商业模型通常提供最先进的性能,而开源模型则提供更多定制和集成的灵活性。

  • 小型语言模型(SLMs)是新兴的轻量级生成式 AI 模型的新趋势,可以生成文本、总结文档、翻译语言和回答问题。在某些情况下,它们提供的能力与较大模型相似。

第三章:通过 API 工作:生成文本

本章涵盖了

  • 根据特定应用对生成式 AI 模型及其分类

  • 列出可用的模型、了解它们的功能以及选择合适的模型的过程

  • OpenAI 提供的完成 API 和聊天完成 API

  • 完成 API 和聊天完成 API 的高级选项,帮助我们引导模型并因此控制生成

  • 在对话中管理令牌以改善用户体验和成本效益的重要性

我们已经看到,大型语言模型(LLMs)提供了一套强大的机器学习工具,这些工具专门设计用于增强自然语言理解和生成。OpenAI 提供了两个显著的 API:完成 API 和聊天完成 API。这些 API 以其动态和有效的文本生成能力而独树一帜,其输出类似于人类。此外,它们还为开发者提供了独特的机遇,可以构建从聊天机器人到写作助手的各种应用。OpenAI 是第一个引入完成 API 和聊天完成 API 模式的公司,现在这一模式几乎包含了所有实现,尤其是在公司想要构建由生成式 AI 驱动的工具和产品时。

OpenAI 的完成 API 是一个高级工具,它生成与上下文相关且连贯的文本以完成用户提示。相反,聊天完成 API 被设计成模拟与机器学习模型的交互,保持对话在多次交流中的上下文,这使得它适合交互式应用。

第三章为企业的扩展奠定了基础。这些 API 可以显著加速智能应用的开发,从而缩短价值实现的时间。我们将主要使用 OpenAI 和 Azure OpenAI 作为示例,经常互换使用。代码模型保持一致,API 也大体相似。许多企业可能会因为 Azure OpenAI 提供的控制而倾向于它,而其他人可能会更偏好 OpenAI。重要的是要注意,我们在这里假设 Azure OpenAI 实例已经作为您 Azure 订阅的一部分部署,我们将在示例的上下文中引用它。

本章概述了完成 API 和聊天完成 API 的基本知识,包括它们之间的区别以及何时使用每个 API。我们将看到如何在应用中实现它们,以及我们如何引导模型生成及其随机性。我们还将看到如何管理令牌,这在部署到生产环境时是关键的操作考虑因素。这些都是构建关键任务应用所需的基本方面。但在开始之前,让我们先了解不同的模型类别及其优势。

3.1 模型类别

根据其特定的应用,生成式人工智能模型可以划分为各种类别,每个类别都包含不同类型的模型。我们首先通过了解生成式人工智能中模型的分类来开始我们的讨论。这种理解将帮助我们确定可用的模型范围,并选择在特定情况下最合适的一个。

不同类型和模型的可用性可能因所使用的 API 而异。例如,Azure OpenAI 和 OpenAI 提供了不同版本的 LLM。一些版本可能会被淘汰,一些可能会受限,而另一些可能仅限于特定组织。

不同的模型具有独特的特性和能力,这直接影响了它们的成本和计算需求。因此,为每个用例选择正确的模型至关重要。在传统的计算机科学中,更大的就是更好的这一观念常常应用于内存、存储、CPU 或带宽。然而,在大型语言模型(LLM)的情况下,这一原则并不总是适用。OpenAI 提供了一系列分类的模型,如表 3.1 所示。请注意,这些模型在 OpenAI 和 Azure OpenAI 中都是相同的,因为底层模型是相同的。

表 3.1 OpenAI 模型类别
模型类别描述
GPT-4最新且最强大的版本是一组多模态模型。GPT-4 在更大的数据集和更多参数上进行了训练,使其能力进一步增强。它可以执行之前模型无法完成的任务。GPT-4 系列中包含各种模型——GPT-4.0、GPT-4 Turbo 和最新的 GPT-4o(全能),这是在发布时该系列中最强大的多模态模型。
GPT-3.5一组在 GPT-3 的基础上进行改进的模型,能够理解和生成自然语言或代码。在不确定的情况下,这些应该是大多数企业的默认模型。
DALL.E一种在给定提示时能够生成图像的模型
Whisper一种用于语音转文本的模型,将音频转换为文本
Embeddings一组将文本转换为数值形式的模型
GPT-3 (Legacy)一组能够生成和理解自然语言的模型。这些是现在被认为是遗留的原始模型集合。在大多数情况下,我们希望从较新的模型开始,例如 3.5 或 4.0,这些模型源自 GPT-3。

每个模型类别都包含一些变体,这些变体通过某些特征(如令牌大小)进一步区分。如前一章所述,令牌大小决定了模型的内容窗口,这定义了它可以处理的输入和输出量。例如,原始 GPT-3 模型的最大令牌大小为 2K。GPT-3.5 Turbo,GPT-3.5 类别中的模型子集,有两个版本——一个令牌大小为 4K,另一个令牌大小为 16K。这是原始 GPT-3 模型令牌大小的两倍和四倍。表 3.2 概述了更受欢迎的模型及其功能。

表 3.2 模型描述和功能
模型功能
Ada (旧版)简单的文本分类、解析和格式化。这个模型是 GPT-3 旧版的一部分。
Babbage (旧版)语义搜索排名、中等复杂度的分类。这个模型是 GPT-3 旧版的一部分。
Curie (旧版)回答问题、高度复杂的分类。这个模型是 GPT-3 旧版的一部分。
Davinci (旧版)摘要、生成创意内容。这个模型是 GPT-3 旧版的一部分。
Cushman-Codex (旧版)GPT-3 系列的后代,在自然语言和数十亿行代码上进行训练。它在 Python 中最强大,并且精通十多种其他编程语言。
Davinci-CodexCushman-codex 的更强大模型
GPT3.5-Turbo专为聊天用例优化的最强大的 GPT-3.5 模型,比 GPT-3 Davinci 便宜 90% 且更有效。
GPT-4, GPT-4 Turbo比任何 GPT-3.5 模型都更强大。它能够执行更复杂的任务,并针对聊天模型进行了优化。
GPT-4o最新 GPT-4o 模型比 GPT-4 和 GPT-4 Turbo 更强大,但速度也快一倍,且便宜 50%。
text-embedding-ada-002, text-embedding-ada-003这个新的嵌入模型取代了五个单独的模型,用于文本搜索、相似度和代码搜索,在大多数任务中表现优于它们;此外,它还便宜了 99.8%。

注意,提到的旧版模型仍然可用,并且按预期工作。然而,新模型更好,拥有更多的市场份额和更长的支持。大多数人应该从 GPT-3.5 Turbo 作为默认模型开始,并根据具体情况使用 GPT-4。有时,甚至是一个较小、较旧的模型,如 GPT-3 Curie,也是好的。这提供了模型能力、成本和整体性能之间的正确平衡。

在生成式 AI 的早期,所有模型都只对某些人开放。这些将因公司、地区以及 Azure 的情况(例如,您的订阅类型)等因素而有所不同。我们必须列出可用的模型及其功能。然而,在列出模型之前,让我们看看要使一切正常工作所需的依赖项。

3.1.1 依赖项

在本节中,我们概述了运行时依赖项和所需的高级配置。为了使一切正常工作,我们至少需要以下项目:

www.python.org/conda install -c conda-forge openaipip install --upgrade openaiapi_keyapi_typeapi_baseapi_versionapi_typeazureapi_baseapi_version'engine'modelmng.bz/yoYdplatform.openai.com/docs/
bit.ly/GenAIBook

将端点和密钥硬编码不是一种推荐的做法。有多种方法可以完成这项任务,其中一种包括使用环境变量。我们将在以下步骤中演示这种方法。其他替代方案可以是从密钥库或环境文件中获取它们。为了简单起见,我们将在这份指南中坚持使用环境变量。然而,我们鼓励您遵循您企业的最佳实践和建议。设置环境变量可以通过以下命令实现。

对于 Windows,这些是

setx AOAI_KEY "your-openai-key"
setx AOAI_ENDPOINT "your-openai-endpoint"

注意:您可能需要重新启动终端以读取新变量。

在 Linux/Mac 上,我们有

export AOAI_ENDPOINT=your-openai-endpoint
export AOAI_KEY=your-openai- key

Bash 使用

echo export AOAI_KEY="YOUR_KEY" >> /etc/environment && source /etc/environment
echo export AOAI_ENDPOINT="YOUR_ENDPOINT" >> /etc/environment && 
      ↪source /etc/environment
docs.conda.io/

首先,让我们创建一个新的 conda 环境并安装所需的 OpenAI Python 库:

$ conda create -n openai python=3.11.3
(base) $ conda activate openai
(openai) $ conda install -c conda-forge openai

现在我们已经安装了依赖项,让我们连接到 Azure OpenAI 端点并获取可用模型的详细信息。

3.1.2 列出模型

正如我们之前概述的,每个组织可能都有不同的模型可供使用。我们将首先了解我们有哪些模型可以使用;我们将使用 API 来帮助我们设置基本环境并使其运行。然后,我将向您展示如何使用 Azure OpenAI Python SDK 来完成这项工作,并概述使用 OpenAI API 时的差异。

如下所示,我们连接到 Azure OpenAI 端点,获取所有可用模型的列表,遍历这些模型,并将每个模型的详细信息打印到控制台。

列表 3.1 列出可用的 Azure OpenAI 模型
import os
import json
from openai import AzureOpenAI                  #1

client = AzureOpenAI(
    azure_endpoint=os.getenv("AOAI_ENDPOINT"),  #2
    api_version="2023-05-15",                   #3
    api_key=os.getenv("AOAI_KEY")   #4
    )

# Call the models API to retrieve a list of available models
models = client.models.list()

# save to file
with open('azure-oai-models.json', 'w') as file:
    models_dict = [model.__dict__ for model in models]
    json.dump(models_dict, file)

# Print out the names of all the available models, and their capabilities
for model in models:
    print("ID:", model.id)
    print("Current status:", model.lifecycle_status)
    print("Model capabilities:", model.capabilities)
    print("-------------------")

#1 必须用于 Azure OpenAI 端点

#2 这是指向通过 Azure 门户发布的端点的环境变量。

#3 从多个选项中选择我们想要使用的 API 版本。

#4 这是包含 API 密钥的环境变量。

运行此代码将向我们展示可用模型的列表。以下列表显示了可用模型的示例;您的确切列表可能会有所不同。

列表 3.2 列出 Azure OpenAI 模型的输出
{
    "id": "gpt-4-vision-preview",
    "created": null,
    "object": "model",
    "owned_by": null
},
{
    "id": "dall-e-3",
    "created": null,
    "object": "model",
    "owned_by": null
  },
  {
    "id": "gpt-35-turbo",
    "created": null,
    "object": "model",
    "owned_by": null
},
…

每个模型都有其独特的功能,这表明了它针对的使用场景——特别是用于聊天补全、补全(即常规文本补全)、嵌入和微调。例如,在需要大量对话交流的基于聊天的交互中,聊天补全模型将是理想的选择。相反,补全模型将最适合文本生成。我们可以在图 3.1 中查看 Azure AI Studio 中的 OpenAI 基础模型。

图 3.1 列出的基础模型
oai.azure.com/portal

3.2 补全 API

完成 API 是一个复杂的工具,用于生成文本以完成用户提供的提示。它是 OpenAI API 的核心,提供了一个简单但强大且灵活的 API。它旨在生成与给定提示一致且上下文合适的文本。

许多非聊天型结构的生成示例都使用完成 API。我们必须使用完成 API 来生成非聊天风格的文本。完成 API 的一些好处包括

  • 上下文理解—完成 API 可以理解提示的上下文并生成相关文本。

  • 多功能性—它可以用于各种应用,从创建内容到回答问题,使其成为多种应用的宝贵工具。

  • 多语言理解—完成 API 能够理解和生成多种语言的内容,使其成为全球资源。

  • 易于实现—完成 API 简单直接,这使得它对各种技能水平的开发者都易于访问。

API 的结构非常简单,如下面的代码片段所示。输入(提示)和输出(完成)都是文本格式。API 响应是一个 JSON 对象,可以使用 text 键从中提取生成的文本。这个响应被称为文本完成。完成试图遵循提示和上下文中提供的内容,并且是潜在输出之一:

from openai import OpenAI
client = OpenAI()

response = client.completions.create(
  model="gpt-3.5-turbo-instruct",
  prompt="Write a few bullets on why pets are so awesome ",
  max_tokens=100,
  temperature=0.8 
)
print(response.choices[0].text.strip())

我们从一个指令开始,即指定我们想要生成的提示。在我们的例子中,指令要求模型生成几个要点,概述为什么宠物很棒。完成 API 有许多参数,但最重要的参数在表 3.3 中详细说明。我们在本章和书中讨论了许多其他参数(例如,提示、标记和温度)。然而,停止序列是一个新概念。我们可以使用这些序列使模型在某个特定点停止生成标记,例如在句子的末尾或列表的末尾。

表 3.3 完成 API
prompt<\|endoftext\|>max_tokensmax_tokenstemperaturestopnmax_tokensstream[DONE]best_ofbest_oftop_ptemperaturelogit_biasuserlogprobssuffixechopresence_ penaltyfrequency_ penaltyfunction_ callfunctions

注意,该表仅列出最常用的参数。它帮助我们理解一些流程和概念。一些参数,如函数,有更高级的使用,这些将在后续章节中关于提示工程中介绍。

我们继续以宠物为主题,并使用模型帮助我们为宠物沙龙业务建议名称。我们要求提供三个名称,并且说明也概述了一些重要的特性。这些说明的特性帮助我们引导模型向一些期望的属性发展。请参阅 API 文档以获取参数的完整列表。让我们调用完成 API 并了解它。

列表 3.3 调用完成 API
import os
from openai import AzureOpenAI

client = AzureOpenAI(
    azure_endpoint=os.getenv("AOAI_ENDPOINT"),
    api_version="2024-05-01-preview",
    api_key=os.getenv("AOAI_KEY"))

prompt_startphrase = "Suggest three names for a new pet salon business.
↪The generated name ideas should evoke positive emotions and the 
↪following key features: Professional, friendly, Personalized Service."

response = client.completions.create(        #1
    model="gpt35",    #2
    prompt=prompt_startphrase,                #3

    temperature=0.7,                          #4
    max_tokens=100,                         
    suffix="\nThats all folks!",            
    stop=None)

responsetext = response.choices[0].text      #5

print("Prompt:" + prompt_startphrase + "\nResponse:" + responsetext)

#1 用于生成文本的完成 API 调用

#2 指定要使用的模型;请注意,此名称将根据您在部署中设置的值而更改

#3 提示

#4 模型配置

#5 从响应中提取生成的文本

恭喜!我们使用了 API 进行第一次文本生成。由于 AI,特别是生成式 AI 的非确定性,运行此操作时您将看到的输出与

$ python .\petsalon.py

输出如下。

**https://github.com/OpenDocCN/ibooker-dl-zh/raw/master/docs/genai-act/img/Prompt.png**为新的宠物沙龙业务建议三个名称。生成的名称想法应唤起积极的情绪,并具有以下关键特性:专业、友好、个性化服务。

    1. 毛皮与羽毛友好宠物沙龙
    1. Happy Tails 定制宠物宠爱

注意:LLM 和大多数其他生成式 AI 模型是非确定性的,这意味着相同的输入可能会产生不同的输出。将温度设置更改为零可以使输出更确定,但可能仍会保留一些可变性。

3.2.1 扩展完成

choicesindexfinish_reasontext
列表 3.4 完成 API 的 API 响应
{
  "choices": [                      #1
    {
      "finish_reason": "stop",
      "index": 0,
      "logprobs": null,
      "text": "\n\n1\. Pawfect Professionals \n 
              ↪2\. Purrsonalized Pet Pampering\n 
              ↪3\. Friendly Fur Services",
              "content_filter_results"={...}
    }
  ],
  "created": 1689007663,                       #2
  "id": "cmpl-7aoL1MaUEf2j3ZLfSvsUOR7EFyjqC",    #3
  "model": "gpt-35-turbo",                 #4
  "object": "text_completion",
  "usage": {                #5
    "completion_tokens": 26,
    "prompt_tokens": 32,
    "total_tokens": 58
  }
}

#1 完成数据数组

#2 响应创建日期时间戳

#3 响应的唯一 ID

#4 生成响应所使用的模型 ID

#5 此请求中使用的标记计数

total_tokens
表 3.4 完成响应属性
choicescreatedidmodelobjecttext_completionusage
logprobs

3.2.2 Azure 内容安全过滤器

nullfinish_reasoncontent_filterfinish_reason

过滤系统使用特定类别来识别和针对输入提示和生成的完成项中的潜在有害内容采取行动。使用这些 API 的应用程序必须处理这种情况,并在适当的退避期间后重试。内容安全过滤器和道德 AI 将在第十三章中更详细地介绍。

null
$ python .\petsalon.py 
Prompt:Suggest three names for a new pet salon business. The generated 
       ↪name ideas should evoke positive emotions and the following key 
       ↪features: Professional, friendly, Personalized Service.
Response:                                    #1
{
  "choices": [
    {
      "finish_reason": "content_filter",      #2
      "index": 0,
      "logprobs": null,
      "text": "",
      "content_filter_results"={...}
    }
  ],
  "created": 1689006467,
  "id": "cmpl-7ao1jIACW1v8mYH879EE1trbT9Ua6",
  "model": "gpt35",
  "object": "text_completion",
  "usage": {
    "completion_tokens": 31,
    "prompt_tokens": 32,
    "total_tokens": 63
  }
}

#1 无响应

#2 内容过滤器是响应结束的原因。

3.2.3 多重完成

n
response = client.completions.create(
    model="gpt-35-turbo",
    prompt=prompt_startphrase,
    temperature=0.7,
    max_tokens=100,
    n=3,
    stop=None)

# loop through the response choices
for choice in response.choices:
    print(choice.text)

当我们运行此更新后的代码时,我们得到列表 3.6 中所示的响应。属性选择是一个数组,我们有三项,索引从零开始。每一项都为我们提供了生成的文本。根据使用情况,在挑选多个完成项时这很有帮助。

列表 3.6 显示多个响应的输出
1\. Pet Pampering Palace
2\. Pet Grooming Haven
3\. Perfect Pet Parlor

1\. Pawsitive Pet Spa
2\. Fur-Ever Friends Pet Salon
3\. Purrfection Pet Care

1\. Pampered Paws Professional Pet Care
2\. Personalized Pet Pampering
3\. Friendly Furrific Pet Care
best_ofnbest_ofnbest_ofn
n
列表 3.7 显示多个响应的输出
{
  "choices": [
    {
      …
  ],
  "created": 1689097645,
  "id": "cmpl-7bBkLk60mA8R9crAKXqTmTwzx2IEI",
  "model": "gpt-35-turbo",
  "object": "text_completion",
  "usage": {
    "completion_tokens": 152,
    "prompt_tokens": 32,
    "total_tokens": 184
  }
}
best_ofn
response = client.completions.create(
    model="gpt-35-turbo",
    prompt=prompt_startphrase,
    temperature=0.7,
    max_tokens=100,
    best_of=5,
    stop=None)

当我们运行此代码时,我们只得到一个完成项,如列表 3.8 所示;然而,我们使用的标记数量与之前相似(171 比 184)。这是因为服务在服务器端生成五个完成项,并返回最佳的一个。API 使用每个标记的对数概率来选择最佳选项。对数概率越高,模型对其预测的信心就越大。

best_of
{
  "choices": [
    {
      "finish_reason": "stop",
      "index": 0,
      "logprobs": null,

      "text": "\n\n1\. Pawsitively Professional Pet Salon\n 
         ↪2\. Friendly Furr Friends Pet Salon\n 
         ↪3\. Personalized Pampered Pets Salon",
               "content_filter_results"={...}
    }
  ],
  "created": 1689098048,
  "id": "cmpl-7bBqqpfuoV5nrgHrahuWGVAiM50Aj",
  "model": "gpt35",
  "object": "text_completion",
  "usage": {
    "completion_tokens": 139,
    "prompt_tokens": 32,
    "total_tokens": 171
  }
}

影响许多响应的一个参数是温度设置。让我们看看这如何改变输出。

3.2.4 控制随机性

temperature

对于企业来说,更有创意的输出是在对多样化输出感兴趣并创建用于内容生成、故事、诗歌、歌词、笑话等用例的文本时。这些通常需要创造力。然而,企业在需要更可靠和精确的答案的用例,如发票生成、提案、代码生成等时,需要更多。这些设置适用于每个 API 调用,因此在同一工作流程中结合不同的温度级别是可能的。

如前例所示,我们建议创意响应的温度设置为 0.8。相反,建议将设置调整为 0.2 以获得更可预测的响应。通过一个例子,让我们看看这些设置如何改变输出,并观察多次调用之间的变化。

n
response = client.completions.create(
    model="gpt-35-turbo",
    prompt=prompt_startphrase,
    temperature=0.8,
    max_tokens=100,
    n=3,
    stop=None)

以下列表展示了三种响应的创意生成。

列表 3.9 温度设置为 0.8 时的完成输出
{
  "choices": [
    {
      "finish_reason": "content_filter",
      "index": 0,            #1
      "logprobs": null,
      "text": "",
      "content_filter_results"={...}
    },
    {
      "finish_reason": "stop",
      "index": 1,            #2
      "logprobs": null,
      "text": "\n\n1\. Pawsitively Professional Pet Styling\n 
                 ↪2\. Fur-Ever Friendly Pet Groomers \n 
                 ↪3\. Tailored TLC Pet Care",
      "content_filter_results"={...}
    },
    {
      "finish_reason": "stop",
      "index": 2,            #3
      "logprobs": null,
      "text": "\n\n1\. Pawsitively Professional Pet Salon \n 
                 ↪2\. Friendly Fur-ternity Pet Care \n 
                 ↪3\. Personalized Pup Pampering Place",
      "content_filter_results"={...}
    }
  ],
  "created": 1689123394,
  "id": "cmpl-7bIRe6Ponn8y1198flJFfagq64r2E",
  "model": "gpt35",
  "object": "text_completion",
  "usage": {
    "completion_tokens": 96,
    "prompt_tokens": 32,
    "total_tokens": 128
  }
}

#1 第一个响应:被内容过滤器阻止

#2 第三个响应

#3 具有非常不同生成文本的最终响应

temperature=0.2
列表 3.10 温度为 0.2 时的完成输出
{
  "choices": [
    {
      "finish_reason": "stop",
      "index": 0,                #1
      "logprobs": null,
      "text": "\n\n1\. Pawsitively Professional Pet Salon\n 
                 ↪2\. Friendly Furr Salon\n 
                 ↪3\. Personalized Pet Pampering",
      "content_filter_results"={...}
    },
    {
      "finish_reason": "stop",
      "index": 1,                #2
      "logprobs": null,
      "text": "\n\n1\. Pawsitively Professional Pet Salon\n 
                 ↪2\. Friendly Fur-Ever Pet Salon\n 
                 ↪3\. Personalized Pet Pampering Salon",
      "content_filter_results"={...}
    },
    {
      "finish_reason": "stop",
      "index": 2,               #3
      "logprobs": null,
      "text": "\n\n1\. Pampered Paws Pet Salon\n 
                 ↪2\. Friendly Fur Salon\n
                 ↪3\. Professional Pet Pampering"
    }
  ],
  ...
}

#1 三个回答中的一个

#2 三个回答中的两个;生成的文本非常相似

#3 最终的回答,生成的文本非常相似

温度值可以高达 2,但并不建议设置得那么高,因为模型开始产生更多幻觉并创建无意义的文本。如果我们想要更多的创造力,通常希望它设置为 0.8,最多为 1.2。让我们看看当温度值变为 1.8 时的例子。在这个例子中,我们甚至没有完成第三次生成,因为我们达到了标记限制并停止了生成。

列表 3.11 温度为 1.8 时的完成输出
{
  "choices": [
    {
      "finish_reason": "stop",
      "index": 0,                #1
      "logprobs": null,
      "text": "\n\n1\. ComfortGroom Pet Furnishing \n2\. Pampered TreaBankant Carers \n3\. Toptech Sunny Haven Promotion.",
      "content_filter_results"={...}
    },
    {
      "finish_reason": "stop",
      "index": 1,               #2
      "logprobs": null,
      "text": "\n\n1: Naturalistov ClearlywowGroomingz 
                    ↪Pet Luxusia \n2: VipalMinderers Pet 
                    ↪Starencatines grooming \n3: Brisasia 
                    ↪Crownsnus Take Care Buddsroshesipalising",
      "content_filter_results"={...}
    },
    {
      "finish_reason": "length",
      "index": 2,
      "logprobs": null,
      "text": "\n\n1\. TrustowStar Pet Salon\n 
              ↪2\. Hartipad TailTagz Grooming & Styles\n 
              ↪3\. LittleLoft Millonista Cosmania DipSavez 
                 ↪Hubopolis ShineBright Princessly 
                 ↪Prosnoiffarianistics Kensoph Cowlosophy 
                 ↪Expressionala Navixfordti Mundulante Effority 
                 ↪DivineSponn BordloveDV EnityzBFA Prestageinato 
                 ↪SuperGold Cloutoilyna Critinarillies 
                 ↪Prochromomumphance Toud",
                 ↪"content_filter_results"={...}
    }
  ],
  ...
}

#1 三个回答中的一个,名称不是很清晰

#2 第二和第三个回答,名称不清晰

3.2.5 使用 top_p 控制随机性

temperaturetop_ptop_p
top_p
top_p
top_ptop_ptop_ptop_p
top_p
温度top_p影响
生成符合常见语言模式的可预测文本
生成的文本可预测,但偶尔会出现不太常见的单词或短语
生成的文本通常连贯,但具有创造性和意外的词汇使用
生成的文本高度多样且不可预测,具有各种词汇选择和想法;具有非常创造性和多样化的输出,但可能包含许多错误

让我们看看一些针对特定场景的高级 API 选项。

3.3 高级完成 API 选项

现在我们已经检查了完成 API 的基本结构并了解了它们的工作原理,我们需要考虑完成 API 的更高级方面。其中许多可能看起来并不复杂,但它们给系统架构增加了许多更多责任,从而复杂了整体实现。

3.3.1 流式完成

完成 API 允许流式响应,提供在信息准备好后立即访问信息的能力,而不是等待完整响应。对于企业来说,在某些情况下,实时内容生成和较低延迟是关键,流式传输在这种情况下可能很重要。此功能可以通过及时处理传入的响应来增强用户体验。

streamtruefalse

流式传输使用服务器发送事件(SSE),这需要在客户端实现。SSE 是一种标准协议,允许服务器在建立初始连接后继续向客户端传输数据。它是从服务器到客户端的长期单向连接。SSE 提供诸如低延迟、减少带宽消耗和简单的配置设置等优势。

n
列表 3.12 流式完成
import os
import sys
from openai import AzureOpenAI

client = AzureOpenAI(
    azure_endpoint=os.getenv("AOAI_ENDPOINT"),
    api_version="2024-05-01-preview",
    api_key=os.getenv("AOAI_KEY"))

prompt_startphrase = "Suggest three names and a tagline  
↪which is at least 3 sentences for a new pet salon business. 
↪The generated name ideas should evoke positive emotions and the 
↪followingkey features: Professional, friendly, Personalized Service."   #1

for response in client.completions.create(         #2
    model="gpt-35-turbo",
    prompt=prompt_startphrase,
    temperature=0.8,
    max_tokens=500,
    stream=True,                                   #3
    stop=None):
    for choice in response.choices:       #4
        sys.stdout.write(str(choice.text)+"\n")
        sys.stdout.flush()

#1 稍微调整了提示以添加描述

#2 我们需要在客户端处理流式响应。

#3 启用流式传输

#4 我们需要遍历数组并处理多个生成。

finish_reasonfinish_reasonfinish_reasonstoplength
列表 3.13 流式完成原因
...
{
  "finish_reason": null,
  "index": 0,
  "logprobs": null,
  "text": " Pet"
}
{
  "finish_reason": null,
  "index": 0,
  "logprobs": null,
  "text": " Pam"
}
{
  "finish_reason": null,
  "index": 0,
  "logprobs": null,
  "text": "pering"
}
{
  "finish_reason": "stop",
  "index": 0,
  "logprobs": null,
  "text": ""
}

3.3.2 影响标记概率:logit_bias

logit_biaslogit_bias
logit_biaslogit_bias
logit_biastiktoken
logit_bias

让我们用一个例子来看看我们如何使这起作用。对于我们的宠物沙龙名称,我们不希望使用“purr”、“purrs”或“meow”这些词。我们首先想做的事情是为这些词创建标记。我们还希望添加带有前导空格的单词,并将它们作为空格大写。大写字母都是不同的标记。所以“Meow”和“Meow”(带有空格)以及“meow”(再次带有空格)对我们来说可能听起来相同,但就标记而言,这些词都是不同的。输出显示了相应单词的标记:

'Purr Purrs Meow Purr purr purrs meow:[30026, 81, 9330, 
↪3808, 42114, 9330, 81, 1308, 81, 1308, 3808, 502, 322]'

现在我们有了标记,我们可以将它们添加到完成调用中。请注意,我们为每个标记分配了一个-100 的偏差,将模型引导远离这些词。

logit_bias
import os
from openai import AzureOpenAI

client = AzureOpenAI(
    azure_endpoint=os.getenv("AOAI_ENDPOINT"),
    api_version="2024-05-01-preview",
    api_key=os.getenv("AOAI_KEY"))

GPT_MODEL = "gpt-35-turbo"

prompt_startphrase = "Suggest three names for a new pet salon 
↪business. The generated name ideas should evoke positive 
↪emotions and the following key features: Professional, 
↪friendly, Personalized Service."

response = client.completions(  
  model=GPT_MODEL,  
  prompt=prompt_startphrase,  
  temperature=0.8,  
  max_tokens=100,  
  logit_bias={
      30026:-100,               #1
      81:-100,                 #1
      9330:-100,               #1
      808:-100,                #1
      42114:-100,              #1
      1308:-100,               #1 
      3808:-100,               #1 
      502:-100,                #1 
      322:-100                 #1
  }  
)  

responsetext =response.choices[0].text

print("Prompt:" + prompt_startphrase + "\nResponse:" + responsetext)

#1 包含标记及其对应偏差值以引导模型在这些特定标记上的字典

在运行此代码时,我们没有想要避免的任何单词。

logit_bias
{
  "choices": [
    {
      "finish_reason": "stop",
      "index": 0,
      "logprobs": null,
      "text": "\n\n1\. Paw Prints Pet Pampering\n2\. Furry Friends Fussing\n3\. Posh Pet Pooches"
    }
  ],
...
}
tiktoken[37, 16682]
logit_bias
GPT_MODEL = "gpt-35-turbo"

response = client.completions.create(
    model=GPT_MODEL,
    prompt=prompt_startphrase,
    temperature=0.8,
    max_tokens=100,
    logit_bias={
        30026:-100,
        81:-100,
        9330:-100,
        808:-100,
        42114:-100,
        1308:-100, 
        3808:-100,
        502:-100,
        322:-100,
        37:5,
        16682:5
    }
)

当我们运行此代码时,我们得到以下列表中显示的输出。正如我们所见,在我们的生成中,“Furry”的强调程度要强得多。完成也花费了更长的时间,因为模型在生成某些标记时与偏差竞争。

logit_bias
{
  "choices": [
    {
      "finish_reason": "stop",
      "index": 0,
      "logprobs": null,
      "text": "\n\n1.FurryFrendz Pet Salon\n2.FurryFurFection Pet Pampering\n3.FurryFurFam Pet Spa"
    }
  ],
  …
}
logit_bias

3.3.3 存在性和频率惩罚

在 API 中,我们还有两个额外的参数,称为 存在性频率 惩罚,通过控制生成的重复性来帮助引导语言模型的输出。这两个参数影响单词(技术上是一系列标记)在完成中再次出现的可能性。更高的存在性惩罚鼓励模型专注于提示并避免使用已经出现在那里的标记。相比之下,更高的频率惩罚会阻止模型重复自己。让我们更详细地看看这两个参数。

存在性惩罚参数

存在性惩罚参数影响相同标记在输出中出现的频率。这可以通过在每次生成标记时将其作为从标记概率中减去的值来实现。这意味着一个标记被使用的越多,它再次被使用的可能性就越小。这有助于使模型在生成过程中使用更多样化的标记并探索新主题。此参数的值可以从 0 到 2。

默认值是 0,意味着模型不关心一个标记是否重复。高存在性惩罚(1.0)使得模型不太可能再次使用相同的标记,并且更高的值使得模型在输出中引入新的主题。低存在性惩罚(0)使得模型坚持文本中的现有主题。每次生成一个标记时,参数值都会从该标记的对数概率中减去。

我们可以通过防止相同的文本被多次重复来提高生成的质量,帮助控制流程,并使输出更具吸引力。现在让我们看看频率惩罚参数。

频率惩罚参数

此参数控制模型在输出中避免重复的程度。频率惩罚(1.0)越高,模型尝试使用不同单词和短语的程度就越高,这导致生成更加多样化。频率惩罚(0.0)越低,模型可以重复相同的单词和短语,输出就越可预测。这与存在惩罚不同,存在惩罚鼓励模型使用新单词和短语。频率惩罚会在标记在输出中每次出现时添加到标记的对数概率中。

这两个参数的最佳值取决于您想通过输出实现什么。通常,选择介于 0.1 和 1.0 之间的值会更好,这会明显影响输出。如果您想要更强的效果,可以将值增加到 2.0,但这可能会降低输出质量。

注意,调整这些参数需要一些尝试和错误才能得到期望的结果,因为模型输出还受到许多其他因素的影响,包括您提供的提示和其他微调参数。图 3.3 显示了存在和频率惩罚参数的相关性。

图 3.3 惩罚存在参数

3.3.4 对数概率

logprobs
logprobslogprobs + 1

基本上,我们使用这种方法来帮助调试和改进提示。如果模型没有生成我们喜欢的文本,我们可以使用这个来查看模型考虑了哪些其他单词(技术上称为标记)。这使我们能够调整一些其他设置来引导模型。相反,我们也可以用同样的方法来控制模型生成中的随机性,使输出更加确定。最后,我们还可以使用这个来了解模型有多自信。如果几个不同单词的概率相同,这意味着模型不确定下一个单词是什么。

假设我们想为一个白色的狗取一个名字;我们可以调用完成 API。在这个例子中,我们得到了名字 Cotton,这还不错:

response = client.completions.create(
    model=GPT_MODEL,
    prompt="Suggest a one word name for a white miniature poodle.",
    temperature=0.8,max_tokens=100,
    stop=None)
logprobs
response = client.completions.create(
    model=GPT_MODEL,
    prompt="Suggest a one word name for a white miniature poodle.",
    temperature=0.8,max_tokens=100,
    logprobs=3,
    stop=None)

如以下列表中的完成输出所示,模型考虑了以下标记:Casper、Coco 和 Snow。

列表 3.18 输出对数概率
{
  "id": "cmpl-7giPQGlKc6c7BaWmHgOLyZqabIruw",
  "object": "text_completion",
  "created": 1690414840,
  "model": "gpt-35-turbo",
  "choices": [
    {
      "text": "\n\nCotton",
      "index": 0,
      "finish_reason": "stop",
      "logprobs": {
        "tokens": [
          "\n",
          "\n",
          "C",
          "otton"
        ],
        "token_logprobs": [
          -0.0008873215,
          -4.361666e-06,
          -1.026479,
          -0.56846446
        ],
        "top_logprobs": [
          {
            "\n": -0.0008873215,
            "\n\n": -7.660001,
            " Angel": -10.180796
          },
          {
            "\n": -4.361666e-06,
            "\n\n": -12.970553,
            "<|endoftext|>": -15.136529
          },
          {
            "C": -1.026479,
            "P": -2.255978,
            "Snow": -2.1068947
          },
          {
            "asper": -2.001854,
            "oco": -1.957575,
            "otton": -0.56846446
          }
        ],
        "text_offset": [
          54,
          55,
          56,
          57
        ]
      }
    }
  ],
  "usage": {
    "completion_tokens": 4,
    "prompt_tokens": 12,
    "total_tokens": 16
  }
}

作为提醒,我们应该谨慎使用此属性,并且仅在需要时使用。这不仅会增加生成的 token 数量,从而增加 API 调用的成本,而且还会消耗时间,增加 API 调用的耗时,从而增加整体延迟。

现在我们已经了解了用于文本生成的完成 API,接下来让我们看看如何使用聊天完成 API。

3.4 聊天完成 API

聊天完成 API 被设计用于促进交互性和动态对话。它是完成 API 的演变,为用户提供更对话性和吸引人的体验。使用此 API,开发者可以创建与用户进行对话的应用程序,非常适合创建聊天机器人、写作助手等。

聊天完成 API 相较于完成 API 的关键优势包括

  • 增强的交互性—聊天完成 API 允许与用户进行更动态和交互式的对话,使用户体验更加吸引人和自然。

  • 上下文理解—API 维护对话的上下文,确保响应相关且连贯。

  • 多轮对话—与更适合单轮任务的完成 API 不同,多轮对话 API 允许开发者模拟包含多个交换的对话。

  • 经济高效—完成 API 使用 GPT-3.5 Turbo 或 GPT-4 模型,其性能与 text-davinci-003 相似,但每个 token 的价格仅为 10%,这使得它成为开发者更经济的选择。

在高层次上,使用聊天完成 API 与完成 API 类似。API 接收一系列消息作为输入,形成与模型交互的基础。消息的顺序很重要,因为它概述了逐个回合的交互。

systemuserassistant
表 3.6 聊天完成 API 角色描述
systemsystemuserassistant
systemuserassistant
列表 3.19 聊天完成 API
import os
from openai import AzureOpenAI

client = AzureOpenAI(
    azure_endpoint=os.getenv("AOAI_ENDPOINT"),
    api_version="2024-05-01-preview",
    api_key=os.getenv("AOAI_KEY"))

GPT_MODEL = "gpt-35-turbo"

response = client.chat.completions.create(     #1
    model=GPT_MODEL,                         #2
    messages = [                             #3
      ↪{"role":"system","content":"You are an AI assistant 
                 ↪that helps people find information."},
      ↪{"role":"user","content":"Hello world"},
      ↪{"role":"assistant","content":"Hello! How can I assist you today?"},
        {"role":"user","content":"I want to know more 
                 ↪about pets and why dogs are good for humans?"}],
    temperature=0.8,
    max_tokens=800,                              #4
    user="amit",                                #4
    top_p=0.95,                                 #4 
    frequency_penalty=0,                        #4
    presence_penalty=0,                         #4
    stop=None                                   #4 
)

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

#1 聊天完成 API 调用

#2 与完成 API 相比,需要不同的模型(Turbo)

#3 构成 API 核心的消息列表

#4 这些参数与完成 API 相同。

chat_completion
logprobsbest_ofecho

上一个示例的输出显示在下一条列表中。用户首先说“Hello, World!”,然后系统通过助手消息回应,询问如何帮助。关于狗的细节是下一个对话回合。

列表 3.20 聊天完成 API 输出
{
  "id": "chatcmpl-7c9HOaRHmaut94oZacjdUqxOL96H3",
  "object": "chat.completion",
  "created": 1689326490,
  "model": "gpt-35-turbo",
  "choices": [
    {
      "index": 0,
      "finish_reason": "stop",
      "message": {
        "role": "assistant",
        "content": "Dogs are often considered man's best 
             ↪friend for good reason. They provide 
             ↪companionship, protection, and loyalty to 
             ↪their owners. Here are some reasons why dogs are 
             ↪good for humans:\n\n1\. They reduce stress: Dogs 
             ↪have been shown to reduce stress and anxiety in 
             ↪their owners. Petting a dog can release endorphins, 
                      ↪which are feel-good hormones that can help to 
                      ↪reduce stress.\n\n2\. They provide companionship..."
      }
    }
  ],
  "usage": {
    "completion_tokens": 238,
    "prompt_tokens": 60,
    "total_tokens": 298
  }
}

3.4.1 系统角色

系统角色(有些人也称其为系统消息)包含在消息数组的开头。此消息为模型提供初始指令,我们可以在系统角色中提供各种信息,包括

  • 对助手的简要描述

  • 助手的个性特征

  • 您希望助手遵循的规则和指令

  • 模型需要的附加信息(例如,来自常见问题解答的相关问题)

我们自定义系统角色,并包括用例的基本指令。从 API 的角度来看,尽管系统角色是可选的,但强烈建议您明确指定,以获得最佳结果。例如,如果我们扩展之前的宠物和宠物美容院聊天示例,我们可以指示模型只以押韵的形式回复。

列表 3.21 聊天完成系统消息示例
GPT_MODEL = "gpt-35-turbo"

response = client.chat.completions.create( 
  engine=GPT_MODEL,
  messages = [
    {"role": "system", "content": "You are a helpful AI 
              ↪assistant that provides truthful information. 
              ↪You answer all questions in rhyme."},  #1
    {"role": "user", "content": "Hi"},
    {"role": "assistant", "content": "Hello there, how can 
              ↪I assist?\nAsk me a question, don't resist!"},
    {"role": "user", "content": "who are the founders of Microsoft?"},
    {"role": "assistant", "content": "Bill Gates and Paul Allen,
              ↪it's true,\nAre the founders of Microsoft, 
              ↪through and through."},
    {"role": "user", "content": "what is a good name for a pet salon?"},
    {"role": "assistant","content": "For a pet salon [
              ↪that's simply divine,\nHere's a name that's [
              ↪sure to shine:\n\"Paws and Pamper\" is what I 
              ↪propose,\nA name that's catchy and easy to compose."}],
  temperature=0.7,
  max_tokens=800,
  top_p=0.95,
  frequency_penalty=0,
  presence_penalty=0,
  stop=None)

#1 指示以押韵的形式回答

在示例中,我们可以进行预期的对话,话题可以轮流变化,但所有答案都是押韵的。

system
列表 3.22 基础系统消息示例
{"role": "system", "content": Assistant is an intelligent chatbot designed to help users answer technical questions about Azure OpenAI service. Only answer questions using the context below. Don’t make up the answer. If you are unsure of an answer, say 'I don't know'.

Context:
- Azure OpenAI Service provides REST API access to OpenAI's powerful language models including the GPT-3, Codex and Embeddings model series.
- Azure OpenAI Service gives customers advanced language AI with OpenAI GPT-3, Codex, and DALL-E models with the security and enterprise promise of Azure.
..."
},
{"role": "user", "content": "What is Azure OpenAI Service?"}

3.4.2 完成原因

finish_reasonlengthmax_tokensfinish_reason
stoplength—max_tokensfunction_call—content_filter—

3.4.3 非聊天场景的聊天完成 API

OpenAI 的聊天完成可用于非聊天场景。该 API 非常相似,设计成一个灵活的工具,可以适应各种用例,而不仅仅是对话。在大多数情况下,推荐的方法是使用聊天完成 API,就像它是完成 API 一样。主要原因是因为较新的模型(Chat 3.5-Turbo 和 GPT-4)比早期模型更高效、更便宜、更强大。我们看到的完成用例,如分析和生成文本以及从知识库中回答问题,都可以使用聊天完成 API。

实现聊天完成 API 的非聊天场景通常涉及使用一系列消息和一个系统消息来结构化对话,以设置助手的行为了。例如,如以下列表所示,系统消息设置助手的角色,用户消息提供任务。

列表 3.23 作为完成 API 示例的聊天完成
GPT_MODEL = "gpt-35-turbo"

response = client.chat.completions.create(  
  model=GPT_MODEL,  
  messages=[  
        {"role": "system", "content": "You are a helpful assistant."},  
        {"role": "user", "content": "Translate the following 
                 ↪English text to Spanish: 'Hello, how are you?'"}  
    ]  
)

我们也可以使用一系列用户消息来提供更多上下文或完成更复杂的任务,如下一列表所示。在这个例子中,第一条用户消息设置任务,第二条用户消息提供更具体的细节。助手生成一个尝试在用户消息中完成任务的响应。

列表 3.24 作为完成 API 示例的聊天完成
GPT_MODEL = "gpt-35-turbo"

response = client.chat.completions.create(  
  model=GPT_MODEL,  
  messages=[  
        {"role": "system", "content": "You are a helpful assistant."},  
        {"role": "user", "content": "I need to write a Python function."},  
        {"role": "user", "content": "This function should take two 
                          ↪numbers as input and return their sum."}  
    ]  
)

3.4.4 管理对话

我们的示例一直在运行,但随着对话的继续,对话将触及模型的标记限制。随着每次对话的回合(即提出的问题和收到的答案),消息列表会增长。提醒一下,GPT-35 Turbo 的标记限制为 4K 标记,而 GPT-4 和 GPT-4 32K 分别为 8K 和 32K;这些包括发送的消息列表的总数和模型响应。如果总数超过相关模型限制,我们会得到一个异常。

没有任何现成的选项可以为我们跟踪这个令牌计数并确保它不超过令牌限制。作为企业应用程序设计的一部分,我们需要跟踪令牌计数,并且只发送不超过限制的提示。

许多企业正在使用聊天 API 实施 ChatGPT 的企业版本。以下是一些可以帮助企业管理这些对话的最佳实践。记住,获取所需输出的最佳方式涉及迭代测试和改进你的指令:

mng.bz/pxVKmng.bz/OmEw
跟踪令牌

如前所述,在使用对话 API 时跟踪令牌至关重要。如果我们超过总令牌大小,体验将受到影响,API 中的总令牌数也会直接影响延迟和调用所需的时间。最后,我们使用的令牌越多,我们支付的越多。以下是一些你可以管理令牌的方法:

tiktokenmax_tokensusage
num_tokens_from_messages

随着对话逐轮进行,我们计算使用的标记数,一旦达到模型限制,旧消息将从对话中移除。请注意,我们从索引 1 开始。这确保我们始终保留索引 0 的系统消息,并且只移除用户/助手消息。

ConsoleChatApp:
import os
from openai import AzureOpenAI
import tiktoken

client = AzureOpenAI(                                 #1
    azure_endpoint=os.getenv("AOAI_ENDPOINT"),      #1
    api_version=”2024-05-01-preview”,               #1         
    api_key=os.getenv(“AOAI_KEY”))                  #1

GPT_MODEL = "gpt-35-turbo"

system_message = {"role": "system", "content": "You are 
                           ↪a helpful assistant        #2
max_response_tokens = 250
token_limit = 4096
conversation = []
conversation.append(system_message)                #2

def num_tokens_from_messages(messages):              #3
    encoding= tiktoken.get_encoding("cl100k_base")    #4
    num_tokens = 0
    for message in messages:                 #5
        num_tokens += 4
        for key, value in message.items():
            num_tokens += len(encoding.encode(value))
            if key == "name":
                num_tokens += -1 
    num_tokens += 2 

print("I am a helpful assistant. I can talk about pets and salons.")

while True:                                        #6
    user_input = input("")     
    conversation.append({"role": "user", "content": user_input})
    conv_history_tokens = num_tokens_from_messages(conversation)

    while conv_history_tokens + max_response_tokens >= token_limit:
        del conversation[1]                      #7
        conv_history_tokens = num_tokens_from_messages(conversation)

    response = client.chat.completions.create(     #8
        model=GPT_MODEL,
        messages=conversation,
        temperature=0.8,
        max_tokens=max_response_tokens)

    conversation.append({"role": "assistant", "content":
    ↪response.choices[0].message.content})
    print("\n" + response.choices[0].message.content)
    print("(Tokens used: " + str(response.usage.total_tokens)  + ")")

#1 设置 OpenAI 环境和配置细节

#2 设置聊天系统消息

#3 函数用于计算对话中所有消息的总标记数

#4 使用 tiktoken 库来计算标记

#5 遍历消息

#6 捕获用户输入

#7 当总标记数超过标记限制时,我们移除第二个标记。第一个标记是系统标记,我们总是想要的。

#8 聊天完成 API 调用

聊天完成与完成 API

聊天完成和完成 API 都旨在生成类似人类的文本,并用于不同的上下文。完成 API 旨在处理单轮任务,为用户提供提示的完成。它最适合只需要单个响应的任务。

systemuserassistant

3.4.5 管理标记的最佳实践

对于 LLM,令牌是新的货币。随着大多数企业从试水转向业务关键用例,管理令牌将成为计算、成本和整体体验的一个重点。从企业应用的角度来看,以下是管理令牌的一些考虑因素:

tiktoken

3.4.6 其他 LLM 提供商

其他供应商现在也提供了企业级 LLM。这些 LLM 可以通过 API 获取,或者在某些情况下,作为企业可以自行托管模型权重。表 3.7 概述了在出版时的一些著名 LLM。请注意,从商业许可的角度来看,存在一些限制。

表 3.7 其他 LLM 提供商
ai.meta.com/llama/developers.generativeai.google/huggingface.co/bigscience/bloommng.bz/YVqzmng.bz/GNxD

有趣的是,所有这些供应商都遵循与 OpenAI 建立的概念和 API 相似的方法。例如,根据他们的文档,谷歌完成 API 等价的 PaLM 模型在下一列表中展示。

列表 3.26 PaLM 生成的文本 API 签名
google.generativeai.generate_text(*,
    model: Optional[model_types.ModelNameOptions] = 'models/text-bison-001',
    prompt: str,
    temperature: Optional[float] = None,
    max_output_tokens: Optional[int] = None,
    top_p: Optional[float] = None,
    top_k: Optional[float] = None,
    stop_sequences: Union[str, Iterable[str]] = None,
) -> text_types.Completion

虽然这些选项存在,并且其中一些来自信誉良好的领先科技公司,但对于大多数企业来说,Azure OpenAI 和 OpenAI 是最成熟的,拥有最多的企业控制和所需的支持。下一章将涉及图像,我们将学习如何从文本过渡到图像,并在此模式中生成内容。

摘要

logit_biassystemuserassistant