Transformers 4.37 中文文档(十)(2)

简介: Transformers 4.37 中文文档(十)

Transformers 4.37 中文文档(十)(1)https://developer.aliyun.com/article/1564902


TensorFlow 模型的 XLA 集成

原文链接:huggingface.co/docs/transformers/v4.37.2/en/tf_xla

加速线性代数,简称 XLA,是用于加速 TensorFlow 模型运行时的编译器。来自官方文档

XLA(加速线性代数)是一个专门用于线性代数的编译器,可以加速 TensorFlow 模型,可能不需要源代码更改。

在 TensorFlow 中使用 XLA 很简单 - 它已经打包在tensorflow库中,并且可以通过任何创建图形函数(例如tf.function)中的jit_compile参数触发。当使用 Keras 方法如fit()predict()时,您可以通过将jit_compile参数传递给model.compile()来简单启用 XLA。但是,XLA 不仅限于这些方法 - 它还可以用于加速任何任意的tf.function

🤗 Transformers 中的几个 TensorFlow 方法已经重写为与 XLA 兼容,包括用于模型的文本生成,如GPT2T5OPT,以及用于语音处理的模型,如Whisper

在🤗 Transformers 内部的 TensorFlow 文本生成模型中,加速的确切数量非常依赖于模型,我们注意到速度提升了约  100 倍。本文将解释如何在这些模型中使用 XLA 来获得最大的性能。我们还将提供额外资源的链接,如果您有兴趣了解更多关于基准测试和我们在  XLA 集成背后的设计理念。

使用 XLA 运行 TF 函数

让我们考虑以下 TensorFlow 模型:

import tensorflow as tf
model = tf.keras.Sequential(
    [tf.keras.layers.Dense(10, input_shape=(10,), activation="relu"), tf.keras.layers.Dense(5, activation="softmax")]
)

上述模型接受维度为(10, )的输入。我们可以使用该模型来运行前向传递,如下所示:

# Generate random inputs for the model.
batch_size = 16
input_vector_dim = 10
random_inputs = tf.random.normal((batch_size, input_vector_dim))
# Run a forward pass.
_ = model(random_inputs)

为了使用 XLA 编译函数运行前向传递,我们需要执行以下操作:

xla_fn = tf.function(model, jit_compile=True)
_ = xla_fn(random_inputs)

model的默认call()函数用于编译 XLA 图。但是,如果有任何其他模型函数您想要编译成 XLA,也是可能的,例如:

my_xla_fn = tf.function(model.my_xla_fn, jit_compile=True)

使用🤗 Transformers 中的 XLA 运行 TF 文本生成模型

要在🤗 Transformers 内启用 XLA 加速生成,您需要安装最新版本的transformers。您可以通过运行以下命令来安装:

pip install transformers --upgrade

然后您可以运行以下代码:

import tensorflow as tf
from transformers import AutoTokenizer, TFAutoModelForCausalLM
# Will error if the minimal version of Transformers is not installed.
from transformers.utils import check_min_version
check_min_version("4.21.0")
tokenizer = AutoTokenizer.from_pretrained("gpt2", padding_side="left", pad_token="</s>")
model = TFAutoModelForCausalLM.from_pretrained("gpt2")
input_string = ["TensorFlow is"]
# One line to create an XLA generation function
xla_generate = tf.function(model.generate, jit_compile=True)
tokenized_input = tokenizer(input_string, return_tensors="tf")
generated_tokens = xla_generate(**tokenized_input, num_beams=2)
decoded_text = tokenizer.decode(generated_tokens[0], skip_special_tokens=True)
print(f"Generated -- {decoded_text}")
# Generated -- TensorFlow is an open-source, open-source, distributed-source application # framework for the

正如您可以注意到的,在generate()上启用 XLA 只是一行代码。其余代码保持不变。但是,上面代码片段中有一些特定于 XLA 的注意事项。您需要注意这些才能实现 XLA 带来的加速。我们将在下一节中讨论这些。

需要注意的事项

当您首次执行启用 XLA 的函数(如上面的xla_generate())时,它将内部尝试推断计算图,这是耗时的。这个过程被称为“跟踪”

您可能会注意到生成时间不够快。连续调用xla_generate()(或任何其他启用 XLA 的函数)不需要推断计算图,只要函数的输入遵循最初构建计算图时的相同形状。虽然对于具有固定输入形状的模态(例如图像)这不是问题,但如果您正在处理具有可变输入形状的模态(例如文本),则必须注意。

为了确保xla_generate()始终使用相同的输入形状,您可以在调用分词器时指定padding参数。

import tensorflow as tf
from transformers import AutoTokenizer, TFAutoModelForCausalLM
tokenizer = AutoTokenizer.from_pretrained("gpt2", padding_side="left", pad_token="</s>")
model = TFAutoModelForCausalLM.from_pretrained("gpt2")
input_string = ["TensorFlow is"]
xla_generate = tf.function(model.generate, jit_compile=True)
# Here, we call the tokenizer with padding options.
tokenized_input = tokenizer(input_string, pad_to_multiple_of=8, padding=True, return_tensors="tf")
generated_tokens = xla_generate(**tokenized_input, num_beams=2)
decoded_text = tokenizer.decode(generated_tokens[0], skip_special_tokens=True)
print(f"Generated -- {decoded_text}")

这样,您可以确保xla_generate()的输入始终接收与其跟踪时相同形状的输入,从而加快生成时间。您可以使用下面的代码进行验证:

import time
import tensorflow as tf
from transformers import AutoTokenizer, TFAutoModelForCausalLM
tokenizer = AutoTokenizer.from_pretrained("gpt2", padding_side="left", pad_token="</s>")
model = TFAutoModelForCausalLM.from_pretrained("gpt2")
xla_generate = tf.function(model.generate, jit_compile=True)
for input_string in ["TensorFlow is", "TensorFlow is a", "TFLite is a"]:
    tokenized_input = tokenizer(input_string, pad_to_multiple_of=8, padding=True, return_tensors="tf")
    start = time.time_ns()
    generated_tokens = xla_generate(**tokenized_input, num_beams=2)
    end = time.time_ns()
    print(f"Execution time -- {(end - start) / 1e6:.1f} ms\n")

在 Tesla T4 GPU 上,您可以期望输出如下:

Execution time -- 30819.6 ms
Execution time -- 79.0 ms
Execution time -- 78.9 ms

第一次调用xla_generate()由于跟踪而耗时,但后续调用速度快得多。请记住,任何时候对生成选项进行更改都会触发重新跟踪,从而导致生成时间变慢。

我们没有在本文档中涵盖🤗 Transformers 提供的所有文本生成选项。我们鼓励您阅读高级用例的文档。

额外资源

在这里,如果您想深入了解🤗 Transformers 中的 XLA 和一般情况下的 XLA,我们为您提供了一些额外资源。

  • 这个 Colab 笔记本提供了一个交互式演示,如果您想要尝试 XLA 兼容的编码器-解码器(如T5)和仅解码器(如GPT2)文本生成模型。
  • 这篇博客文章提供了 XLA 兼容模型的比较基准概述,以及对 TensorFlow 中 XLA 的友好介绍。
  • 这篇博客文章讨论了我们在🤗 Transformers 中为 TensorFlow 模型添加 XLA 支持的设计理念。
  • 学习更多关于 XLA 和 TensorFlow 图的推荐帖子:

使用 torch.compile() 优化推理

huggingface.co/docs/transformers/v4.37.2/en/perf_torch_compile

本指南旨在提供有关在🤗 Transformers 中使用 torch.compile() 为计算机视觉模型引入的推理加速的基准测试信息。

torch.compile 的好处

根据模型和 GPU,torch.compile() 在推理过程中可以提高高达 30%的速度。要使用 torch.compile(),只需安装任何版本高于 2.0 的torch

编译模型需要时间,因此如果您只编译模型一次而不是每次推理时都编译,这将非常有用。要编译您选择的任何计算机视觉模型,请按照以下示例在模型上调用 torch.compile()

from transformers import AutoModelForImageClassification
model = AutoModelForImageClassification.from_pretrained(MODEL_ID).to("cuda")
+ model = torch.compile(model)

compile() 有多种编译模式,它们在编译时间和推理开销方面有所不同。max-autotunereduce-overhead 花费更长的时间,但推理速度更快。默认模式在编译速度上最快,但与 reduce-overhead 相比在推理时间上效率不高。在本指南中,我们使用了默认模式。您可以在这里了解更多信息。

我们对torch.compile在不同的计算机视觉模型、任务、硬件类型和批处理大小上进行了基准测试,使用的是torch版本 2.0.1。

基准测试代码

下面您可以找到每个任务的基准测试代码。我们在推理之前对 GPU 进行预热,并使用相同的图像进行 300 次推理的平均时间。

使用 ViT 进行图像分类

import torch
from PIL import Image
import requests
import numpy as np
from transformers import AutoImageProcessor, AutoModelForImageClassification
url = 'http://images.cocodataset.org/val2017/000000039769.jpg'
image = Image.open(requests.get(url, stream=True).raw)
processor = AutoImageProcessor.from_pretrained("google/vit-base-patch16-224")
model = AutoModelForImageClassification.from_pretrained("google/vit-base-patch16-224").to("cuda")
model = torch.compile(model)
processed_input = processor(image, return_tensors='pt').to(device="cuda")
with torch.no_grad():
    _ = model(**processed_input)
使用 DETR 进行目标检测
from transformers import AutoImageProcessor, AutoModelForObjectDetection
processor = AutoImageProcessor.from_pretrained("facebook/detr-resnet-50")
model = AutoModelForObjectDetection.from_pretrained("facebook/detr-resnet-50").to("cuda")
model = torch.compile(model)
texts = ["a photo of a cat", "a photo of a dog"]
inputs = processor(text=texts, images=image, return_tensors="pt").to("cuda")
with torch.no_grad():
    _ = model(**inputs)
使用 Segformer 进行图像分割
from transformers import SegformerImageProcessor, SegformerForSemanticSegmentation
processor = SegformerImageProcessor.from_pretrained("nvidia/segformer-b0-finetuned-ade-512-512")
model = SegformerForSemanticSegmentation.from_pretrained("nvidia/segformer-b0-finetuned-ade-512-512").to("cuda")
model = torch.compile(model)
seg_inputs = processor(images=image, return_tensors="pt").to("cuda")
with torch.no_grad():
    _ = model(**seg_inputs)

下面您可以找到我们进行基准测试的模型列表。

图像分类

图像分割

目标检测

下面您可以找到使用和不使用 torch.compile() 的推理持续时间的可视化,以及每个模型在不同硬件和批处理大小下的百分比改进。

下面您可以找到每个模型使用和不使用 compile() 的推理持续时间(毫秒)。请注意,OwlViT 在较大批处理大小时会导致 OOM。

A100(批处理大小:1)

任务/模型 torch 2.0 - 无编译 torch 2.0 - 编译
图像分类/ViT 9.325 7.584
图像分割/Segformer 11.759 10.500
目标检测/OwlViT 24.978 18.420
图像分类/BeiT 11.282 8.448
目标检测/DETR 34.619 19.040
图像分类/ConvNeXT 10.410 10.208
图像分类/ResNet 6.531 4.124
图像分割/Mask2former 60.188 49.117
图像分割/Maskformer 75.764 59.487
图像分割/MobileNet 8.583 3.974
目标检测/Resnet-101 36.276 18.197
目标检测/Conditional-DETR 31.219 17.993


Transformers 4.37 中文文档(十)(3)https://developer.aliyun.com/article/1564904

相关文章
|
3月前
|
存储 机器学习/深度学习 编解码
Transformers 4.37 中文文档(五)(5)
Transformers 4.37 中文文档(五)
189 0
|
3月前
|
存储 缓存 Shell
Transformers 4.37 中文文档(一)(3)
Transformers 4.37 中文文档(一)
212 1
Transformers 4.37 中文文档(一)(3)
|
3月前
|
存储 PyTorch TensorFlow
Transformers 4.37 中文文档(二)(2)
Transformers 4.37 中文文档(二)
106 7
|
3月前
|
编解码 缓存 算法
Transformers 4.37 中文文档(一百)(2)
Transformers 4.37 中文文档(一百)
33 1
|
3月前
|
自然语言处理 PyTorch TensorFlow
Transformers 4.37 中文文档(一百)(6)
Transformers 4.37 中文文档(一百)
30 1
|
3月前
|
存储 JSON 缓存
Transformers 4.37 中文文档(一百)(1)
Transformers 4.37 中文文档(一百)
41 1
|
3月前
|
PyTorch TensorFlow 算法框架/工具
Transformers 4.37 中文文档(四)(3)
Transformers 4.37 中文文档(四)
30 1
|
3月前
|
存储 自然语言处理 测试技术
Transformers 4.37 中文文档(八)(1)
Transformers 4.37 中文文档(八)
25 2
|
3月前
|
并行计算 PyTorch 算法框架/工具
Transformers 4.37 中文文档(八)(5)
Transformers 4.37 中文文档(八)
115 2
|
3月前
|
存储 PyTorch TensorFlow
Transformers 4.37 中文文档(二)(1)
Transformers 4.37 中文文档(二)
63 1