Press "Enter" to skip to content

使用🤗 Optimum Intel和OpenVINO加速您的模型

使用🤗 Optimum Intel和OpenVINO加速您的模型 四海 第1张

去年7月,我们宣布Intel和Hugging Face将合作构建Transformer模型的最先进但简单的硬件加速工具。今天,我们非常高兴地宣布,我们已经将Intel OpenVINO添加到Optimum Intel中。您现在可以在各种Intel处理器上轻松执行OpenVINO Runtime的推理(请参阅支持设备的完整列表),并使用Hugging Face hub或本地托管的Transformer模型。您还可以使用OpenVINO神经网络压缩框架(NNCF)对模型进行量化,减小模型的大小和预测延迟,几乎只需几分钟。

这个首次发布基于OpenVINO 2022.2,并且可以使用我们的OVModels对大量PyTorch模型进行推理。可以在许多编码器模型(BERT,DistilBERT等)上应用训练后静态量化和量化感知训练。更多编码器模型将在即将发布的OpenVINO版本中支持。目前,编码器解码器模型的量化尚未启用,但随着我们对下一个OpenVINO版本的集成,这个限制将被解除。

让我们向您展示如何在几分钟内开始使用!

使用Optimum Intel和OpenVINO对Vision Transformer进行量化

在这个例子中,我们将对在food101数据集上进行图像分类的Vision Transformer(ViT)模型进行训练后静态量化。

量化是一种降低模型参数的内存和计算要求的过程。减少位数意味着推理时所需的内存较少,并且由于整数运算,矩阵乘法等操作可以更快地执行。

首先,让我们创建一个虚拟环境并安装所有依赖项。

virtualenv openvino
source openvino/bin/activate
pip install pip --upgrade
pip install optimum[openvino,nncf] torchvision evaluate

接下来,转到Python环境,导入适当的模块并下载原始模型及其特征提取器。

from transformers import AutoFeatureExtractor, AutoModelForImageClassification
​
model_id = "juliensimon/autotrain-food101-1471154050"
model = AutoModelForImageClassification.from_pretrained(model_id)
feature_extractor = AutoFeatureExtractor.from_pretrained(model_id)

训练后静态量化需要进行校准步骤,通过该步骤将数据馈送到网络中以计算量化激活参数。在这里,我们从原始数据集中取300个样本来构建校准数据集。

from optimum.intel.openvino import OVQuantizer
​
quantizer = OVQuantizer.from_pretrained(model)
calibration_dataset = quantizer.get_calibration_dataset(
    "food101",
    num_samples=300,
    dataset_split="train",
)

与图像数据集一样,我们需要应用与训练时相同的图像转换。我们使用特征提取器中定义的预处理方法。我们还定义了一个数据整理函数,以批量提供格式正确的张量给模型。

import torch
from torchvision.transforms import (
    CenterCrop,
    Compose,
    Normalize,
    Resize,
    ToTensor,
)
​
normalize = Normalize(mean=feature_extractor.image_mean, std=feature_extractor.image_std)
_val_transforms = Compose(
    [
        Resize(feature_extractor.size),
        CenterCrop(feature_extractor.size),
        ToTensor(),
        normalize,
    ]
)
def val_transforms(example_batch):
    example_batch["pixel_values"] = [_val_transforms(pil_img.convert("RGB")) for pil_img in example_batch["image"]]
    return example_batch
​
calibration_dataset.set_transform(val_transforms)
​
def collate_fn(examples):
    pixel_values = torch.stack([example["pixel_values"] for example in examples])
    labels = torch.tensor([example["label"] for example in examples])
    return {"pixel_values": pixel_values, "labels": labels}

对于我们的第一次尝试,我们使用量化的默认配置。您还可以指定在校准步骤中使用的样本数量,默认为300。

from optimum.intel.openvino import OVConfig
​
quantization_config = OVConfig()
quantization_config.compression["initializer"]["range"]["num_init_samples"] = 300

我们现在可以对模型进行量化了。 OVQuantizer.quantize() 方法对模型进行量化并将其导出为OpenVINO格式。 结果图由两个文件表示:一个描述网络拓扑的XML文件和一个描述权重的二进制文件。 结果模型可以在任何目标Intel®设备上运行。

save_dir = "quantized_model"

# 应用静态量化并将结果量化模型导出为OpenVINO IR格式
quantizer.quantize(
    quantization_config=quantization_config,
    calibration_dataset=calibration_dataset,
    data_collator=collate_fn,
    remove_unused_columns=False,
    save_directory=save_dir,
)
feature_extractor.save_pretrained(save_dir)

一两分钟后,模型被量化了。 然后,我们可以使用我们的 OVModelForXxx 类轻松加载它,这相当于Transformers库中的 AutoModelForXxx 类。 同样,我们可以创建管道并使用OpenVINO Runtime进行推理。

from transformers import pipeline
from optimum.intel.openvino import OVModelForImageClassification
​
ov_model = OVModelForImageClassification.from_pretrained(save_dir)
ov_pipe = pipeline("image-classification", model=ov_model, feature_extractor=feature_extractor)
outputs = ov_pipe("http://farm2.staticflickr.com/1375/1394861946_171ea43524_z.jpg")
print(outputs)

为了验证量化对准确性没有产生负面影响,我们进行了评估步骤,比较了原始模型和量化模型的准确性。我们在数据集的子集上评估了这两个模型(只使用了20%的评估数据集)。我们观察到两个模型的准确性几乎没有损失,都为87.6

from datasets import load_dataset
from evaluate import evaluator

# 在评估数据集的20%上运行评估步骤
eval_dataset = load_dataset("food101", split="validation").select(range(5050))
task_evaluator = evaluator("image-classification")

ov_eval_results = task_evaluator.compute(
    model_or_pipeline=ov_pipe,
    data=eval_dataset,
    metric="accuracy",
    label_mapping=ov_pipe.model.config.label2id,
)

trfs_pipe = pipeline("image-classification", model=model, feature_extractor=feature_extractor)
trfs_eval_results = task_evaluator.compute(
    model_or_pipeline=trfs_pipe,
    data=eval_dataset,
    metric="accuracy",
    label_mapping=trfs_pipe.model.config.label2id,
)
print(trfs_eval_results, ov_eval_results)

观察量化模型,我们可以看到其内存大小从344MB减少了3.8倍,变为90MB。在5050个图像预测的快速基准测试中,我们还注意到推理延迟加速了2.4倍,从98ms减少到41ms每个样本。对于几行代码来说,这并不差!

⚠️ 一个重要的事情要提到的是,模型在第一次推理之前会被编译,这会增加第一次推理的延迟。因此,在进行自己的基准测试之前,请务必通过至少进行一次预测来预热模型。

您可以在Hugging Face hub上找到托管的结果模型。要加载它,您可以轻松执行以下操作:

from optimum.intel.openvino import OVModelForImageClassification
​
ov_model = OVModelForImageClassification.from_pretrained("echarlaix/vit-food101-int8")

现在轮到你了

​ 如您所见,使用 🤗 Optimum Intel 和 OpenVINO 加速您的模型非常容易。如果您想开始使用,请访问Optimum Intel存储库,并别忘了给它一个 ⭐星。您还可以在那里找到其他示例。如果您想深入了解OpenVINO,Intel文档可以提供帮助。

​ 尝试一下并告诉我们您的想法。我们非常乐意听取您在Hugging Face论坛上的反馈,请随时提出功能请求或在Github上报告问题。​

愿您享受使用 🤗 Optimum Intel,感谢您的阅读。

Leave a Reply

Your email address will not be published. Required fields are marked *