1.为什么需要部署
2.部署难题
3.部署流程
4.实战模型部署
5.总结
在软件工程中,部署指把开发完毕的软件投入使用的过程,包括环境配置、软件安装等步骤。对于深度学习模型来说,模型部署指让训练好的模型在特定环境中运行的过程。
运行模型所需的环境难以配置。深度学习模型通常是由一些框架编写,比如 PyTorch、TensorFlow。由于框架规模、依赖环境的限制,这些框架不适合在手机、开发板等生产环境中安装。
深度学习模型的结构通常比较庞大,需要大量的算力才能满足实时运行的需求。模型的运行效率需要优化。
step1. 使用任意一种DL框架搭建神经网络模型,并通过训练确定网络中的参数。
step2. 将模型结构和参数转换成一种只描述网络结构的中间表示
step3.用面向硬件的高性能编程框架(CUDA, OpenCL), 能够高效执行神经网络中算子推理引擎把中间表示转换为特定的文件格式, 并在对应的硬件平台上高效执行。
4.1 创建pytorch模型
step1: conda create -n python==3.6 pytorch_gpu
step2: conda activate pytroch_gpu
step3: conda install pytorch torchvision cudatoolkit=11.3 -c pytorch
step4: conda install pytorch torchvsion cpuonly -c pytorch
step5: pip install onnxruntion onnx opencv-python
4.2 创建一个DL网络模型结构
4.3 中间表示 – ONNX
x = torch.randn(1, 3, 512, 512)
with torch.no_grad:
torch.onnx_export(
model,
x,
"srcnn.onnx“,
opset_version=11,
input_names = ['input'],
output_name = ['output']
)
其中,torch.onnx.export 是 PyTorch 自带的把模型转换成 ONNX 格式的函数。
参数说明:
model:要转换的模型
x:模型的任意一组输入
“srcnn.onnx”:导出的 ONNX 文件的文件名。
opset_version : ONNX 算子集的版本。深度学习的发展会不断诞生新算子,为了支持这些新增的算子,ONNX会经常发布新的算子集,目前已经更新15个版本。我们令 opset_version = 11,即使用第11个 ONNX 算子集,是因为 SRCNN 中的 bicubic (双三次插值)在 opset11 中才得到支持。
input_names:输入tensor 的名称,后面会用。
output_names:输出tensor的名称,后面会用。
为什么需要为模型提供一组输入呢? 这涉及到 ONNX 转换的原理。从 PyTorch 的模型到 ONNX 的模型,本质上是一种语言上的翻译。直觉上的想法是像编译器一样彻底解析原模型的代码,记录所有控制流。但我们通常只用 ONNX 记录不考虑控制流的静态图。因此,PyTorch 提供了一种叫做追踪(trace)的模型转换方法:给定一组输入,再实际执行一遍模型,即把这组输入对应的计算图记录下来,保存为 ONNX 格式。export 函数用的就是追踪导出方法,需要给任意一组输入,让模型跑起来。我们的测试图片是三通道,256x256大小的,这里也构造一个同样形状的随机张量。
import onnx
onnx_model = onnx.load('srcnn.onnx')
try:
onnx.checker.check_model(onnx_model)
except Exception:
print('Model incorrect')
else:
print('Model correct')
其中, onnx.load 读取一个onnx模型, check_model 用于检查模型格式是否正确。
4.3 推理引擎 - ONNX Runtime
添加如下代码运行模型:
import cv2
import onnxruntion
import numpy as np
input_img = cv2.imread('1.png').astype(np.float32)
input_img = np.transpose(input_img, [2, 0, 1])
input_img = np.expand_dims(input_img, 0)
ort_session = onnxruntion.InferenceSession('srcnn.onnx')
ort_inputs = {'input' : input_img}
ort_output = ort_session.run(['output'], ort_inputs)[0]
ort_output = np.squeeze(ort_ouput, 0)
ort_output = np.clip(ort_output, 0, 255)
ort_output = np.transpose(ort_output, [1, 2, 0]).astype(np.uint8)
cv2.imwrite('1,png', ort_output)
仅仅采用了静态输入的方式导出onnx;需要匹配模型导出时指定的输入尺寸。
相关知识点:
模型部署,指把训练好的模型在特定环境中运行的过程。模型部署要解决模型框架兼容性差和模型运行速度慢这两大问题。
模型部署的常见流水线是“深度学习框架-中间表示-推理引擎”。其中比较常用的一个中间表示是 ONNX。
深度学习模型实际上就是一个计算图。模型部署时通常把模型转换成静态的计算图,即没有控制流(分支语句、循环语句)的计算图。
PyTorch 框架自带对 ONNX 的支持,只需要构造一组随机的输入,并对模型调用 torch.onnx.export 即可完成 PyTorch 到 ONNX 的转换。
推理引擎 ONNX Runtime 对 ONNX 模型有原生的支持。给定一个 .onnx 文件,只需要简单使用 ONNX Runtime 的 Python API 就可以完成模型推理。