TRT3-trt-basic - 1 basic

2023-12-02 16:10
文章标签 basic trt trt3

本文主要是介绍TRT3-trt-basic - 1 basic,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言:

- tensorrt的工作流程如下图:

  • - 首先定义网络
  • - 优化builder参数
  • - 通过builder生成engine,用于模型保存、推理等
  • - engine可以通过序列化和逆序列化转化模型数据类型(转化为二进制byte文件,加快传输速率),再进一步推动模型由输入张量到输出张量的推理。![avatar](./figure/2.tensortr-workflow.jpg)

 code structure:

code structure

  • 1. 定义 builder, config 和network,其中builder表示所创建的构建器,config表示创建的构建配置(指定TensorRT应该如何优化模型),network为创建的网络定义。
  • 2. 输入,模型结构和输出的基本信息
  • 1. 生成engine模型文件
  • 2. 序列化模型文件并存储
  • - [官方文档参考部分 C++ API](https://docs.nvidia.com/deeplearning/tensorrt/developer-guide/index.html#:~:text=the%20Polygraphy%20repository.-,3.%C2%A0The%20C%2B%2B%20API,-This%20chapter%20illustrates)

头文件和定义log类


// tensorRT include
#include <NvInfer.h>
#include <NvInferRuntime.h>// cuda include
#include <cuda_runtime.h>// system include
#include <stdio.h>
//第一件事,log类,获得msg。然后可以根据级别决定要不要输出
class TRTLogger : public nvinfer1::ILogger{
public:virtual void log(Severity severity, nvinfer1::AsciiChar const* msg) noexcept override{if(severity <= Severity::kVERBOSE){printf("%d: %s\n", severity, msg);}}
};

 第一件事,log类,获得msg。然后可以根据级别决定要不要输出

定义配置

    // ----------------------------- 1. 定义 builder, config 和network -----------------------------// 这是基本需要的组件//形象的理解是你需要一个builder去build这个网络,网络自身有结构,这个结构可以有不同的配置nvinfer1::IBuilder* builder = nvinfer1::createInferBuilder(logger);// 创建一个构建配置,指定TensorRT应该如何优化模型,tensorRT生成的模型只能在特定配置下运行nvinfer1::IBuilderConfig* config = builder->createBuilderConfig();// 创建网络定义,其中createNetworkV2(1)表示采用显性batch size,新版tensorRT(>=7.0)时,不建议采用0非显性batch size// 因此贯穿以后,请都采用createNetworkV2(1)而非createNetworkV2(0)或者createNetworknvinfer1::INetworkDefinition* network = builder->createNetworkV2(1);// 构建一个模型/*Network definition:image|linear (fully connected)  input = 3, output = 2, bias = True     w=[[1.0, 2.0, 0.5], [0.1, 0.2, 0.5]], b=[0.3, 0.8]|sigmoid|prob 期望的输出*/

输入输出,模型的基本信息

// ----------------------------- 2. 输入,模型结构和输出的基本信息 -----------------------------const int num_input = 3;   // in_channelconst int num_output = 2;  // out_channelfloat layer1_weight_values[] = {1.0, 2.0, 0.5, 0.1, 0.2, 0.5}; // 前3个给w1的rgb,后3个给w2的rgb float layer1_bias_values[]   = {0.3, 0.8};//输入指定数据的名称、数据类型和完整维度,将输入层添加到网络nvinfer1::ITensor* input = network->addInput("image", nvinfer1::DataType::kFLOAT, nvinfer1::Dims4(1, num_input, 1, 1));nvinfer1::Weights layer1_weight = make_weights(layer1_weight_values, 6);nvinfer1::Weights layer1_bias   = make_weights(layer1_bias_values, 2);//添加全连接层 pytorch 叫linearauto layer1 = network->addFullyConnected(*input, num_output, layer1_weight, layer1_bias);      // 注意对input进行了解引用//添加激活层 auto prob = network->addActivation(*layer1->getOutput(0), nvinfer1::ActivationType::kSIGMOID); // 注意更严谨的写法是*(layer1->getOutput(0)) 即对getOutput返回的指针进行解引用// 将我们需要的prob标记为输出network->markOutput(*prob->getOutput(0));printf("Workspace Size = %.2f MB\n", (1 << 28) / 1024.0f / 1024.0f); // 256Mibconfig->setMaxWorkspaceSize(1 << 28);builder->setMaxBatchSize(1); // 推理时 batchSize = 1 

输入通道为3,输出通道为2

将image读为nvinfer1::ITensor的格式(1、3、1、1)的tensor

将weight和bias读为nvinfer1::Weights的格式

利用addFullyConnected创建全链接层。

添加激活层addActivation,这一层的input就是layer1层的输出,激活函数选用kSIGMOID。

得到prob这个layer,用markoutput标记为最终的输出。

生成模型

    // ----------------------------- 3. 生成engine模型文件 -----------------------------//TensorRT 7.1.0版本已弃用buildCudaEngine方法,统一使用buildEngineWithConfig方法nvinfer1::ICudaEngine* engine = builder->buildEngineWithConfig(*network, *config);if(engine == nullptr){printf("Build engine failed.\n");return -1;}

 builder->buildEngineWithConfig这个过程就是合并算子,查找特定支持,各种优化等。

如果失败了,那engine就为空指针。

存储文件

// ----------------------------- 4. 序列化模型文件并存储 -----------------------------// 将模型序列化,并储存为文件nvinfer1::IHostMemory* model_data = engine->serialize();FILE* f = fopen("engine.trtmodel", "wb");fwrite(model_data->data(), 1, model_data->size(), f);fclose(f);

这段代码是将TensorRT引擎序列化为二进制文件的过程。

首先,engine->serialize()用于将TensorRT引擎对象engine序列化为一块内存。返回的值是IHostMemory类型指针,它包含了序列化后的模型数据和序列化后的模型大小。

接下来,通过打开一个文件指针f,使用fopen函数创建一个名为"engine.trtmodel"的二进制文件,以进行写入操作。

最后,使用fwrite函数将model_data中的模型数据写入到文件中。model_data->data()表示获取模型数据的起始地址,model_data->size()表示模型数据的大小(以字节为单位),1表示每次写入一个字节。

拿到engine这个实例过后,要将其存储为文件,这时候就可以通过serialize()方法对其序列化进行存储,得到IHostMemory类型的文件。

到这里主要流程就结束拉!

释放

    // 卸载顺序按照构建顺序倒序model_data->destroy();engine->destroy();network->destroy();config->destroy();builder->destroy();printf("Done.\n");return 0;

一定要按照反顺序来做!

重点总结:

  1. 必须使用createNetworkV2,并指定为1(表示显性batch)。createNetwork已经废弃,非显性batch官方不推荐。这个方式直接影响推理时enqueue还是enqueueV2
  2. builder、config等指针,记得释放,否则会有内存泄漏,使用ptr->destroy()释放
  3. markOutput表示是该模型的输出节点,mark几次,就有几个输出,addInput几次就有几个输入。这与推理时相呼应。只保存输入输出不保存中间的内容,这也是为了节省内存。
  4. workspaceSize是工作空间大小,某些layer需要使用额外存储时,不会自己分配空间,而是为了内存复用,直接找tensorRT要workspace空间。指的这个意思。比如一个layer出现了三次,如果每一次都要给他分配一块内存的话,那就会占用很大的空间,就浪费掉了,因为别人又不能用。所以实际上他不需要这样做,有需要直接去trt要woorkspace空间就可以了。这样内存就可以复用。
  5. 保存的模型只能适配编译时的trt版本、编译时指定的设备。也只能保证在这种配置下是最优的。如果用trt跨不同设备执行,有时候可以运行,但不是最优的,也不推荐

这篇关于TRT3-trt-basic - 1 basic的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/445968

相关文章

查看Excel 中的 Visual Basic 代码,要先设置excel选项

1. excel VB的简单介绍 百度安全验证 2.excel选项设置 excel表格中在选项->自定义功能区域,选择开发工具,visual baisc/查看代码,即可看到代码。 3.excel已经设置,可以直接查看

Basic Calculator 总结

Basic Calculator 思路:stack中间存数,遇见+,-都当符号位,push num或者-num进去;最后相加;重要的是如何处理括号,那么这里一种方法是用递归调用;count左右括号,如果为0,那么就是一个反括号的位置了,那么 //(      ) //j......i; substring(j + 1, i); 这题的通用解法,可以扩展到二三题; class Solutio

做克隆虚拟机的basic

新建一台虚拟机(之前写的有这一步) 虚拟机里操作 vi /etc/hostname    改称basic (可改可不改)  vi /etc/sysconfig/network-scripts/ifcfg-ens33 TYPE=EthernetPROXY_METHOD=noneBROWSER_ONLY=noBOOTPROTO=staticDEFROUTE=yesIPV4_FAILU

【Http认证方式】——Basic认证

今天在访问请求:http://192.168.2.113:8080/geoserver/rest/workspaces时,浏览器弹出窗口需要输入用户名和密码 ,并且,如果不输入或者输入错误,浏览器返回 可以在火狐浏览器的网络监控这里看到请求的详细信息,

微积分复习笔记 Calculus Volume 1 - 1.2 Basic Classes of Functions

1.2 Basic Classes of Functions - Calculus Volume 1 | OpenStax

【Material-UI】Select 组件中的 Basic Select 使用详解

文章目录 一、Basic Select 概述1. 介绍2. Basic Select 的特点 二、Basic Select 组件的基本用法3. 代码详解 三、Basic Select 组件的常见用法1. 设置默认值2. 响应用户操作3. 自定义菜单项 四、Basic Select 组件的布局与样式1. 使用 `sx` 属性自定义样式2. 控制组件的宽度3. 菜单的位置控制 五、Basic S

正则表达式:Visual Basic中的强大文本处理工具

正则表达式:Visual Basic中的强大文本处理工具 在软件开发中,文本处理是一项常见且关键的任务。正则表达式作为一种强大的文本模式匹配工具,能够用于执行各种复杂的字符串搜索、替换、验证等操作。Visual Basic(VB),作为一门流行的编程语言,提供了对正则表达式的支持。本文将详细介绍如何在Visual Basic中使用正则表达式,包括其基本概念、功能特点以及实际应用示例。 一、正则

超越基础:Visual Basic在科学计算与数据分析的革新应用

标题:超越基础:Visual Basic在科学计算与数据分析的革新应用 Visual Basic(VB),最初以其易于学习和使用而闻名,常被视为入门级编程语言。然而,VB的潜力远不止于简单的应用程序开发。在科学计算和数据分析领域,VB通过其强大的编程能力和对复杂算法的支持,展现出了其独特的应用价值。本文将探讨Visual Basic在科学计算和数据分析中的应用,并提供实际代码示例。 1. Vi

超越传统:探索Visual Basic在操作系统插件开发的新境界

标题:超越传统:探索Visual Basic在操作系统插件开发的新境界 Visual Basic(VB),作为微软的老牌编程语言,以其简洁的语法和快速的开发能力在软件开发历史上占有一席之地。尽管VB并非现代操作系统插件或扩展开发的主流选择,但其在特定场景下仍具有一定的可行性。本文将探讨Visual Basic在开发操作系统插件或扩展时的应用潜力,并提供实际代码示例。 1. Visual Bas

Visual Basic数据绑定:简化编程的艺术

标题:“Visual Basic数据绑定:简化编程的艺术” 在Visual Basic(VB)中,数据绑定是一种强大的技术,它允许开发者将用户界面控件与数据源直接关联,从而简化数据的展示和更新过程。本文将详细介绍如何在Visual Basic中实现数据绑定,包括基本概念、步骤以及代码示例,帮助你掌握这项提高开发效率的技术。 一、数据绑定的基本概念 数据绑定是将控件的属性与数据源的字段进行关联