ONNXRuntime与PyTorch运行时间对比

        在网上看到一些对比ONNXRuntime与PyTorch运行效率的文章,很多人运行的结果展示出ONNX可以提升几倍的运行效率,那么究竟有没有这么神奇呢,我来试一试。

        系统:Ubuntu18.04

        CPU:    Intel8750H

        显卡:2070

        模型选择最常用的ResNet50

import torch
import torchvision.models as models

# import
model = models.resnet50(pretrained=True)

        首先将模型导出为onnx

# PyTorch model
torch.save(model, 'resnet.pth')

# random input
data = torch.rand(1,3,224,224)
# ONNX needs data example
torch.onnx.export(model, data, 'resnet.onnx')

        之后加载这两个模型

import onnxruntime

# PyTorch model
torch_model = torch.load('resnet.pth')
# ONNX model
onnx_model = onnxruntime.InferenceSession('resnet.onnx')
#torch_model.to("cuda:0")

        将模型多次运行,计算平均用时。

from timeit import timeit
import numpy as np

data = np.random.rand(1,3,224,224).astype(np.float32)
torch_data = torch.from_numpy(data)


def torch_inf():
    torch_model(torch_data)

def onnx_inf():
    onnx_model.run(None,{
                onnx_model.get_inputs()[0].name: data
           })
n = 200

#warmup
#for i in range(1,100):
#    torch_inf()
torch_t = timeit(lambda : torch_inf(), number=n)/n
onnx_t = timeit(lambda : onnx_inf(), number=n)/n

print(f"PyTorch {torch_t} VS ONNX {onnx_t}")

        我得到的效果是这样的

PyTorch 0.12086693297999773 VS ONNX 0.005529450080002789

        到这里,我们可以看到,ONNX的运行时间远远小于PyTorch。

        但是,这里有一个重要的问题。很多文章在这样测试的时候,忽略了model.eval()。这会让模型中一些inference时用不到的层也在执行。所以,我们在代码中加上

torch_model.eval()

        之后的输出就变成了

PyTorch 0.09768170792000092 VS ONNX 0.006109018884999386

        可以看到,效率差异没有那么的巨大了。那么如果使用GPU进行对比呢?

        我把onnxruntime换成onnxruntime-gpu,之后代码稍加改动

import onnxruntime

# PyTorch model
torch_model = torch.load('resnet.pth')
# ONNX model
onnx_model = onnxruntime.InferenceSession('resnet.onnx')
torch_model.to("cuda:0")
torch_data = torch.from_numpy(data).to("cuda:0")
torch_model.eval()

        此时的输出为

PyTorch 0.0061957750350029525 VS ONNX 0.006347028439995484

        那么,在GPU环境下,使用onnxruntime的时间和PyTorch基本是一致的。

要在PyTorch中使用ONNX Runtime运行ONNX模型,需要安装ONNX Runtime包。 安装ONNX Runtime: ``` pip install onnxruntime ``` 在Python中加载ONNX模型: ```python import onnxruntime as ort # Load model model_path = 'model.onnx' ort_session = ort.InferenceSession(model_path) # Input shape input_shape = ort_session.get_inputs()[0].shape # Input name input_name = ort_session.get_inputs()[0].name # Output name output_name = ort_session.get_outputs()[0].name # Input data import numpy as np input_data = np.ones(input_shape, dtype=np.float32) # Run inference output_data = ort_session.run([output_name], {input_name: input_data})[0] ``` 首先,我们导入onnxruntime包并加载ONNX模型。我们使用ort.InferenceSession()方法创建一个会话对象。然后使用ort_session.get_inputs()和ort_session.get_outputs()方法来获取输入和输出的元数据信息,这将帮助我们准备输入和输出数据。 在本例中,我们首先检索输入的形状,然后检索输入和输出的名称。接下来,我们为输入数据创建具有正确形状的numpy数组,并将其传递给run()方法以获取任意数量的输出。 最后,我们得到输出数据和格式化输出,以便在屏幕上获取矩阵的值。 ONNX Runtime提供了多种推理选项以优化性能和内存使用。可以使用以下代码设置性能和优化选项: ```python # Options ort_session.set_providers(['CPUExecutionProvider']) ort_session.set_providers(['CUDAExecutionProvider']) ort_session.set_providers(['TensorrtExecutionProvider']) ort_session.set_providers(['MIGraphXExecutionProvider']) ort_session.set_providers([ort.SessionOptions.ExecutionProvider_CPU]) ort_session.set_providers([ort.SessionOptions.ExecutionProvider_CUDA]) ort_session.set_providers([ort.SessionOptions.ExecutionProvider_Tensorrt]) ort_session.set_providers([ort.SessionOptions.ExecutionProvider_MIGraphX]) ort_session.set_optimization_level(0) ort_session.set_optimization_level(1) ort_session.set_optimization_level(2) ``` 这里我们可以设置CPU,CUDA,Tensorrt和MIGraphX的执行提供程序。此外,还可以设置优化级别以控制推理选项的优化程度。 在实际应用中,通常需要对使用ONNX Runtime对模型执行推理进行更多配置,以便在具体数据和平台上获得最佳性能。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值