65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Intel® Extension for PyTorch 加速 PyTorch

starIconstarIconstarIconstarIconstarIcon

5.00/5 (2投票s)

2022 年 12 月 12 日

CPOL

6分钟阅读

viewsIcon

5095

一个开源扩展,可提升 PyTorch 性能

Intel 工程师与 PyTorch* 开源社区合作,以提高深度学习 (DL) 训练和推理性能。Intel® PyTorch 扩展是一个开源扩展,可优化 Intel® 处理器上的 DL 性能。许多优化最终将包含在未来的 PyTorch 主线版本中,但该扩展允许 PyTorch 用户更快地获得最新的功能和优化。除了 CPU,Intel PyTorch 扩展还将很快支持 Intel® GPU。

Intel PyTorch 扩展同时优化了命令式模式和图模式(**图 1**)。优化涵盖 PyTorch 算子、图和运行时。优化的算子和内核通过 PyTorch 分发机制进行注册。在执行过程中,Intel PyTorch 扩展会用其优化后的对应项覆盖一部分 ATen 算子,并为常见的用例提供一套额外的自定义算子和优化器。在图模式下,会应用额外的图优化过程来最大化性能。运行时优化封装在运行时扩展模块中,该模块为用户提供了几个 PyTorch 前端 API,以便更精细地控制线程运行时。

图 1. Intel® PyTorch* 扩展。

优化一瞥

内存布局是与视觉相关的算子的基本优化。为输入张量使用正确的内存格式可以显著提高 PyTorch 模型性能。“通道优先内存格式”通常对多个硬件后端都有益

这对 Intel 处理器同样适用。通过 Intel PyTorch 扩展,我们建议使用“通道优先”内存格式,即。

model = model.to(memory_format=torch.channels_last)
input = input.to(memory_format=torch.channels_last)

oneAPI 深度神经网络库 (oneDNN) 引入了用于权重的块状内存布局,以实现更好的向量化和缓存重用。为了避免运行时转换,我们在执行 oneDNN 算子之前将权重转换为预定义的最佳块格式。这项技术称为权重预打包,当用户调用扩展提供的 ipex.optimize 前端 API 时,它将用于推理和训练。

Intel PyTorch 扩展提供了几个自定义算子来加速流行的拓扑结构,包括用于 DLRM 等推荐模型的融合交互和合并嵌入袋,以及用于对象检测工作负载的 ROIAlign 和 FrozenBatchNorm。

优化器在训练性能中起着重要作用,因此我们在 Intel PyTorch 扩展中提供了高度优化的融合和拆分优化器。我们通过 ipex.optimize 前端提供 Lamb、Adagrad 和 SGD 的融合内核,因此用户无需更改其模型代码。这些内核在权重更新步骤中融合了模型参数及其梯度的内存密集型算子链,以便数据可以保留在缓存中,而无需再次从内存中加载。我们正在努力在即将推出的扩展版本中提供更多融合优化器。

BF16 混合精度训练通过加速计算、降低内存带宽压力和减少内存消耗来提供显著的性能提升。然而,在训练后期,权重更新会变得太小而无法累积。一种常见做法是保留 FP32 格式的权重主副本,这会使内存需求翻倍。增加的内存使用量会给需要大量权重的模型(如推荐模型)的工作负载带来负担,因此我们对 BF16 训练应用了“拆分”优化。我们将 FP32 参数拆分为上半部分和下半部分。上半部分是前 16 位,可以精确地视为 BF16 数字。下半部分是最后 16 位,用于保留精度。在执行前向和后向传播时,上半部分受益于 Intel CPU 上的原生 BF16 支持。在执行参数更新时,我们将上半部分和下半部分连接起来,将参数恢复到 FP32,从而避免精度损失。

深度学习从业者已经证明了较低数值精度的有效性。使用 32 位累加器的 16 位乘法器可以提高训练和推理性能,而不会影响精度。即使对于某些推理工作负载,使用 32 位累加器的 8 位乘法器也有效。较低的精度通过以下两种方式提高性能:额外的乘法-累加吞吐量提高了计算密集型操作的性能,而较小的占用空间通过减少内存层次结构中的内存事务来提高了内存带宽密集型操作的性能。

Intel 在第 3 代 Intel® Xeon® 可扩展处理器中引入了原生的 BF16 支持,具有 BF16→ FP32 融合乘加 (FMA) 和 FP32→BF16 转换 Intel® AVX-512 指令,可将理论计算吞吐量提高一倍(相对于 FP32 FMA)。BF16 将在下一代 Intel Xeon 可扩展处理器中通过 Intel® Advanced Matrix Extensions (Intel® AMX) 指令集进一步加速。

量化是指通过降低权重和/或激活值的数值精度来压缩深度网络中的信息。通过将参数信息从 FP32 转换为 INT8,模型会变小,从而在内存和计算需求方面节省大量成本。Intel 在第 2 代 Intel Xeon 可扩展处理器中引入了 AVX-512 VNNI 指令集扩展。它提供了更快的 INT8 数据计算,并提高了吞吐量。PyTorch 提供了几种不同的量化模型的方法。(请参阅 PyTorch 中的实际量化。)

图优化,例如算子融合,通过优化整体计算和内存带宽来最大化底层内核实现的性能。Intel PyTorch 扩展基于 TorchScript IR 应用算子融合过程,这得益于 oneDNN 的融合能力和扩展中专门的融合内核。整个优化对用户来说是完全透明的。常量折叠是一种编译时图优化,它用预先计算的常量节点替换具有常量输入的算子。对于推理,卷积+BatchNorm 折叠可以为许多模型带来可观的性能优势。用户可以通过 ipex.optimize 前端 API 获得此优势。值得注意的是,我们正在与 PyTorch 社区合作,以更好地将融合能力与 PyTorch NNC(神经网络编译器)结合起来,以达到最佳效果。

示例

Intel PyTorch 扩展可以作为 Python 程序的模块加载,或作为 C++ 程序的库链接。用户只需进行最少的代码更改即可获得所有优势。下面包含了一些示例,但您可以在我们的教程中找到更多示例。

BF16 训练

...
import torch
...
model = Model()
model = model.to(memory_format=torch.channels_last)
criterion = ...
optimizer = ...
model.train()
#################### code changes ####################
import intel_extension_for_pytorch as ipex
model, optimizer = ipex.optimize(model, optimizer=optimizer, dtype=torch.bfloat16)
######################################################
...
with torch.cpu.amp.autocast():
    # Setting memory_format to torch.channels_last could improve performance
    # with 4D input data.
    data = data.to(memory_format=torch.channels_last)
    optimizer.zero_grad()
    output = model(data)
    loss = ...
    loss.backward()
...

BF16 推理

...
import torch
...
model = Model()
model = model.to(memory_format=torch.channels_last)
model.eval()
#################### code changes ####################
import intel_extension_for_pytorch as ipex
model = ipex.optimize(model, dtype=torch.bfloat16)
######################################################
...
with torch.cpu.amp.autocast(),torch.no_grad():
    # Setting memory_format to torch.channels_last could improve performance
    # with 4D input data.
    data = data.to(memory_format=torch.channels_last)
    model = torch.jit.trace(model, data)
    model = torch.jit.freeze(model)
with torch.no_grad():
    output = model(data)
...

INT8 推理 – 校准

import os
import torch
model = Model()
model.eval()
data = torch.rand(<shape>)
# Applying torch.fx.experimental.optimization.fuse against model performs
# conv-batchnorm folding for better performance.
import torch.fx.experimental.optimization as optimization
model = optimization.fuse(model, inplace=True)
#################### code changes ####################
import intel_extension_for_pytorch as ipex
conf = ipex.quantization.QuantConf(qscheme=torch.per_tensor_affine)
for d in calibration_data_loader():
    # conf will be updated with observed statistics during calibrating with the dataset
    with ipex.quantization.calibrate(conf):
        model(d)
conf.save('int8_conf.json', default_recipe=True)
with torch.no_grad():
    model = ipex.quantization.convert(model, conf, torch.rand(<shape>))
######################################################
model.save('quantization_model.pt')

INT8 推理 – 部署

import torch
#################### code changes ####################
import intel_extension_for_pytorch as ipex
######################################################
model = torch.jit.load('quantization_model.pt')
model.eval()
data = torch.rand(<shape>)
with torch.no_grad():
    model(data)

性能

**图 2** 和 **图 3** 显示了使用 Intel PyTorch 扩展的潜在性能提升。基准测试在 2.3 GHz Intel Xeon Platinum 8380 处理器上进行。(有关硬件和软件配置的更多信息,请参阅测量详细信息。)离线是指使用套接字的所有核心运行具有大批量的单实例推理(**图 2**)。实时是指运行多实例、单批次推理,每个实例使用四个核心。

图 2. 使用 Intel® PyTorch* 扩展进行离线推理的性能提升。

图 3. 使用 Intel® PyTorch* 扩展进行推理的性能提升。

未来工作

Intel PyTorch 扩展的目的是快速为 PyTorch 用户带来在 Intel 处理器上的额外性能。我们将大部分优化上游到 PyTorch 主线,同时不断为最新的 Intel 硬件试验新功能和优化。我们鼓励用户尝试开源项目,并在 GitHub 存储库中提供反馈。

相关内容

技术文章

点播网络研讨会和工作坊

获取软件

Intel® AI Analytics Toolkit
通过优化的深度学习框架和高性能 Python* 库加速端到端的机器学习和数据科学管道。

立即获取
查看所有工具

© . All rights reserved.