精通 Transformers(四)(2)

简介: 精通 Transformers(四)

精通 Transformers(四)(1)https://developer.aliyun.com/article/1510719

使用 Locust 进行负载测试

我们可以使用许多应用程序来对服务进行负载测试。这些应用程序和库中的大多数都提供了有关服务的响应时间和延迟的有用信息。它们还提供了有关故障率的信息。Locust 是这一目的最好的工具之一。我们将使用它来对三种用于提供基于 Transformer 的模型的方法进行负载测试:仅使用 fastAPI、使用 docker 化的 fastAPI 以及使用 fastAPI 进行 TFX-based 服务。让我们开始吧:

  1. 首先,我们必须安装 Locust:
$ pip install locust
  1. 此命令将安装 Locust。下一步是使提供相同任务的所有服务使用相同的模型。修正此测试的最重要的两个参数将确保所有服务均被设计成满足单一目的。使用相同的模型将帮助我们凝固其他任何内容,并集中于方法的部署性能。
  2. 一切准备就绪后,您可以开始测试 API 的负载。您必须准备一个locustfile来定义您的用户及其行为。以下代码是一个简单的locustfile
from locust import HttpUser, task
from random import choice
from string import ascii_uppercase
class User(HttpUser):
    @task
    def predict(self):
        payload = {"text": ''.join(choice(ascii_uppercase) for i in range(20))}
        self.client.post("/sentiment", json=payload)
  1. 通过使用HttpUser并创建从中继承的User类,我们可以定义一个HttpUser类。@task装饰器对于定义用户生成后必须执行的任务至关重要。predict函数是用户生成后将重复执行的实际任务。它将生成一个长度为20的随机字符串并发送到您的 API。
  2. 要开始测试,您必须启动您的服务。一旦您启动了服务,运行以下代码以启动 Locust 负载测试:
$ locust -f locust_file.py
  1. Locust 将根据您在locustfile中提供的设置启动。您的终端将显示以下内容:

    图 10.5—启动 Locust 负载测试后的终端
    正如您所看到的,您可以打开网络接口的 URL,即 http://0.0.0.0:8089
  2. 打开 URL 之后,您将看到一个界面,如下截图所示:
    图 10.6—Locust 网络接口
  3. 我们将把要模拟的总用户数设定为10生成速率设定为1主机设定为http://127.0.0.1:8000,这是我们服务运行的地方。在设置这些参数之后,点击开始 swarming
  4. 此时,界面将会改变,测试将开始。要随时停止测试,点击停止按钮。
  5. 你还可以点击Charts选项卡查看结果的可视化:
    图 10.7 – 来自 Charts 选项卡的 Locust 测试结果
  6. 现在 API 的测试准备好了,让我们测试所有三个版本并比较结果,看哪个执行效果更好。请记住,服务必须在你要提供服务的机器上独立测试。换句话说,你必须一次运行一个服务并测试它,关闭服务,运行另一个服务并测试它,依此类推。
    结果显示在下表中:

表 1 – 比较不同实现的结果

在上表中,每秒请求数RPS)表示 API 每秒响应的请求数,而平均响应时间RT)表示服务响应给定调用所需的毫秒数。这些结果显示了基于 TFX 的 fastAPI 是最快的。它具有更高的 RPS 和较低的平均 RT。所有这些测试都是在一台配有 Intel® Core™ i7-9750H CPU 和 32 GB RAM、GPU 禁用的机器上进行的。

在这一节中,你学习了如何测试你的 API 并测量其性能,重要参数如 RPS 和 RT。然而,真实世界的 API 还可以执行许多其他压力测试,比如增加用户数量使其表现得像真实用户一样。要执行这样的测试并以更真实的方式报告其结果,重要的是阅读 Locust 的文档并学习如何执行更高级的测试。

总结

在这一章中,你学习了使用 fastAPI 提供 Transformer 模型的基础知识。你还学会了如何以更高级和更有效的方式提供模型,比如使用 TFX。然后,你学习了负载测试和创建用户的基础知识。让这些用户分组生成或逐个生成,然后报告压力测试的结果,是本章的另一个主要主题。之后,你学习了 Docker 的基础知识以及如何将你的应用程序打包成 Docker 容器的形式。最后,你学会了如何提供基于 Transformer 的模型。

在下一章中,你将学习 Transformer 的解构、模型视图,并使用各种工具和技术监视训练。

参考资料

第十一章:注意力可视化和实验跟踪

在本章中,我们将涵盖两个不同的技术概念,注意力可视化实验跟踪,并通过诸如 exBERTBertViz 等复杂工具来实践它们。这些工具提供了重要的可解释性和可解释性功能。首先,我们将讨论如何利用这些工具来可视化注意力的内部部分。解释所学的表示是很重要的,也要理解 Transformer 中自注意力头所编码的信息。我们将看到某些头部对应于语法或语义的某个方面。其次,我们将学习如何通过记录和使用 TensorBoardWeights & BiasesW&B)来监视实验。这些工具使我们能够高效地托管和跟踪实验结果,例如损失或其他指标,这有助于我们优化模型训练。通过本章的学习,您将学会如何使用 exBERT 和 BertViz 查看自己模型的内部部分,并最终能够利用 TensorBoard 和 W&B 监视和优化模型。

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

  • 解释注意力头
  • 跟踪模型指标

技术要求

本章的代码可在 github.com/PacktPublishing/Mastering-Transformers/tree/main/CH11 找到,这是本书的 GitHub 代码库。我们将使用 Jupyter Notebook 运行需要 Python 3.6.0 或更高版本的编码练习,并且需要安装以下包:

  • tensorflow
  • pytorch
  • Transformers >=4.00
  • tensorboard
  • wandb
  • bertviz
  • ipywidgets

查看以下链接以查看代码演示视频:

bit.ly/3iM4Y1F

解释注意力头

与大多数深度学习DL)架构一样,Transformer 模型的成功以及它们如何学习尚未完全理解,但我们知道,Transformer —— 令人惊讶地 —— 学到了许多语言特征。大量的学到的语言知识分布在预训练模型的隐藏状态和自注意头中。已经发表了大量的最新研究,并开发了许多工具,以理解和更好地解释这些现象。

感谢一些自然语言处理NLP)社区工具,我们能够解释 Transformer 模型中自注意力头所学到的信息。由于令牌之间的权重,头部可以被自然地解释。我们很快会在本节的进一步实验中看到,某些头对应于语法或语义的某个方面。我们还可以观察到表面级模式和许多其他语言特征。

在本节中,我们将使用社区工具进行一些实验来观察这些模式和注意头部的特征。最近的研究已经揭示了自注意的许多特征。在我们进行实验之前,让我们先介绍一些。例如,大多数头部倾向于关注分隔符标记,如分隔符SEP)和分类CLS),因为这些标记永远不被屏蔽,并且特别携带段级信息。另一个观察是,大多数头部很少关注当前标记,但一些头部专门关注下一个或上一个标记,特别是在较早的层中。以下是最近研究中发现的其他模式列表,我们可以在我们的实验中轻松观察到:

  • 同一层中的注意头表现出类似的行为。
  • 特定头对应于语法或语义关系的特定方面。
  • 一些头部对直接对象倾向于关注它们的动词,例如**。
  • 在一些头中,名词修饰语会关注它们的名词(例如the hot waterthe next layer),或所有格代词会关注头部(例如her car)。
  • 一些头部对被动助动词进行编码,例如Been damaged, was taken
  • 在一些头部中,指代提及关注自己,例如talks-negotiation, she-her, President-Biden
  • 较低的层通常包含有关词位置的信息。
  • 语法特征在 transformer 中较早出现,而高级语义信息出现在更上层。
  • 最终层是最具任务特异性的,并因此对下游任务非常有效。

为了观察这些模式,我们可以在这里使用两个重要工具exBERTBertViz。这些工具功能几乎相同。我们将从 exBERT 开始。

用 exBERT 可视化注意力头部

exBERT 是一个可视化工具,用于查看 Transformers 内部部分。我们将使用它来可视化BERT-base-cased模型的自注意头部,这是 exBERT 界面的默认模型。除非另有说明,我们将在以下示例中使用BERT-base-cased模型。这包含 12 层,每层 12 个自注意头部,共计 144 个自注意头部。

我们将逐步学习如何使用 exBERT,如下所示:

  1. 让我们点击由Hugging Face托管的 exBERT 链接:huggingface.co/exbert
  2. 输入句子**The cat is very sad.**并查看输出,如下所示:
    图 11.1 – exBERT 界面
    在上面的屏幕截图中,左侧的标记关注右侧的标记。线条的厚度代表权重的值。由于 CLS 和 SEP 标记具有非常频繁和密集的连接,我们简化起见切断了与它们相关的链接。请参阅隐藏特殊标记切换按钮。现在我们看到的是第 1 层的关注映射,其中线条对应于所有头部上权重的总和。这被称为多头注意力机制,其中 12 个头部并行工作。这个机制可以让我们捕捉比单头注意力更广泛的关系。这就是为什么我们在图 11.1中看到一个广泛的关注模式。我们还可以通过点击头部列观察任何特定的头部。
    如果您在左侧悬停在一个标记上,您将看到将它连接到右侧的具体权重。有关使用界面的更详细信息,请阅读文章exBERT:一个用于探索Transformers模型中学到表示的可视分析工具,作者本杰明·胡佛亨德里克·施特罗贝尔特塞巴斯蒂安·格赫尔曼2019 年,或观看以下链接的视频:exbert.net/
  3. 现在,我们将尝试支持本节介绍部分中其他研究人员的发现。让我们以某些头部专门关注下一个或前一个标记,尤其是在较早的层模式为例,看是否有一个头部支持这一点。
  4. 在本章的其余部分中,我们将使用**<层编号,头部编号>*符号来表示特定的自注意头部,在这里,指数从 exBERT 的 1 开始,从 BertViz 的 0 开始。例如,*❤️,7>表示 exBERT 第三层的第七个头部。当您选择<2,5>(或<4,12>或<6,2>)**头部时,您将得到以下输出,其中每个标记只关注前一个标记:
    图 11.2 – 上一个标记关注模式
  5. 对于**<2, 12>❤️, 4>**头部,您将得到一个模式,其中每个标记都与下一个标记关联,如下所示:
    图 11.3 – 下一个标记关注模式
    这些头部对其他输入句子具有相同的功能,即它们独立于输入工作。您可以自己尝试不同的句子。
    我们可以使用注意力头部进行先进的语义任务,例如使用探测分类器进行代词消解。首先,我们将从定性上检查内部表示是否具有代词消解(或核指代消解)的能力。代词消解被认为是一项具有挑战性的语义关系任务,因为代词与其先行词之间的距离通常非常大。
  6. 现在,我们拿句子The cat is very sad. Because it could not find food to eat. 作为例子。当你检查每个头部时,你会注意到*<9,9><9,12>头部编码了代词关系。当你悬停在<9,9>*头上的it时,我们会得到以下输出:
    图 11.4 – <9,9>头部的指代模式
    *<9,12>*头也用于代词关系。同样,在悬停在it上时,我们得到以下输出:

    图 11.5 – <9,12>头部的指代模式
    从上述截图中,我们看到it代词强烈关注它的先行词cat。我们稍微改变一下句子,让it代词现在指代food标记而不是cat,就像the cat did not eat the food because it was not fresh中一样。如下截图所示,与*<9,9>*头相关的截图中,it正确地关注了它的先行词food,如预期所示:

    图 11.6 – 第二个例子的<9,9>头部的模式
  7. 让我们再做一次运行,这次代词指代的是cat,就像The cat did not eat the food because it was very angry中一样。在*<9,9>*头中,it 标记大部分关注cat标记,如下截图所示:
    图 11.7 – 第二个输入的<9,9>头部的模式
  8. 我觉得这些例子已经足够了。现在,我们将以不同的方式使用 exBERT 模型来评估模型的容量。让我们重新启动 exBERT 界面,选择最后一层(第 12 层),并保留所有头部。然后,输入句子the cat did not eat the food.并将food标记掩码。双击掩码掩码了food标记,如下所示:

图 11.8 – 通过掩码评估模型

当你悬停在那个被掩码的标记上时,你可以看到Bert-base-cased模型的预测分布,如上述截图所示。第一个预测是food,这是预期的。有关工具的更详细信息,你可以使用 exBERT 的网页,位于exbert.net/

干得好!在下一节中,我们将使用 BertViz 并编写一些 Python 代码来访问注意力头。

精通 Transformers(四)(3)https://developer.aliyun.com/article/1510722

相关文章
|
4月前
|
机器学习/深度学习 自然语言处理 PyTorch
精通 Transformers(一)(2)
精通 Transformers(一)
93 4
|
4月前
|
API TensorFlow 算法框架/工具
精通 Transformers(四)(1)
精通 Transformers(四)
46 0
精通 Transformers(四)(1)
|
4月前
|
编解码 自然语言处理 数据可视化
精通 Transformers(四)(4)
精通 Transformers(四)
92 0
|
4月前
|
自然语言处理 数据可视化 NoSQL
精通 Transformers(四)(3)
精通 Transformers(四)
51 0
|
2月前
|
自然语言处理 安全 PyTorch
Transformers 4.37 中文文档(一)(4)
Transformers 4.37 中文文档(一)
21 1
|
2月前
|
存储 JSON 缓存
Transformers 4.37 中文文档(一百)(1)
Transformers 4.37 中文文档(一百)
29 1
|
2月前
|
PyTorch TensorFlow 调度
Transformers 4.37 中文文档(一)(5)
Transformers 4.37 中文文档(一)
37 1
|
2月前
|
数据可视化 PyTorch 算法框架/工具
Transformers 4.37 中文文档(五)(3)
Transformers 4.37 中文文档(五)
22 0
|
2月前
|
数据采集 测试技术 语音技术
Transformers 4.37 中文文档(六)(1)
Transformers 4.37 中文文档(六)
22 0
|
4月前
|
自然语言处理 算法 算法框架/工具
精通 Transformers(一)(4)
精通 Transformers(一)
86 4