兰州seo整站优化服务商,企业网站seo优化方案,广州黄埔建网站,网站建站平台排行榜官方文档onnx序列化教程与推理教程 一、构建TensorRT序列化模型二、搭建阶段#xff08;三步走#xff09;2.1 创建网络2.2 使用ONNX解析器导入模型2.3 构建推理引擎 三、反序列化模型四、执行推理 一、构建TensorRT序列化模型
本博客主要说明的是TensorRT C API#xff0c… 官方文档onnx序列化教程与推理教程 一、构建TensorRT序列化模型二、搭建阶段三步走2.1 创建网络2.2 使用ONNX解析器导入模型2.3 构建推理引擎 三、反序列化模型四、执行推理 一、构建TensorRT序列化模型
本博客主要说明的是TensorRT C API从我们获取到onnx模型开始的流程。C API可以通过引用头文NvInfer.h来进行访问使用其命名空间nvinfer1代码示例
#include NvInfer.husing namespace nvinfer1;需要说明的是TensorRT C的接口类都以I为前缀开头例如ILoggerIBuilder等等。如果在此之前不存在则TensorRT第一次调用CUDA时会自动创建CUDA上下文。在第一次调用TensorRT之前最好自己创建和配置CUDA上下文。
并且由于需要展示各对象的存在周期实例代码中没有使用智能指针但是建议在实际使用中加上智能指针来配合TensorRT接口。
二、搭建阶段三步走
要创建构建器首先必须实例化ILogger接口。这个例子捕获所有警告消息但忽略信息性消息:
inline const char* severity_string(nvinfer1::ILogger::Severity t) {switch (t) {case nvinfer1::ILogger::Severity::kINTERNAL_ERROR: return internal_error;case nvinfer1::ILogger::Severity::kERROR: return error;case nvinfer1::ILogger::Severity::kWARNING: return warning;case nvinfer1::ILogger::Severity::kINFO: return info;case nvinfer1::ILogger::Severity::kVERBOSE: return verbose;default: return unknow;}
}class My_Logger : public nvinfer1::ILogger
{
public:virtual void log(Severity severity, const char* msg) noexcept override{// suppress info-level messages// 捕获所有警告类消息并输出if (severity Severity::kWARNING)// 打印带颜色的字符格式如下// printf(\033[47;33m打印的文本\033[0m);// 其中 \033[ 是起始标记// 47 是背景颜色// ; 分隔符// 33 文字颜色// m 开始标记结束// \033[0m 是终止标记// 其中背景颜色或者文字颜色可不写// 部分颜色代码 https://blog.csdn.net/ericbar/article/details/79652086printf(\033[31m%s: %s\033[0m\n, severity_string(severity), msg);}
} my_logger;然后你可以使用刚刚实例化的一个my_logger作为参数来实例化一个builder
IBuilder* builder createInferBuilder(my_logger); 2.1 创建网络
创建构建器之后优化模型的第一步是创建网络定义:
uint32_t flag 1U static_castuint32_t(NetworkDefinitionCreationFlag::kEXPLICIT_BATCH); INetworkDefinition* network builder-createNetworkV2(flag);为了使用ONNX解析器导入模型需要使用kEXPLICIT_BATCH标志。有关更多信息请参阅显式批处理与隐式批处理部分。
2.2 使用ONNX解析器导入模型
现在我们可以通过ONNX模型来填充网络定义ONNX解析器API位于文件nvonnxparser.h中解析器位于nvonnxparser c命名空间中
#include “NvOnnxParser.h”using namespace nvonnxparser;我们可以通过创建一个ONNX解析器来填充网络定义
IParser* parser createParser(*network, my_logger);然后我们可以读取ONNX模型路径并处理各类问题
//your onnx models path
const char* ONNX_MODEL ;
//virtual bool parseFromFile(const char* onnxModelFile, int verbosity);
bool parser_status parser-parseFromFile(ONNX_MODEL, static_castint32_t(ILogger::Severity::kWARNING));
for (int32_t i 0; i parser.getNbErrors(); i)
{
std::cout parser-getError(i)-desc() std::endl;
}需要注意的是TensorRT网络定义的一个重要方面是它包含指向模型权重的指针这些指针由构建器复制到优化的引擎中。由于网络是使用解析器创建的所以解析器拥有权重占用的内存因此在构建器运行之前不可以删除解析器对象。 2.3 构建推理引擎
下一步则是创建一个构建配置来告诉TensorRT该如何优化模型
IBuilderConfig* config builder-createBuilderConfig();这个接口有很多属性你可以设置这些属性来控制TensorRT如何优化网络。一个重要的属性是最大工作空间大小。层实现通常需要一个临时工作区这个参数限制了网络中任何层可以使用的最大大小。如果提供的工作空间不足TensorRT可能无法找到一个层的实现。默认情况下工作区被设置为给定设备的总全局内存大小;必要时限制它例如当要在单个设备上构建多个引擎时
config-setMemoryPoolLimit(MemoryPoolType::kWORKSPACE, 1U 20);一旦指定了配置就可以构建引擎
IHostMemory* serializedModel builder-buildSerializedNetwork(*network, *config);由于序列化的引擎包含必要的权重副本。解析器网络定义构建器配置和构建器不再是必需的可以安全地删除:
delete parser;
delete network;
delete config;
delete builder;然后可以将引擎保存到磁盘并且可以删除序列化引擎的缓冲区
delete serializedmodel;注意:序列化引擎不能跨平台或跨TensorRT版本移植。引擎是特定于它们所构建的确切GPU模型的(除了平台和TensorRT版本)。(PS在TensorRT8.6版本开始之后可以通过在导出模型时添加一句代码来实现导出模型对不同GPU平台的适配前提是基于Ampere架构的GPU可以参考我之前的博客关于8.6版本开始的硬件兼容性的一些试错)
由于构建引擎的目的是作为一个离线过程它可能会花费大量时间。有关如何使构建器运行得更快请参阅优化构建器性能部分。
三、反序列化模型
假设我们之前已经序列化了一个优化的模型现在希望执行推理那么我们必须创建runtime接口的实例与构建器一样运行时也需要一个日志记录器的实例
IRuntime* runtime createInferRuntime(my_logger);当我们已经把模型读入缓冲区后我们可以将模型反序列化来得到一个engine
ICudaEngine* engine runtime-deserializeCudaEngine(modelData, modelSize);四、执行推理
引擎保存优化的模型但是为了执行推理我们必须为中间激活管理额外的状态这是通过ExecutionContext的接口来实现的