概述
PyTorch 是一个基于 Python 的深度学习模型开发框架。它是业界最流行的 AI 框架之一,广泛用于各种计算机视觉和自然语言处理应用。PyTorch 由 Meta 开发,现已成为 Linux 基金会的一部分。英特尔与开源 PyTorch 项目合作,优化 PyTorch 框架以适配 Intel® 硬件。最新的优化和功能首先在 Intel® Extension for PyTorch 中发布,然后再集成到 PyTorch 中。英特尔扩展提供了量化功能,可为大型深度学习模型提供良好的精度结果。
本文介绍了量化、量化类型,并演示了如何通过应用 Intel® Extension for PyTorch 量化来加速基于 PyTorch 的模型的代码示例。
什么是量化?
量化是系统地降低模型中所有或几个层的精度。这意味着将高精度类型(如深度学习中主要使用的单精度浮点数 (FP32))转换为低精度类型,例如 FP16(16位)或 int8(8位)。
这有助于实现:
- 更低的内存带宽
- 更小的存储空间
- 在精度损失最小甚至没有损失的情况下实现更高的性能
量化对于基于 Transformer 架构的大型模型(如 BERT 或 GPT)尤为重要。
量化有两种类型:
- 静态量化:对模型的权重和激活进行量化,当内存带宽和计算节省很重要时使用。
- 动态量化:权重提前量化,但激活在推理过程中动态量化。
如何执行静态量化和动态量化
英特尔扩展通过最新功能和优化扩展了 PyTorch,以在英特尔硬件上获得额外的性能提升。
Intel® Extension for 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 收集的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 解决方案。
有关第四代 Intel® Xeon® 可扩展处理器的更多详细信息,请访问 英特尔® AI 平台概述,了解英特尔如何赋能开发者在这些强大的 CPU 上运行端到端 AI 流水线。