著者: ヤン・イーチェン
1. 背景
最も人気のあるオープンソースの深層学習フレームワークの 1 つである PyTorch は、使いやすさと柔軟性により、学術コミュニティや研究コミュニティの間で人気があります。以前は、OpenVINO™ による PyTorch モデルのサポートは ONNX の移行段階にのみあり、OpenVINO™ ランタイムによってオフラインで直接ロードできるようにするには、PyTorch 動的モデルを ONNX 静的形式にエクスポートする必要がありましたが、PyTorch には次の機能も提供されていました。公式 torch.onnx. エクスポート インターフェイスは、開発者が ONNX モデルをエクスポートするのに役立ちますが、結局のところ、そこにはそのような「仲介者」が存在し、動的/静的入力設定など、多くの追加の構成作業も OpenVINO™ 開発者に不便をもたらします。 、opset バージョン設定が待機します。
2. OpenVINO™ は PyTorch モデル オブジェクトを直接サポートします
【RL1】 【RL2】 【YE3】 【 LR4】 【 LR5】 【LR6】 【YE7】
OpenVINO™ 2023.0 のリリースにより、新しい PyTorch フロントエンドが OpenVINO™ ツール ライブラリにプリインストールされ、開発者に新しい PyTorch モデルのサポート パスを提供し、よりフレンドリーなユーザー エクスペリエンスをもたらす - OpenVINO™ のモツールです。 PyTorchモデル オブジェクトを OpenVINO™ モデル オブジェクトに直接変換することが可能であり、開発者は中間移行としてONNX モデルを使用する必要がありません。
import torchvision
import torch
from openvino.tools.mo import convert_model
model = torchvision.models.resnet50(pretrained=True)
ov_model = convert_model(model)
中間移行方法としての ONNX と比較して、新しい PyTorch フロントエンドには次の特徴があります。
ONNXの移行 |
新しい PyTorchフロントエンド |
|
オフライン変換 |
サポート |
サポート |
オンライン変換 |
サポートされていません。ONNX ファイルをエクスポートする必要があります |
サポート |
変換ステップ |
面倒な |
インターフェイスを呼び出す必要があるのは 1 回だけです |
パラメータ設定 |
多くの |
中くらい |
オペレーターサポート |
リッチ |
中くらい |
現在サポートされている PyTorch モデル オブジェクトは次のとおりです。
- torch.nn.モジュール
- torch.jit.ScriptModule
- torch.jit.ScriptFunction
OpenVINO™ の内部では、PyTorch フロントエンドはモデル エクスポート用の TorchScript に基づいており、TorchScript は 2 つのモデル エクスポート モードをサポートしています。1 つはトレースと呼ばれ、もう 1 つはスクリプティングと呼ばれます。このうち、Tracing とは、モデルの実行中に実行されるモジュール演算子を PyTorch が追跡し、計算フロー グラフをリアルタイムに構築し、最終的にそれを中間表現に要約することを指します。ユーザーは、関数、モジュール、ジェネレーター、コルーチンなど、Python コードの詳細を理解する必要がありません。トレースは、渡された Tensor と Tensor Function を忠実に記録します。これは、関係のない単純なモジュールや関数に非常に適しています。標準的な畳み込みニューラル ネットワークなどのデータ関連の制御フローですが、欠点は、制御フローや、if ステートメントやループなどの計算グラフのダイナミクスをトレースが認識できないことです。たとえば、ループを拡張します。一方では、コンパイル最適化のためのスペースが増加する可能性がありますが、他方では、異なる推論が使用されるときにループが動的に長くなる場合、Tracing はこれを認識できません。トレース中のループのみを記録します。データ依存の制御フローを含むモジュールと関数を変換するために、実行時に構築されるのではなく、Python ソース コード レベルから解析するスクリプト メカニズムが提供されます。スクリプトはすべてのコードを理解し、実際にコンパイラのように構文分析やその他の操作を実行します。スクリプトは Python/Pytorch に埋め込まれた DSL に相当し、その文法は PyTorch 文法のサブセットにすぎません。つまり、スクリプトがサポートしていない演算や文法がいくつかあるため、コンパイル時に問題が発生します。
先ほどの例では、PyTorch フロントエンドはスクリプトを使用してモデルをエクスポートします。Tracing メソッドを使用したい場合は、インターフェースに example_input パラメータを追加できます。このとき、PyTorch フロントエンドは Tracing メソッドを呼び出しますTracing メソッドが失敗した場合は、Scripting モードを呼び出します。
import torchvision
import torch
from openvino.tools.mo import convert_model
model = torchvision.models.resnet50(pretrained=True)
ov_model = convert_model(model, example_input=torch.zeros(1, 3, 100, 100))
example_input で現在サポートされているデータ形式は次のとおりです。
- openvino.runtime.Tensor
- トーチ.テンソル
- np.ndarray
- テンソルを含むリストまたはタプル (openvino.runtime.Tensor / torch.Tensor / np.ndarray)
- key が入力名、value がテンソルである辞書 (openvino.runtime.Tensor / torch.Tensor / np.ndarray)
上記の 2 つの例では、動的入力モデル オブジェクトをエクスポートしていることに注意してください。モデルの入力形状を指定したい場合は、追加パラメーター input_shape/input を再度追加し、入力形状をパラメーターとして渡し、いずれかを選択します。この場合は、以下の実戦部分を参照できます。
最後に、開発者が後で使用するために静的 IR ファイルをエクスポートしたい場合は、次のインターフェイスを呼び出して OpenVINO™ モデル オブジェクトをシリアル化することもできます。
serialize(ov_model, str(ir_model_xml))
3、BERT モデルケースの戦闘
次に、例を使用して、BERT モデルの変換から定量化までのプロセス全体を完了する方法を見てみましょう。
1. PyTorchモデル オブジェクトを取得します。
torch_model = BertForSequenceClassification.from_pretrained(PRETRAINED_MODEL_DIR)
2. モデル パラメーターを設定し、OpenVINO™モデル オブジェクトに変換します。BERT は複数入力モデルであるため、追加の input=input_info パラメーターがここに追加され、これを使用して各入力の形状とデータ型を指定できます。マルチ入力モデル。
input_shape = PartialShape([1, -1])
input_info = [("input_ids", input_shape, np.int64),("attention_mask", input_shape, np.int64),("token_type_ids", input_shape, np.int64)]
default_input = torch.ones(1, MAX_SEQ_LENGTH, dtype=torch.int64)
inputs = {
"input_ids": default_input,
"attention_mask": default_input,
"token_type_ids": default_input,
}
model = convert_model(torch_model, example_input=inputs, input=input_info)
3. 検証データセットを準備し、量子化を開始します。前のステップで取得したモデルは openvino.runtime.Model タイプであり、NNCF ツールによって直接ロードできます。
calibration_dataset = nncf.Dataset(data_source, transform_fn)
# Quantize the model. By specifying model_type, we specify additional transformer patterns in the model.
quantized_model = nncf.quantize(model, calibration_dataset,
model_type=ModelType.TRANSFORMER)
4. 量子化されたモデルオブジェクトをコンパイルし、推論を実行します
compiled_quantized_model = core.compile_model(model=quantized_model, device_name="CPU")
output_layer = compiled_quantized_model.outputs[0]
result = compiled_quantized_model(inputs)[output_layer]
result = np.argmax(result)
print(f"Text 1: {sample['sentence1']}")
print(f"Text 2: {sample['sentence2']}")
print(f"The same meaning: {'yes' if result == 1 else 'no'}")
最終的な結果は次のとおりです。
本文 1: ウォルマートは、100 万人を超える国内従業員全員を検査して、彼らが合法的に雇用されているかどうかを確認すると発表した。
本文 2: 同社はまた、100 万人を超えるすべての国内従業員を調査して、法的地位を確保する予定であると述べた。
同じ意味:はい
完全な例とパフォーマンスの精度の比較については、以下を参照してください。
4. まとめ
最近リリースされた最新バージョンとして、OpenVINO™ 2023.0 の mo ツールは、ONNX を介した中間移行なしで PyTorch モデル オブジェクトを OpenVINO™ オブジェクトに直接変換できるため、開発者にとってオフライン変換や追加構成の必要性がなくなり、よりフレンドリーなユーザー エクスペリエンスが実現します。 。この機能はプレリリース状態にあるため、一部のオペレーターがサポートしていない可能性がありますが、現時点では、開発者は引き続き以前のパスを使用して、ONNX フロントエンドに依存して PyTorch モデルを変換できます。
[RL1]コンバージョンを行わないことが優れている理由の「利点」をリストアップする必要があります。つまり、私たちにとって改宗するかどうかはあまり重要ではないのです。list out は、値プロパティのような 1. 2. 3. 4. 5. を意味します。
[RL2]また、ONNX の利点を列挙しますか? できれば、この投稿が ONNX が悪いという偏見に偏らないようにできれば、これを誤解する人もいるかもしれません
[YE3]完了
ONNX を「クロスアウト」すべきではありません。他のブランドに対して行うと、ONNX 上でも見栄えが悪くなります。 【LR4】
一番良いのは、PyTorch と OpenVINO を一緒にストーリーのみを表示することです。 【LR5】
[LR6] ONNX を脇に置いて孤独に見せることもできますが、大丈夫です :)
[YE7]完了