• 教程 >
  • 使用 Better Transformer 进行快速 Transformer 推理
快捷方式

使用 Better Transformer 进行快速 Transformer 推理

作者: Michael Gschwind

本教程介绍了 Better Transformer (BT) 作为 PyTorch 1.12 版本的一部分。在本教程中,我们将展示如何使用 Better Transformer 和 torchtext 进行生产推理。Better Transformer 是一种可用于生产的快速路径,可通过在 CPU 和 GPU 上提供高性能来加速 Transformer 模型的部署。对于基于 PyTorch 核心 nn.module 或 torchtext 的模型,快速路径功能可以透明地工作。

可以使用 Better Transformer 快速路径执行加速的模型是使用以下 PyTorch 核心 torch.nn.moduleTransformerEncoderTransformerEncoderLayerMultiHeadAttention 的模型。此外,torchtext 已更新为使用核心库模块以受益于快速路径加速。(将来可能会在快速路径执行中启用其他模块。)

Better Transformer 提供两种类型的加速

  • 针对 CPU 和 GPU 的原生多头注意力 (MHA) 实现,以提高整体执行效率。

  • 利用 NLP 推理中的稀疏性。由于输入长度可变,输入标记可能包含大量填充标记,可以跳过对这些标记的处理,从而实现显著的加速。

快速路径执行受某些条件约束。最重要的是,模型必须在推理模式下执行,并对不收集梯度带信息的输入张量进行操作(例如,使用 torch.no_grad 运行)。

要在 Google Colab 中遵循此示例,请点击此处

本教程中的 Better Transformer 功能

  • 加载预训练模型(在 PyTorch 1.12 版本之前创建,不使用 Better Transformer)

  • 在 CPU 上运行和基准测试推理,使用和不使用 BT 快速路径(仅限原生 MHA)

  • 在(可配置)DEVICE 上运行和基准测试推理,使用和不使用 BT 快速路径(仅限原生 MHA)

  • 启用稀疏性支持

  • 在(可配置)DEVICE 上运行和基准测试推理,使用和不使用 BT 快速路径(原生 MHA + 稀疏性)

其他信息

有关 Better Transformer 的更多信息,请参阅 PyTorch.Org 博客 更快 Transformer 推理的 Better Transformer

  1. 设置

1.1 加载预训练模型

我们按照 torchtext.models 中的说明,从预定义的 torchtext 模型中下载 XLM-R 模型。我们还设置 DEVICE 以在加速器上执行测试。(根据您的环境适当地启用 GPU 执行。)

import torch
import torch.nn as nn

print(f"torch version: {torch.__version__}")

DEVICE = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")

print(f"torch cuda available: {torch.cuda.is_available()}")

import torch, torchtext
from torchtext.models import RobertaClassificationHead
from torchtext.functional import to_tensor
xlmr_large = torchtext.models.XLMR_LARGE_ENCODER
classifier_head = torchtext.models.RobertaClassificationHead(num_classes=2, input_dim = 1024)
model = xlmr_large.get_model(head=classifier_head)
transform = xlmr_large.transform()

1.2 数据集设置

我们设置了两种类型的输入:一个小输入批次和一个带有稀疏性的大的输入批次。

small_input_batch = [
               "Hello world",
               "How are you!"
]
big_input_batch = [
               "Hello world",
               "How are you!",
               """`Well, Prince, so Genoa and Lucca are now just family estates of the
Buonapartes. But I warn you, if you don't tell me that this means war,
if you still try to defend the infamies and horrors perpetrated by
that Antichrist- I really believe he is Antichrist- I will have
nothing more to do with you and you are no longer my friend, no longer
my 'faithful slave,' as you call yourself! But how do you do? I see
I have frightened you- sit down and tell me all the news.`

It was in July, 1805, and the speaker was the well-known Anna
Pavlovna Scherer, maid of honor and favorite of the Empress Marya
Fedorovna. With these words she greeted Prince Vasili Kuragin, a man
of high rank and importance, who was the first to arrive at her
reception. Anna Pavlovna had had a cough for some days. She was, as
she said, suffering from la grippe; grippe being then a new word in
St. Petersburg, used only by the elite."""
]

接下来,我们选择小或大输入批次,预处理输入并测试模型。

input_batch=big_input_batch

model_input = to_tensor(transform(input_batch), padding_value=1)
output = model(model_input)
output.shape

最后,我们设置基准迭代次数

ITERATIONS=10
  1. 执行

2.1 在 CPU 上运行和基准测试推理,使用和不使用 BT 快速路径(仅限原生 MHA)

我们在 CPU 上运行模型,并收集性能信息

  • 第一次运行使用传统的(“慢路径”)执行。

  • 第二次运行通过使用 model.eval() 将模型置于推理模式并使用 torch.no_grad() 禁用梯度收集来启用 BT 快速路径执行。

当模型在 CPU 上执行时,您可以看到性能提升(幅度将取决于 CPU 模型)。请注意,快速路径性能分析显示大部分执行时间都在原生 TransformerEncoderLayer 实现 aten::_transformer_encoder_layer_fwd 中。

print("slow path:")
print("==========")
with torch.autograd.profiler.profile(use_cuda=False) as prof:
  for i in range(ITERATIONS):
    output = model(model_input)
print(prof)

model.eval()

print("fast path:")
print("==========")
with torch.autograd.profiler.profile(use_cuda=False) as prof:
  with torch.no_grad():
    for i in range(ITERATIONS):
      output = model(model_input)
print(prof)

2.2 在(可配置)DEVICE 上运行和基准测试推理,使用和不使用 BT 快速路径(仅限原生 MHA)

我们检查 BT 稀疏性设置

model.encoder.transformer.layers.enable_nested_tensor

我们禁用 BT 稀疏性

model.encoder.transformer.layers.enable_nested_tensor=False

我们在 DEVICE 上运行模型,并收集在 DEVICE 上原生 MHA 执行的性能信息

  • 第一次运行使用传统的(“慢路径”)执行。

  • 第二次运行通过使用 model.eval() 将模型置于推理模式并使用 torch.no_grad() 禁用梯度收集来启用 BT 快速路径执行。

在 GPU 上执行时,您应该会看到显著的加速,特别是对于小输入批次设置

model.to(DEVICE)
model_input = model_input.to(DEVICE)

print("slow path:")
print("==========")
with torch.autograd.profiler.profile(use_cuda=True) as prof:
  for i in range(ITERATIONS):
    output = model(model_input)
print(prof)

model.eval()

print("fast path:")
print("==========")
with torch.autograd.profiler.profile(use_cuda=True) as prof:
  with torch.no_grad():
    for i in range(ITERATIONS):
      output = model(model_input)
print(prof)

2.3 在(可配置)DEVICE 上运行和基准测试推理,使用和不使用 BT 快速路径(原生 MHA + 稀疏性)

我们启用稀疏性支持

model.encoder.transformer.layers.enable_nested_tensor = True

我们在 DEVICE 上运行模型,并收集在 DEVICE 上原生 MHA 和稀疏性支持执行的性能信息

  • 第一次运行使用传统的(“慢路径”)执行。

  • 第二次运行通过使用 model.eval() 将模型置于推理模式并使用 torch.no_grad() 禁用梯度收集来启用 BT 快速路径执行。

在 GPU 上执行时,您应该会看到显著的加速,特别是对于包含稀疏性的大的输入批次设置

model.to(DEVICE)
model_input = model_input.to(DEVICE)

print("slow path:")
print("==========")
with torch.autograd.profiler.profile(use_cuda=True) as prof:
  for i in range(ITERATIONS):
    output = model(model_input)
print(prof)

model.eval()

print("fast path:")
print("==========")
with torch.autograd.profiler.profile(use_cuda=True) as prof:
  with torch.no_grad():
    for i in range(ITERATIONS):
      output = model(model_input)
print(prof)

总结

在本教程中,我们介绍了使用 PyTorch 核心 Better Transformer 对 Transformer Encoder 模型的支持,在 torchtext 中使用 Better Transformer 快速路径执行进行快速 Transformer 推理。我们演示了在 BT 快速路径执行可用之前训练的模型中使用 Better Transformer。我们演示并基准测试了两种 BT 快速路径执行模式的使用,即原生 MHA 执行和 BT 稀疏性加速。

文档

访问 PyTorch 的全面开发者文档

查看文档

教程

获取适合初学者和高级开发人员的深入教程

查看教程

资源

查找开发资源并获得问题的解答

查看资源