• onnx转换TensorRT的步骤


    A. 解析onnx

    已有的trt不适配,需要将onnx转为trt

    1. parse onnx
    2. serialize trt
    3. 保存trt文件

    注意:如果不使用Int8模式,onnx的parser代码几乎通用

    概览

    构建阶段

    1. 建立logger(日志)
    2. 建立builder(网络元数据)
    3. 创建network(计算图)(API独需)
    4. 生成序列化的网络(网络的trt内部表示)

    运行阶段

    1. 建立engine(可执行代码)
    2. 创建context(gpu进程)
    3. buffer准备(host+device)
    4. 拷贝host to device
    5. 执行推理execute
    6. 拷贝device to host
    7. 善后

    A.1 构建阶段

    1. 创建logger

    记录器

    getTRTLogger();

    2. 创建builder

    模型搭建的入口,网络的trt内部表示和引擎都是builder的成员方法生成的

    builder.create_optimization_profile():创建用于dynamic shape输入的配置器

    createInferBuilder()

    builder.create_network():创建tensorrt网络对象

    createNetworkV2()

    在builderconfig下面进行细节设置


    另外builder需要创建optimazation profile

    在给定输入张量的最小最常见最大尺寸后,将设置的profile传给config

    1. auto profile = builder->createOptimizationProfile();
    2. profile->setDimensions();
    3. config->addOptimizationProfile(profile);

    3. 设置builder config

    进行设置网络属性

    config=builder.create_builder_config()

    auto config = std::unique_ptr<nvinfer1::IBuilderConfig, samplesCommon::InferDeleter>(builder->createBuilderConfig());
    
    1. 指定构建期可用显存
    2. 设置标志位开关
    3. 指定校正器
    4. 添加用于dynamic shape输入的配置器
    1. config->addOptimizationProfile(profile);//添加用于dynamic shape输入的配置器
    2. config->setFlag();

    4. 搭建network

    创建network(计算图)是API独需的因为其他两种方法使用parser从onnx导入,不用一层层添加

    network=builder.create_network()

    在onnx-parser中一旦模型parser解析完成,network就自动填好了,成为了serialized network

    onnx-parser解析

    1. createParser(*network, sample::gLogger.getTRTLogger();
    2. parser->parseFromFile(modelFile.c_str(), static_cast(sample::gLogger.getReportableSeverity()));

    A.2 运行阶段 runtime

    5. 生成TRT内部表示-serialized network

    build_serialized_network(network,config)

    6. 生成engine

    推理引擎,可执行的代码段

    生成engine:

    m_engine = std::unique_ptr<nvinfer1::ICudaEngine, samplesCommon::InferDeleter>(builder->buildEngineWithConfig(*network, *config), samplesCommon::InferDeleter());
    

    7. 创建context

    context即GPU进程

    创建context:

    python:engine.create_execution_context()

     m_context = std::unique_ptr<nvinfer1::IExecutionContext, samplesCommon::InferDeleter>(m_engine->createExecutionContext(), samplesCommon::InferDeleter());
    

    绑定输入输出

    仅dynamic shape需要

    8. 准备buffer

    1. 内存和显存的分别申请
    2. 拷贝
    3. 释放

    python:cudart.cudaMalloc(inputHost.nbytes)[1]

    课程第四部分会对buffer部分的优化做介绍

    9. 执行计算-execute

    拷贝到cuda buffer上执行再拷贝回host,这一步一般是B.解析trt中做,但是读取onnx后也可以做

    10. 序列化引擎

    engine->serialize()

    11. 导出trt

    特殊情况

    遇到tensorrt不支持的onnx模型节点

    1. 修改源模型
    2. 修改onnx计算图,onnx-surgeon
    3. tensorrt中实现plugin
    4. 修改parser:修改源码,重新编译trt,因为tensorrt部分开源

    B. 解析trt

    已有trt,直接导入然后使用

    parse TRT后得到engine和context

    1. 创建logger

    getTRTLogger()

    2. 创建cudaruntime

    createInferRuntime()

    3. 解析/反序列化trt文件,生成引擎

    runtime->deserializeCudaEngine()

    4. 创建context

    engine->createExecutionContext()

    5. 使用

  • 相关阅读:
    springboot系列(二十):如何通过redis实现手机号验证码功能 |超级详细,建议收藏
    IT30--制造业数字化战略规划(论文1)
    高校为什么需要大数据挖掘平台?
    由浅到深带你详谈Java实现数组扩容的三种方式【建议收藏】
    uni-app中拦截webview窗口的URL请求
    ui自动化-appium
    免费,C++蓝桥杯等级考试真题--第7级(含答案解析和代码)
    【C/C++】C语言太细了
    Python之numpy
    ChatGPT终于接上视觉能力!
  • 原文地址:https://blog.csdn.net/weixin_55035144/article/details/133745613