PyTorch 2.0 チュートリアル : 画像と動画 : 配備のために Vision Transformer を最適化する (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 05/05/2023 (2.0.0)
* 本ページは、PyTorch 2.0 Tutorials の以下のページを翻訳した上で適宜、補足説明したものです:
- Image and Video : Optimizing Vision Transformer Model for Deployment
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
- 人工知能研究開発支援
- 人工知能研修サービス(経営者層向けオンサイト研修)
- テクニカルコンサルティングサービス
- 実証実験(プロトタイプ構築)
- アプリケーションへの実装
- 人工知能研修サービス
- PoC(概念実証)を失敗させないための支援
- お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
◆ お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。
- 株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
- sales-info@classcat.com ; Website: www.classcat.com ; ClassCatJP
PyTorch 2.0 チュートリアル : 画像と動画 : 配備のために Vision Transformer を最適化する
Vision Transformer モデルは、あらゆる種類の SOTA 結果を獲得するために自然言語処理で導入された、最先端のアテンション・ベースの transformer モデルをコンピュータビジョン・タスクに応用します。Facebook Data-efficient 画像 Transformer DeiT は画像分類のために ImageNet 上で訓練された Vision Transformer モデルです。
このチュートリアルでは、最初に DeiT が何であるかそれをどのように利用するかをカバーし、それからモデルのスクリプト化、量子化、最適化そして iOS と Android apps での利用の完全なステップを通り抜けます。量子化、最適化モデルと非量子化、非最適化モデルのパフォーマンスも比較し、ステップとともにモデルに量子化と最適化を適用することの利益を示します。
DeiT とは何か
2012 年に深層学習がテイクオフしてから畳込みニューラルネットワーク (CNN) は画像分類のための主要モデルを持ってきましたが、CNN は典型的には SOTA 結果を獲得するには訓練のために何億もの画像を要求します。DeiT は遥かに少ないデータを必要とする vision transformer モデルで画像分類を遂行する際にトップクラスの CNN と競争するために訓練のためのリソースを計算し、これは DeiT の 2 つの主要コンポーネントにより可能にされます :
- データ増強、これは遥かに大規模なデータセット上の訓練をシミュレートします ;
- ネイティブ distillation (蒸留)、これは transformer ネットワークに CNN の出力から学習することを可能にします。
DeiT はデータとリソースへの制限されたアクセスで Transformer がコンピュータビジョン・タスクに成功的に適用できることを示します。DeiT のより多くの詳細については、レポジトリ と 論文 を見てください。
DeiT で画像を分類する
DeiT を使用してどのように画像を分類するかの詳細については DeiT レポジトリの README に従ってください、あるいは
素早いテストのためには、最初に必要なパッケージをインストールしてください :
pip install torch torchvision timm pandas requests
Google Colab で実行するには、以下のコマンドを実行して依存関係をインストールしてから :
!pip install timm pandas requests
下のスクリプトを実行します :
from PIL import Image
import torch
import timm
import requests
import torchvision.transforms as transforms
from timm.data.constants import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD
print(torch.__version__)
# should be 1.8.0
model = torch.hub.load('facebookresearch/deit:main', 'deit_base_patch16_224', pretrained=True)
model.eval()
transform = transforms.Compose([
transforms.Resize(256, interpolation=3),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize(IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD),
])
img = Image.open(requests.get("https://raw.githubusercontent.com/pytorch/ios-demo-app/master/HelloWorld/HelloWorld/HelloWorld/image.png", stream=True).raw)
img = transform(img)[None,]
out = model(img)
clsidx = torch.argmax(out)
print(clsidx.item())
2.0.0+cu117 Downloading: "https://github.com/facebookresearch/deit/zipball/main" to /var/lib/jenkins/.cache/torch/hub/main.zip Downloading: "https://dl.fbaipublicfiles.com/deit/deit_base_patch16_224-b5f2ef4d.pth" to /var/lib/jenkins/.cache/torch/hub/checkpoints/deit_base_patch16_224-b5f2ef4d.pth 269
この出力は 269 になるはずです、これはクラスインデックスから ラベルファイル への ImageNet リストに従って、‘timber wolf, grey wolf, gray wolf, Canis lupus’ にマップされます。
画像を分類するために DeiT モデルを利用できることを検証した今、モデルが iOS と Android apps 上で動作できるようにどのように変更するかを見ましょう。
DeiT のスクリプト化
モバイル上でモデルを使用するため、最初にモデルをスクリプト化する必要があります。素早い概要のためには Script and Optimize レシピ を見てください。前のステップで使用された DeiT モデルをモバイル上で実行できる TorchScript 形式に変換するためには下のコードを実行してください。
model = torch.hub.load('facebookresearch/deit:main', 'deit_base_patch16_224', pretrained=True)
model.eval()
scripted_model = torch.jit.script(model)
scripted_model.save("fbdeit_scripted.pt")
Using cache found in /var/lib/jenkins/.cache/torch/hub/facebookresearch_deit_main
サイズ約 346MB のスクリプト化されたモデルファイル fbdeit_scripted.pt が生成されます。
DeiT を量子化する
ほぼ同じである推論精度を保持する一方で訓練モデルのサイズを本質的に減じるには、量子化がモデルに適用できます。DeiT で使用される transformer モデルのおかげで、動的量子化をモデルに容易に適用できます、何故ならば動的量子化は LSTM と transformer モデルのために最善に動作するからです (より詳細については ここ を見てください)。
今は下のコードを実行します :
# Use 'x86' for server inference (the old 'fbgemm' is still available but 'x86' is the recommended default) and ``qnnpack`` for mobile inference.
backend = "x86" # replaced with ``qnnpack`` causing much worse inference speed for quantized model on this notebook
model.qconfig = torch.quantization.get_default_qconfig(backend)
torch.backends.quantized.engine = backend
quantized_model = torch.quantization.quantize_dynamic(model, qconfig_spec={torch.nn.Linear}, dtype=torch.qint8)
scripted_quantized_model = torch.jit.script(quantized_model)
scripted_quantized_model.save("fbdeit_scripted_quantized.pt")
/opt/conda/lib/python3.10/site-packages/torch/ao/quantization/observer.py:214: UserWarning: Please use quant_min and quant_max to specify the range for observers. reduce_range will be deprecated in a future release of PyTorch.
これはモデル fbdeit_quantized_scripted.pt のスクリプト化そして量子化されたバージョンを生成します、サイズ約 89MB を持ち、346MB の非量子化モデルサイズの 74% 縮小です!
同じ推論結果を生成するために scripted_quantized_model を利用できます :
out = scripted_quantized_model(img)
clsidx = torch.argmax(out)
print(clsidx.item())
# The same output 269 should be printed
269
DeiT を最適化する
モバイル上で量子化そしてスクリプト化されたモデルを使用する前の最後のステップはそれを最適化することです :
from torch.utils.mobile_optimizer import optimize_for_mobile
optimized_scripted_quantized_model = optimize_for_mobile(scripted_quantized_model)
optimized_scripted_quantized_model.save("fbdeit_optimized_scripted_quantized.pt")
生成された fbdeit_optimized_scripted_quantized.pt ファイルは量子化、スクリプト化、しかし非最適化モデルとおよそ同じサイズを持ちます。推論結果は同じままです。
out = optimized_scripted_quantized_model(img)
clsidx = torch.argmax(out)
print(clsidx.item())
# Again, the same output 269 should be printed
269
インタープリタを使用する
Lite インタープリタがどのくらいのモデルサイズ縮小と推論スピードアップの結果を出せるかを見るために、モデルの lite バージョンを作成しましょう。
optimized_scripted_quantized_model._save_for_lite_interpreter("fbdeit_optimized_scripted_quantized_lite.ptl")
ptl = torch.jit.load("fbdeit_optimized_scripted_quantized_lite.ptl")
モバイル上で lite バージョンを実行するとき lite モデルサイズは非 lite バージョンと同等ですが、推論スピードアップは期待されます。
推論スピードの比較
推論スピードが 4 つのモデル – 元のモデル、スクリプト化モデル、量子化とスクリプト化モデル、最適化・量子化とスクリプト化モデル – についてどのように異なるかを見るには、下のコードを実行します :
with torch.autograd.profiler.profile(use_cuda=False) as prof1:
out = model(img)
with torch.autograd.profiler.profile(use_cuda=False) as prof2:
out = scripted_model(img)
with torch.autograd.profiler.profile(use_cuda=False) as prof3:
out = scripted_quantized_model(img)
with torch.autograd.profiler.profile(use_cuda=False) as prof4:
out = optimized_scripted_quantized_model(img)
with torch.autograd.profiler.profile(use_cuda=False) as prof5:
out = ptl(img)
print("original model: {:.2f}ms".format(prof1.self_cpu_time_total/1000))
print("scripted model: {:.2f}ms".format(prof2.self_cpu_time_total/1000))
print("scripted & quantized model: {:.2f}ms".format(prof3.self_cpu_time_total/1000))
print("scripted & quantized & optimized model: {:.2f}ms".format(prof4.self_cpu_time_total/1000))
print("lite model: {:.2f}ms".format(prof5.self_cpu_time_total/1000))
original model: 298.14ms scripted model: 322.95ms scripted & quantized model: 226.33ms scripted & quantized & optimized model: 207.08ms lite model: 210.38ms
Google Colab 上で実行した結果は :
original model: 1236.69ms scripted model: 1226.72ms scripted & quantized model: 593.19ms scripted & quantized & optimized model: 598.01ms lite model: 600.72ms
以下の結果は各モデルでかかった推論時間と元のモデルに相対する各モデルのパーセンテージ削減を要約しています。
import pandas as pd
import numpy as np
df = pd.DataFrame({'Model': ['original model','scripted model', 'scripted & quantized model', 'scripted & quantized & optimized model', 'lite model']})
df = pd.concat([df, pd.DataFrame([
["{:.2f}ms".format(prof1.self_cpu_time_total/1000), "0%"],
["{:.2f}ms".format(prof2.self_cpu_time_total/1000),
"{:.2f}%".format((prof1.self_cpu_time_total-prof2.self_cpu_time_total)/prof1.self_cpu_time_total*100)],
["{:.2f}ms".format(prof3.self_cpu_time_total/1000),
"{:.2f}%".format((prof1.self_cpu_time_total-prof3.self_cpu_time_total)/prof1.self_cpu_time_total*100)],
["{:.2f}ms".format(prof4.self_cpu_time_total/1000),
"{:.2f}%".format((prof1.self_cpu_time_total-prof4.self_cpu_time_total)/prof1.self_cpu_time_total*100)],
["{:.2f}ms".format(prof5.self_cpu_time_total/1000),
"{:.2f}%".format((prof1.self_cpu_time_total-prof5.self_cpu_time_total)/prof1.self_cpu_time_total*100)]],
columns=['Inference Time', 'Reduction'])], axis=1)
print(df)
"""
Model Inference Time Reduction
0 original model 1236.69ms 0%
1 scripted model 1226.72ms 0.81%
2 scripted & quantized model 593.19ms 52.03%
3 scripted & quantized & optimized model 598.01ms 51.64%
4 lite model 600.72ms 51.43%
"""
Model Inference Time Reduction 0 original model 298.14ms 0% 1 scripted model 322.95ms -8.32% 2 scripted & quantized model 226.33ms 24.09% 3 scripted & quantized & optimized model 207.08ms 30.54% 4 lite model 210.38ms 29.44% '\n Model Inference Time Reduction\n0\toriginal model 1236.69ms 0%\n1\tscripted model 1226.72ms 0.81%\n2\tscripted & quantized model 593.19ms 52.03%\n3\tscripted & quantized & optimized model 598.01ms 51.64%\n4\tlite model 600.72ms 51.43%\n'
更に学習する
- Facebook Data-efficient Image Transformers
- Vision Transformer with ImageNet and MNIST on iOS
- Vision Transformer with ImageNet and MNIST on Android
以上