🤗 Optimum IntelとOpenVINOでモデルを高速化しましょう
'🤗 Optimum IntelとOpenVINOでモデル高速化!'
昨年7月、インテルとHugging Faceは、Transformerモデルのための最新かつシンプルなハードウェアアクセラレーションツールの開発で協力することを発表しました。本日、私たちはOptimum IntelにIntel OpenVINOを追加したことをお知らせできて非常に嬉しく思います。これにより、Hugging FaceハブまたはローカルにホストされるTransformerモデルを使用して、様々なIntelプロセッサ上でOpenVINOランタイムによる推論を簡単に実行できます(サポートされているデバイスの完全なリストを参照)。OpenVINOニューラルネットワーク圧縮フレームワーク(NNCF)を使用してモデルを量子化し、サイズと予測レイテンシをわずか数分で削減することもできます。
この最初のリリースはOpenVINO 2022.2をベースにしており、私たちのOVModels
を使用して、多くのPyTorchモデルに対する推論を実現しています。事後トレーニング静的量子化と量子化感知トレーニングは、多くのエンコーダモデル(BERT、DistilBERTなど)に適用することができます。今後のOpenVINOリリースでさらに多くのエンコーダモデルがサポートされる予定です。現在、エンコーダデコーダモデルの量子化は有効化されていませんが、次のOpenVINOリリースの統合により、この制限は解除されるはずです。
では、数分で始める方法をご紹介します!
- マルチリンガルASRのためのWhisperの調整を行います with 🤗 Transformers
- Diffusersを使用したDreamboothによる安定した拡散のトレーニング
- 新しい価格設定をご紹介します
Optimum IntelとOpenVINOを使用してVision Transformerを量子化する
この例では、食品101データセットでイメージ分類のためにファインチューニングされた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形式でエクスポートします。 結果のグラフは2つのファイルで表されます。ネットワークトポロジを説明する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)
1〜2分後、モデルが量子化されました。 次に、TransformersライブラリのAutoModelForXxx
クラスに相当するOVModelForXxx
クラスで簡単にモデルをロードできます。 同様に、パイプラインを作成し、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から90MBに3.8倍減少しました。 5050の画像予測でクイックベンチマークを実行すると、レイテンシが98msから41msの2.4倍高速化されていることもわかります。 それは少ないコードでの成果ですね!
⚠️ 重要なポイントとして、モデルは最初の推論の直前にコンパイルされるため、最初の推論のレイテンシが膨らみます。 自分自身のベンチマークを行う前に、少なくとも1回の予測でモデルをウォームアップすることを忘れないでください。
結果のモデルはHugging Faceハブでホストされています。 読み込むには、次のように簡単に行うことができます:
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で楽しんでください。読んでくださり、ありがとうございました。
We will continue to update VoAGI; if you have any questions or suggestions, please contact us!
Was this article helpful?
93 out of 132 found this helpful
Related articles