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