使用 Intel® 神经压缩器为 PyTorch 实现易用性量化
创建时间:2025 年 4 月 1 日 | 最后更新时间:2025 年 4 月 1 日 | 最后验证:未验证
概述 ¶
大多数深度学习应用在推理时使用 32 位浮点精度。但低精度数据类型,尤其是 int8,由于性能显著提升而受到更多关注。采用低精度的一个关键问题是如何轻松减轻可能的精度损失并达到预定的精度要求。
Intel® Neural Compressor 旨在通过扩展 PyTorch,加入以精度驱动的自动调优策略来解决上述问题,帮助用户快速在 Intel 硬件上找到最佳量化模型,包括 Intel 深度学习加速(Intel DL Boost)和 Intel 高级矩阵扩展(Intel AMX)。
Intel®神经压缩器已作为开源项目发布在 GitHub 上。
功能
易用性 Python API:Intel®神经压缩器为用户提供简单的 Python 前端 API 和实用工具,用户只需对原始代码进行少量修改即可进行神经网络压缩。通常,只需在原始代码中添加 5 到 6 个条款。
量化:Intel®神经压缩器支持在 PyTorch fx 图模式和 eager 模型上对训练后静态量化、训练后动态量化和量化感知训练进行精度驱动的自动调优过程。
本教程主要关注量化部分。关于如何使用 Intel® Neural Compressor 进行剪枝和蒸馏,请参阅 Intel® Neural Compressor github 仓库中的相应文档。
入门指南
安装¶
# install stable version from pip
pip install neural-compressor
# install nightly version from pip
pip install -i https://test.pypi.org/simple/ neural-compressor
# install stable version from from conda
conda install neural-compressor -c conda-forge -c intel
支持的 Python 版本为 3.6 或 3.7 或 3.8 或 3.9
用法
用户要开始使用英特尔® 神经压缩器量化 API,需要进行一些小的代码更改。支持 PyTorch fx graph 模式和 eager 模式。
英特尔® 神经压缩器以 FP32 模型和 yaml 配置文件作为输入。为了构建量化过程,用户可以通过 yaml 配置文件或 Python API 指定以下设置:
校准数据加载器(静态量化所需)
评估数据加载器
评估指标
Intel® 神经压缩器支持一些流行的数据加载器和评估指标。有关如何在 yaml 配置文件中配置它们的详细信息,用户可以参考内置数据集。
如果用户想使用自开发的加载器或评估指标,Intel® 神经压缩器通过使用 Python 代码注册自定义加载器/指标来支持这一点。
请参考 yaml 模板了解 yaml 配置文件格式。
上行代码中用注释标出了对 Intel® Neural Compressor 所需的代码更改。
模型
本教程中,使用 LeNet 模型来演示如何处理 Intel® Neural Compressor。
# main.py
import torch
import torch.nn as nn
import torch.nn.functional as F
# LeNet Model definition
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(1, 10, kernel_size=5)
self.conv2 = nn.Conv2d(10, 20, kernel_size=5)
self.conv2_drop = nn.Dropout2d()
self.fc1 = nn.Linear(320, 50)
self.fc1_drop = nn.Dropout()
self.fc2 = nn.Linear(50, 10)
def forward(self, x):
x = F.relu(F.max_pool2d(self.conv1(x), 2))
x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2))
x = x.reshape(-1, 320)
x = F.relu(self.fc1(x))
x = self.fc1_drop(x)
x = self.fc2(x)
return F.log_softmax(x, dim=1)
model = Net()
model.load_state_dict(torch.load('./lenet_mnist_model.pth', weights_only=True))
预训练模型权重 lenet_mnist_model.pth 来源于此处。
以精度驱动的量化
Intel®神经网络压缩器支持基于精度的自动调优,以生成满足预定义精度目标的最佳 int8 模型。
下面是一个通过自动调优在 PyTorch FX 图模式下量化简单网络的示例。
# conf.yaml
model:
name: LeNet
framework: pytorch_fx
evaluation:
accuracy:
metric:
topk: 1
tuning:
accuracy_criterion:
relative: 0.01
# main.py
model.eval()
from torchvision import datasets, transforms
test_loader = torch.utils.data.DataLoader(
datasets.MNIST('./data', train=False, download=True,
transform=transforms.Compose([
transforms.ToTensor(),
])),
batch_size=1)
# launch code for Intel® Neural Compressor
from neural_compressor.experimental import Quantization
quantizer = Quantization("./conf.yaml")
quantizer.model = model
quantizer.calib_dataloader = test_loader
quantizer.eval_dataloader = test_loader
q_model = quantizer()
q_model.save('./output')
在 conf.yaml 文件中,Intel® Neural Compressor 内置的 top1 指标被指定为评估方法,并将 1%的相对精度损失设置为自动调优的精度目标。Intel® Neural Compressor 将遍历所有可能的按操作级别量化的配置组合,以找到达到预定义精度目标的最佳 int8 模型。
除了这些内置指标之外,Intel® Neural Compressor 还支持通过 Python 代码自定义指标:
# conf.yaml
model:
name: LeNet
framework: pytorch_fx
tuning:
accuracy_criterion:
relative: 0.01
# main.py
model.eval()
from torchvision import datasets, transforms
test_loader = torch.utils.data.DataLoader(
datasets.MNIST('./data', train=False, download=True,
transform=transforms.Compose([
transforms.ToTensor(),
])),
batch_size=1)
# define a customized metric
class Top1Metric(object):
def __init__(self):
self.correct = 0
def update(self, output, label):
pred = output.argmax(dim=1, keepdim=True)
self.correct += pred.eq(label.view_as(pred)).sum().item()
def reset(self):
self.correct = 0
def result(self):
return 100. * self.correct / len(test_loader.dataset)
# launch code for Intel® Neural Compressor
from neural_compressor.experimental import Quantization
quantizer = Quantization("./conf.yaml")
quantizer.model = model
quantizer.calib_dataloader = test_loader
quantizer.eval_dataloader = test_loader
quantizer.metric = Top1Metric()
q_model = quantizer()
q_model.save('./output')
在上述示例中,实现了一个包含 update()和 result()函数的类,用于记录每个 mini-batch 的结果并在最后计算最终精度。
量化感知训练
除了训练后静态量化、训练后动态量化之外,Intel® Neural Compressor 还支持以精度驱动的自动调优机制进行量化感知训练。
下面是一个在 PyTorch FX 图模式下对简单网络进行量化感知训练的示例。
# conf.yaml
model:
name: LeNet
framework: pytorch_fx
quantization:
approach: quant_aware_training
evaluation:
accuracy:
metric:
topk: 1
tuning:
accuracy_criterion:
relative: 0.01
# main.py
model.eval()
from torchvision import datasets, transforms
train_loader = torch.utils.data.DataLoader(
datasets.MNIST('./data', train=True, download=True,
transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])),
batch_size=64, shuffle=True)
test_loader = torch.utils.data.DataLoader(
datasets.MNIST('./data', train=False, download=True,
transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])),
batch_size=1)
import torch.optim as optim
optimizer = optim.SGD(model.parameters(), lr=0.0001, momentum=0.1)
def training_func(model):
model.train()
for epoch in range(1, 3):
for batch_idx, (data, target) in enumerate(train_loader):
optimizer.zero_grad()
output = model(data)
loss = F.nll_loss(output, target)
loss.backward()
optimizer.step()
print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
epoch, batch_idx * len(data), len(train_loader.dataset),
100. * batch_idx / len(train_loader), loss.item()))
# launch code for Intel® Neural Compressor
from neural_compressor.experimental import Quantization
quantizer = Quantization("./conf.yaml")
quantizer.model = model
quantizer.q_func = training_func
quantizer.eval_dataloader = test_loader
q_model = quantizer()
q_model.save('./output')
仅性能量化
为了性能基准测试,Intel® Neural Compressor 可以直接使用虚拟数据集生成 int8 模型。
下面是一个使用 PyTorch FX 图模式和一个虚拟数据集量化简单网络的示例。
# conf.yaml
model:
name: lenet
framework: pytorch_fx
# main.py
model.eval()
# launch code for Intel® Neural Compressor
from neural_compressor.experimental import Quantization, common
from neural_compressor.experimental.data.datasets.dummy_dataset import DummyDataset
quantizer = Quantization("./conf.yaml")
quantizer.model = model
quantizer.calib_dataloader = common.DataLoader(DummyDataset([(1, 1, 28, 28)]))
q_model = quantizer()
q_model.save('./output')
量化输出
用户可以通过 Intel® Neural Compressor 打印的日志了解有多少操作被量化,如下所示:
2021-12-08 14:58:35 [INFO] |********Mixed Precision Statistics*******|
2021-12-08 14:58:35 [INFO] +------------------------+--------+-------+
2021-12-08 14:58:35 [INFO] | Op Type | Total | INT8 |
2021-12-08 14:58:35 [INFO] +------------------------+--------+-------+
2021-12-08 14:58:35 [INFO] | quantize_per_tensor | 2 | 2 |
2021-12-08 14:58:35 [INFO] | Conv2d | 2 | 2 |
2021-12-08 14:58:35 [INFO] | max_pool2d | 1 | 1 |
2021-12-08 14:58:35 [INFO] | relu | 1 | 1 |
2021-12-08 14:58:35 [INFO] | dequantize | 2 | 2 |
2021-12-08 14:58:35 [INFO] | LinearReLU | 1 | 1 |
2021-12-08 14:58:35 [INFO] | Linear | 1 | 1 |
2021-12-08 14:58:35 [INFO] +------------------------+--------+-------+
量化模型将在./output 目录下生成,其中包含两个文件:1. best_configure.yaml 2. best_model_weights.pt
第一个文件包含每个操作的量化配置,第二个文件包含激活的 int8 权重、零点和缩放信息。
部署
用户可以使用以下代码加载量化模型并进行推理或性能基准测试。
from neural_compressor.utils.pytorch import load
int8_model = load('./output', model)
教程
请访问 Intel® Neural Compressor 的 GitHub 仓库以获取更多教程。