PyTorch モデルから変換¶
PyTorch モデルを変換するには、openvino.convert_model
関数を使用します。
torchvision
のモデルを使用した PyTorch モデル変換の例を次に示します。
import torchvision
import torch
import openvino as ov
model = torchvision.models.resnet50(weights='DEFAULT')
ov_model = ov.convert_model(model)
openvino.convert_model
関数は、次の PyTorch モデル・オブジェクト・タイプをサポートします。
torch.nn.Module
派生クラスtorch.jit.ScriptModule
torch.jit.ScriptFunction
torch.nn.Module
を入力モデルとして使用する場合、openvino.convert_model
では、example_input
パラメーターが必要になることがあります。内部的には、torch.jit.trace
関数の機能を使用して、モデル変換プロセス中にモデルのトレースをトリガーします。
example_input
を使用すると、example_input
なしの変換と比較して、正確性とパフォーマンスの点で OpenVINO モデルの品質が向上します。example_input
の必要性は特定の PyTorch モデルの実装によって異なりますが、使用可能であれば example_input
パラメーターを常に設定することを推奨します。
example_input
パラメーターの値は、入力テンソルの要素のタイプと形状を知ることで簡単に分かります。すべてのケースに適しているわけではありませんが、乱数は多くの場合、この用途に有用です。
import torchvision
import torch
import openvino as ov
model = torchvision.models.resnet50(weights='DEFAULT')
ov_model = ov.convert_model(model, example_input=torch.rand(1, 3, 224, 224))
通常、PyTorch モデルを評価またはテストするコードが、モデル自体に提供されており、適切な example_input
値を生成するのに使用できます。torchvision
の resnet50
モデルを使用する変更例を以下に示します。既存の PyTorch アプリケーションの推論を OpenVINO に切り替える方法と、example_input
の値を取得する方法を示します。
from torchvision.io import read_image
from torchvision.models import resnet50, ResNet50_Weights
import requests, PIL, io, torch
# Get a picture of a cat from the web:
img = PIL.Image.open(io.BytesIO(requests.get("https://placekitten.com/200/300").content))
# Torchvision model and input data preparation from https://pytorch.org/vision/stable/models.html
weights = ResNet50_Weights.DEFAULT
model = resnet50(weights=weights)
model.eval()
preprocess = weights.transforms()
batch = preprocess(img).unsqueeze(0)
# PyTorch model inference and post-processing
prediction = model(batch).squeeze(0).softmax(0)
class_id = prediction.argmax().item()
score = prediction[class_id].item()
category_name = weights.meta["categories"][class_id]
print(f"{category_name}: {100 * score:.1f}% (with PyTorch)")
# OpenVINO model preparation and inference with the same post-processing
import openvino as ov
compiled_model = ov.compile_model(ov.convert_model(model, example_input=batch))
prediction = torch.tensor(compiled_model(batch)[0]).squeeze(0).softmax(0)
class_id = prediction.argmax().item()
score = prediction[class_id].item()
category_name = weights.meta["categories"][class_id]
print(f"{category_name}: {100 * score:.1f}% (with OpenVINO)")
対話型の Python チュートリアルでその他の例を確認してください。
注
上記の例では、openvino.save_model
関数は使用されていません。それは、この関数の使用法に関する PyTorch 固有の詳細情報がないためです。すべての例で、変換された OpenVINO モデルは、ov.save_model(ov_model, 'model.xml')
を呼び出すことで IR に保存できます。
サポートされる入力パラメーター・タイプ¶
モデルに単一の入力がある場合、example_input
では次の入力タイプがサポートされます。
openvino.Tensor
torch.Tensor
tuple
またはネストされたタプルの任意の組み合わせ
モデルに複数の入力がある場合、入力値は list
、tuple
、または dict
に結合されます。
list
またはtuple
内の値は、元のモデルが指定したのと同じ順序である必要があります。dict
には、元のモデルの引数名の名前からのキーがあります。
list
、tuple
、または dict
は、複数の入力だけでなく単一の入力にも使用できます。
モデルに単一の入力パラメーターがあり、この入力タイプが tuple
である場合、複数の入力の場合と同様に、常に追加の list
、tuple
、または dict
に囲んで渡す必要があります。この場合、model((a, b))
と model(a, b)
間のあいまいさを解消する必要があります。
非テンソル・データ・タイプ¶
tuple
や dict
などの非テンソル・データ・タイプがモデルの入出力に出現するとフラット化されます。フラット化とは、tuple
内の各要素が個別の入力または出力として表現されることを意味します。同じことが dict
値にも当てはまり、dict
のキーはモデルの入出力名を形成するために使用されます。元の非テンソル入力または出力は、このフラット化プロセスの結果として生じる新しい入力または出力に置き換えられます。このフラット化手順は、最もネストされたデータタイプがテンソルであると仮定されるまで、tuples
、lists
、および dicts
によるネストへは再帰的に適用されます。
例えば、元のモデルが example_input=(a, (b, c, (d, e)))
で呼び出された場合 (a
、b
、… e
はテンソル)、元のモデルには 2 つの入力があることを意味します。1 つ目はテンソル a
で、2 つ目は 2 つのテンソル b
と c
とネストされたタプル (d, e)
を含むタプル (b, c, (d, e))
です。次に、結果として得られる OpenVINO モデルにはシグネチャー (a, b, c, d, e)
が含まれます。これは、元のモデルの 2 つの入力の代わりに、すべてテンソルタイプの 5 つの入力を持つことを意味します。
モデルに {"x": a, "y": b, "z": c}
などの dict
入力がある場合、OpenVINO モデル・シグネチャーの複数の入力に分解されます: (a, b, c)
。ここで、入力はそれぞれ x
、y
、および z
の名前を想定します。
注
フラット化の重要な点は、固定数の要素とキー値を持つ tuple
と dict
のみがサポートされることです。このような入力構造は、convert_model
の example_input
パラメーターで明確にする必要があります。出力のフラット化は、与えられた example_input
を使用して再現する必要があり、変換が完了すると変更できなくなります。
次のチュートリアルで、非テンソル・データ・タイプを使用したモデル変換の例を確認してください。
PyTorch モデルを ONNX 形式にエクスポート¶
PyTorch モデルを変換する別の方法は、最初に torch.onnx.export
を使用して PyTorch モデルを ONNX にエクスポートし、次に、結果の .onnx
ファイルを openvino.convert_model
で OpenVINO モデルに変換することです。上位の章で説明したように、モデルを PyTorch から OpenVINO に直接変換できない場合のバックアップ・ソリューションとして検討できます。ONNX を介した変換は、コード、変換時間、使用するメモリーの点でコストが高くなる可能性があります。
PyTorch から ONNX にモデルをエクスポートする方法については、PyTorch モデルを ONNX 形式にエクスポートを参照してください。
ONNX モデルを変換に従って、OpenVINO モデルを作成します。
これら 2 つのステップを組み合わせて使用する例を示します。
import torchvision
import torch
import openvino as ov
model = torchvision.models.resnet50(weights='DEFAULT')
# 1. Export to ONNX
torch.onnx.export(model, (torch.rand(1, 3, 224, 224), ), 'model.onnx')
# 2. Convert to OpenVINO
ov_model = ov.convert_model('model.onnx')
注
バージョン 1.8.1 では、すべての PyTorch 操作をデフォルトで使用される ONNX opset 9 にエクスポートできるわけではありません。デフォルトの opset 9 へのエクスポートが機能しない場合は、モデルを opset 11 以降にエクスポートすることを推奨します。その場合は、torch.onnx.export
の opset_version
オプションを使用してください。ONNX opset の詳細については、オペレータースキーマを参照してください。