介绍
将PyTorch和TensorFlow模型导入OpenVINO非常简单,只需几行代码即可。在PyTorch或TensorFlow中开发的模型可以轻松集成到OpenVINO的推理管道中,以在各种设备上获得最佳性能。开发人员不再需要管理模型导出或转换脚本:相反,模型可以以其原生格式被加载和部署。
下面的例子展示了如何在OpenVINO中轻松加载TensorFlow和PyTorch模型。模型被加载、转换为OpenVINO格式,并且只需几行代码就可以编译用于推理。
虽然上述例子提供了简单的方法来导入模型到OpenVINO,还有其他选项可以提供更多的自定义性和灵活性。这份解决方案简报的其余部分描述了各种选项,解释了何时使用每个选项,并提供了展示如何使用它们的代码片段。
在OpenVINO中处理模型
OpenVINO中的模型状态
在OpenVINO中,模型可以有三种状态:保存在磁盘上、加载但未编译(ov.Model)或加载并编译(ov.CompiledModel)。
保存在磁盘上:顾名思义,此状态的模型由一个或多个完全代表神经网络的文件组成。由于OpenVINO不仅支持其专有格式,还支持其他框架,因此模型的存储方式可能会有所不同。例如:
已加载但未编译:在此状态下,通过解析文件或转换现有框架对象,在内存中创建了一个模型对象(ov.Model)。由于尚未关联任何特定设备,因此还无法使用该对象进行推理,但它允许进行定制化,例如变更其输入形状、应用量化,甚至添加预处理步骤。
已加载且编译:当为运行模型对象(ov.CompiledModel)指定一个或多个设备时,便达到了这个状态,允许进行设备优化并启用推理。
在OpenVINO中读取、转换和保存模型的函数
OpenVINO提供了几个用于处理模型的函数:
从文件创建一个ov.Model。
支持的文件格式:OpenVINO IR、ONNX、PaddlePaddle、TensorFlow和TensorFlow Lite。PyTorch文件不直接支持。
OpenVINO文件直接读取,其他格式自动转换。
从文件或ov.Model对象创建一个ov.CompiledModel。
支持的文件格式:OpenVINO IR、ONNX、PaddlePaddle、TensorFlow和TensorFlow Lite。PyTorch文件不直接支持。
OpenVINO文件直接读取,其他格式自动转换。
从文件或Python内存对象创建一个ov.Model。
支持的文件格式:ONNX、PaddlePaddle、TensorFlow和TensorFlow Lite。
支持的框架对象:PaddlePaddle、TensorFlow和PyTorch。
该方法仅在Python API中可用。
将一个ov.Model保存为OpenVINO IR格式。
默认情况下将权重压缩为FP16。
该方法仅在Python API中可用。
本解决方案简报中的代码段展示了如何使用这些函数的示例。
TensorFlow 导入选项
OpenVINO直接支持TensorFlow,允许开发者在OpenVINO推理管道中使用他们的模型,无需更改。然而,存在多种方法,选择何种方法最佳可能并不明显。下图旨在简化这一决策过程,给定某个特定的上下文,尽管可能需要根据用例的特定情况考虑一些额外的因素。
方法1. 使用ov.convert_model函数转换(仅限Python)
如上所述,如果你的起点是内存中的Python对象,例如tf.keras.Model或tf.Module,直接获取OpenVINO模型的方法是使用ov.convert_model。这个方法生成一个ov.Model(三种状态之一),之后可以重新塑形,保存到OpenVINO IR,或编译以进行推理。代码可能如下所示:
import openvino as ov
import tensorflow as tf
# 1a. Convert model created with TF code
model = tf.keras.applications.resnet50.ResNet50(weights="imagenet")
ov_model = ov.convert_model(model)
# 1b. Convert model from file
ov_model = ov.convert_model("model.pb")
# 2. Compile model from memory
core = ov.Core()
compiled_model = core.compile_model(ov_model)
方法 2:使用ov.compile_model函数从文件中转换
如果你是从文件开始的话,你需要检查模型是否已经就绪或者是否需要进行定制,比如应用量化或者重塑其输入。
如果模型不需要定制,应当使用 ov.Core.compile_model,它读取、转换(如果需要的话)并编译模型,一步到位地为推理做好准备。代码应该像这样:
import openvino as ov
# 1. Compile model from file
core = ov.Core()
compiled_model = core.compile_model("model.pb")
方法 3. 使用ov.read_model函数从文件转换
如果模型确实需要自定义,可以使用 ov.read_model,因为它直接返回一个准备好进行量化或调整其输入形状的ov.Model。
import openvino as ov
# 1. Convert model from file
core = ov.Core()
ov_model = ov.read_model("model.pb")
# 2. Compile model from memory
compiled_model = core.compile_model(ov_model)
方法4. 使用OpenVINO模型转换器 (ovc CLI) 从文件转换
然而,如果事先已经知道输入的重塑,或者模型有多个输出但只需要其中一些,OpenVINO提供了两种等效的方式在转换模型时进行这些操作。其中一个是命令行指令ovc,另一个是前面提到的ov.convert_model(在方法1中讨论过)。
ovc工具与ov.convert_model类似,区别在于它是通过命令行工作而不是Python环境。它将把模型转换为OpenVINO IR格式,应用你指定的任何配置,并将转换后的模型保存到磁盘。如果你不是在Python中处理模型(例如,如果你是在C++环境中开发),或者如果你更喜欢使用命令行而不是Python脚本,那么这个工具很有用。
下面的代码展示了如何使用ovc转换模型,然后为推理加载它:
# 1. Convert model from file
ovc model.pb
import openvino as ov
# 2. Load model from file
core = ov.Core()
ov_model = core.read_model("model.xml")
# 3. Compile model from memory
compiled_model = core.compile_model(ov_model)
支持的模型格式
OpenVINO的不同功能支持从文件和Python对象中加载模型,允许使用TensorFlow 1.X和2.X的多种格式。
在TensorFlow 2.X中,模型通常以SavedModel格式保存,其中包含模型的检查点和训练信息。还支持另外两种格式:旧版Keras H5(.h5)和较新的Keras v3(.keras)。相比之下,TensorFlow 1.X的模型通常导出为冻结图,虽然还使用非冻结格式如SavedModel和MetaGraph。
因此,OpenVINO对TensorFlow模型的支持如下:
SavedModel — <SAVED_MODEL_DIRECTORY> 或 <INPUT_MODEL>.pb
Checkpoint — <INFERENCE_GRAPH>.pb 或 <INFERENCE_GRAPH>.pbtxt
MetaGraph — <INPUT_META_GRAPH>.meta
tf.keras.Model
tf.keras.layers.Layer
tf.Module
tf.function
tf.compat.v1.Graph
tf.compat.v1.GraphDef
tf.compat.v1.session
tf.train.checkpoint
注意TensorFlow 2.X的Keras H5和Keras v3格式并不是直接支持的,但是仍然为前者提供了指导。
OpenVINO还支持TensorFlow Lite文件。
PyTorch 导入选项
OpenVINO对PyTorch的直接支持允许开发者在OpenVINO推理流水线中无需更改即可使用他们的模型。OpenVINO提供了多种使用PyTorch的方式,因此在特定情况下可能不清楚哪种方法是最佳途径。以下图表旨在简化这个决策,给定一个特定的上下文,尽管取决于用例,可能需要考虑一些额外的因素。
PyTorch 模型可以直接从 Python 对象导入到 OpenVINO 中,尽管也可以使用保存的 PyTorch 文件。要使用保存的 PyTorch 文件,首先需要在 PyTorch 中加载它,将其转换为 Python 对象。
一旦将模型作为 PyTorch Python 对象加载,你可以决定是直接开始使用 OpenVINO 框架及其功能,还是在利用 OpenVINO 的优化的同时,仍然在 PyTorch 框架内操作。
方法1:使用 ov.convert_model 函数进行转换
如果首选OpenVINO,ov.convert_model 是要使用的方法。它生成一个 ov.Model(三种状态之一),该模型可以稍后被重新塑形、保存到 OpenVINO IR 或编译以进行推理。代码实现可能如下所示:
import openvino as ov
import torch
from torchvision.models import resnet50
# 1a. Convert model created with PyTorch code
model = resnet50(weights="DEFAULT")
model.eval()
ov_model = ov.convert_model(model, example_input=torch.rand(1, 3, 224, 224))
# 1b. Convert model loaded from PyTorch file
model = torch.load("model.pt")
model.eval()
ov_model = ov.convert_model(model)
# 2. Compile model from memory
core = ov.Core()
compiled_model = core.compile_model(ov_model)
请注意,是否需要设置example_input取决于使用的模型。然而,如果条件允许,建议始终设置它,因为这通常会导致更好的模型质量。
方法2:在PyTorch中使用OpenVINO后端
如果首选PyTorch语法,从PyTorch 2.0和OpenVINO 2023.1开始,可以通过在torch.compile中指定OpenVINO作为后端来优化PyTorch模型。
import openvino.torch
import torch
from torchvision.models import resnet50
# 1a. Compile model created with PyTorch code
model = resnet50(weights="DEFAULT")
model.eval()
compiled_model = torch.compile(model, backend="openvino")
# 1b. Compile model loaded from PyTorch file
model = torch.load("model.pt")
model.eval()
compiled_model = torch.compile(model, backend="openvino")
方法 3. 将模型导出为ONNX并使用OpenVINO的某种方法
如果前两种方法都无法成功转换模型,还有第三种方法,这种方法曾是在OpenVINO中使用PyTorch的主要方式,但现在主要被认为是备选方案。该方法包括将PyTorch模型导出为ONNX,然后使用OpenVINO中可用的不同方法加载它。
import torch
import openvino as ov
from torchvision.models import resnet50
# 1. Export PyTorch model to ONNX
model = resnet50(weights="DEFAULT")
model.eval()
dummy_input = torch.randn(1,3,224,224)
torch.onnx.export(model, dummy_input, "model.onnx")
# 2. Use an OpenVINO method to read and compile it, for example, compile_model
core = ov.Core()
compiled_model = core.compile_model("model.onnx")
支持的模型格式
由于PyTorch没有保存格式可以包含重现模型所需的一切而不使用torch,OpenVINO只支持直接加载Python对象。支持情况如下:
torch.nn.Module
torch.jit.ScriptModule
torch.jit.ScriptFunction
ONNX、PaddlePaddle和TensorFlow Lite 导入选项
TensorFlow和PyTorch并不是唯一受支持的框架,OpenVINO 也支持 ONNX、PaddlePaddle和TensorFlow Lite。本节的目的是简要介绍如何将它们导入到 OpenVINO 中。
ONNX、PaddlePaddle和TensorFlow Lite文件的支持情况与TensorFlow文件相同,即在 'TensorFlow 导入选项' 中描述的所有文件方法都适用于它们。唯一似乎也支持Python对象的是PaddlePaddle。
所有框架的完整支持情况如下:
文件 <input_model>.onnx
文件 <input_model>.pdmodel
paddle.hapi.model.Model
paddle.fluid.dygraph.layers.Layer
paddle.fluid.executor.Executor
文件 <input_model>.tflite
保存为IR以避免推理代码中的大型依赖项
另一个考虑因素是,要转换Python对象,原始框架在环境中是必需的。像TensorFlow和PyTorch这样的框架往往是庞大的依赖(多达数千兆字节),并不是所有的推理环境都有足够的空间来容纳它们。将模型转换为 OpenVINO IR 可以在 OpenVINO 是唯一依赖项的环境中使用它们,所需的磁盘空间要少得多。另一个好处是,直接加载和编译 OpenVINO 通常比加载原始框架中的模型,然后转换和编译它所需的运行时内存要少。
下面的示例显示了如何利用 OpenVINO IR:
# Run once
import openvino as ov
import tensorflow as tf
# 1. Convert model created with TF code
model = tf.keras.applications.resnet50.ResNet50(weights="imagenet")
ov_model = ov.convert_model(model)
# 2. Save model as OpenVINO IR
ov.save_model(ov_model, 'model.xml', compress_to_fp16=True) # enabled by default
# Repeat as needed
import openvino as ov
# 3. Load model from file
core = ov.Core()
ov_model = core.read_model("model.xml")
# 4. Compile model from memory
compiled_model = core.compile_model(ov_model)