モデルのデプロイメントとは、トレーニングされた深層学習モデルを特定の環境で実行するプロセスを指します。モデルの導入で直面する困難:
- モデルを実行するために必要な環境を構成するのは困難です。深層学習モデルは通常、PyTorch や TensorFlow などのいくつかのフレームワークによって記述されます。フレームワークのサイズと依存環境の制限により、このフレームワークは携帯電話や開発ボードなどの実稼働環境へのインストールには適していません。
- 深層学習モデルの構造は通常比較的大きく、リアルタイム操作の要件を満たすには大量の計算能力が必要であり、操作効率を最適化する必要があります。
これらの問題のため、モデルの展開は単純な環境構成とインストールだけでは実現できません。現在、モデルをデプロイするための一般的なパイプラインがあります。
モデルを最終的に特定の環境にデプロイするには、任意の深層学習フレームワークを使用してネットワーク構造を定義し、トレーニングを通じてネットワーク内のパラメーターを決定できます。その後、モデルの構造とパラメータがネットワーク構造のみを記述する中間表現に変換され、ネットワーク構造に対するいくつかの最適化が中間表現に対して実行されます。最後に、ハードウェア指向の高性能プログラミング フレームワーク (CUDA、OpenCL など) で記述された推論エンジンは、深層学習ネットワークで演算子を効率的に実行でき、中間表現を特定のファイル形式に変換し、モデルを実行します。対応するハードウェア プラットフォーム上で効率的に実行できます。
PyTorchモデルを作成する
a.構成環境
#プリインストールされた Python 3.7 を使用して、deploy という仮想環境を作成します conda create -ndeploy python=3.7 -y #仮想環境に入ります conda activatedeploy #GPU バージョンの PyTorch をインストールします #公式 Web サイトから適切な構成を選択し、ダウンロード パス --- https://pytorch.org/get-started/locally/ cconda install pytorch torchvision cudatoolkit=11.3 -c pytorch # ONNX Runtime、ONNX、OpenCV をインストール pip install onnxruntime onnx opencv-python |
b. PyTorchモデルを作成する
os をインポート
cv2 をインポート numpy を np として インポート インポート要求 トーチを インポート torch.onnx をトーチからインポート nn
クラス SuperResolutionNet(nn.Module): def __init__(self, upscale_factor): super().__init__() self.upscale_factor = upscale_factor self。 img_upsampler = nn.Upsample( scale_factor=self.upscale_factor, mode='bicubic', align_corners=False)
self.conv1 = nn.Conv2d(3,64,kernel_size=9,padding=4) self.conv2 = nn.Conv2d( 64,32,kernel_size=1,padding=0) self.conv3 = nn.Conv2d(32,3,kernel_size=5,padding=2)
self.relu = nn.ReLU()
def forward(self, x): x = self.img_upsampler(x) out = self.relu(self.conv1(x)) out = self.relu(self.conv2(out) ) out = self.conv3(out) return out
# チェックポイントのダウンロードとテストイメージの URL = ['https://download.openmmlab.com/mmediting/restorers/srcnn/srcnn_x4k915_1x16_1000k_div2k_20200608-4186f232.pth', 'https://raw .githubusercontent.com/open-mmlab/mmediting/master/tests/data/face/000001.png'] names = ['srcnn.pth', 'face.png'] for URL、zip 内の名前(urls, names) : os.path.exists(name) でない場合: open(name, 'wb').write(requests.get(url)。コンテンツ)
def init_torch_model(): torch_model = SuperResolutionNet(upscale_factor=3)
state_dict = torch.load('srcnn.pth')['state_dict'] # list(state_dict.keys()) の old_key の
チェックポイントを調整します: new_key = '.'.join(old_key) .split('.')[1:]) state_dict[new_key] = state_dict.pop(old_key) torch_model.load_state_dict(state_dict) torch_model.eval() return torch_model model = init_torch_model() input_img = cv2.imread('face. png').astype(np.float32) # HWC から NCHW へinput_img = np.transpose(input_img, [2, 0, 1]) input_img = np.expand_dims(input_img, 0) # 推論torch_output = model(torch.from_numpy( input_img)).detach().numpy()
# NCHW から HWC へ torch_output = np.squeeze(torch_output, 0) torch_output = np.clip(torch_output, 0, 255) torch_output = np.transpose(torch_output, [1, 2, 0]).astype(np.uint8)
#画像を表示 cv2.imwrite("face_torch.png", torch_output) |
このコードは、古典的な超解像度ネットワークSRCNNを作成します。SRCNN は、まず画像を対応する解像度にアップサンプリングし、次に 3 つの畳み込み層で画像を処理します。スクリプトが正常に実行されると、超解像度の顔の写真がface_torch.pngに保存されます。
PyTorch モデルが正しくテストされたら、モデルのデプロイを正式に開始しましょう。次のタスクは、PyTorch モデルを中間表現 ONNX で記述されたモデルに変換することです。
c. PyTorchモデルをONNXで記述されたモデルに変換します。
ONNX (Open Neural Network Exchange) は、Facebook と Microsoft が 2017 年に共同でリリースした計算グラフの標準記述形式です。現在、ONNX は複数の機関の共同メンテナンスのもと、さまざまな深層学習フレームワークやさまざまな推論エンジンとドッキングしています。したがって、ONNX は、コンパイラーの中間言語と同様に、深層学習フレームワークから推論エンジンへの橋渡しと見なされます。さまざまなフレームワークの互換性が異なるため、ONNX は通常、展開が容易な静的グラフを表すためにのみ使用されます。
# PyTorch 的模型转换成 ONNX 格式的模型 x = torch.randn(1, 3, 256, 256)
with torch.no_grad(): torch.onnx.export( model, x, "srcnn.onnx", opset_version=11, input_names=['input'], output_names=['output']) |
其中torch.onnx.export 是 PyTorch 自带的把模型转换成 ONNX 格式的函数。前三个参数分别是要转换的模型、模型的任意一组输入、导出的 ONNX 文件的文件名。
从 PyTorch 的模型到 ONNX 的模型,PyTorch提供了一种叫做追踪(trace)的模型转换方法:给定一组输入,再实际执行一遍模型,即把这组输入对应的计算图记录下来,保存为 ONNX 格式。export 函数用的就是追踪导出方法,需要给任意一组输入,让模型跑起来。测试图片是三通道256x256 大小的,这里也构造一个同样形状的随机张量。
opset_version 表示 ONNX 算子集的版本。input_names, output_names 是输入、输出 tensor 的名称。代码运行成功,目录下会新增一个 srcnn.onnx 的 ONNX 模型文件
# 验证模型文件是否正确,直接加在前面的代码后面就行 import onnx
onnx_model = onnx.load("srcnn.onnx") try: onnx.checker.check_model(onnx_model) except Exception: print("Model incorrect") else: print("Model correct") |
d.在ONNX Runtime上运行模型和推理
推理引擎-ONNX Runtime 是由微软维护的一个跨平台机器学习推理加速器。ONNX Runtime 是直接对接ONNX的,即ONNX Runtime可以直接读取并运行.onnx文件,而不需要再把.onnx格式的文件转换成其他格式的文件。也就是说,对于 PyTorch - ONNX - ONNX Runtime 这条部署流水线,只要在目标设备中得到 .onnx 文件,并在 ONNX Runtime 上运行模型,模型部署就算大功告成了。
ONNX Runtime 提供了 Python 接口。
# ONNX Runtime完成模型推理,还是在之前脚本后添加代码 import onnxruntime
ort_session = onnxruntime.InferenceSession("srcnn.onnx") ort_inputs = {'input': input_img} ort_output = ort_session.run(['output'], ort_inputs)[0]
ort_output = np.squeeze(ort_output, 0) ort_output = np.clip(ort_output, 0, 255) ort_output = np.transpose(ort_output, [1, 2, 0]).astype(np.uint8) cv2.imwrite("face_ort.png", ort_output) |
onnxruntime.InferenceSession 用于获取一个 ONNX Runtime 推理器,其参数是用于推理的 ONNX 模型文件。推理器的 run 方法用于模型推理,其第一个参数为输出张量名的列表,第二个参数为输入值的字典。其中输入值字典的 key 为张量名,value 为 numpy 类型的张量值。输入输出张量的名称需要和 torch.onnx.export 中设置的输入输出名对应。
如果代码正常运行的话,另一幅超分辨率照片会保存在 face_ort.png 中。这幅图片和刚刚得到的 face_torch.png 是一样的。即ONNX Runtime 成功运行了 SRCNN 模型,完成模型部署。
以后再想实现超分辨率的操作,只需要提供一个srcnn.onnx文件,并帮助用户配置好 ONNX Runtime 的 Python 环境,用几行代码就可以运行模型。或者可以利用 ONNX Runtime 编译出一个可以直接执行模型的应用程序。只需给用户提供 ONNX 模型文件,并让用户在应用程序选择要执行的 ONNX 模型文件名就可以运行模型了。