pytorch.onnx.export方法参数详解,以及onnxruntime-gpu推理性能测试

2023-11-19

Torch.onnx.export执行流程:

1、如果输入到torch.onnx.export的模型是nn.Module类型,则默认会将模型使用torch.jit.trace转换为ScriptModule

2、使用args参数和torch.jit.trace将模型转换为ScriptModule,torch.jit.trace不能处理模型中的循环和if语句

3、如果模型中存在循环或者if语句,在执行torch.onnx.export之前先使用torch.jit.script将nn.Module转换为ScriptModule

4、模型转换成onnx之后,预测结果与之前会有稍微的差别,这些差别往往不会改变模型的预测结果,比如预测的概率在小数点之后五六位有差别。

Onnx模型导出,并能够处理动态的batch_size:

Torch.onnx.export导出模型:

检查导出的模型:

onnxruntime执行导出的onnx模型:

onnxruntime-gpu推理性能测试:

备注:安装onnxruntime-gpu版本时,要与CUDA以及cudnn版本匹配

网络结构:修改Resnet18输入层和输出层,输入层接收[N, 1, 64, 1001]大小的数据,输出256维

测试数据(重复执行10000次,去掉前两次的模型warmup):

输入数据batch_size = 1:[1, 1, 64, 1001]
        pytorch:            2.59 ms
        onnxruntime-gpu:    2.28 ms
        性能提升:           12%
        GPU峰值使用率:       95% vs 50% (Tesla P40, pytorch在前)
        CPU使用率:           单核100%

输入数据batch_size = 2:[2, 1, 64, 1001]
        pytorch:            2.92 ms
        onnxruntime-gpu:    2.73 ms
        性能提升:           6.5%
        GPU峰值使用率:       100% vs 41% (Tesla P40, pytorch在前)
        CPU使用率:           单核100%

输入数据batch_size = 4:[4, 1, 64, 1001]
        pytorch:            3.93 ms
        onnxruntime-gpu:    3.94 ms
        性能提升:           0%
        GPU峰值使用率:       100% vs 33% (Tesla P40, pytorch在前)
        CPU使用率:           单核100%

输入数据batch_size = 8:[8, 1, 64, 1001]
        pytorch:            6.84 ms
        onnxruntime-gpu:    21 ms
        性能提升:           -207%
        GPU峰值使用率:       100% vs 61% (Tesla P40, pytorch在前)
        CPU使用率:           单核100%

输入数据batch_size = 16:[16, 1, 64, 1001]
        pytorch:            13.85 ms
        onnxruntime-gpu:    11.41 ms
        性能提升:           17.6%
        GPU峰值使用率:       100% vs 29% (Tesla P40, pytorch在前)
        CPU使用率:           单核100%

输入数据batch_size = 32:[32, 1, 64, 1001]
        pytorch:            22.64 ms
        onnxruntime-gpu:    23.56 ms
        性能提升:           0%
        GPU峰值使用率:       100% vs 28% (Tesla P40, pytorch在前)
        CPU使用率:           单核100%

结论:onnxruntime可以提升模型推理速度,但是不擅长处理批量数据,不知道能不能这样理解?还是说只对于我这个网络模型是这个情况,没找到规律,也没找到参考文档,暂时还没搞清楚。关于这个问题,github上找到了这几个问题可以参考:

Gap in inference time between onnxruntime and torch vanishes when increasing the batch size · Issue #9660 · microsoft/onnxruntime · GitHub

https://github.com/microsoft/onnxruntime/issues/2796

https://towardsdatascience.com/an-empirical-approach-to-speedup-your-bert-inference-with-onnx-torchscript-91da336b3a41

 

onnx模型导出及onnxruntime推理完整代码:

import torch
import torchvision
import onnx
import onnxruntime
import numpy as np
import os

# 设置pytorch下载的预训练模型保存位置
os.environ["TORCH_HOME"] = "./pretrained_models"


def pytorch_2_onnx():
    """
    将pytorch模型导出为onnx,导出时pytorch内部使用的是trace或者script先执行一次模型推理,然后记录下网络图结构
    所以,要导出的模型要能够被trace或者script进行转换
    :return:
    """
    # 加载预训练模型
    model = torchvision.models.alexnet(pretrained=True)
    print(model)

    model_path = "alexnet.onnx"

    # pytorch转换为onnx内部使用trace或者script,需要提供一组输入数据执行一次模型推理过程,然后进行trace记录
    dummy_input = torch.randn(4, 3, 224, 224, device="cpu")
    input_names = ["input_data"] + ["learned_%d" % i for i in range(16)]
    output_names = ["output_data"]

    torch.onnx.export(
        model,  # pytorch网络模型
        dummy_input,    # 随机的模拟输入
        model_path,     # 导出的onnx文件位置
        export_params=True,     # 导出训练好的模型参数
        verbose=10,             # debug message
        training=torch.onnx.TrainingMode.EVAL,  # 导出模型调整到推理状态,将dropout,BatchNorm等涉及的超参数固定
        input_names=input_names,    # 为静态网络图中的输入节点设置别名,在进行onnx推理时,将input_names字段与输入数据绑定
        output_names=output_names,  # 为输出节点设置别名
        # 如果不设置dynamic_axes,那么对于输入形状为[4, 3, 224, 224],在以后使用onnx进行推理时也必须输入[4, 3, 224, 224]
        # 下面设置了输入的第0维是动态的,以后推理时batch_size的大小可以是其他动态值
        dynamic_axes={
            # a dictionary to specify dynamic axes of input/output
            # each key must also be provided in input_names or output_names
            "input_data": {0: "batch_size"},
            "output_data": {0: "batch_size"}
        })
    return model_path


def onnx_check(model_path):
    """
    验证导出的模型格式时候正确
    :param model_path:
    :return:
    """
    onnx_model = onnx.load(model_path)
    onnx.checker.check_model(onnx_model)
    print(onnx.helper.printable_graph(onnx_model.graph))


def onnx_inference(model_path):
    """
    模型推理
    :param model_path: 
    :return: 
    """
    # 使用onnxruntime-gpu在GPU上进行推理
    session = onnxruntime.InferenceSession(model_path,
                                           providers=[
                                               ("CUDAExecutionProvider", {  # 使用GPU推理
                                                   "device_id": 0,
                                                   "arena_extend_strategy": "kNextPowerOfTwo",
                                                   "gpu_mem_limit": 4 * 1024 * 1024 * 1024,
                                                   "cudnn_conv_algo_search": "EXHAUSTIVE",
                                                   "do_copy_in_default_stream": True,
                                                   # "cudnn_conv_use_max_workspace": "1"    # 在初始化阶段需要占用好几G的显存
                                               }),
                                               "CPUExecutionProvider"       # 使用CPU推理
                                           ])
    # session = onnxruntime.InferenceSession(model_path)
    data = np.random.randn(2, 3, 224, 224).astype(np.float32)

    # 获取模型原始输入的字段名称
    input_name = session.get_inputs()[0].name
    output_name = session.get_outputs()[0].name
    print("input name: {}".format(input_name))

    # 以字典方式将数据输入到模型中
    outputs = session.run([output_name], {input_name: data})
    print(outputs)


if __name__ == '__main__':
    model_path = pytorch_2_onnx()

    onnx_check(model_path)

    onnx_inference(model_path)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

pytorch.onnx.export方法参数详解,以及onnxruntime-gpu推理性能测试 的相关文章

  • 在pytorch张量中过滤数据

    我有一个张量X like 0 1 0 5 1 0 0 1 2 0 我想实现一个名为的函数filter positive 它可以将正数据过滤成新的张量并返回原始张量的索引 例如 new tensor index filter positive
  • 一次热编码期间出现 RunTimeError

    我有一个数据集 其中类值以 1 步从 2 到 2 i e 2 1 0 1 2 其中 9 标识未标记的数据 使用一种热编码 self one hot encode labels 我收到以下错误 RuntimeError index 1 is
  • 使 CUDA 内存不足

    我正在尝试训练网络 但我明白了 我将批量大小设置为 300 并收到此错误 但即使我将其减少到 100 我仍然收到此错误 更令人沮丧的是 在 1200 个图像上运行 10 epoch 大约需要 40 分钟 有什么建议吗 错了 我怎样才能加快这
  • 为什么 pytorch matmul 在 cpu 和 gpu 上执行时得到不同的结果?

    我试图找出 numpy pytorch gpu cpu float16 float32 数字之间的舍入差异 而我发现的内容让我感到困惑 基本版本是 a torch rand 3 4 dtype torch float32 b torch r
  • BatchNorm 动量约定 PyTorch

    Is the 批归一化动量约定 http pytorch org docs master modules torch nn modules batchnorm html 默认 0 1 与其他库一样正确 例如Tensorflow默认情况下似乎
  • 如何从已安装的云端硬盘文件夹中永久删除?

    我编写了一个脚本 在每次迭代后将我的模型和训练示例上传到 Google Drive 以防发生崩溃或任何阻止笔记本运行的情况 如下所示 drive path drive My Drive Colab Notebooks models if p
  • 在Pytorch中计算欧几里得范数..理解和实现上的麻烦

    我见过另一个 StackOverflow 线程讨论计算欧几里德范数的各种实现 但我很难理解特定实现的原因 如何工作 该代码可以在 MMD 指标的实现中找到 https github com josipd torch two sample b
  • BertForSequenceClassification 是否在 CLS 向量上进行分类?

    我正在使用抱脸变压器 https huggingface co transformers index html使用 PyTorch 打包和 BERT 我正在尝试进行 4 向情感分类并正在使用BertFor序列分类 https hugging
  • Pytorch .to('cuda') 或 .cuda() 不起作用并且卡住了

    我正在尝试做 pytorch 教程 当我尝试将他们的设备设置为 cuda 时 它不起作用并且我的代码运行被卡住 有关具体信息 我正在使用 conda 环境 蟒蛇3 7 3 火炬1 3 0 cuda 10 2 NVIDIA RTX2080TI
  • Huggingface 变形金刚模块未被 anaconda 识别

    我正在使用 Anaconda python 3 7 Windows 10 我尝试通过安装变压器https huggingface co transformers https huggingface co transformers 在我的环境
  • 如何将 35 类城市景观数据集转换为 19 类?

    以下是我的代码的一小段 使用它 我可以在城市景观数据集上训练名为 lolnet 的模型 但数据集包含 35 个类别 标签 0 34 imports trainloader torch utils data DataLoader datase
  • softmax_cross_entropy_with_logits 的 PyTorch 等效项

    我想知道 TensorFlow 是否有等效的 PyTorch 损失函数softmax cross entropy with logits TensorFlow 是否有等效的 PyTorch 损失函数softmax cross entropy
  • 当前向包含多个自动分级节点时,PyTorch 关于使用非完整后向挂钩的警告

    最近升级后 当运行 PyTorch 循环时 我现在收到警告 当前向包含多个自动分级节点时使用非完整后向钩子 训练仍在运行并完成 但我不确定应该将其放置在哪里register full backward hook功能 我尝试将它添加到神经网络
  • 如何让火车装载机使用特定数量的图像?

    假设我正在使用以下调用 trainset torchvision datasets ImageFolder root imgs transform transform trainloader torch utils data DataLoa
  • PyTorch 如何计算二阶雅可比行列式?

    我有一个正在计算向量的神经网络u 我想计算关于输入的一阶和二阶雅可比矩阵x 单个元素 有人知道如何在 PyTorch 中做到这一点吗 下面是我项目中的代码片段 import torch import torch nn as nn class
  • PyTorch 中的数据增强

    我对 PyTorch 中执行的数据增强有点困惑 现在 据我所知 当我们执行数据增强时 我们保留原始数据集 然后添加它的其他版本 翻转 裁剪 等 但 PyTorch 中似乎并没有发生这种情况 据我从参考文献中了解到 当我们使用data tra
  • PyTorch 中的标签平滑

    我正在建造一个ResNet 18分类模型为斯坦福汽车使用迁移学习的数据集 我想实施标签平滑 https arxiv org pdf 1701 06548 pdf惩罚过度自信的预测并提高泛化能力 TensorFlow有一个简单的关键字参数Cr
  • Tensorflow 到 ONNX 的转换

    我目前正在尝试转换我使用本教程创建的已保存 且正在工作 的 pb 文件 https github com thtrieu darkflow https github com thtrieu darkflow 到 onnx 文件中 我目前正在
  • 带有填充掩码的 TransformerEncoder

    我正在尝试使用 src key padding mask 不等于 none 来实现 torch nn TransformerEncoder 想象输入的形状src 20 95 二进制填充掩码的形状为src mask 20 95 填充标记的位置
  • 设置 torch.gather(...) 调用的结果

    我有一个形状为 n x m 的 2D pytorch 张量 我想使用索引列表来索引第二个维度 可以使用 torch gather 完成 然后然后还设置新值到索引的结果 Example data torch tensor 0 1 2 3 4

随机推荐