使用C++将yolov8 onnx格式转化为tensorrt格式

 更新时间:2024年11月15日 09:31:22   作者:爱喝生椰的程序员  
这篇文章主要为大家详细介绍了如何使用C++将yolov8 onnx格式转化为tensorrt格式,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下

我们使用TensorRT进行加速推理时,需要先将onnx格式转化为tensorrt格式,以下是使用C++来进行转化代码以及对应的CMakeLists.txt文件

操作系统:ubuntu20.04

C++代码:

// main.cpp
#include <iostream>
#include <memory>
#include <fstream>
#include <assert.h>
#include "NvInfer.h"
#include "NvOnnxParser.h"
#include "common.h"

class Logger : public nvinfer1::ILogger{
    void log(Severity severity, const char* msg) noexcept override {
        // suppress info-level messages
        if (severity <= Severity::kWARNING)
            std::cout << msg << std::endl;
    }
} logger;


int main(int argc, char** argv){
    if(argc !=2){
        std::cerr << "usage: ./build [onnx_file_path]" <<std::endl;
        return -1;
    }

    // 获取onnx文件路径
    char* onnx_file_path = argv[1];

    //================1.创建builder====================
    auto builder = std::unique_ptr<nvinfer1::IBuilder>(nvinfer1::createInferBuilder(logger));
    if(!builder){
        std::cerr << "Failed to creater builder" <<std::endl;
        return -1;
    }

    //===============2.创建network=====================
    const auto explicitBatch= 1U <<static_cast<uint32_t>(nvinfer1::NetworkDefinitionCreationFlag::kEXPLICIT_BATCH);
    auto network = std::unique_ptr<nvinfer1::INetworkDefinition>(builder->createNetworkV2(explicitBatch));
    if (!network){
        std::cout << "Failed to create network" << std::endl;
        return -1;
    }

    // =============创建onnxparser用于解析onnx文件===========
    auto parser = std::unique_ptr<nvonnxparser::IParser>(nvonnxparser::createParser(*network, logger));
    // 调用onnxparser的parseFromFile方法解析onnx文件
    auto parsed = parser->parseFromFile(onnx_file_path, static_cast<int>(nvinfer1::ILogger::Severity::kWARNING));
    if (!parsed){
        std::cout << "Failed to parse onnx file" << std::endl;
        return -1;
    }
    // 配置网络参数
    auto input = network->getInput(0);
    auto profile = builder->createOptimizationProfile();
    profile->setDimensions(input->getName(), nvinfer1::OptProfileSelector::kMIN, nvinfer1::Dims4{1, 3, 960, 960}); // 设置最小尺寸
    profile->setDimensions(input->getName(), nvinfer1::OptProfileSelector::kOPT, nvinfer1::Dims4{1, 3, 960, 960}); // 设置最优尺寸
    profile->setDimensions(input->getName(), nvinfer1::OptProfileSelector::kMAX, nvinfer1::Dims4{1, 3, 960, 960}); // 设置最大尺寸

    //==============创建config配置=====================
    auto config = std::unique_ptr<nvinfer1::IBuilderConfig>(builder->createBuilderConfig());
    if (!config){
        std::cout << "Failed to create config" << std::endl;
        return -1;
    }

    config->addOptimizationProfile(profile);
    // 设置精度,设置为FP16,设置为INT8需要额外calibrator 
    config->setFlag(nvinfer1::BuilderFlag::kFP16);
    // 设置最大batchsize
    builder->setMaxBatchSize(1);
    // 设置最大工作空间
    config->setMemoryPoolLimit(nvinfer1::MemoryPoolType::kWORKSPACE, 1 << 30);

    //创建流
    auto profileStream = samplesCommon::makeCudaStream();
    if(!profileStream){
        return -1;
    }
    config->setProfileStream(*profileStream);

    // ==========创建engine ==========
    auto plan = std::unique_ptr<nvinfer1::IHostMemory>(builder->buildSerializedNetwork(*network, *config));
    if (!plan){
        std::cout << "Failed to create engine" << std::endl;
        return -1;
    }

    // ========== 5. 序列化保存engine ==========
    std::ofstream engine_file("./yolov8x.engine", std::ios::binary);
    assert(engine_file.is_open() && "Failed to open engine file");
    engine_file.write((char *)plan->data(), plan->size());
    engine_file.close();

    std::cout << "Engine build success!" << std::endl;
    return 0;
}

CMakeLists.txt文件:

cmake_minimum_required(VERSION 3.10)
project(TensorRT_Test LANGUAGES CXX CUDA)

set(CMAKE_CUDA_STANDARD 14)
set(CMAKE_CXX_STANDARD 14)

# 添加头文件路径 cuda tensorRT
include_directories(/usr/local/cuda-11.8/include)
include_directories(/xxx/tensorRT/TensorRT-8.6.1.6/include)
include_directories(/xxx/tensorRT/TensorRT-8.6.1.6/samples/common/)

# 添加库文件
link_directories(/usr/local/cuda-11.8/lib64)
link_directories(/xxx/tensorRT/TensorRT-8.6.1.6/lib)

add_executable(build main.cpp)
target_link_libraries(build nvinfer nvonnxparser cudart)

注意:

在CMakeLists.txt中cuda及TensorRT的头文件和库文件路径需要改成自己的

使用方法:

以yolov8为例,使用cmake编译好后会生成build可执行文件,执行以下命令即可等待生成yolov8x.engine文件

./build <onnx_path>

到此这篇关于使用C++将yolov8 onnx格式转化为tensorrt格式的文章就介绍到这了,更多相关C++ yolov8 onnx转tensorrt内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

相关文章

  • C++ 中const和复合类型

    C++ 中const和复合类型

    本文给大家讲述的是C++ 中比较难理解的const和复合类型,结合自己的一些经验,分享给大家,希望大家能够喜欢。
    2016-02-02
  • C++实现LeetCode(48.旋转图像)

    C++实现LeetCode(48.旋转图像)

    这篇文章主要介绍了C++实现LeetCode(48.旋转图像),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • C语言 将字符串逆序输出的实例

    C语言 将字符串逆序输出的实例

    这篇文章主要介绍了C语言将字符串逆序输出的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • c语言左移和右移的示例详解

    c语言左移和右移的示例详解

    这篇文章主要介绍了c语言左移和右移的示例详解,移位操作符的两个操作数必须是整型的。整个移位表达式的值的类型也是整型的,而且,左移位操作符与右移位操作符的运算并不对称。
    2020-07-07
  • 简介C/C++预处理器的一些工作

    简介C/C++预处理器的一些工作

    这篇文章主要介绍了C/C++预处理器的一些工作,有助于理解编译器底层的工作流程,需要的朋友可以参考下
    2015-07-07
  • c++中std::placeholders的使用方法

    c++中std::placeholders的使用方法

    std::placeholders 是 C++ 标准库中的一个工具,用于在函数对象绑定时创建占位符,本文就来详细的介绍一下,具有一定的参考价值,感兴趣的可以了解一下
    2025-02-02
  • C++实现合并排序的方法

    C++实现合并排序的方法

    这篇文章主要介绍了C++实现合并排序的方法,实例分析了合并排序的原理与相关实现技巧,需要的朋友可以参考下
    2015-07-07
  • C语言中队列的结构和函数接口的使用示例

    C语言中队列的结构和函数接口的使用示例

    队列只允许一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO的性质;队列可用数组和链表 的方法实现,使用链表的结构实现更优一些,因为如果使用数组节,出队列时删去首元素需要将整个数组前移,效率比较低
    2023-02-02
  • C语言实现飞机订票系统

    C语言实现飞机订票系统

    这篇文章主要为大家详细介绍了C语言实现飞机订票系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-12-12
  • C++计算任意两个日期天数差的方法详解

    C++计算任意两个日期天数差的方法详解

    这篇文章主要为大家详细介绍了如何利用C++实现任意两个日期天数差,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考一下
    2024-02-02

最新评论