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

通过 8 位量化轻松优化深度学习

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2022 年 5 月 17 日

CPOL

8分钟阅读

viewsIcon

5590

在本文中,我们将探讨如何使用 OpenVINOTM 工具包的神经网络压缩框架在 PyTorch 中进行 8 位量化。

作者:Alexander Kozlov、Yury Gorbachev、Alexander Suslov、Vasily Shamporov 和 Nikolay Lyalyushkin

如果你们来我家,可能会听到童话故事。世界各地都有不同的语音助手,它们可以做些非凡的事情。我的女儿喜欢让我们的助手给她讲关于奇妙世界的故事。

这几乎就像我们自己生活在科幻世界里。我惊叹于语音识别技术发展得如此之快,已经成为主流。二十年前,电影中那些能听懂语音的电脑似乎还很遥远。如今,我们已经习惯于使用语音识别来播放音乐或设置闹钟。随着硬件和软件的不断发展,我可以想象,在三年内,成年人可能就可以和他们的语音助手进行有趣的对话了。

计算机视觉领域也取得了类似的进步,目前已被应用于安全、安保和智能城市等领域。与语音识别一样,如果深度学习推理在边缘设备上进行,应用程序的响应速度会更快。连接到数据中心会引入不可避免的延迟。

然而,边缘设备的资源有限,因此需要优化深度学习模型以获得最佳性能。

一种方法是量化,即将用于参数信息的 32 位浮点数 (FP32) 转换为 8 位整数 (INT8)。在精度损失不大的情况下,可以在内存和计算需求方面节省大量成本。

使用低精度数字,可以同时处理更多的数字,从而提高应用程序性能。从 FP32 量化到 INT8 的理论最大性能提升是 4 倍。

目前的 Intel® CPU 和 Intel® 集成 GPU 支持 INT8,但旧硬件不支持。

克服量化的挑战

量化存在两个挑战:

  • 如何轻松地进行。过去,这是一个耗时的过程。
  • 如何保持精度。

Neural Network Compression Framework (NNCF) 解决了这两个挑战。NNCF 是一个高级算法套件,用于优化机器学习和深度学习模型,以便在 Intel® Distribution of OpenVINO™ 工具包中进行推理。NNCF 可与 PyTorch 和 TensorFlow 的模型配合使用。

NNCF 的主要功能之一是 8 位统一量化,它利用最新的学术研究来创建准确快速的模型。本文将介绍的这项技术称为量化感知训练 (QAT)。这种方法在模型训练期间模拟权重和激活的量化,以便在推理时将模型中的操作视为 8 位操作。然后使用微调来恢复量化造成的精度损失。与在模型训练完成后进行量化相比,QAT 具有更好的精度和可靠性。

与其他优化工具不同,NNCF 不需要用户手动更改模型或了解量化原理。它是高度自动化的。您只需使用 NNCF 特定的调用包装模型,然后在原始训练数据集上进行常规的微调。

如何使用 NNCF 进行统一 8 位量化

在此分步示例中,我们将使用Torchvision 库中的 PyTorch ResNet-18 图像分类模型。它已使用 ImageNet 进行了预训练,可用于各种应用。除了分类任务(例如,对犬种进行分类)之外,它还可以作为对象检测、人员识别或图像分割等管道的一部分。

您可以在此处下载包含以下步骤的 Jupyter Notebook。.

步骤 1:安装先决条件

创建一个单独的 Python 虚拟环境,并将其中的先决条件安装进去。

$pip install nncf[torch]
$pip install openvino openvino-dev

步骤 2:从 Python 代码导入 NNCF

通过在训练程序中添加以下 Python 指令来导入 NNCF:

import torch
import torchvision
import nncf # Important - should be imported directly after torch
from nncf import NNCFConfig
from nncf.torch import create_compressed_model
from nncf.torch.initialization import register_default_init_args

步骤 3:准备模型和数据

我们假设用户拥有原始 FP32 模型的训练流水线,其中包含模型加载、数据准备和训练循环等步骤。

model = torchvision.models.resnet18(pretrained=True) 
train_loader, val_loader = create_data_loaders(...) # placeholder for DataLoader

nncf_config_dict = {
    "input_info": {
      "sample_size": [1, 3, 64, 64]
    },
    "compression": {
        "algorithm": "quantization", # specify the algorithm here
    }
}

# Load a configuration file to specify compression
nncf_config = NNCFConfig.from_dict(nncf_config_dict)

# Provide data loaders for compression algorithm initialization, if necessary
nncf_config = register_default_init_args(nncf_config, train_loader)

# Apply the specified compression algorithms to the model
compression_ctrl, model = create_compressed_model(model, nncf_config)

OpenVINO™ 推理引擎在训练期间使用插入到模型中的量化规则,在推理时将模型转换为 INT8。

调用 create_compressed_model 会插入在训练期间模拟 8 位量化的操作。这种模拟有助于微调过程调整模型,以恢复由量化过程引起的精度偏差。

步骤 4:照常微调模型

接下来,使用常规的微调过程来提高精度。通常需要几个 epoch 的微调,学习率要小,与原始模型训练结束时通常使用的学习率相同。以下是我们训练程序中微调代码的一个简单示例。我们没有更改此代码。

total_epochs = 5
for epoch in range(total_epochs): 
    for i, (images, target) in enumerate(train_loader):
        output = model(images)
        loss = criterion(output, target)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

训练流水线无需其他更改。

步骤 5:将模型导出为 ONNX

要在 OpenVINO 推理引擎中使用 PyTorch 模型,我们首先需要将其转换为 ONNX。

我们将使用 NNCF 辅助函数将量化模型导出为 ONNX 格式。对于图像分类模型,API 非常简单。对于其他一些模型,您可能需要为导出添加其他功能,例如,一个虚拟的前向函数。

微调完成后,我们将调用此代码将微调后的模型导出为 ONNX 格式。

compression_ctrl.export_model('resnet18_int8.onnx')

步骤 6:将 ONNX 模型导出为 OpenVINO™ 中间表示 (IR)

OpenVINO 中间表示 (IR) 是 OpenVINO 推理引擎使用的文件格式。我们现在可以通过调用 OpenVINO™ 模型优化器工具将 ONNX 模型转换为 OpenVINO IR 格式。

表示模型的两个文件将保存到当前目录。我们使用 --mean_values 和 --scale_values 参数添加均值并将输出乘以标准差。这些值用于在训练期间对输入进行归一化,代表所有训练图像的颜色强度的均值和标准差。

使用这些模型优化器选项,在部署时无需对输入数据进行归一化。预处理将成为模型的一部分。

$mo \
--input_model resnet18_int8.onnx \
--input_shape "[1, 3, 64, 64]" \
--mean_values "[123.675, 116.28, 103.53]" \
--scale_values "[58.395, 57.12, 57.375]"

有关更多信息,请参阅模型优化器开发者指南

使用 OpenVINO 工具包测量性能

现在我们已经创建了一个优化模型,它将在 OpenVINO 推理引擎中以 8 位精度运行。

最后一步,我们将测量原始 FP32 模型和新 INT8 模型的推理性能。为此,我们使用 OpenVINO 工具包中的推理性能测量工具——Benchmark Tool。它使用随机生成的数据来测量推理性能,因此不会产生数据加载带来的开销。默认情况下,Benchmark Tool 会在 CPU 上以异步模式运行推理 60 秒。它以延迟(每张图像毫秒)和吞吐量(每秒帧数)的值返回推理速度。

为了获得更准确的性能,我们建议在关闭其他应用程序后,在终端中运行 Benchmark Tool (benchmark_app)。使用

$benchmark_app -m model.xml -d CPU

在 CPU 上为期一分钟的异步推理进行基准测试。

将 CPU 更改为 GPU 以在 Intel GPU 上进行基准测试。运行

$benchmark_app --help

以查看所有命令行选项的概述。

要测试我们在第 6 步导出的模型,我们使用

$benchmark_app -m resnet18_int8.xml -d CPU

您可以以相同的方式对原始 FP32 或 FP16 OpenVINO IR 模型进行基准测试以比较结果。

使用支持 Intel® Deep Learning Boost 技术的 Intel® Xeon® Platinum 8280 处理器,INT8 优化实现了 3.62 倍的加速(参见表 1)。在本地设置中使用 11 代 Intel® Core™ i7–1165G7 处理器和相同的指令集,加速为 3.63 倍。这些数字是使用 OpenVINO 2021.4.2 版本的 OpenVINO 基准测试基础架构测得的。

推理硬件 FP32 INT8 加速
Intel(R) Xeon(R) Platinum 8280 CPU @ 2.70GHz 1578 FPS 5714 FPS 3.62x
11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz 97 FPS 353 FPS 3.63x
表 1:使用 Neural Network Compression Framework 实现的 INT8 优化加速。FPS 是每秒帧数。

硬件配置
- 基于 Xeon 8280 的平台:1 节点,2 个 Intel Xeon 8280 CPU,Intel 参考平台,总 DDR4 内存 384 GB(12 插槽/32GB/2934),Ubuntu 18.04.6 LTS,5.0.0-23-generic。
- 基于 Core i7-1165G7 的平台:1 节点,1 个 Intel Core i7-1165G7 CPU,Intel 参考平台,总 DDR4 内存 8 GB(1 插槽/1GB/3200),Microsoft Windows 10 Enterprise,10.0.19042 N/A Build 19042。
图像分类推理:ResNet-18,BS=1,INT8,使用 OpenVINO 2021.4.2,由 Intel 于 2022 年 2 月 3 日测试。

结论

在本文中,我们演示了如何使用 NNCF 8 位量化感知训练来加速 PyTorch 模型的推理。正如我们所展示的,这个过程很简单,不需要对训练代码进行重大更改。使用 OpenVINO 进行部署的流程与浮点模型保持一致。

在未来的文章中,我们将展示如何在 TensorFlow 中使用 NNCF 进行模型推理优化,并介绍更多可以帮助实现加速的高级优化技术。

资源

声明和免责声明

性能因使用情况、配置和其他因素而异。详细信息请访问 www.Intel.com/PerformanceIndex

性能结果基于所显示日期在特定配置下进行的测试,可能无法反映所有公开可用的更新。有关配置详情,请参阅备份。任何产品或组件都不能做到绝对安全。

您的成本和结果可能会有所不同。

英特尔技术可能需要启用硬件、软件或服务激活。

Intel 否认所有明示和暗示的保修,包括但不限于适销性、特定用途的适用性以及不侵权的暗示保证,以及因履行过程、交易过程或贸易用途而产生的任何保证。

结果已估算或模拟。

© Intel Corporation。Intel、Intel 标志、OpenVINO 和 OpenVINO 标志是 Intel Corporation 或其子公司的商标。其他名称和品牌可能被声明为他人的财产。

© . All rights reserved.