Transformers 文档

导出到 TorchScript

Hugging Face's logo
加入 Hugging Face 社区

并获取增强版文档体验

开始

导出到 TorchScript

这是我们使用 TorchScript 进行实验的最初阶段,我们仍在探索其在可变输入大小模型中的能力。这是我们关注的重点,我们将在即将发布的版本中深入分析,提供更多代码示例、更灵活的实现以及比较基于 Python 的代码与编译后的 TorchScript 的基准测试。

根据 TorchScript 文档

TorchScript 是一种从 PyTorch 代码创建可序列化和可优化模型的方法。

有两个 PyTorch 模块,JIT 和 TRACE,允许开发人员将他们的模型导出以便在其他程序(如效率导向的 C++ 程序)中重用。

我们提供了一个接口,允许您将 🤗 Transformers 模型导出到 TorchScript,以便它们可以在与基于 PyTorch 的 Python 程序不同的环境中重用。在这里,我们将解释如何使用 TorchScript 导出和使用我们的模型。

导出模型需要两件事

  • 使用 torchscript 标志实例化模型
  • 使用虚拟输入进行前向传播

这些需求意味着开发人员应注意以下详细说明的事项。

TorchScript 标志和绑定的权重

torchscript 标志是必需的,因为大多数 🤗 Transformers 语言模型在它们的 Embedding 层和 Decoding 层之间具有绑定的权重。TorchScript 不允许您导出具有绑定的权重的模型,因此有必要事先解绑并克隆权重。

使用 torchscript 标志实例化的模型具有分离的 Embedding 层和 Decoding 层,这意味着它们不应该在线下进行训练。训练会导致这两个层不同步,从而导致意外的结果。

对于没有语言模型头的模型,情况并非如此,因为这些模型没有绑定的权重。这些模型可以在没有 torchscript 标志的情况下安全导出。

虚拟输入和标准长度

虚拟输入用于模型的前向传递。虽然输入的值会通过各层传播,但 PyTorch 会跟踪在每个张量上执行的不同操作。这些记录的操作随后被用于创建模型的跟踪

跟踪是相对于输入的维度创建的。因此,它受到虚拟输入维度的约束,并且不适用于任何其他序列长度或批次大小。当尝试使用不同的尺寸时,会引发以下错误

`The expanded size of the tensor (3) must match the existing size (7) at non-singleton dimension 2`

我们建议您使用至少与推理过程中将馈送到模型的最大输入一样大的虚拟输入尺寸来跟踪模型。填充可以帮助填充缺失的值。但是,由于模型是用更大的输入尺寸跟踪的,因此矩阵的尺寸也会很大,从而导致更多计算。

注意每个输入所执行的操作总数,并在导出不同序列长度的模型时密切关注性能。

在 Python 中使用 TorchScript

本节演示如何保存和加载模型,以及如何使用跟踪进行推理。

保存模型

要使用 TorchScript 导出 BertModel,请从 BertConfig 类实例化 BertModel,然后将其保存到磁盘,文件名 traced_bert.pt

from transformers import BertModel, BertTokenizer, BertConfig
import torch

enc = BertTokenizer.from_pretrained("google-bert/bert-base-uncased")

# Tokenizing input text
text = "[CLS] Who was Jim Henson ? [SEP] Jim Henson was a puppeteer [SEP]"
tokenized_text = enc.tokenize(text)

# Masking one of the input tokens
masked_index = 8
tokenized_text[masked_index] = "[MASK]"
indexed_tokens = enc.convert_tokens_to_ids(tokenized_text)
segments_ids = [0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1]

# Creating a dummy input
tokens_tensor = torch.tensor([indexed_tokens])
segments_tensors = torch.tensor([segments_ids])
dummy_input = [tokens_tensor, segments_tensors]

# Initializing the model with the torchscript flag
# Flag set to True even though it is not necessary as this model does not have an LM Head.
config = BertConfig(
    vocab_size_or_config_json_file=32000,
    hidden_size=768,
    num_hidden_layers=12,
    num_attention_heads=12,
    intermediate_size=3072,
    torchscript=True,
)

# Instantiating the model
model = BertModel(config)

# The model needs to be in evaluation mode
model.eval()

# If you are instantiating the model with *from_pretrained* you can also easily set the TorchScript flag
model = BertModel.from_pretrained("google-bert/bert-base-uncased", torchscript=True)

# Creating the trace
traced_model = torch.jit.trace(model, [tokens_tensor, segments_tensors])
torch.jit.save(traced_model, "traced_bert.pt")

加载模型

现在您可以从磁盘加载之前保存的 BertModeltraced_bert.pt,并在之前初始化的 dummy_input 上使用它

loaded_model = torch.jit.load("traced_bert.pt")
loaded_model.eval()

all_encoder_layers, pooled_output = loaded_model(*dummy_input)

使用跟踪的模型进行推理

使用跟踪的模型进行推理,方法是使用它的 __call__ dunder 方法

traced_model(tokens_tensor, segments_tensors)

使用 Neuron SDK 将 Hugging Face TorchScript 模型部署到 AWS

AWS 推出了 Amazon EC2 Inf1 实例系列,用于在云中以低成本、高性能执行机器学习推理。Inf1 实例由 AWS Inferentia 芯片提供支持,这是一款定制的硬件加速器,专门用于深度学习推理工作负载。 AWS Neuron 是 Inferentia 的 SDK,支持跟踪和优化 transformers 模型,以便在 Inf1 上部署。Neuron SDK 提供以下功能:

  1. 易于使用的 API,只需更改一行代码即可跟踪和优化 TorchScript 模型,以便在云中进行推理。
  2. 开箱即用的性能优化,可 提高性价比
  3. 支持使用 PyTorchTensorFlow 构建的 Hugging Face transformers 模型。

影响

基于 BERT(来自 Transformers 的双向编码器表示) 架构或其变体(如 distilBERTroBERTa)的 transformers 模型在 Inf1 上运行效果最佳,适用于非生成任务,如抽取式问答、序列分类和标记分类。但是,根据此 AWS Neuron MarianMT 教程,文本生成任务仍然可以适应在 Inf1 上运行。有关可以在 Inferentia 上开箱即用转换的模型的更多信息,请参阅 Neuron 文档的 模型架构匹配 部分。

依赖项

使用 AWS Neuron 转换模型需要 Neuron SDK 环境,该环境在 AWS 深度学习 AMI 上预先配置。

为 AWS Neuron 转换模型

使用与 在 Python 中使用 TorchScript 相同的代码,使用 BertModel 跟踪模型,以将模型转换为 AWS NEURON。导入 torch.neuron 框架扩展,通过 Python API 访问 Neuron SDK 的组件。

from transformers import BertModel, BertTokenizer, BertConfig
import torch
import torch.neuron

您只需要修改以下代码行:

- torch.jit.trace(model, [tokens_tensor, segments_tensors])
+ torch.neuron.trace(model, [tokens_tensor, segments_tensors])

这使 Neuron SDK 能够跟踪模型并针对 Inf1 实例对其进行优化。

要详细了解 AWS Neuron SDK 的功能、工具、示例教程和最新更新,请参阅 AWS NeuronSDK 文档

< > GitHub 上的更新