Transformers-自然语言处理(六)

Transformers 自然语言处理(六)

原文:zh.annas-archive.org/md5/a1e65552fc41f3b5a667f63d9bed854c

译者:飞龙

协议:CC BY-NC-SA 4.0

第十六章:Transformers驱动副驾驶员的出现

工业 4.0I4.0)达到成熟时,一切都将关于机器对机器的连接、通信和决策。人工智能将主要嵌入成熟的按需付费云 AI 解决方案中。大型科技公司将吸收大部分才华横溢的 AI 专家,创建 API、接口和集成工具。

AI 专家将从开发转变为设计,成为架构师、集成者和云 AI 管道管理员。因此,AI 更像是工程顾问的工作,而不是工程开发者的工作。

第一章Transformers是什么?,介绍了基础模型,Transformers可以完成它们未经训练的自然语言处理任务。第十五章从自然语言处理到任务无关的Transformers模型,将基础模型Transformers扩展到可以执行视觉任务、自然语言处理任务等的任务无关模型。

本章将把 OpenAI GPT-3 模型扩展到各种副驾驶员任务。新一代 AI 专家和数据科学家将学习如何与 AI 副驾驶员合作,帮助他们自动生成源代码并做出决策。

本章将首先更详细地探讨提示工程。示例任务包括将会议记录转换为摘要。Transformers提高了我们的生产力。但是,我们将看到自然语言对 AI 仍然是一个挑战。

我们将学习如何将 OpenAI Codex 作为副驾驶员。GitHub Copilot 在我们编写程序时使用 Codex 为我们建议源代码。Codex 也可以将自然语言转换为代码。

然后,我们将发现具有特定领域 GPT-3 引擎的新 AI 方法。本章将展示如何生成具有 12288 维度的嵌入并将其插入机器学习算法中。我们还将看到如何要求转换器自动生成说明。

在研究Transformers驱动的推荐系统之前,我们将看到如何过滤偏见的输入和输出。2020 年代的人工智能必须以道德方法构建。

推荐系统渗透到每个社交媒体平台,推荐视频、帖子、消息、书籍和其他我们可能想消费的产品。我们将在这个过程中构建一个基于 ML 的教育多用途Transformers推荐系统。

Transformers模型分析序列。它们起初用于自然语言处理,但已成功扩展到计算机视觉。我们将探索在 JAX 中开发的基于Transformers的计算机视觉程序。

最后,我们将看到 AI 副驾驶员如何促进虚拟系统向元宇宙的过渡,在本十年中将会扩展。当你开发应用程序时,你是飞行员。但是,当你有要开发的代码时,激活的完成只限于方法,而不是代码行。IDE 可能会建议方法列表。副驾驶员可以生成整段代码的完成!

本章涵盖以下主题:

  • 提示工程

  • GitHub Copilot

  • Codex 语言到源代码模型

  • 嵌入数据集

  • 嵌入式驱动的机器学习

  • 指导系列

  • 内容过滤模型

  • 探索基于转换器的推荐系统

  • 将自然语言处理序列学习扩展到行为预测

  • 在 JAX 中实现转换器模型

  • 将转换器模型应用于计算机视觉

让我们从提示工程开始,这是一种必须获得的关键能力。

提示工程

说一种特定的语言不是遗传的。我们大脑中没有一个包含我们父母语言的语言中心。我们的大脑在我们的生活早期工程化我们的神经元,以便说、阅读、写作和理解一种语言。每个人的语言电路都取决于他们的文化背景以及在早年如何与他们交流。

随着我们成长,我们发现我们听到的很多东西都是混乱的:未完整的句子、语法错误、词语误用、发音错误以及许多其他扭曲。

我们使用语言传达信息。我们很快发现我们需要将我们的语言适应我们所面向的人或观众。我们可能需要尝试额外的“输入”或“提示”来得到我们期望的结果(“输出”)。像 GPT-3 这样的基础级转换器模型可以以无限多种方式执行数百种任务。我们必须像学习任何其他语言一样学习转换器提示和响应的语言。与人或接近人类水平的转换器进行有效沟通必须包含最少的信息以最大化结果。我们代表获得结果所需的最小输入信息为minI,以及任何系统的最大输出为maxR

我们可以将这种沟通链表示为:

minI(input) maxR(output)

我们将用“提示”取代“输入”,以便转换器表明我们的输入会影响模型的反应。输出是“响应”。与转换器的对话,d(T),可以表示为:

d(T)=minI(prompt) maxR(response)

minI(prompt)1时,maxR(response)的概率也1

minI(prompt) 0时,maxR(response)的概率也0

d(T)的质量取决于我们能够定义minI(prompt)的程度。

如果你的提示倾向于达到1,那么它将产生倾向于1的概率。

如果你的提示趋向于达到0,那么它将产生趋向于0的输出概率。

你的提示是影响概率的内容的一部分!为什么?因为转换器将在其估计中包含提示和响应。

作为孩子或成年人学习一门语言需要很多年的时间。学习Transformers语言和如何有效设计minI(prompt)也需要相当长的时间。我们需要了解它们,它们的架构以及算法计算预测的方式。然后我们需要花相当多的时间来理解如何设计输入,提示,以使Transformers表现出我们期望的行为。

本节重点介绍口头语言。OpenAI GPT-3 的 NLP 任务的提示通常来自会议记录或对话,这些记录往往是非结构化的。将会议记录或对话转换成摘要可能是相当具有挑战性的。本节将专注于总结相同对话的七种情况下的笔记,从随意英语到具有有限上下文的随意或正式英语。

我们将从具有有意义上下文的随意英语开始。

具有有意义上下文的随意英语

随意英语是用较短的句子和有限的词汇说话的。

让我们要求 OpenAI GPT-3 执行“笔记到摘要”的任务。转到 www.openai.com。登录或注册。然后转到示例页面并选择笔记到摘要

我们将给 GPT-3 提供所有必要的信息,以总结简和汤姆之间的随意对话。简和汤姆是两位开始工作的开发人员。汤姆提供咖啡给简。简拒绝了这个提议。

在这种情况下,minI(prompt)=1,因为输入信息是正确的,如图 16.1所示:

图 16.1:总结了详细记录的笔记

当我们点击生成时,我们得到了一个令人惊讶的好答案,如图 16.2所示:

图形用户界面、文本、应用程序、电子邮件  自动生成的描述

图 16.2:GPT-3 提供了一个可以接受的摘要

我们能否得出结论,AI 可以在我们混乱的日常对话、会议和漫无目的的闲聊中找到结构?答案并不容易。我们现在将通过添加一个代称来使输入复杂化。

以代称为特征的随意英语

汤姆提到了coffee这个词,让 GPT-3 保持正确的方向。但如果汤姆用java代替coffee呢?咖啡是指饮料,而java是一种来自爪哇岛的成分。代称是当我们使用一个对象的属性时,比如用java代替coffee。Java 也是一种编程语言,其标志是一杯咖啡。

我们面临着java的三种可能定义:指咖啡的成分咖啡(代称),爪哇岛和一种编程语言的名称。GPT-3 现在有一个多义性(同一个词的几个含义)问题需要解决。

人类掌握了多义性。我们学会了单词的不同含义。我们知道一个词没有上下文是没有多大意义的。在这种情况下,简和汤姆是开发人员,使情况复杂化。他们是在谈论咖啡还是语言?

对于人类来说答案很容易,因为汤姆随后谈到了他的妻子,她已经停止喝咖啡了。但是当词语java代替coffee时,GPT-3 可能会因为这种多义性而产生错误的答案:

图形用户界面,文本 自动生成的描述

图 16.3:当提示混淆时 GPT-3 的错误响应

因此我们证实了当minI(prompt)**0时,maxR(response)0的概率。

如果我们加入省略号,人类的对话会变得更加难以分析。

具有省略号的非正式英语

情况可能会变得更糟。假设汤姆正在喝一杯咖啡,简看着他和咖啡杯,然后随意地打了个招呼。

汤姆没有问简是否想要咖啡或者 Java,而是说:

"想要一些吗?"

汤姆省略了coffee这个词,这是一个省略号。简仍然可以通过看着他拿着一杯咖啡来理解汤姆的意思。

OpenAI GPT-3 检测到了drinking这个词,并成功地将这个动词与问题想要一些吗?联系起来。我们不需要某种编程语言的想要一些。由 GPT-3 产生的以下摘要仍然是正确的:

文本 自动生成的描述

图 16.4:GPT-3 产生的正确响应

现在,让我们看看当存在人类可以理解但对人工智能仍然是一个挑战的模糊背景时会发生什么。

具有模糊背景的非正式英语

如果我们进一步思考,汤姆并不需要提及他的妻子才能让理解他在说什么,因为他正在拿着一杯咖啡。

让我们去掉汤姆提到他的妻子和动词drinking。让我们保留想要一些而不是咖啡或 Java:

图 16.5:模糊的输入情境

输出反映了对话的明显混乱:

图 16.6:GPT-3 的不良响应

提示太模糊了,导致了一条不足的回答,我们可以总结为:

d(T)0,因为当 minI(prompt)0时,maxR(response)0的概率

当人类进行交流时,他们会将文化、过去的关系、视觉情境和其他不可见因素带入对话。对于第三方来说,这些不可见因素可能包括:

  • 阅读文字而看不到人们正在做什么(行动、面部表情、身体语言等)。

  • 听人们提到我们不了解的事物(电影、体育、工厂的问题等)。

  • 来自与我们不同文化的文化事件

列举的例子还有很多!

我们可以看到这些不可见因素让人工智能失明

现在让我们将传感器引入到情境中。

使用传感器的非正式英语

现在我们将视频传感器引入房间进行思想实验。想象一下我们可以使用图像字幕处理视频源,并在对话开始时提供上下文,比如:

人类有时会产生只有彼此了解的对话。考虑一下简和汤姆之间的对话。视频镜头显示汤姆正在喝咖啡,简在键盘上打字。简和汤姆是两个开发者,在开放空间里摸索着努力工作的一天。

然后我们以以下混乱的聊天作为提示:

Tom: "hi" Jane: "yeah sure" Tom: "Want some?" Jane: "Nope" Tom: "Cool. You're trying then." Jane: "Yup" Tom: "Sleep better?" Jane: "Yeah. Sure."

GPT-3 的输出是可以接受的,虽然在开头缺少了重要的语义词:

Summarize: A developer can be seen typing on her keyboard. Another developer enters the room and offers her a cup of coffee. She declines, but he insists. They chat about her sleep and the coffee. 

结果可能会在每一次运行中有所不同。GPT-3 查看了最高的概率并选择了最好的其中之一。GPT-3 完成了这个实验,因为图像标题提供了上下文。

然而,如果汤姆没有拿着一杯咖啡,剥夺了 GPT-3 的视觉背景,那该怎么办?

没有可见的上下文的随意英语

对于 AI 来说最困难的情况是如果汤姆每天都提到一个事件,但今天不是。假设汤姆每天早晨都拿着一杯咖啡进来。他现在进来了,问简是否在拿一杯咖啡之前想要一些。我们的思维实验是想象所有可能的情况。在这种情况下,我们的思维实验中的视频镜头将什么也没有揭示,我们又回到了混乱中。此外,视频镜头无法看到他们是开发者、会计还是顾问。所以,让我们剔除掉这部分上下文,只剩下以下上下文。让我们再进一步。对话包含Tom:Jane:。所以我们不需要提及上下文。我们得到的是:

Tom: "hi" Jane: "yeah sure" Tom: "Want some?" Jane: "Nope" Tom: "Cool. You're trying then." Jane: "Yup" Tom: "Sleep better?" Jane: "Yeah. Sure."

输出是相当惊人的。简和汤姆使用的随意语言导致 GPT-3 得出荒谬的结论。请记住,GPT-3 是一种随机算法。输入中最微小的变化可能会导致完全不同的输出。GPT-3 试图猜测他们在谈论什么。GPT-3 发现这段对话是关于消费某物。他们的随意语言导致了关于非法物质的荒谬预测,出于道德原因,我不在本节中重现这些。

GPT-3 确定语言水平并将其与相关情境关联起来。

如果我们使用正式英语重现相同的实验会发生什么?

没有上下文的正式英语对话

现在让我们把所有的上下文都剔除掉,但提供正式的英语。正式英语包含更长的句子、良好的语法和礼貌。我们可以使用正式的英语表达不包含上下文的相同对话:

汤姆:“早上好,简” 简:“早上好,汤姆” 汤姆:“你也要来点吗?” 简:“不,谢谢。我很好。” 汤姆:“太棒了。你走在了正确的道路上!” 简:“是的,我是的” 汤姆:“这些日子你睡得更好吗?” 简:“是的,谢谢。”

GPT-3 自然地理解了汤姆所说的“喝”与这种程度的英语和良好的礼貌。输出结果相当令人满意:

总结:汤姆对简说“早上好”。汤姆给了她他喝的东西。简说“不,谢谢。我很好。” 汤姆说“太棒了”并且她走在了正确的道路上。简说:“是的,我是。” 汤姆问她这些日子她睡得更好吗。

我们可以通过引入其他人物和其他对象并生成无数的情况,想象出同一对话的无尽变化。

让我们总结一下这些实验。

提示工程培训

我们的思维常常是混乱的。人类使用许多方法来重构无结构的句子。人类经常需要询问额外的问题才能理解别人在说什么。与 OpenAI GPT-3 这样的经过训练的转换器交互时,您需要接受这一点

请记住,与转换器的 对话 d(T) 和响应 maxR(response),取决于您的输入的质量 minI(prompt),如本节开始时所定义的:

d(T)=minI(prompt) maxR(response)

minI(prompt)1 时,maxR(response)1 的概率。

minI(prompt)0 时,maxR(response)0 的概率。

练习提示工程,并以时间来衡量您的进步。提示工程是一项将您带入下一个 AI 水平的新技能。

提示工程能力导致能够掌握协助工具。

协助工具

欢迎来到由 OpenAI 提供并在 Visual Studio 中提供的 AI 驱动的开发协助工具的世界。

GitHub Copilot

让我们从 GitHub Copilot: 开始

github.com/github/copilot-docs

在这一节中,我们将使用 GitHub Copilot 与 PyCharm (JetBrains):

github.com/github/copilot-docs/tree/main/docs/jetbrains

按照文档中的说明在 PyCharm 中安装 JetBrains 并激活 OpenAI GitHub Copilot。

与 GitHub Copilot 合作是一个四步骤的过程(见 图 16.7):

  • OpenAI Codex 是在互联网上公开的代码和文本上进行训练的。

  • 训练模型被插入到 GitHub Copilot 服务中。

  • GitHub 服务管理编辑器中编写的代码(在本例中为 PyCharm)和 OpenAI Codex 之间的双向流动。 GitHub 服务管理器提出建议,然后将交互发送回进行改进。

  • 代码编辑器是我们的开发工作空间。

包含图表的图片 说明自动生成

图 16.7:GitHub Copilot 的四步流程

按照 GitHub Copilot 提供的说明,在 PyCharm 中登录 GitHub。对于任何问题,请阅读 copilot.github.com/#faqs

一旦在 PyCharm 编辑器中设置好,只需键入:

import matplotlib.pyplot as plt
def draw_scatterplot 

一旦代码被输入,您可以打开 OpenAI GitHub 建议窗格并查看建议:

文本描述自动生成

图 16.8:您键入的代码的建议

一旦选择了您喜欢的副驾驶建议,它将出现在编辑器中。您可以使用 Tab 键确认建议。您可以等待另一个建议,比如绘制散点图:

import matplotlib.pyplot as plt
def draw_scatterplot(x, y):
    plt.scatter(x, y)
    plt.xlabel('x')
    plt.ylabel('y')
    plt.show()
draw_scatterplot([1, 2, 3, 4, 5], [1, 4, 9, 16, 25]) 

绘图将被显示:

图表,散点图 说明自动生成

图 16.9:GitHub Copilot 散点图

您可以在本书的 GitHub 存储库的 Chapter16 文件夹中找到的 GitHub_Copilot.py 上运行结果。

该技术是无缝的、不可见的,并将逐渐扩展到所有开发领域。该系统装载了 GPT-3 功能以及其他流水线。该技术适用于 Python、JavaScript 等。

它需要通过提示工程进行培训,以适应由 OpenAI Codex 驱动的 GitHub Copilot 的工作方式。

让我们直接进入 OpenAI Codex,这可能是使用副驾驶进行训练的好地方。

Codex

OpenAI Codex 不仅提供源代码建议。Codex 还可以将自然语言转换为源代码。

转到 OpenAI 网站并点击链接到 Codex 界面:

beta.openai.com/codex-javascript-sandbox

提供说明,结果将显示在 Codex 窗口和界面右侧的源代码中。

本节中的示例包含使用提示窗格的几个序列:

图 16.10:Codex 的 JavaScript 沙盒

我们在 提供说明... 窗格中输入自然语言,生成将运行的 JavaScript。

例如,我用自然语言输入了两条说明:

绘制 50 个各种颜色的小乒乓球

使球变圆

Codex 源自 GPT-3。在某些情况下,该引擎被称为“davinci-codex”。这意味着 Codex 继承了 GPT-3 引擎的属性。为了理解这一点,让我们看看其中的一个参数:top_p。引擎对引擎的输出进行采样。例如,如果 top_p 设置为 0.1,它将仅考虑采样中的前 10%。它将检索该前 10% 概率质量中的标记。由于整个计算是随机的,可能需要一些前选项和另一组前选项来运行。请耐心等待,花时间设计提示。

您的 AI 引擎学习路径:

  1. 学习了解 Codex 引擎的行为。

  2. 接受随机算法的自由创造性本质。

  3. 习惯于用更好的提示来驾驭它们。然后,随着引擎的改进,您将能够随着 Codex 的成长而成长。

脚本将出现在 JavaScript 窗格中,带有注释的说明和代码:

/* draw 50 small ping pong balls of all sorts of colors */
var balls = [];
for (var i = 0; i < 50; i++) {
  var ball = document.createElement('div');
  ball.style.width = '10px';
  ball.style.height = '10px';
  ball.style.backgroundColor = 'hsl(' + Math.random() * 360 + ', 100%, 50%)';
  ball.style.position = 'absolute';
  ball.style.left = Math.random() * window.innerWidth + 'px';
  ball.style.top = Math.random() * window.innerHeight + 'px';
  document.body.appendChild(ball);
  balls.push(ball);
}
/* Make the balls round */
for (var i = 0; i < balls.length; i++) {
  balls[i].style.borderRadius = '50%';
} 

结果显示如下:

图表,散点图  自动生成的描述

图 16.11:创建五十个多彩的球

现在让我们要求程序移动球:

`Make all of the balls move inside the window` 

代码已生成:

/* make all of the balls move inside the window. */
var moveBalls = function() {
  for (var i = 0; i < balls.length; i++) {
    var ball = balls[i];
    ball.style.left = (parseInt(ball.style.left) + Math.random() * 10 - 5) + 'px';
    ball.style.top = (parseInt(ball.style.top) + Math.random() * 10 - 5) + 'px';
  }
  window.requestAnimationFrame(moveBalls);
};
moveBalls(); 

一旦球移动,通过单击 导出到 JSFiddle 按钮将代码导出到 HTML:

包含标志的图片  自动生成的描述

图 16.12:导出到 JSFiddle 按钮

JSFiddle 创建了一个 HTML 页面:

文本  自动生成的描述

图 16.13:JSFiddle 创建 HTML 页面

在这种情况下,代码已保存到 codex.html,它位于本章文件夹中的 GitHub 存储库中。您可以打开并观看使用自然编程语言创建 HTML 页面的创新结果。

领域特定的 GPT-3 引擎

本节探讨可以执行领域特定任务的 GPT-3 引擎。我们将在本节的三个子部分中运行三个模型:

  • Embedding2ML 使用 GPT-3 为 ML 算法提供嵌入

  • 指示系列要求 GPT-3 为任何任务提供说明

  • 内容过滤器,用于过滤偏见或任何形式的不可接受的输入和输出

打开 Domain_Specific_GPT_3_Functionality.ipynb

我们将从 embedding2ML(将嵌入作为 ML 输入)开始。

Embedding2ML

OpenAI 已经训练了几个具有不同维度和不同功能的嵌入模型:

  • 艾达(1,024 维度)

  • 巴贝奇(2,048 维度)

  • 居里(4,096 维度)

  • 达芬奇(12,288 维度)

对于每个引擎的更多解释,您可以在 OpenAI 的网站上找到更多信息:

beta.openai.com/docs/guides/embeddings.

达芬奇模型提供具有 12,288 维度的嵌入。在本节中,我们将利用达芬奇的力量生成供应链数据集的嵌入。但是,我们不会将嵌入发送到Transformers的嵌入子层!

我们将嵌入发送到 scikit-learn 库中的聚类机器学习程序中的六个步骤:

  • 步骤 1:安装和导入 OpenAI,并输入 API 密钥

  • 步骤 2:加载数据集

  • 步骤 3:合并列

  • 步骤 4:运行 GPT-3 嵌入

  • 步骤 5:使用嵌入进行聚类(k-means)

  • 步骤 6:可视化聚类(t-SNE)

过程总结在 图 16.14 中:

形状,多边形  自动生成的描述

图 16.14:将嵌入发送到聚类算法的六个步骤流程

打开 Google Colab 文件,Domain_Specific_GPT_3_Functionality.ipynb,并转到笔记本的 Embedding2ML with GPT-3 engine 部分。

本节中描述的步骤与笔记本单元格相匹配。让我们总结一下流程的每个步骤。

步骤 1: 安装和导入 OpenAI

让我们从以下子步骤开始:

  1. 运行单元格

  2. 重新启动运行时

  3. 再次运行单元格以确保,因为你重新启动了运行时:

    try:
      import openai
    except:
      !pip install openai
      import openai 
    
  4. 输入 API 密钥:

    openai.api_key="[YOUR_KEY]" 
    

我们现在加载数据集。

步骤 2: 加载数据集

在运行该单元之前加载文件。我上传了tracking.csv(在本书的 GitHub 存储库中可用),其中包含 SCM 数据:

import pandas as pd
df = pd.read_csv('tracking.csv', index_col=0) 

数据包含七个字段:

  • ID

  • 时间

  • 产品

  • 用户

  • 得分

  • 摘要

  • 文本

让我们使用以下命令打印前几行:

print(df) 
 Time Product  User  Score        Summary   Text     
Id                                                                    
1     01/01/2016 06:30   WH001  C001      4        on time   AGV1     
2     01/01/2016 06:30   WH001  C001      8           late     R1  NaN
3     01/01/2016 06:30   WH001  C001      2          early    R15  NaN
4     01/01/2016 06:30   WH001  C001     10  not delivered    R20  NaN
5     01/01/2016 06:30   WH001  C001      1        on time     R3  NaN
...                ...     ...   ...    ...            ...    ...  ...
1049  01/01/2016 06:30   WH003  C002      9        on time   AGV5  NaN
1050  01/01/2016 06:30   WH003  C002      2           late  AGV10  NaN
1051  01/01/2016 06:30   WH003  C002      1          early   AGV5  NaN
1052  01/01/2016 06:30   WH003  C002      6  not delivered   AGV2  NaN
1053  01/01/2016 06:30   WH003  C002      3        on time   AGV2  NaN
[1053 rows x 7 columns] 

我们可以组合列来构建我们想要的聚类。

步骤 3: 合并列

我们可以将产品列与摘要组合以获得产品及其交付状态的视图。请记住,这只是一个实验性的练习。在实际项目中,仔细分析并决定你想要组合的列。

下面的示例代码可以用你选择的任何选项来替换,以进行你的实验:

df['combined'] = df.Summary.str.strip()+ "-" + df.Product.str.strip()
print(df) 

我们现在可以看到一个名为combined的新列:

 Time Product  User  ... Text           combined
Id                                    ...                                 
1     01/01/2016 06:30 WH001  C001  ... AGV1             on time-WH001
2     01/01/2016 06:30 WH001  C001  ... R1  NaN           late-WH001
3     01/01/2016 06:30 WH001  C001  ... R15  NaN          early-WH001
4     01/01/2016 06:30 WH001  C001  ... R20  NaN  not delivered-WH001
5     01/01/2016 06:30 WH001  C001  ... R3  NaN        on time-WH001
...                ...     ...   ...  ...    ...  ...                  ...
1049  01/01/2016 06:30 WH003  C002  ... AGV5  NaN        on time-WH003
1050  01/01/2016 06:30 WH003  C002  ... AGV10  NaN         late-WH003
1051  01/01/2016 06:30 WH003  C002  ... AGV5  NaN          early-WH003
1052  01/01/2016 06:30 WH003  C002  ... AGV2  NaN  not delivered-WH003
1053  01/01/2016 06:30 WH003  C002  ... AGV2  NaN        on time-WH003
[1053 rows x 8 columns] 

我们现在将在combined列上运行嵌入模型。

步骤 4: 运行 GPT-3 嵌入

我们现在将运行davinci-similarity模型,为combined列获取 12,288 维度:

import time
import datetime
# start time
start = time.time()
def get_embedding(text, engine="davinci-similarity"):
   text = text.replace("\n", " ")
   return openai.Engine(id=engine).embeddings(input = [text])['data'][0]['embedding']
df['davinci_similarity'] = df.combined.apply(lambda x: get_embedding(x, engine='davinci-similarity'))
# end time
end = time.time()
etime=end-start
conversion = datetime.timedelta(seconds=etime)
print(conversion)
print(df) 

结果令人印象深刻。我们为 combined 列有 12,288 维度:

0:04:44.188250
                  Time  ...                                 davinci_similarity
Id                      ...                                                   
1     01/01/2016 06:30  ...  [-0.0047378824, 0.011997132, -0.017249448, -0....
2     01/01/2016 06:30  ...  [-0.009643857, 0.0031537763, -0.012862709, -0....
3     01/01/2016 06:30  ...  [-0.0077407444, 0.0035147679, -0.014401976, -0...
4     01/01/2016 06:30  ...  [-0.007547746, 0.013380095, -0.018411927, -0.0...
5     01/01/2016 06:30  ...  [-0.0047378824, 0.011997132, -0.017249448, -0....
...                ...  ...                                                ...
1049  01/01/2016 06:30  ...  [-0.0027823148, 0.013289047, -0.014368941, -0....
1050  01/01/2016 06:30  ...  [-0.0071367626, 0.0046446105, -0.010336877, 0....
1051  01/01/2016 06:30  ...  [-0.0050991694, 0.006131069, -0.0138306245, -0...
1052  01/01/2016 06:30  ...  [-0.0066779135, 0.014575769, -0.017257102, -0....
1053  01/01/2016 06:30  ...  [-0.0027823148, 0.013289047, -0.014368941, -0....
[1053 rows x 9 columns] 

现在我们需要将结果转换为numpy矩阵:

#creating a matrix
import numpy as np
matrix = np.vstack(df.davinci_similarity.values)
matrix.shape 

矩阵的形状为 1,053 行 x 12,288 列,这相当令人印象深刻:

(1053, 12288) 

矩阵现已准备好发送到 scikit-learn 机器学习聚类算法。

步骤 5: 使用嵌入进行聚类(k-means 聚类)

我们通常将传统数据集发送到 k-means 聚类算法。我们将一个 12,288 维度的数据集发送到 ML 算法,而不是发送到 transformer 的下一个子层。

我们首先从 scikit-learn 导入 k-means:

from sklearn.cluster import KMeans 

我们现在运行一个传统的 k-means 聚类算法,使用我们的 12,288 维度数据集:

n_clusters = 4
kmeans = KMeans(n_clusters = n_clusters,init='k-means++',random_state=42)
kmeans.fit(matrix)
labels = kmeans.labels_
df['Cluster'] = labels
df.groupby('Cluster').Score.mean().sort_values() 

输出如请求的四个聚类:

Cluster
2    5.297794
0    5.323529
1    5.361345
3    5.741697 

我们可以打印数据集内容的标签:

print(labels) 

输出是:

[2 3 0 ... 0 1 2] 

现在让我们使用 t-SNE 可视化聚类。

步骤 6: 可视化聚类(t-SNE)

t-SNE 保留局部相似性。PCA 最大化大的成对距离。在这种情况下,小的成对距离。

笔记本将使用matplotlib来显示 t-SNE:

from sklearn.manifold import TSNE
import matplotlib
import matplotlib.pyplot as plt 

在可视化之前我们需要运行 t-SNE 算法:

#t-SNE
tsne = TSNE(n_components=2, perplexity=15, random_state=42, init='random', learning_rate=200)
vis_dims2 = tsne.fit_transform(matrix) 

现在我们可以在matplotlib中显示结果:

x = [x for x,y in vis_dims2]
y = [y for x,y in vis_dims2]
for category, color in enumerate(['purple', 'green', 'red', 'blue']):
    xs = np.array(x)[df.Cluster==category]
    ys = np.array(y)[df.Cluster==category]
    plt.scatter(xs, ys, color=color, alpha=0.3)
    avg_x = xs.mean()
    avg_y = ys.mean()

    plt.scatter(avg_x, avg_y, marker='x', color=color, s=100)
plt.title("Clusters of embeddings-t-SNE") 

该图显示了聚类周围堆积了许多数据点。还有许多数据点环绕着附加到最近质心的聚类:

图表,散点图 说明自动生成

图 16.15: 嵌入-t-SNE 的聚类

我们运行了一个大型的 GPT-3 模型,嵌入了 12,288 维度。然后我们将结果送入聚类算法。将 Transformer 和机器学习相结合的潜力是无限的!

如果您希望查看数据框,请转到笔记本的Peeking into the embeddings部分。

现在让我们看一下指示系列。

指示系列

个人助手、元宇宙中的头像、网站等在用户请求帮助时需要提供清晰的指示。转到Domain_Specific_GPT_3_Functionality.ipynbinstruct series部分。

在这一部分,我们将要求一个 Transformer 解释如何在 Microsoft Edge 中设置家长控制,使用以下提示:解释如何在 Edge 中设置家长控制

我们首先运行完成单元:

import os
import openai
os.environ['OPENAI_API_KEY'] ='[YOUR_API_KEY]'
print(os.getenv('OPENAI_API_KEY'))
openai.api_key = os.getenv("OPENAI_API_KEY")
response = openai.Completion.create(
  engine="davinci-instruct-beta",
  prompt="Explain how to set up parent control in Edge.\n\n\nACTIONS:",
  temperature=0,
  max_tokens=120,
  top_p=1,
  frequency_penalty=0,
  presence_penalty=0
)
r = (response["choices"][0])
print(r["text"]) 

响应是根据请求的指示列表:

1\. Start Internet Explorer.
2\. Click on the tools menu.
3\. Click on the Internet options.
4\. Click on the advanced tab.
5\. Click to clear or select the enable personalized favorite menu check box. 

您可以要求的指示数量是无限的!发挥您的创造力和想象力找到更多例子!

有时输入或输出是不可接受的。让我们看看如何实施内容过滤器。

内容过滤器

偏见、不可接受的语言和任何形式的不道德输入都应该从您的 AI 应用程序中排除。

OpenAI 训练的模型之一是内容过滤器。我们将在本节中运行一个示例。转到Domain_Specific_GPT_3_Functionality.ipynb的内容过滤器部分。

我的建议是过滤输入和输出,如图 16.16所示:

图描述自动生成

图 16.16:实现内容过滤器

我的建议是实施一个三步过程:

  1. 对所有输入数据应用内容过滤器

  2. 让 AI 算法根据训练运行

  3. 对所有输出数据应用内容过滤器

在本节中,输入和输出数据将被命名为content

以以下输入为例:

content = "Small and fat children should not play basketball at school." 

这个输入是不可接受的!学校不是 NBA。篮球应该保持每个人的一个良好的锻炼。

现在让我们在单元content-filter-alpha中运行内容过滤器:

response = openai.Completion.create(
      en      prompt = "<|endoftext|>"+content+"\n--\nLabel:",
      temperature=0,
      max_tokens=1,
      top_p=1,
      frequency gine="content-filter-alpha",
_penalty=0,
      presence_penalty=0,
      logprobs=10
    ) 

内容过滤器将结果存储在response中,一个字典对象。我们检索选择的值以获取可接受性的级别:

r = (response["choices"][0])
print("Content filter level:", r["text"]) 

内容过滤器返回三个值之一:

  • 0 – 安全

  • 1 – 敏感

  • 2 – 不安全

在这种情况下,结果当然是 2:

Content filter level: 2 

内容过滤器可能不够。我建议添加其他算法来控制和过滤输入/输出内容:规则库、字典和其他方法。

现在我们已经探索了特定领域的模型,让我们构建一个基于 Transformer 的推荐系统。

基于 Transformer 的推荐系统

Transformer 模型学习序列。学习语言序列是一个很好的开始,考虑到每天在社交媒体和云平台上发布的数十亿条消息。消费者行为、图像和声音也可以用序列表示。

在本节中,我们将首先创建一个通用序列图,然后在 Google Colaboratory 中构建一个基于 Transformer 的通用推荐系统。然后,我们将看到如何在元人中部署它们。

让我们首先定义通用序列。

通用序列

许多活动可以用实体和它们之间的链接表示。因此,它们被组织成序列。例如,YouTube 上的一个视频可以是实体 A,链接可以是一个人从视频 A 转到视频 E 的行为。

另一个例子是发烧是一个实体 F,链接是医生可能做出的导致微判断 B 的推理。消费者在亚马逊购买产品 D 可以生成到建议 C 或另一个产品的链接。例子是无穷无尽的!

我们可以用六个字母定义本节中的实体:

E={A,B,C,D,E,F}

当我们说一种语言时,我们遵循语法规则,无法摆脱它们。

例如,假设 A =”我”, E =”吃”, 和 D =”糖”。表达我吃糖的事实只有一种正确的序列:“我吃糖。”

如果有人说“吃糖我”,听起来会有点奇怪。

在这个序列中,表示这些规则的链接是:

A->E (我吃)

E->D(吃糖)

我们可以通过观察行为、学习数据集与 ML,或者手动听取专家的意见来自动推断任何领域的规则。

在本节中,我们假设我们已经观察了一个 YouTube 用户几个月,他花了几个小时观看视频。我们注意到用户始终从一种类型的视频转移到另一种类型的视频。例如,从歌手 B 的视频到歌手 D 的视频。这个人 P 的行为规则 X 似乎是:

X(P)={AE,BD,BF,C,CD,DB,DC,DE,EA,ED,FB}

我们可以将实体系统表示为图中的顶点,将链接表示为边。例如,如果我们将 X(P) 应用到顶点,我们得到以下无向图:

包含文本、时钟的图片  自动生成描述

图 16.17:YouTube 用户视频组合的图

假设顶点是观众喜欢的歌手的视频,C 是观众偏爱的歌手。我们可以给予观众过去几周内进行的统计转换(链接或边)一个值为 1 的值。我们还可以给观众最喜欢的歌手的视频一个值为 100 的值。

对于这个观众,路径由(边,顶点)值 V(R(P)): 表示

V(X(P))={AE=1,BD=1,BF=1,C=100,CD=1,DB=1,DE=1,EA=1,ED=1,FB=1}

推荐系统的目标是建议导致歌手 C 的视频的序列,或在某些情况下直接建议 C

我们可以用奖励矩阵 R 来表示无向图:

 A,B,C,D,E,F     
R = ql.matrix([ [0,0,0,0,1,0],   A 
                [0,0,0,1,0,1],   B 
                [0,0,100,1,0,0], C 
                [0,1,1,0,1,0],   D 
                [1,0,0,1,0,0],   E 
                [0,1,0,0,0,0]])  F 

让我们使用这个奖励矩阵模拟观众 X 在几个月内的活动。

使用 MDP 进行数据集管道模拟的 RL

在本节中,我们将模拟人物P观看 YouTube 上歌曲视频的行为X,我们将其定义为X(P)。我们将确定P的行为值为V(X(P))。然后,我们将这些值组织到奖励矩阵R中,用于我们现在将在 Bellman 方程中实现的马尔可夫决策过程MDP)。

打开KantaiBERT_Recommender.ipynb,它位于本书 GitHub 存储库的本章文件夹中。该笔记本是KantaiBERT.ipynb的修改版本,描述在第四章从头开始预训练 RoBERTa 模型中。

第四章中,我们使用kant.txt训练了一个变换器,其中包含 Immanuel Kant 的一些作品。在本节中,我们将通过强化学习RL)生成一个人行为的数千个序列。RL 不在本书的范围之内,但本节包含一些提醒。

第一步是训练一个变换器模型,以学习和模拟一个人的行为。

使用 MDP 训练客户行为

KantaiBERT.ipynb第四章中通过加载kant.txt来开始训练具有 DistilBERT 架构的 RoBERTa。kant.txt 包含了 Immanuel Kant 的作品。在本节中,我们将使用在本章通用序列部分中定义的奖励矩阵R生成序列:

R = ql.matrix([ [0,0,0,0,1,0],    
                [0,0,0,1,0,1],    
                [0,0,100,1,0,0],  
                [0,1,1,0,1,0],    
                [1,0,0,1,0,0],    
                [0,1,0,0,0,0]]) 

程序的第一个单元格是:

Step 1A Training: Dataset Pipeline Simulation with RL using an MDP:

此单元格使用 Bellman 方程实现 MDP:

 `# The Bellman MDP based Q function`
 `Q[current_state, action] = R[current_state, action] + gamma * MaxValue` 

在这个方程中:

  • R 是原始奖励矩阵。

  • Q 是更新后的矩阵,与R的大小相同。但是,它通过强化学习进行更新,以计算每个实体(顶点)之间链接(边)的相对值。

  • gamma 是一个学习率,设置为 0.8,以避免过度拟合训练过程。

  • MaxValue 是下一个顶点的最大值。例如,如果 YouTube 视频的观看者P正在观看歌手A,程序可能会增加E的值,以便此建议可以作为推荐出现。

逐渐地,程序将尝试找到最佳值,以帮助观众找到最佳的观看视频。一旦强化程序学习了最佳的链接(边),它就可以推荐最佳的观看序列。

原始奖励矩阵已经被训练成为操作矩阵。如果我们添加原始实体,则训练值明显出现:

 `A       B       C       D       E       F`
`[[  0\.      0\.      0\.      0\.    258.44    0\.   ]  A`
 `[  0\.      0\.      0\.    321.8     0\.    207.752]  B`
 `[  0\.      0\.    500\.    321.8     0\.      0\.   ]  C`
 `[  0\.    258.44  401\.      0\.    258.44    0\.   ]  D`
 `[207.752   0\.      0\.    321.8     0\.      0\.   ]  E`
 `[  0\.    258.44    0\.      0\.      0\.      0\.   ]] F` 

人物P的行为值V的原始序列是:

V(X(P))={AE=1,BD=1,BF=1,C=100, CD=1,DB=1,DE=1,EA=1,ED=1,FB=1}

它们已经被训练成:

V(X(P))={AE=259.44, BD=321.8 ,BF=207.752, C=500, CD=321.8 ,DB=258.44, DE=258.44, EA=207.752, ED=321.8, FB=258.44}

这是相当大的变化!

现在,可以推荐一系列P最喜欢的歌手的激动人心的视频。假设P观看了歌手E的视频。训练矩阵的第E行将推荐该行中最高值的视频,即D=321.8。因此,歌手D的视频将出现在P的 YouTube 视频源中。

本节的目标不是停留在这个阶段。相反,本节使用 MDP 创建有意义的序列,以创建转换器用于训练的数据集。

YouTube 不需要生成序列来创建数据集。YouTube 将所有观众的所有行为存储在大数据中。然后,谷歌强大的算法接管,推荐在观众的视频源中播放最佳视频。

其他平台使用余弦相似度来进行预测,如第九章匹配标记化器和数据集中实现的那样。

MDP 可以为 YouTube 观众,亚马逊购买者,谷歌搜索结果,医生的诊断路径,供应链以及任何类型的序列进行训练。转换器正在将序列学习、训练和预测带到另一个水平。

让我们实现一个模拟,为转换器模型创建行为序列。

使用 MDP 模拟消费者行为

一旦程序的 RL 部分在第 1 个单元格,第 2 个单元格训练完成后,Step 1B Applying: Dataset Pipeline Simulation with MDP将模拟 YouTube 观众在几个月内的行为。它还将包括类似的观众档案,使总共模拟了 10,000 个视频观看序列。

第 2 个单元格开始创建kant.txt文件,该文件将用于训练 KantaiBERT 转换器模型:

""" Simulating a decision-making process"""
f = open("kant.txt", "w") 

然后引入实体(顶点):

conceptcode=["A","B","C","D","E","F"]
Now the number of sequences is set to 10,000:
maxv=10000 

该函数选择一个名为origin的随机起始顶点:

origin=ql.random.randint(0,6) 

该程序使用训练好的矩阵从原点选择任何域的最佳序列。在本例中,我们假设它们是一个人喜欢的歌手,如以下示例:

`FBDC EDC EDC DC BDC AEDC AEDC BDC BDC AEDC BDC AEDC EDC BDC AEDC DC AEDC DC…/…` 

一旦计算出 10,000 个序列,kant.txt将包含转换器的数据集。

使用kant.txt,程序的剩余部分与第四章中描述的KantaiBERT.ipynb中相同。

转换器现在已准备好进行推荐。

提出建议

第四章中,KantaiBERT.ipynb包含以下掩码序列:

fill_mask("Human thinking involves human<mask>.") 

此序列是特定的,并与伊曼纽尔·康德的作品相关。此笔记本具有可用于任何领域的通用数据集。

在这个笔记本中,输入为:

fill_mask("BDC<mask>.") 

输出包含重复项。需要一个清理函数来过滤它们,以获得两个非重复序列:

[{'score': 0.00036507684853859246,
  'sequence': 'BDC FBDC.',
  'token': 265,
  'token_str': ' FBDC'},
 {'score': 0.00023987806343939155,
  'sequence': 'BDC DC.',
  'token': 271,
  'token_str': ' DC'}] 

序列是有意义的。有时观众会观看相同的视频,有时不会。行为可能是混乱的。这就是机器学习和人工智能如何应用于超人类的地方。

超人类推荐系统

一旦序列生成,它们将被转换回自然语言用于用户界面。这里的超人指的是一个接受大量特征的推荐系统,比如:

  • 超过人类的推理能力,具有如此多的参数

  • 比人类能做出更准确的预测

这些实用的超人在这个语境下还不是数字化的人类,而是强大的计算工具。我们将在元宇宙中人类和 AI 联合驾驶员部分详细介绍数字意义上的超人。

例如,BDC 序列可能是歌手B的歌曲,然后是歌手D的歌曲,然后是P喜欢的歌手C的歌曲。

一旦序列转换为自然语言,就会出现几种可能的选项:

  • 该序列可以发送给一个机器人或者数字化人类。

    当一项新兴技术出现时,赶紧跳上这列列车,并一同享受吧!你将会了解这项技术,并与之一同发展。你可以搜索其他超人平台。无论如何,通过学习如何规避限制并找到使用新技术的方式,你都可以保持在前沿。

  • 你可以在等待 API 时使用超人做一个教育视频。

  • 一个超人可以作为语音信息被插入到界面中。例如,在车上使用谷歌地图时,你听到的是声音。它听起来像是一个人类。有时我们甚至会误以为它是一个人,但其实不是。它是一个机器。

  • 它也可以是亚马逊中的看不见的内嵌建议。它会提供建议,引导我们做微观决策。它会像销售员一样影响我们。它是一个看不见的超人。

在这种情况下,通用序列由 MDP 创建,并由 RoBERTa transformer 进行训练。这表明 transformers 可以应用于任何类型的序列。

让我们看看 transformers 如何应用于计算机视觉。

计算机视觉

这本书是关于自然语言处理,而不是计算机视觉。然而,在前一节中,我们实现了一个可以应用于许多领域的通用序列。计算机视觉就是其中之一。

Dosovitskiy等人(2021)的文章标题就把一切都说清楚了: 一张图片价值 16x16 个词:大规模图像识别的 Transformer。作者将一张图片处理为序列。结果证明了他们的观点。

谷歌已经在 Colaboratory 笔记本中提供了视觉 transformers。在本书的 GitHub 代码库的Chapter16目录中打开Vision_Transformer_MLP_Mixer.ipynb

打开Vision_Transformer_MLP_Mixer.ipynb包含了一个在JAX()中的 transformer 计算机视觉模型。JAX 结合了 Autograd 和 XLA。JAX 可以区分 Python 和 NumPy 函数。JAX 通过使用编译技术和并行化来加速 Python 和 NumPy。

笔记本是自说明的。您可以探索它以了解它的工作原理。然而,请记住,当工业 4.0 成熟并进入工业 5.0 时,最佳实现将通过在云 AI 平台上集成您的数据来实现。本地开发将减少,公司将转向云 AI,而不必承担本地开发、维护和支持的成本。

笔记本的目录包含我们在本书中已经多次经历的Transformers过程。然而,这一次,它仅应用于数字图像信息的序列:

图形用户界面,应用程序 描述自动生成

图 16.18: 我们的视觉Transformers笔记本

笔记本遵循标准的深度学习方法。它显示了一些带有标签的图片:

# Show some images with their labels.
images, labels = batch['image'][0][:9], batch['label'][0][:9]
titles = map(make_label_getter(dataset), labels.argmax(axis=1))
show_img_grid(images, titles) 

图形用户界面 描述自动生成,置信度中等

图 16.19: 带有标签的图像

本章中的图像来自从小图像中学习多层特征Alex Krizhevsky,2009:https://www.cs.toronto.edu/kriz/learning-features-2009-TR.pdf。它们是`CIFAR-10`和`CIFAR-100`数据集的一部分(`toronto.edu`):https://www.cs.toronto.edu/kriz/cifar.html。

笔记本包含标准的Transformers过程,然后显示训练图片:

# Same as above, but with train images.
# Note how images are cropped/scaled differently.
# Check out input_pipeline.get_data() in the editor at your right to see how the
# images are preprocessed differently.
batch = next(iter(ds_train.as_numpy_iterator()))
images, labels = batch['image'][0][:9], batch['label'][0][:9]
titles = map(make_label_getter(dataset), labels.argmax(axis=1))
show_img_grid(images, titles) 

包含屏幕截图的图片 描述自动生成

图 16.20: 训练数据

Transformers程序可以对随机图片进行分类。将最初设计用于自然语言处理的Transformers模型用于通用序列推荐器,然后用于计算机视觉,似乎是一种奇迹。然而,我们只是开始探索序列训练的泛化。

模型的简单性令人惊讶!视觉Transformers依赖于Transformers的架构。它不包含卷积神经网络的复杂性。然而,它产生了可比较的结果。

现在,机器人和机器人可以配备Transformers模型,以理解语言并解释图像以了解周围的世界。

视觉Transformers可以在超人类和元宇宙中实现。

元宇宙中的人类和人工智能联合驾驶员

人类和超人工智能正在融入元宇宙。探索元宇宙超出了本书的范围。本书提供的工具箱展示了通往由人类和超人工智能构成的元宇宙的路径。

头像、计算机视觉和视频游戏体验将使我们与他人的交流沉浸式。我们将从看手机转变为与他人在同一地点。

从看到到变成

从看到变成是自然的过程。我们发明了计算机,加上了屏幕,然后发明了智能手机,现在使用应用程序进行视频会议。

现在我们可以进入虚拟现实进行各种类型的会议和活动。

例如,我们将在智能手机上使用 Facebook 的元宇宙,感觉就像在与见面的人(个人和专业人士)身处相同的地点。感受到的存在无疑将是智能手机通信的一次重大进化。

感受到的存在在某个地方与在手机上看着小屏幕很不一样。

元宇宙将使不可能变为可能:太空漫步,在巨浪上冲浪,在森林散步,拜访恐龙,以及我们想象的其他任何地方。

是的,人工智能有局限性、危险、威胁,以及与人类技术相关的一切。然而,正如我们在内容过滤中所看到的那样,我们可以使用 AI 来控制 AI。

本书中的Transformers工具结合新兴的元宇宙技术将让我们真正到达另一个世界。

充分利用你在本书中学到的知识和技能,在元宇宙或现实世界中创造你的道德未来。

总结

本章描述了 AI 副驾驶机器人的崛起,具有人类决策水平的能力。工业 4.0 已经打开了机器互联的大门。机器之间的微决策将加快交易速度。AI 副驾驶机器人将提高我们在各个领域的生产力。

我们看到如何使用 OpenAI Codex 在编码时生成源代码,甚至可以使用自然语言指令。

我们利用 MDP 程序生成的数据集来训练一个 RoBERTa Transformers模型,构建了基于Transformers的推荐系统。数据集结构是一个多用途序列模型。因此,元人类可以获得多领域的推荐功能。

接着,本章展示了视觉Transformers如何将图像分类为信息序列进行处理。

最后,我们看到元宇宙将通过元人类界面使推荐变得可见,或者在社交媒体中深度嵌入功能中变得不可见,例如。

Transformers已经涌现出创新的副驾驶机器人和模型,进入一个极其复杂的新时代。这个旅程将是具有挑战性和令人兴奋的!

问题

  1. 不存在可以自动生成代码的 AI 副驾驶机器人。(True/False)

  2. AI 副驾驶机器人永远不会取代人类。(True/False)

  3. GPT-3 引擎只能做一项任务。(True/False)

  4. Transformers可以被训练成推荐者。(True/False)

  5. Transformers只能处理语言。(True/False)

  6. 一个Transformers序列只能包含单词。(True/False)

  7. 视觉Transformers无法与 CNN 相提并论。(True/False)

  8. 具有计算机视觉的 AI 机器人不存在。(True/False)

  9. 自动产生 Python 源代码是不可能的。(True/False)

  10. 也许有一天我们会成为机器人的副驾驶员。(True/False)

参考文献

加入我们书籍的 Discord 空间

加入书籍的 Discord 工作空间,与作者一起参加每月的 Ask me Anything 会话:

https://www.packt.link/Transformers

附录 I:Transformers模型术语

过去几十年产生了卷积神经网络CNNs)、循环神经网络RNNs)和更多类型的人工神经网络ANNs)。它们都有一定数量的共同词汇。

当应用于Transformers时,Transformers模型引入了一些新词汇,并略微不同地使用现有词汇。本附录简要描述了Transformers模型,以澄清深度学习词汇在应用于Transformers时的使用情况。

Transformers模型架构的动机取决于深度学习的工业化方法。Transformers的几何特性增强了并行处理。此外,Transformers的架构完全符合硬件优化要求。例如,谷歌利用Transformers的堆栈结构设计了领域特定的优化硬件,需要较少的浮点数精度。

设计Transformers模型意味着考虑硬件。因此,Transformers的架构从一开始就结合了软件和硬件优化。

本附录定义了一些神经网络语言的新用法。

堆栈

一个堆栈包含大小相同的层,与经典的深度学习模型不同,如图 I.1所示。一个堆栈从底部到顶部运行。堆栈可以是编码器或者解码器。

图 I.1:层形成一个堆栈

Transformers堆栈随着升高而学习并看到更多。每一层将其学到的内容传递给下一层,就像我们的记忆一样。

想象一下,堆栈就像纽约市的帝国大厦。在底部,你看不到太多。但是当你升上更高层的办公室并透过窗户望出去时,你将看到更多,更远的景色。最后,在顶部,你将拥有一个美妙的曼哈顿景色!

子层

每个层包含子层,如图 I.2所示。不同层的每个子层具有相同的结构,这有助于硬件优化。

原始Transformers包含从底部到顶部运行的两个子层:

  • 自注意力子层,专为自然语言处理和硬件优化而设计

  • 一种经过一些调整的经典前馈网络

图 I.2:一个层包含两个子层

注意头部

自注意力子层被分为 n 个独立和相同的层,称为头部。例如,原始Transformers包含八个头部。

图 I.3将头部表示为处理器,以显示Transformers的工业化结构适合硬件设计:

包含文字的图片,自动生成描述

图 I.3:自注意力子层包含头部

注意,图 I.3中的注意头部被表示为微处理器,以突出Transformers架构的并行处理能力。

transformer 结构适用于自然语言处理和硬件优化需求。

加入我们书的 Discord 空间

加入该书的 Discord 工作区,与作者一起参加每月的问我任何事活动:

www.packt.link/Transformers

附录 II:对Transformers模型的硬件约束

Transformer 模型无法没有优化的硬件存在。内存和硬盘管理设计仍然是关键组成部分。然而,计算能力仍然是先决条件。要训练第二章中描述的原始 Transformer 几乎是不可能的,开始使用 Transformer 模型架构,没有 GPU。GPU 处于高效Transformers模型的战斗的中心。

这个附录将引导您在三个步骤中了解 GPU 的重要性:

  • Transformers的架构和规模

  • CPU 与 GPU

  • 在 PyTorch 中实现 GPU,作为任何其他优化语言优化的示例

Transformers的架构和规模

关于硬件驱动设计的线索出现在第二章开始使用 Transformer 模型架构多头关注的架构部分中:

“然而,通过分析具有一个 d[model] 块的序列,我们只会一次得到一个观点。此外,要找到其他观点需要相当长的计算时间。

一个更好的方法是将每个单词 x(一个序列的所有单词)的 d[model] = 512 维分成 8 个 d[k] = 64 维。

然后我们可以并行运行这 8 个“头部”,加快训练速度,并获得关于每个单词如何与另一个单词相关的 8 个不同的表示子空间:

包含表格描述的图像

图 II.1:多头表示

您现在可以看到有 8 个头并行运行。

我们可以很容易地看出,强迫注意力头学习 8 种不同角度的动机。然而,深入挖掘原始 8 个注意力头并行执行不同计算的动机直接导致硬件优化。

Brown等人(2020 年)在语言模型——少量训练者中,arxiv.org/abs/2005.14165,描述了他们如何设计 GPT 模型。他们证实Transformers架构是硬件驱动的。

我们将模型跨 GPUs 进行分区,同时沿深度和宽度维度,以最小化节点间的数据传输。每个模型的精确结构参数基于跨 GPU 模型布局中的计算效率和负载平衡而选择。

Transformer 在构造(编码器和解码器)和大小上有所不同。但它们都有需要并行处理的硬件约束。我们需要进一步了解为什么 GPU 如此特殊。

为什么 GPU 如此特殊

第二章开始使用 Transformer 模型架构多头关注的架构部分中出现了 GPU 驱动设计的线索。

注意力被定义为“缩放点积注意力”,用以下方程表示,我们将 QKV 带入其中:

我们现在可以得出以下结论:

  • 注意力头(Attention heads)是为并行计算设计的。

  • 注意力头基于matmul,矩阵乘法。

GPU 是为并行计算而设计的。

CPU中央处理单元)被优化用于串行处理。但如果我们通过串行处理来运行注意力头,那么训练一个有效的 Transformer 模型将需要更长的时间。非常小的教育型 Transformer 可以在 CPU 上运行。但是,它们不符合最先进模型的标准。

GPU图形处理单元)是专为并行处理而设计的。Transformer 模型是为并行处理(GPU)而设计的,而不是串行处理(CPU)

GPU 也是为矩阵乘法而设计的。

例如,NVIDIA GPU 包含加速矩阵操作的张量核心。包括 Transformer 模型在内的大部分人工智能算法使用矩阵操作。NVIDIA GPU 包含大量用于矩阵操作的硬件优化。以下链接提供了更多信息:

谷歌的张量处理单元TPU)是 NVIDIA GPU 的等价物。使用 TPU 时,TensorFlow 将优化张量的使用。

BERT[BASE](110M 参数)最初是使用 16 个 TPU 芯片进行训练的。BERT[LARGE](340M 参数)是使用 64 个 TPU 芯片进行训练的。有关训练 BERT 的更多信息,请参见arxiv.org/abs/1810.04805

我们已经确定了 Transformer 的架构完全符合并行硬件的约束条件。我们仍然需要解决在 GPU 上运行源代码的问题。

在代码中实现 GPU

PyTorch,以及其他语言和框架,管理着 GPU。PyTorch 包含张量(tensors),就像 TensorFlow 一样。张量可能看起来像 NumPy np.arrays()。然而,NumPy 不适合并行处理。张量使用 GPU 的并行处理特性。

在 PyTorch 中,张量(Tensors)打开了在 GPU 上分布式数据的大门,以及其他框架:pytorch.org/tutorials/intermediate/ddp_tutorial.html

Chapter03笔记本BERT_Fine_Tuning_Sentence_Classification_GPU.ipynb中,我们使用CUDA(Compute Unified Device Architecture)与 NVIDIA GPU 通信。CUDA 是 NVIDIA 平台上的通用计算平台。特定的指令可以添加到我们的源代码中。更多信息,请参见developer.nvidia.com/cuda-zone

Chapter03笔记本中,我们使用 CUDA 指令将我们的模型和数据传输到 NVIDIA GPU 上。PyTorch有一个指令来指定我们希望使用的设备:torch.device

更多信息,请参见pytorch.org/docs/stable/notes/cuda.html

我们将解释device以说明 PyTorch 和一般程序中 GPU 的实现。让我们重点关注选择设备、数据并行性、将模型加载到设备和将批次数据添加到设备上。每个项目符号都包含了设备的使用方式和BERT_Fine_Tuning_Sentence_Classification_GPU.ipynb中的单元格号:

  • 选择设备(Cell 3)

    程序检查 CUDA 是否可用于 NVIDIA GPU。如果没有,设备将是 CPU:

    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    !nvidia-smi 
    
  • 数据并行(Cell 16)

    如果有多个 GPU 可用,则可以将模型分布到几个 GPU 上进行并行计算:

    model = BertForSequenceClassification.from_pretrained("bert-base-uncased", num_labels=2)
    model = nn.DataParallel(model) 
    
  • 将模型加载到设备上(cell 16)

    模型被发送到设备:

     model.to(device) 
    
  • 将批次添加到设备(cell 20)用于训练和验证数据

    数据批次被添加到可用的 GPU(1n)中:

    # Add batch to GPU
    batch = tuple(t.to(device) for t in batch) 
    

在接下来的部分中,我描述了我进行的测试,以说明使用 GPU 来运行一个包含三个运行时配置的章节笔记本的Transformers模型的用法。

使用 Google Colab 测试 GPU

在本节中,我描述了我进行的非正式测试,以说明 GPU 的潜力。我们将使用相同的Chapter03笔记本:BERT_Fine_Tuning_Sentence_Classification_GPU.ipynb

我在三种情况下运行了笔记本:

  • 带 CPU 的免费 Google Colab

  • 带 GPU 的免费 Google Colab

  • Google Colab Pro

带 CPU 的免费 Google Colab

在 CPU 上几乎不可能微调或训练一个拥有数百万或数十亿参数的Transformers模型。CPU 大多是顺序的。Transformers模型是为并行处理而设计的。

运行时菜单和更改运行时类型子菜单中,您可以选择硬件加速器:无(CPU)GPUTPU

这个测试是在无(CPU)下运行的,如图 II.2所示:

图形用户界面、文本、应用、聊天或文本消息 自动生成的描述

图 II.2:选择硬件加速器

当笔记本进入训练循环时,从一开始就会减慢速度:

图 II.3:训练循环

经过 15 分钟,实际上什么都没有发生。

CPU 并不是为并行处理而设计的。Transformers模型是为并行处理而设计的,所以除了玩具模型之外,它们需要 GPU。

带 GPU 的免费 Google Colab

让我们回到笔记本设置中选择一个GPU

包含文本描述的图像

图 II.4 选择 GPU

在写作时,我测试了 Google Colab,并且 VM 配备了带有 CUDA 11.2 的 NVIDIA K80:

自动生成的表格描述

图 II.5:激活了 NVIDIA K80 GPU

训练循环正常进行,持续约 20 分钟。然而,截至测试时(2021 年 11 月),Google Colab VMs 并不提供多于一个 GPU。GPU 价格昂贵。无论如何,图 II.6显示,训练循环在合理的时间内完成:

自动生成的文本描述

图 II.6:配备 K80 GPU 的训练循环

我发现测试 Google Colab Pro 是否提供更快的 GPU 很有趣。

Google Colab Pro 配备了 GPU

通过 Google Colab 提供的 VM 配备了 NVIDIA P100 GPU,如图 II.7所示。这很有趣,因为原始 Transformer 训练时,根据 Vaswani 等人(2017)《关注力就是你所需的一切》,用了 8 个 NVIDIA P100s,用了 12 小时来训练具有 10⁶×65 个参数的基础模型,并且使用了 8 个 GPU:

具有中等置信度自动生成的表描述

图 II.7:Google Colab Pro VM 配备了 P100 GPU

训练循环时间大大缩短,持续时间不到 10 分钟,如图 II.8所示:

自动生成的文本描述

图 II.8:配备 P100 GPU 的训练循环

加入我们书籍的 Discord 空间

加入该书的 Discord 空间,与作者进行每月的 问我任何事 专题讨论会:

www.packt.link/Transformers

附录 III:使用 GPT-2 进行通用文本完成

这个附录是第七章GPT-3 引擎与超人类Transformers崛起使用 GPT-2 进行通用文本完成一节的详细解释。这一节描述了如何实现 GPT-2 Transformers模型来完成通用文本。

你可以直接在第七章中阅读这本笔记本的用法,或者在附录中构建程序并运行它,以更深入地了解 GPT 模型的工作原理。

我们将克隆 OpenAI_GPT_2 代码库,下载 345M 参数的 GPT-2 Transformers模型,并与其交互。我们将输入上下文句子,并分析Transformers生成的文本。目标是看看它如何创建新内容。

这一部分分为九个步骤。在 Google Colaboratory 中打开 OpenAI_GPT_2.ipynb。这个笔记本在本书的 GitHub 代码库的 AppendixIII 目录中。你会注意到笔记本也被分成了和本节相同的九个步骤和单元格。

逐步运行笔记本的单元格。这个过程很枯燥,但克隆 OpenAI GPT-2 代码库产生的结果是令人满意的。我们看到我们可以用几行代码运行一个 GPT-3 引擎。但是这个附录给了你机会,即使代码不再被优化,也可以看到 GPT-2 模型是如何工作的。

Hugging Face 有一个封装 GPT-2 模型的包装器。作为 OpenAI API 的一个替代方案很有用。然而,在这个附录中的目标不是为了避免 GPT-2 模型底层组件的复杂性,而是为了探索它们!

最后,重要的是我们正在运行一个低级别的 GPT-2 模型,而不是一个一行代码调用即可获得结果的简易版本(OpenAI GPT-3 API,Hugging Face 封装等)。我们正在从零开始理解 GPT-2 的架构,所以可能会收到一些弃用消息。但这样的努力值得成为 4.0 工业人工智能专家。

让我们开始激活 GPU。

第 1 步:激活 GPU

我们必须激活 GPU 来训练我们的 GPT-2 345M 参数Transformers模型。

要激活 GPU,请进入 笔记本设置 中的 运行时 菜单以充分利用 VM:

图 III.1:GPU 硬件加速器

我们可以看到激活 GPU 是更好性能的先决条件,这将让我们进入 GPT Transformers的世界。所以现在让我们克隆 OpenAI 的 GPT-2 代码库。

第 2 步:克隆 OpenAI GPT-2 代码库

目前 OpenAI 仍然允许我们下载 GPT-2。这种方式可能在将来被停止,或者可能我们会获得更多资源。此时,Transformers的发展和使用速度如此之快,以至于没人能预见市场会如何发展,即使是主要的研究实验室自己也不行。

我们将在 VM 上克隆 OpenAI 的 GitHub 目录:

#@title Step 2: Cloning the OpenAI GPT-2 Repository
!git clone https://github.com/openai/gpt-2.git 

克隆结束后,您应该在文件管理器中看到该代码库的出现:

图 III.2: 克隆的 GPT-2 存储库

点击 src,您会看到我们从 OpenAI 安装的运行模型所需的 Python 文件:

图 III.3: 运行模型的 GPT-2 Python 文件

您会发现我们没有需要的 Python 训练文件。在 附录 IV用 GPT-2 训练语言模型 部分 自定义文本完成与 GPT-2中训练 GPT-2 模型时,我们将安装它们。

现在让我们安装所需的内容。

步骤 3: 安装要求

要自动安装所需的内容:

#@title Step 3: Installing the requirements
import os          # when the VM restarts import os necessary
os.chdir("/content/gpt-2")
!pip3 install -r requirements.txt 

逐个单元格运行时,我们可能需要重新启动虚拟机,然后再次导入os

本笔记本的要求是:

  • Fire 0.1.3 用于生成命令行界面CLIs

  • regex 2017.4.5 用于正则表达式使用

  • Requests 2.21.0,一个 HTTP 库

  • tqdm 4.31.1 用于显示循环的进度条

可能会要求您重新启动笔记本。

现在不要重新启动它让我们等到检查 TensorFlow 的版本

步骤 4: 检查 TensorFlow 的版本

OpenAI 提供的 GPT-2 345M Transformers模型使用 TensorFlow 1.x。这将在运行程序时导致几个警告。但是,我们将忽略它们,并在我们的普通机器上以全速运行训练 GPT 模型的薄冰上。

在 2020 年代,GPT 模型已经达到了 1750 亿个参数,使我们在没有超级计算机的情况下无法高效地进行训练。参数的数量只会继续增加。

企业巨头的研究实验室,例如 Facebook AI、OpenAI 和 Google Research/Brain,正在加速转向超级Transformers,并且正在留下一些供我们学习和理解的东西。但是,不幸的是,他们没有时间回头更新他们分享的所有模型。然而,我们还有这个笔记本!

TensorFlow 2.x 是最新的 TensorFlow 版本。然而,旧程序仍然可能有所帮助。这就是为什么 Google Colaboratory VMs 预先安装了 TensorFlow 1.x 和 TensorFlow 2.x 的版本的一个原因。

我们将在此笔记本中使用 TensorFlow 1.x:

#@title Step 4: Checking the Version of TensorFlow 
#Colab has tf 1.x and tf 2.x installed
#Restart runtime using 'Runtime' -> 'Restart runtime...'
%tensorflow_version 1.x
import tensorflow as tf
print(tf.__version__) 

输出应该是:

TensorFlow 1.x selected.
1.15.2 

无论是否显示tf 1.x版本,请重新运行单元格以确保,然后重新启动虚拟机。在继续之前重新运行此单元格以确保

如果在过程中遇到 TensforFlow 错误(忽略警告),请重新运行此单元格,重新启动虚拟机,确保重新运行。

每次重新启动虚拟机时都要做这个。虚拟机的默认版本是 tf.2

我们现在准备下载 GPT-2 模型。

步骤 5: 下载 345M 参数 GPT-2 模型

我们现在将下载训练好的 345M 参数 GPT-2 模型:

#@title Step 5: Downloading the 345M parameter GPT-2 Model
# run code and send argument
import os # after runtime is restarted
os.chdir("/content/gpt-2")
!python3 download_model.py '345M' 

模型目录的路径是:

/content/gpt-2/models/345M

它包含我们运行模型所需的信息:

图 III.4: 345M 参数模型的 GPT-2 Python 文件

hparams.json 文件包含了 GPT-2 模型的定义:

  • "n_vocab": 50257,模型词汇表的大小

  • "n_ctx": 1024,上下文大小

  • "n_embd": 1024,嵌入大小

  • "n_head": 16,头的数量

  • "n_layer": 24,层数

encoder.jsonvacab.bpe 包含了标记化的词汇表和 BPE 单词对。如有必要,请花几分钟时间返回并阅读第 3 步: 训练一个分词器子节,第四章从零开始预训练 RoBERTa 模型

checkpoint 文件包含了检查点时的训练参数。例如,它可能包含了 1,000 步的训练参数,就像我们在第 9 步: 训练 GPT-2 模型章节的附录 IV中,使用 GPT-2 进行自定义文本完成部分将要做的那样。

checkpoint 文件与其他三个重要文件保存在一起:

  • model.ckpt.meta 描述了模型的图结构。它包含GraphDefSaverDef等。我们可以使用tf.train.import_meta_graph([path]+'model.ckpt.meta')检索信息。

  • model.ckpt.index 是一个字符串表。键包含张量的名称,值是BundleEntryProto,其中包含张量的元数据。

  • model.ckpt.data 包含TensorBundle collection中所有变量的值。

我们已经下载了我们的模型。现在我们将在激活模型之前经历一些中间步骤。

步骤 6-7: 中间指令

在本节中,我们将经历步骤 677a,这些是通向步骤 8的中间步骤,其中我们将定义和激活模型。

在与模型交互时,我们希望将 UTF 编码的文本打印到控制台:

#@title Step 6: Printing UTF encoded text to the console
!export PYTHONIOENCODING=UTF-8 

我们要确保我们在src目录下:

#@title Step 7: Project Source Code
import os # import after runtime is restarted
os.chdir("/content/gpt-2/src") 

我们已经准备好与 GPT-2 模型交互。我们可以直接运行它,就像我们在附录 IV中的使用 GPT-2 进行语言模型训练部分将要做的那样。然而,在本节中,我们将讨论代码的主要方面。

interactive_conditional_samples.py 首先导入与模型交互所需的必要模块:

#@title Step 7a: Interactive Conditional Samples (src)
#Project Source Code for Interactive Conditional Samples:
# /content/gpt-2/src/interactive_conditional_samples.py file 
import json
import os
import numpy as np
import tensorflow as tf 

我们已经经历了激活模型的中间步骤。

步骤 7b-8: 导入并定义模型

现在我们将使用interactive_conditional_samples.py激活与模型的交互。

我们需要导入三个同时也在 /content/gpt-2/src中的模块:

import model, sample, encoder 

这三个程序是:

  • model.py 定义了模型的结构: 超参数,多头tf.matmul操作,激活函数以及所有其他属性。

  • sample.py 处理交互并控制将生成的样本。它确保标记更有意义。

    Softmax 值有时可能模糊不清,就像在低清晰度下查看图像。sample.py 包含一个名为temperature的变量,将使值更清晰,增加更高的概率并软化更低的概率。

    sample.py 可以激活 Top-k采样。Top-k采样对预测序列的概率分布进行排序。分布的头部具有较高的概率值,排除掉尾部具有较低概率的部分,以防止模型预测低质量的标记。

    sample.py 也可以激活用于语言建模的 Top-p采样。Top-p采样不对概率分布进行排序。相反,它选择具有较高概率的词,直到此子集的概率之和或可能序列的核心超过 p

  • encoder.py 使用定义好的模型 encoder.jsonvocab.bpe 对样本序列进行编码。它既包含了一个 BPE 编码器,又包含了文本解码器。

你可以双击打开这些程序来进一步探索它们。

interactive_conditional_samples.py 将调用所需的函数与模型进行交互,以初始化以下信息:来自 model.py 定义模型的超参数,以及来自 sample.py 的样本序列参数。它将使用 encode.py 进行编码和解码序列。

interactive_conditional_samples.py 将恢复本节的 第 5 步:下载 345M 参数 GPT-2 模型 子部分中定义的检查点数据。

你可以双击打开interactive_conditional_samples.py并尝试调整其参数:

  • model_name 是模型名称,如 "124M""345M,",依赖于 models_dir

  • models_dir 定义包含模型的目录。

  • seed 为随机生成器设置一个随机整数。可以设置种子以重现结果。

  • nsamples 是要返回的样本数。如果设置为 0,它将继续生成样本,直到你双击单元格的 run 按钮或按下 Ctrl + M

  • batch_size 决定了批处理的大小,对内存和速度有影响。

  • length 是生成文本的标记数。如果设置为 none,则依赖于模型的超参数。

  • temperature 决定了 Boltzmann 分布的级别。如果温度很高,完成结果将更加随机。如果温度很低,结果将变得更加确定。

  • top_k 控制 Top-k在每一步考虑的标记数。 0表示没有限制。推荐值为 40

  • top_p 控制 Top-p

对于本节中的程序,我们刚刚探索的参数场景将是:

  • model_name = "345M"

  • seed = None

  • nsamples = 1

  • batch_size = 1

  • length = 300

  • temperature = 1

  • top_k = 0

  • models_dir = '/content/gpt-2/models'

这些参数将影响模型的行为,它如何受到上下文输入的条件影响,并生成文本完成序列。首先使用默认值运行笔记本。然后,您可以通过双击程序,编辑它并保存它来更改代码的参数。在每次重新启动 VM 时将删除更改。如果您希望创建交互场景,请保存程序并重新加载它。

程序现在已准备好提示我们与其交互。

步骤 9:与 GPT-2 交互

在本节中,我们将与 GPT-2 345M 模型交互。

系统运行时会有更多消息,但只要 Google Colaboratory 保持 tf 1.x,我们就会使用此笔记本运行模型。如果这本笔记本过时了,我们可能会有一天不得不使用 GPT-3 引擎,或者例如使用 Hugging Face GPT-2 包装器,未来它可能也会被弃用。

与此同时,GPT-2 仍在使用,所以让我们与模型交互吧!

要与模型交互,请运行 interact_model 单元格:

#@title Step 9: Interacting with GPT-2
interact_model('345M',None,1,1,300,1,0,'/content/gpt-2/models') 

将提示您输入一些上下文:

图 III.5:用于文本完成的上下文输入

由于这是一个标准的 GPT-2 模型,您可以尝试任何类型的上下文。

我们可以尝试以艾曼纽尔·康德(Emmanuel Kant)的句子开头:

`Human reason, in one sphere of its cognition, is called upon to`
`consider questions, which it cannot decline, as they are presented by`
`its own nature, but which it cannot answer, as they transcend every`
`faculty of the mind.` 

按下 Enter 键生成文本。由于 GPT-2 模型没有在我们的数据集上训练,而且我们正在运行一个随机模型,输出将相对随机。

让我们看看我运行模型时生成的前几行内容:

"We may grant to this conception the peculiarity that it is the only causal logic. 
In the second law of logic as in the third, experience is measured at its end: apprehension is afterwards closed in consciousness.
The solution of scholastic perplexities, whether moral or religious, is not only impossible, but your own existence is blasphemous." 

要停止单元格,请双击单元格的运行按钮。

您还可以按 Ctrl + M 停止生成文本,但它可能会将代码转换为文本,您将不得不将其复制回程序单元格。

输出内容丰富。我们可以观察到几个事实:

  • 我们输入的上下文 条件化 了模型生成的输出。

  • 上下文是模型的演示。它从模型中学到了要说的话,而没有修改其参数。

  • 文本完成受上下文影响。这为不需要微调的转换器模型打开了大门。

  • 从语义的角度来看,输出可能更有趣。

  • 从语法的角度来看,输出是令人信服的。

您可以通过阅读 附录 IV使用 GPT-2 进行自定义文本完成,看看我们是否可以通过在自定义数据集上训练模型获得更令人印象深刻的结果。

参考资料

加入我们书籍的 Discord 空间

加入书籍的 Discord 工作空间,与作者进行每月的 问我任何 会话:

www.packt.link/Transformers

附录 IV:使用 GPT-2 进行自定义文本完成

这个与第七章相关的附录,GPT-3 引擎崛起的超人类变形车,描述了如何使用 GPT-2 模型定制文本完成。

本附录展示了如何构建、训练 GPT-2 模型,并在 12 个步骤中与自定义文本进行交互。

打开本附录的 GitHub 仓库中的Training_OpenAI_GPT_2.ipynb。您会注意到笔记本也被分成了与本附录相同的 12 个步骤和单元格。

逐步运行笔记本中的每个单元格。这个过程是单调乏味的,但克隆 OpenAI GPT-2 仓库产生的结果是令人满意的。我们不会使用 GPT-3 API 或 Hugging Face 包装器。

我们会忙于了解模型是如何构建和训练的。您会看到一些弃用消息,但我们需要进入模型内部,而不是包装器或 API。然而,这个努力是值得的。

让我们开始激活 GPU。

训练 GPT-2 语言模型

在本节中,我们将在一个自定义数据集上训练一个 GPT-2 模型,然后与我们定制的模型进行交互。我们将使用与第四章中相同的kant.txt数据集,从头开始预训练 RoBERTa 模型

我们将逐步打开笔记本并运行每个单元格。

步骤 1:先决条件

本节中提到的文件可以在本书的 GitHub 仓库的AppendixIV目录中找到:

  • 如果您在 Google Colab 上运行它,请在 Google Colab 的笔记本运行时菜单中启用 GPU,就像附录 III第 1 步:激活 GPU中所解释的那样。

  • 使用内置文件管理器将以下 Python 文件上传到 Google Colaboratory:train.pyload_dataset.pyencode.pyaccumulate.pymemory_saving_gradients.py

  • 这些文件最初来自N Shepperd的 GitHub 仓库:github.com/nshepperd/gpt-2。但是,您可以从本书的 GitHub 仓库的AppendixIV\``gpt-2-train_files目录中下载这些文件。

  • N Shepperd的 GitHub 仓库提供了训练我们的 GPT-2 模型所需的文件。我们不会克隆N Shepperd的仓库,而是将从N Shepperd的仓库中获取的五个训练文件添加到 OpenAI 的仓库中。

  • 用内置文件管理器将dset.txt上传到 Google Colaboratory。数据集被命名为dset.txt,这样在阅读本附录后,您可以用自定义输入替换其内容而无需修改程序。

  • 这个数据集位于本附录的 GitHub 仓库中的gpt-2-train_files目录中。这是第四章中使用的kant.txt数据集,从头开始预训练 RoBERTa 模型

我们现在将逐步进行训练过程的初始步骤。

第 2 至第 6 步:训练过程的初始步骤

本小节将仅简要介绍步骤 2 到 6,因为我们在附录 III使用 GPT-2 进行通用文本补全中对其进行了详细描述。然后我们将把数据集和模型复制到项目目录中。

该程序现在克隆 OpenAI 的 GPT-2 仓库,而不是N Shepperd的仓库:

#@title Step 2: Cloning the OpenAI GPT-2 Repository
#!git clone https://github.com/nshepperd/gpt-2.git
!git clone https://github.com/openai/gpt-2.git 

我们已经从N Shepperd的目录中上传了训练 GPT-2 模型所需的文件。

程序现在安装所需软件:

#@title Step 3: Installing the requirements
import os             #when the VM restarts import os necessary
os.chdir("/content/gpt-2")    
!pip3 install -r requirements.txt 

该笔记本需要toposort,这是一种拓扑排序算法:

!pip install toposort 

安装完所需软件后,请不要重新启动笔记本。相反,请等待直到您检查了 TensorFlow 版本,在您的会话期间只重新启动虚拟机一次。之后,如果有必要,则重新启动。深入了解代码而不仅仅是包装和 API 是繁琐但值得的。

现在我们检查 TensorFlow 版本,以确保我们正在运行tf 1.x版本:

#@title Step 4: Checking TensorFlow version
#Colab has tf 1.x , and tf 2.x installed
#Restart runtime using 'Runtime' -> 'Restart runtime...'
%tensorflow_version 1.x
import tensorflow as tf
print(tf.__version__) 

无论显示了tf 1.x版还是没有,请重新运行该单元格以确保,重新启动虚拟机,并重新运行该单元格。这样,您可以确保您正在运行带有tf 1.x的虚拟机。

该程序现在会下载我们将与我们的数据集训练的 117M 参数的 GPT-2 模型:

#@title Step 5: Downloading 117M parameter GPT-2 Model
# run code and send argument
import os # after runtime is restarted
os.chdir("/content/gpt-2")
!python3 download_model.py '117M' #creates model directory 

我们将复制数据集和 117M 参数的 GPT-2 模型到src目录中:

#@title Step 6: Copying the Project Resources to src
!cp /content/dset.txt /content/gpt-2/src/
!cp -r /content/gpt-2/models/ /content/gpt-2/src/ 

目标是将我们训练模型所需的所有资源分组到src项目目录中。

现在我们将浏览 N Shepperd 的训练文件。

第 7 步:N Shepperd 训练文件

我们将使用的训练文件来自N Shepperd的 GitHub 仓库。我们在本附录的第 1 步:先决条件中上传了它们。现在我们将把它们复制到我们的项目目录中:

#@title Step 7: Copying the N Shepperd Training Files
#Referfence GitHub repository: https://github.com/nshepperd/gpt-2
import os # import after runtime is restarted
!cp /content/train.py /content/gpt-2/src/
!cp /content/load_dataset.py /content/gpt-2/src/
!cp /content/encode.py /content/gpt-2/src/
!cp /content/accumulate.py /content/gpt-2/src/
!cp /content/memory_saving_gradients.py /content/gpt-2/src/ 

现在训练文件已经准备好激活。让我们开始探索它们,首先是encode.py

第 8 步:对数据集进行编码

在训练之前,数据集必须被编码。您可以双击encode.py在 Google Colaboratory 中查看文件。

encode.py通过调用load_dataset.py中的load_dataset函数加载dset.txt

from load_dataset import load_dataset
…/…
chunks = load_dataset(enc, args.in_text, args.combine, encoding=args.encoding) 

encode.py还加载 OpenAI 的编码程序encode.py来对数据集进行编码:

import encoder
…/…
enc = encoder.get_encoder(args.model_name,models_dir) 

编码的数据集以NumPy数组的形式保存,并存储在out.npz中。现在,npz是由编码器生成的数组的NumPy压缩存档:

import numpy as np
np.savez_compressed(args.out_npz, *chunks) 

当我们运行该单元格时,数据集将被加载、编码并保存在out.npz中:

#@title Step 8:Encoding dataset
import os # import after runtime is restarted
os.chdir("/content/gpt-2/src/")
model_name="117M"
!python /content/gpt-2/src/encode.py dset.txt out.npz 

我们的 GPT-2 117M 模型已经准备好进行训练。

第 9 步:训练 GPT-2 模型

现在我们将对我们的数据集训练 GPT-2 117M 模型。我们将数据集的编码名称发送给程序:

#@title Step 9:Training the Model
#Model saved after 1000 steps
import os # import after runtime is restarted
os.chdir("/content/gpt-2/src/")
!python train.py --dataset out.npz 

当您运行该单元格时,它将一直训练,直到您停止它。训练在 1,000 步后保存模型。当训练超过 1,000 步时,请停止它。保存的模型检查点位于/content/gpt-2/src/checkpoint/run1中。您可以在笔记本的第 10A 步:复制训练文件单元格中检查这些文件的列表。

您可以通过双击单元格的运行按钮来停止训练。训练将结束,并且训练参数将被保存。

您也可以在 1,000 步后停止训练模型,方法是使用Ctrl + M。程序将停止并保存训练参数。它会将代码转换为文本(您需要将其复制回代码单元格)并显示以下消息:

图 IV.1:自动保存训练好的 GPT-2 模型

该程序使用/content/gpt-2/src/memory_saving_gradients.py/content/gpt-2/src/accumulate.py程序来管理优化器和梯度。

train.py包含了可以调整以修改训练过程的完整参数列表。首先不要改变它们运行笔记本。然后,如果你愿意,可以尝试修改训练参数,看看能否获得更好的结果。

GPT-3 模型会在训练过程中生成一些样本供您阅读。在我训练 GPT-2 的过程中,系统生成了一个让我感到启迪的样本:

The world is not a thing in itself, but is a representation of the world in itself. 

世界的形象是我们人类创造的,也是 AI 学到的。有趣!

让我们继续我们的实验,为我们的训练模型创建一个目录。

步骤 10:创建训练模型目录

本节将为我们的模型创建一个临时目录,存储我们需要的信息,并将其重命名以替换我们下载的 GPT-2 117M 模型目录。

我们首先创建一个名为tgmodel的临时目录:

#@title Step 10: Creating a Training Model directory
#Creating a Training Model directory named 'tgmodel'
import os
run_dir = '/content/gpt-2/models/tgmodel'
if not os.path.exists(run_dir):
  os.makedirs(run_dir) 

然后我们复制包含我们训练模型时保存的训练参数的检查点文件,这是在本节的步骤 9:训练模型中进行的。

#@title Step 10A: Copying training Files
!cp /content/gpt-2/src/checkpoint/run1/model-1000.data-00000-of-00001 /content/gpt-2/models/tgmodel
!cp /content/gpt-2/src/checkpoint/run1/checkpoint /content/gpt-2/models/tgmodel
!cp /content/gpt-2/src/checkpoint/run1/model-1000.index /content/gpt-2/models/tgmodel
!cp /content/gpt-2/src/checkpoint/run1/model-1000.meta /content/gpt-2/models/tgmodel 

我们的tgmodel目录现在包含我们的 GPT-2 模型的训练参数。

我们在附录 III使用 GPT-2 进行通用文本补全步骤 5:下载 345M 参数 GPT-2 模型中描述了这些文件的内容。

我们现在将从我们下载的 GPT-2 117M 模型中检索超参数和词汇文件:

#@title Step 10B: Copying the OpenAI GPT-2 117M Model files
!cp /content/gpt-2/models/117M/encoder.json /content/gpt-2/models/tgmodel
!cp /content/gpt-2/models/117M/hparams.json /content/gpt-2/models/tgmodel
!cp /content/gpt-2/models/117M/vocab.bpe /content/gpt-2/models/tgmodel 

我们的tgmodel目录现在包含我们完整定制的 GPT-2 117M 模型。

我们的最后一步是将我们下载的原始 GPT-2 模型重命名,并将我们的模型名称设置为117M

#@title Step 10C: Renaming the model directories
import os
!mv /content/gpt-2/models/117M  /content/gpt-2/models/117M_OpenAI
!mv /content/gpt-2/models/tgmodel  /content/gpt-2/models/117M 

我们训练好的模型现在是克隆的 OpenAI GPT-2 代码库将要运行的模型。让我们与我们的模型交互吧!

步骤 11:生成无条件样本

在本节中,我们将与在我们的数据集上训练的 GPT-2 117M 模型进行互动。我们将首先生成一个无条件样本,不需要我们输入任何内容。然后,我们将输入一个上下文段落,以从我们训练好的模型获得一个条件文本补全响应。

让我们先运行一个无条件样本:

#@title Step 11: Generating Unconditional Samples
import os # import after runtime is restarted
os.chdir("/content/gpt-2/src")
!python generate_unconditional_samples.py --model_name '117M' 

由于这是一个无条件的样本生成器,你不需要输入上下文句子。

要停止该单元格,双击单元格的运行按钮,或按Ctrl + M

结果是随机的,但从语法的角度来看是合理的。从语义的角度来看,结果并不那么有趣,因为我们没有提供上下文。但仍然,这个过程是了不起的。它创造了帖子,写了一个标题,日期,想象了组织和地址,提出了一个主题,甚至想象了网页链接!

开头的几行令人难以置信:

Title: total_authority
Category:
Style: Printable
Quote:
Joined: July 17th, 2013
Posts: 0
Offtopic link: "Essential research, research that supports papers being peer reviewed, research that backs up one's claims for design, research that unjustifiably accommodates scientific uncertainties, and research that persuades opens doors for science and participation in science",
href: https://groups.google.com/search?q=Author%3APj&src=ieKZP4CSg4GVWDSJtwQczgTWQhAWBO7+tKWn0jzz7o6rP4lEy&s sl=cTheory%20issue1&fastSource=posts&very=device
Offline
Joined: May 11th, 2014
Posts: 1729
Location: Montana AreaJoined: May 11th, 2014Posts: 1729Location: Montana
Posted: Fri Dec 26, 2017 9:18 pm Post subject: click
I. Synopsis of the established review group
The "A New Research Paradigm" and Preferred Alternative (BREPG) group lead authors John Obi (Australian, USA and Chartered Institute of Tropical and Climate Change Research), Marco Xiao (China and Department of Sociology/Ajax, International Institute of Tropical and Climate Change Research, Shanghai University) and Jackie Gu (US/Pacific University, Interselicitas de NASA and Frozen Planet Research Research Center, Oak Ridge National Laboratory). Dr. Obi states: "Our conclusions indicate that the existence of the new peer reviewed asan-rubie study predisposes journal publishers to read scientific publishers constantly to seek a consignment of, and to be affiliated with, a large target certain of their persons. The current practice of supplying books with peer review by commonly-overruled specialists itself spreads from part to part, sufficient to spread the impact of peer reviews by experts to all levels of the organization, so as to increase the extent of exposure to the term of deviation that source profiles or findings require". 

无条件的随机文本生成器的结果很有趣,但并不令人信服。

第 12 步:交互式上下文和补全示例

现在我们将运行一个有条件的示例。我们输入的上下文将使模型以我们想要的方式进行思考,通过生成定制段落来完成文本。

运行单元格并探索魔法:

#@title Step 12: Interactive Context and Completion Examples
import os # import after runtime is restarted
os.chdir("/content/gpt-2/src")
!python interactive_conditional_samples.py --temperature 0.8 --top_k 40 --model_name '117M' 

如果需要,花几分钟回顾附录 III 的第 9 步:与 GPT-2 交互中的参数。程序提示我们输入上下文:

图 IV.2:文本补全的上下文输入

让我们来看看埃曼纽尔·康德在附录 III 的第 9 步:与 GPT-2 交互中写的同一段落,使用 GPT-2 进行通用文本补全

Human reason, in one sphere of its cognition, is called upon to
consider questions, which it cannot decline, as they are presented by
its own nature, but which it cannot answer, as they transcend every
faculty of the mind. 

按下Enter键来生成文本,就像之前一样。尽管输出可能会从一个运行到另一个运行而变化,但它是有结构和逻辑的,这使得Transformers具有吸引力。这次,结果不是随机的,而且令人印象深刻。

让我们来看看 GPT-2 模型生成的开头几行:

"Now, what is the nature of the reason, except that it is of a kind and power of mind that is so called on to think, and to understand?
The reason is the thing which apprehends, and seeks to understand, the objects of its minds, which apprehend and apprehend the things of itself. No one can speak of this reason without the understanding and the understanding of the human reason. But that knowledge and understanding which is the most natural of all the faculties, which, because it is understood by the human reason, is the most natural of all the faculties, is not without reason, but only without understanding. The human reason, who sees and knows the things which the natural sense, which, though in the natural sense, does not understand, is the source of every other knowledge which we understand. The reason is the thing which does not understand, but understands the things which we comprehend, and therefore, is not to be understood. I mean that the reason is the thing which does not understand, but knows only the things which we do understand…." 

要停止单元格,双击单元格的运行按钮,或输入Ctrl + M

哇!我怀疑有谁能看出我们训练过的 GPT-2 模型产生的文本补全与人类之间的区别。它也可能在每次运行时生成不同的输出。这可能是输出的样子,例如:

The first question, to which it is obliged to respond, is, how can it be true that a mind which is ignorant of the truth of any proposition can, or ought, to, accept any proposition which it has not given it? And this question has been so well answered that it is impossible for any man to believe in the existence of any mind which has never received any information. 
"It is not the mind of any man, as far as we can judge, which is the subject of any philosophical inquiry. It is the mind of the minds of men, in their opinion, which they consider the most to be their most important subject. And if they can see through this, they will see it, and they will understand it, and they will understand it." 

我认为我们的模型在这个哲学、推理和逻辑的抽象练习中可能会胜过许多人类!

限制在于文本会随着每次运行而变化。因此,尽管看起来很出色,但它并不会满足我们在日常生活中的每一个需求。

我们可以从我们的实验中得出一些结论:

  • 训练良好的Transformers模型可以产生接近人类水平的文本补全。

  • 在复杂和抽象推理方面,GPT-2 模型几乎可以达到人类水平的文本生成。

  • 文本上下文是通过展示预期的内容来有效地对模型进行条件化的一种方法。

  • 如果提供了上下文句子,文本补全就是基于文本条件生成文本。

  • 尽管文本处于人类水平,但这并不意味着它会满足我们所有的需求。目前,它在局部是有趣的,但在整体上并不有效。

你可以尝试输入一些条件化的文本上下文示例来实验文本补全。你也可以用自己的数据训练我们的模型。只需用你自己的内容替换dset.txt文件的内容,然后看看会发生什么!

请记住,我们训练的 GPT-2 模型会像人类一样做出反应。如果你输入一个简短的、不完整的、不引人注意的或者棘手的上下文,你将会得到困惑或者糟糕的结果。这是因为 GPT-2 期望我们做到最好,就像在现实生活中一样!

参考资料

加入我们书籍的 Discord 空间

加入书籍的 Discord 工作空间,与作者进行每月的 问我任何问题 会议:

www.packt.link/Transformers

posted @ 2024-04-30 11:42  绝不原创的飞龙  阅读(5)  评论(0编辑  收藏  举报