概述
PyTorch 是一个基于 Python 的深度学习模型开发框架。它是最受欢迎的行业标准 AI 框架之一,被广泛应用于计算机视觉和自然语言处理等众多领域。PyTorch 由 Meta 开发,现在是 Linux 基金会的一部分。英特尔与开源 PyTorch 项目合作,以优化 PyTorch 框架以适应英特尔® 硬件。最新的优化和功能首先在英特尔® 扩展 PyTorch 中发布,然后再将其合并到 PyTorch 中。英特尔扩展提供了量化功能,以实现大型深度学习模型的良好精度结果。
本文介绍了量化、量化类型,并通过一个代码示例演示了如何通过应用英特尔扩展 PyTorch 量化来加速基于 PyTorch 的模型。
什么是量化?
量化是对模型中所有或多个层精度的系统降低。这意味着将高精度类型(如深度学习中广泛使用的单精度浮点数(FP32))转换为低精度类型,例如 FP16(16 位)或 int8(8 位)。
这有助于实现:
- 降低内存带宽
- 存储量低
- 性能更高,精度损失最小或为零
量化对于大型模型尤为重要,例如基于 Transformer 架构的模型(如 BERT 或 GPT)
量化有两种类型:
- 静态:将模型的权重和激活量进行量化,当内存带宽和计算节省很重要时使用。
- 动态:权重在事先进行量化,但在推理过程中动态量化激活量。
如何执行静态和动态量化
英特尔扩展为 PyTorch 添加了最新的功能和优化,以在英特尔硬件上提供额外的性能提升。
该扩展可以作为 Python 模块加载或作为 C++库链接。Python 用户可以通过导入 intel_extension_for_pytorch 动态启用它。该扩展提供了内置的量化功能,以提供大多数流行深度学习工作负载(包括卷积神经网络(CNN)、自然语言处理(NLP)和推荐模型)的良好统计精度。英特尔扩展中的量化功能目前支持训练后量化。
要使用静态量化将现有的 FP32 模型量化为 int8 模型:
- 准备量化配置。对于默认静态量化配置,请使用 ipex.quantization.default_static_qconfig。
- 使用 ipex.quantization.prepare 方法准备模型进行校准。
- 对数据集进行校准。这种校准针对静态量化,因为它需要代表性数据集来确定最优量化参数,因此用户应分批向模型提供数据以进行校准。
- 使用 ipex.quantization.convert 方法将模型从 FP32 转换为 int8。此函数根据应用的校准和配置将 FP32 模型转换为 int8。
要使用动态量化将现有的 FP32 模型量化为 int8 模型,这与静态量化类似:
- 准备量化配置。对于默认动态量化配置,使用 ipex.quantization.default_dynamic_qconfig。
- 使用 ipex.quantization.prepare 方法准备 FP32 模型。提供参数,例如要量化的 FP32 模型、准备好的配置、示例输入和信息。
- 使用 ipex.quantization.convert 方法将模型从 FP32 转换为 int8。输入模型是步骤 2 中准备好的模型。
代码示例
数据集
对于静态量化,模型使用 CIFAR-10 数据集进行校准。CIFAR-10 是由 Alex Krizhevsky、Vinod Nair 和 Geoffrey Hinton 收集的 800 万张小图像数据集的一个子集。
该数据集包含 60,000 张图像,分为 10 个类别(飞机、汽车、鸟、猫、鹿、狗、青蛙、马、船和跑道)。每个类别恰好有 6,000 张图像。所有图像都是 32 x 32 像素,并且是彩色的。此外,这些类别是完全互斥的,这意味着类别之间没有重叠。
实现
代码示例演示了如何使用 Intel Extension for PyTorch 对 ResNet*-50 模型进行量化(使用静态和动态量化)。代码示例中实现了以下步骤:
下载并准备数据集
在这里,我们使用 torchvision 中可用的 CIFAR-10 数据集。
- 为了使数据适合模型:
- 转换数据。
- 将图片大小从 32 x 32 像素更改为 224 x 224 像素。
- 将它们转换为张量。
- 对它们进行归一化。
- 准备数据集的转换,如下所示:
transform = torchvision.transforms.Compose([
torchvision.transforms.Resize((224, 224)),
torchvision.transforms.ToTensor(),
torchvision.transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
- 初始化数据集。
test_dataset = torchvision.datasets.CIFAR10(root=DATA, train=False, transform=transform, download=Ture)
准备数据加载器。
要为静态量化校准创建特定大小批次的加载器,请按如下所示创建:
calibration_data_loader = torch.utils.data.DataLoader(
dataset=test_dataset,
batch_size=128
)
创建模型
使用 Torchvision 库中可用的预训练 ResNet-50 模型,默认权重。准备好的模型为 FP32。
model_fp32 = torchvision.models.resnet50(weights=torchvision.models.ResNet50_Weights.DEFAULT)
应用静态量化
创建一个实现之前描述步骤的 staticQuantize 函数。
- 执行静态量化,我们需要:
- 之前加载的 FP32 模型
- 示例数据
- 校准数据集
- 准备量化配置:
config_static = ipex.quantization.default_static_qconfig
在此代码示例中,我们使用默认的量化配置,但您也可以定义自己的配置。
- 使用声明的配置准备模型:
prepared_model_static = prepare(model_fp32,
qconfig_static,
example_inputs=data,
inplace=False)
- 使用校准数据集校准模型。从数据集中连续批次地给模型提供数据。
for batch_idx, (data, target) in enumerate(calibration_data_loader):
prepared_model_static(data)
if batch_idx % 10 == 0:
print("Batch %d/%d complete, continue ..." %(batch_idx+1, len(calibration_data_loader)))
- 转换模型。
converted_model_static = convert(prepared_model_static)
应用动态量化。
创建与 staticQuantize 函数类似的 dynamicQuantize 函数。
- 执行动态量化,我们只需要:
- 之前加载的 FP32 模型
- 示例数据
- 准备量化配置:
qconfig_dynamic = ipex.quantization.default_dynamic_qconfig
- 准备模型。
prepared_model_dynamic = prepare(model_fp32,
qconfig_dynamic,
example_inputs=data,
inplace=False)
- 将模型从 FP32 转换为 int8。
converted_model_dynamic = convert(prepared_model_dynamic)
这样就创建了两个函数,以利用量化提供的优化:
- DynamicQuantize 用于模型的动态量化
- StaticQuantize 用于静态模型量化
下一步
今天就开始使用 Intel Extension for PyTorch 量化扩展,并利用它为深度学习工作负载实现更好的精度结果。此外,Intel® Neural Compressor 提供量化功能,以提高推理速度。
了解并整合 Intel 的其他 AI 和机器学习框架优化以及端到端工具组合到您的 AI 工作流程中。
了解基于统一、开放、标准化的 oneAPI 编程模型,它是 Intel AI 软件组合的基础,有助于您准备、构建、部署和扩展您的 AI 解决方案。
关于第 4 代英特尔® 至强® 可扩展处理器的更多详细信息,请访问英特尔® AI 平台概述,了解英特尔如何赋能开发者在这些强大的 CPU 上运行端到端 AI 管道。