概览
PyTorch 是一个基于 Python 的深度学习模型开发框架。它是最受欢迎的行业标准 AI 框架之一,广泛用于计算机视觉和自然语言处理应用。PyTorch 由 Meta 开发,现已成为 Linux 基金会的一部分。Intel 与开源 PyTorch 项目合作,针对英特尔® 硬件优化 PyTorch 框架。最新的优化和功能首先在 Intel® Extension for PyTorch 中发布,然后再将其上游贡献到 PyTorch 中。Intel 扩展提供了量化功能,可为大型深度学习模型提供良好的精度结果。
本文介绍了量化、量化类型,并演示了如何通过应用 Intel Extension for PyTorch 量化来加速基于 PyTorch 的模型的代码示例。
什么是量化?
量化是系统性地降低模型中所有或部分层的精度。这意味着将较高精度类型(如深度学习中主要使用的单精度浮点数 (FP32))转换为较低精度类型,例如 FP16(16 位)或 int8(8 位)。
这有助于实现:
- 降低内存带宽
- 降低存储需求
- 在精度损失极小或为零的情况下提高性能
量化对于基于 Transformer 架构(如 BERT 或 GPT)的大型模型尤为重要。
量化有两种类型:
- 静态量化:这量化模型的权重和激活,在内存带宽和计算节省很重要时使用。
- 动态量化:权重提前量化,但激活在推理过程中动态量化。
如何执行静态量化和动态量化
Intel 扩展通过最新的功能和优化扩展了 PyTorch,以便在英特尔硬件上额外提升性能。
Intel Extension for PyTorch 安装说明
该扩展可以作为 Python 模块加载或作为 C++ 库链接。Python 用户可以通过导入 intel_extension_for_pytorch 来动态启用它。该扩展提供内置量化功能,可为大多数流行的深度学习工作负载(包括卷积神经网络 (CNN)、自然语言处理 (NLP) 和推荐模型)提供良好的统计精度。Intel 扩展中的量化功能目前支持训练后量化。
使用静态量化将现有 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 收集的 8000 万个小型图像数据集的子集。
此数据集包含 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 提供量化以提高推理速度。
查阅并将英特尔的其他AI 和机器学习框架优化以及端到端工具组合整合到您的 AI 工作流程中。
了解统一、开放、基于标准的 oneAPI 编程模型,它构成了英特尔 AI 软件组合的基础,可帮助您准备、构建、部署和扩展 AI 解决方案。
有关第四代英特尔® 至强® 可扩展处理器的更多详细信息,请访问英特尔® AI 平台概览,在那里您可以了解英特尔如何帮助开发者在这些强大的 CPU 上运行端到端 AI 流水线。