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

去年七月,我們宣佈英特爾和 Hugging Face 將合作構建用於 Transformer 模型的先進而簡單的硬體加速工具。今天,我們很高興地宣佈,我們已將英特爾 OpenVINO 新增到 Optimum 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 AutoImageProcessor, AutoModelForImageClassification
model_id = "juliensimon/autotrain-food101-1471154050"
model = AutoModelForImageClassification.from_pretrained(model_id)
processor = AutoImageProcessor.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=processor.image_mean, std=processor.image_std)
size = processor.size["height"]
_val_transforms = Compose(
[
Resize(size),
CenterCrop(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"
# Apply static quantization and export the resulting quantized model to OpenVINO IR format
quantizer.quantize(
quantization_config=quantization_config,
calibration_dataset=calibration_dataset,
data_collator=collate_fn,
remove_unused_columns=False,
save_directory=save_dir,
)
processor.save_pretrained(save_dir)
一兩分鐘後,模型已經量化完成。然後,我們可以使用我們的 OVModelForXxx
類輕鬆載入它,這些類等同於 `transformers` 庫中的 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, image_processor=processor)
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
# We run the evaluation step on 20% of the evaluation dataset
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, image_processor=processor)
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 減少到 90MB,縮小了 **3.8 倍**。對 5050 張影像預測進行快速基準測試,我們還注意到延遲加快了 **2.4 倍**,從每樣本 98 毫秒降至 41 毫秒。這對於幾行程式碼來說還不錯!
⚠️ 需要提及的重要一點是,模型在第一次推理之前才會編譯,這會增加第一次推理的延遲。因此,在進行您自己的基準測試之前,請務必先透過至少一次預測來預熱模型。
您可以在 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 愉快,感謝您的閱讀。