Proceso de implementación del modelo PyTorch (ONNX Runtime)

La implementación del modelo se refiere al proceso de hacer que un modelo de aprendizaje profundo entrenado se ejecute en un entorno específico. Dificultades que enfrenta el despliegue del modelo:

  • El entorno requerido para ejecutar el modelo es difícil de configurar. Los modelos de aprendizaje profundo generalmente están escritos por algunos marcos, como PyTorch y TensorFlow. Debido a las limitaciones del tamaño del marco y del entorno dependiente, el marco no es adecuado para la instalación en entornos de producción, como teléfonos móviles y placas de desarrollo.
  • La estructura del modelo de aprendizaje profundo suele ser relativamente grande y requiere una gran cantidad de potencia informática para cumplir con los requisitos de operación en tiempo real, y la eficiencia de la operación debe optimizarse.

Debido a estas dificultades, la implementación del modelo no se puede lograr mediante una configuración e instalación sencillas del entorno. Actualmente existe una canalización popular para la implementación de modelos:

        Para que el modelo se implemente finalmente en un entorno determinado, se puede usar cualquier marco de aprendizaje profundo para definir la estructura de la red, y los parámetros en la red se pueden determinar mediante el entrenamiento. Después de eso, la estructura y los parámetros del modelo se convertirán en una representación intermedia que solo describe la estructura de la red, y se realizarán algunas optimizaciones para la estructura de la red en la representación intermedia. Finalmente, escrito en un marco de programación de alto rendimiento orientado al hardware (como CUDA, OpenCL), el motor de inferencia que puede ejecutar de manera eficiente los operadores en la red de aprendizaje profundo convertirá la representación intermedia en un formato de archivo específico y ejecutará el modelo. eficientemente en la plataforma de hardware correspondiente.

Crear un modelo de PyTorch

A. Entorno de configuración

#Cree un entorno virtual llamado deployment con Python 3.7 preinstalado
conda create -n deployment python=3.7 -y
# Ingrese el entorno virtual
conda active deployment
# Instale la versión Gpu de PyTorch
# Seleccione la configuración adecuada del sitio web oficial y copie el ruta de descarga --- https://pytorch.org/get-started/locally/
cconda install pytorch torchvision cudatoolkit=11.3 -c pytorch
# Install ONNX Runtime, ONNX, OpenCV
pip install onnxruntime onnx opencv-python

b. Crear un modelo de PyTorch

import os

import cv2
import numpy as np
solicitudes de importación
import torch
import torch.onnx
from torch import nn

class 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,tamaño_del_núcleo=1,relleno=0)
        self.conv3 = nn.Conv2d(32,3,tamaño_del_núcleo=5,relleno=2)

        self.relu = nn.ReLU()

    def adelante(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

# Descargue el punto de control y
las URL de la imagen de prueba = ['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']
nombres = ['srcnn.pth', 'face.png']
para url, nombre en zip(urls, nombres) :
    si no, os.path.exists(name):
        open(name, 'wb').write(requests.get(url).contenido)

def init_torch_model():
    torch_model = SuperResolutionNet(upscale_factor=3)

    state_dict = torch.load('srcnn.pth')['state_dict']

    # Adaptar el punto de control
    para old_key en list(state_dict.keys()):
        new_key = '.'.join(old_key .split('.')[1:])
        state_dict[nueva_clave] = 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 a NCHW
input_img = np.transpose(input_img, [2, 0, 1])
input_img = np.expand_dims(input_img, 0)

# Inferencia
torch_output = model(torch.from_numpy( input_img)).separar().numpy()

# NCHW a 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)

# Mostrar imagen
cv2.imwrite("face_torch.png", torch_output)

El código crea una red clásica de súper resolución SRCNN . SRCNN primero aumenta la muestra de la imagen a la resolución correspondiente y luego procesa la imagen con 3 capas convolucionales. Si el script se ejecuta con normalidad, se guardará una foto de la cara en superresolución en face_torch.png .

Después de que el modelo de PyTorch se haya probado correctamente, comencemos oficialmente a implementar el modelo. Nuestra próxima tarea es convertir el modelo PyTorch en un modelo descrito por la representación intermedia ONNX.

c. Convierta el modelo PyTorch en un modelo descrito por ONNX

ONNX (Open Neural Network Exchange) es un formato lanzado conjuntamente por Facebook y Microsoft en 2017 para descripciones estándar de gráficos computacionales. En la actualidad, bajo el mantenimiento conjunto de varias instituciones, ONNX se ha acoplado a varios marcos de aprendizaje profundo y varios motores de inferencia. Por lo tanto, ONNX se considera un puente entre el marco de aprendizaje profundo y el motor de inferencia, al igual que el lenguaje intermedio del compilador. Debido a la diferente compatibilidad de varios marcos, ONNX generalmente solo se usa para representar gráficos estáticos que son más fáciles de implementar.

#  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 模型文件名就可以运行模型了。

Supongo que te gusta

Origin blog.csdn.net/xs1997/article/details/131747242
Recomendado
Clasificación