男生可以做网站编辑工作吗成都网站制作工具
2026/4/16 22:17:34 网站建设 项目流程
男生可以做网站编辑工作吗,成都网站制作工具,绿色wordpress主题模板,网站开发 教程一、前言#xff1a;为什么学这个hello案例#xff1f; 这个案例是TensorRT的「入门敲门砖」#xff0c;核心目标不是实现复杂功能#xff0c;而是掌握TensorRT构建模型的4个核心步骤#xff0c;理解builder、config、network、engine这些核心组件的作用#xff0c;为后续…一、前言为什么学这个hello案例这个案例是TensorRT的「入门敲门砖」核心目标不是实现复杂功能而是掌握TensorRT构建模型的4个核心步骤理解builder、config、network、engine这些核心组件的作用为后续YOLO等复杂模型的高性能部署打基础。简单说这个案例就是教你「用TensorRT的C API把一个极简的神经网络输入→全连接→Sigmoid→输出从「设计图」变成「可运行的优化模型文件」」。二、核心概念先搞懂盖房子比喻先把TensorRT的核心组件用「盖房子」的比喻讲清楚避免一上来看代码懵TensorRT组件盖房子对应角色核心作用TRTLogger日志类监理记录构建过程中的警告、信息、错误出问题时能查原因IBuilder构建器施工队负责把「网络设计图」变成「可运行的模型engine」做底层优化IBuilderConfig施工规范/资质规定施工的「资源上限」比如最大临时空间、最大批处理量TRT按此优化模型INetworkDefinition房子的设计图定义网络的输入、输出、层结构比如全连接层、激活层ICudaEngine引擎盖好的成品房子TRT优化后的最终模型可直接用于推理是「可执行文件」级别的产物IHostMemory房子的「户型图二进制文件」把engine序列化成二进制数据方便保存到硬盘、后续加载使用三、hello案例代码逐段拆解这份代码的核心逻辑是「定义组件→设计网络→构建模型→保存模型」我们按代码执行顺序拆解对应笔记里的4个核心步骤。// tensorRT include#includeNvInfer.h#includeNvInferRuntime.h// cuda include#includecuda_runtime.h// system include#includestdio.hclassTRTLogger:publicnvinfer1::ILogger{public:virtualvoidlog(Severity severity,nvinfer1::AsciiCharconst*msg)noexceptoverride{if(severitySeverity::kVERBOSE){printf(%d: %s\n,severity,msg);}}};nvinfer1::Weightsmake_weights(float*ptr,intn){nvinfer1::Weights w;w.countn;w.typenvinfer1::DataType::kFLOAT;w.valuesptr;returnw;}intmain(){// 本代码主要实现一个最简单的神经网络 figure/simple_fully_connected_net.pngTRTLogger logger;// logger是必要的用来捕捉warning和info等// ----------------------------- 1. 定义 builder, config 和network -----------------------------// 这是基本需要的组件//形象的理解是你需要一个builder去build这个网络网络自身有结构这个结构可以有不同的配置nvinfer1::IBuilder*buildernvinfer1::createInferBuilder(logger);// 创建一个构建配置指定TensorRT应该如何优化模型tensorRT生成的模型只能在特定配置下运行nvinfer1::IBuilderConfig*configbuilder-createBuilderConfig();// 创建网络定义其中createNetworkV2(1)表示采用显性batch size新版tensorRT(7.0)时不建议采用0非显性batch size// 因此贯穿以后请都采用createNetworkV2(1)而非createNetworkV2(0)或者createNetworknvinfer1::INetworkDefinition*networkbuilder-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. 输入模型结构和输出的基本信息 -----------------------------constintnum_input3;// in_channelconstintnum_output2;// out_channelfloatlayer1_weight_values[]{1.0,2.0,0.5,0.1,0.2,0.5};// 前3个给w1的rgb后3个给w2的rgbfloatlayer1_bias_values[]{0.3,0.8};//输入指定数据的名称、数据类型和完整维度将输入层添加到网络nvinfer1::ITensor*inputnetwork-addInput(image,nvinfer1::DataType::kFLOAT,nvinfer1::Dims4(1,num_input,1,1));nvinfer1::Weights layer1_weightmake_weights(layer1_weight_values,6);nvinfer1::Weights layer1_biasmake_weights(layer1_bias_values,2);//添加全连接层autolayer1network-addFullyConnected(*input,num_output,layer1_weight,layer1_bias);// 注意对input进行了解引用//添加激活层autoprobnetwork-addActivation(*layer1-getOutput(0),nvinfer1::ActivationType::kSIGMOID);// 注意更严谨的写法是*(layer1-getOutput(0)) 即对getOutput返回的指针进行解引用// 将我们需要的prob标记为输出network-markOutput(*prob-getOutput(0));printf(Workspace Size %.2f MB\n,(128)/1024.0f/1024.0f);// 256Mibconfig-setMaxWorkspaceSize(128);builder-setMaxBatchSize(1);// 推理时 batchSize 1// ----------------------------- 3. 生成engine模型文件 -----------------------------//TensorRT 7.1.0版本已弃用buildCudaEngine方法统一使用buildEngineWithConfig方法nvinfer1::ICudaEngine*enginebuilder-buildEngineWithConfig(*network,*config);if(enginenullptr){printf(Build engine failed.\n);return-1;}// ----------------------------- 4. 序列化模型文件并存储 -----------------------------// 将模型序列化并储存为文件nvinfer1::IHostMemory*model_dataengine-serialize();FILE*ffopen(engine.trtmodel,wb);fwrite(model_data-data(),1,model_data-size(),f);fclose(f);// 卸载顺序按照构建顺序倒序model_data-destroy();engine-destroy();network-destroy();config-destroy();builder-destroy();printf(Done.\n);return0;}3.1 第一步引入头文件定义基础工具准备施工材料// tensorRT核心头文件构建模型、运行时推理#includeNvInfer.h#includeNvInferRuntime.h// CUDA头文件TRT依赖CUDA运行#includecuda_runtime.h// 系统头文件文件操作、打印#includestdio.h// 1. 定义日志类继承TRT的ILogger负责打印TRT的日志信息classTRTLogger:publicnvinfer1::ILogger{public:// 重写log方法控制日志打印级别virtualvoidlog(Severity severity,nvinfer1::AsciiCharconst*msg)noexceptoverride{// 只打印级别VERBOSE的日志包括INFO、WARNING、ERROR等if(severitySeverity::kVERBOSE){printf(%d: %s\n,severity,msg);}}};// 2. 辅助函数把float数组封装成TRT的Weights结构体权重/偏置专用nvinfer1::Weightsmake_weights(float*ptr,intn){nvinfer1::Weights w;w.countn;// 权重数量w.typenvinfer1::DataType::kFLOAT;// 数据类型浮点型w.valuesptr;// 权重数据的指针returnw;}关键解读TRTLogger是必须的TRT的所有操作都会产生日志没有日志类会导致程序运行异常也无法排查问题make_weights是简化代码的辅助函数TRT的层比如全连接层需要权重/偏置以Weights结构体传入这个函数把普通float数组转成对应格式。3.2 第二步初始化核心组件组建施工队制定规范画设计图intmain(){// 目标构建一个极简神经网络输入(3维) → 全连接层(输出2维) → Sigmoid → 输出(2维)TRTLogger logger;// 创建监理日志对象// ----------------------------- 1. 定义 builder, config 和network -----------------------------// 1.1 创建施工队builder传入日志对象让施工队的操作被监理记录nvinfer1::IBuilder*buildernvinfer1::createInferBuilder(logger);// 1.2 创建施工规范config指定TRT优化模型的规则nvinfer1::IBuilderConfig*configbuilder-createBuilderConfig();// 1.3 创建设计图networkcreateNetworkV2(1) 显性batch size新版TRT≥7.0推荐0已废弃nvinfer1::INetworkDefinition*networkbuilder-createNetworkV2(1);关键解读createNetworkV2(1)是重点「显性batch size」明确指定批处理大小比如这里batch1推理时用enqueueV2接口「隐性batch size0」TRT自动处理批次已被官方废弃不要用这三个组件是TRT构建模型的「基础三件套」缺一不可。3.3 第三步设计网络结构画设计图输入→层→输出// ----------------------------- 2. 输入模型结构和输出的基本信息 -----------------------------constintnum_input3;// 输入维度比如RGB 3通道constintnum_output2;// 输出维度比如二分类// 全连接层的权重6个值 → 2个输出神经元 × 3个输入神经元floatlayer1_weight_values[]{1.0,2.0,0.5,0.1,0.2,0.5};// 全连接层的偏置2个值 → 对应2个输出神经元floatlayer1_bias_values[]{0.3,0.8};// 2.1 定义输入层addInput(名称, 数据类型, 维度)// Dims4是NCHW格式(batch数, 通道数, 高度, 宽度) → 这里是1批、3通道、1高1宽一维数据nvinfer1::ITensor*inputnetwork-addInput(image,nvinfer1::DataType::kFLOAT,nvinfer1::Dims4(1,num_input,1,1));// 2.2 封装权重和偏置nvinfer1::Weights layer1_weightmake_weights(layer1_weight_values,6);nvinfer1::Weights layer1_biasmake_weights(layer1_bias_values,2);// 2.3 添加全连接层addFullyConnected(输入张量, 输出维度, 权重, 偏置)autolayer1network-addFullyConnected(*input,num_output,layer1_weight,layer1_bias);// 2.4 添加Sigmoid激活层addActivation(输入张量, 激活类型)autoprobnetwork-addActivation(*layer1-getOutput(0),nvinfer1::ActivationType::kSIGMOID);// 2.5 标记输出节点告诉TRT这是网络的最终输出推理时要取这个值network-markOutput(*prob-getOutput(0));关键解读张量维度Dims4TRT默认用NCHW格式批数、通道数、高度、宽度哪怕是一维数据比如3个输入值也要写成(1,3,1,1)层的调用规则addFullyConnected的第一个参数是「解引用的输入张量」*input因为addInput返回的是指针layer1-getOutput(0)全连接层的输出张量一个层可能有多个输出0是第一个markOutput标记几次就有几个输出addInput几次就有几个输入——推理时要和这个数量对应否则会报错。3.4 第四步配置并生成Engine按规范施工盖出成品房子// 3.1 设置施工资源上限最大工作空间256MB// 1 28 2^28 268435456 字节 256MBprintf(Workspace Size %.2f MB\n,(128)/1024.0f/1024.0f);config-setMaxWorkspaceSize(128);// 3.2 设置最大批处理大小推理时batchSize不能超过这个值这里设为1builder-setMaxBatchSize(1);// ----------------------------- 3. 生成engine模型文件 -----------------------------// 用「设计图施工规范」构建engine成品房子buildEngineWithConfig是新版TRT推荐接口替代废弃的buildCudaEnginenvinfer1::ICudaEngine*enginebuilder-buildEngineWithConfig(*network,*config);if(enginenullptr){printf(Build engine failed.\n);return-1;}关键解读setMaxWorkspaceSizeTRT优化模型时比如层融合、精度校准需要临时内存这个参数指定「最大可用临时内存」太小会导致构建失败一般设256MB~1GB足够setMaxBatchSize限制推理时的最大批大小比如设1就只能单张图片推理设8就最多一次推8张buildEngineWithConfig核心构建接口TRT会根据network设计图和config规范对网络做层融合、算子优化、精度优化最终生成高效的engine。3.5 第五步序列化并保存Engine把房子转成文件保存// ----------------------------- 4. 序列化模型文件并存储 -----------------------------// 4.1 序列化engine把二进制的模型数据存到IHostMemory中nvinfer1::IHostMemory*model_dataengine-serialize();// 4.2 写入文件保存为engine.trtmodel后续推理时直接加载这个文件即可FILE*ffopen(engine.trtmodel,wb);// 二进制写入模式fwrite(model_data-data(),1,model_data-size(),f);fclose(f);// 4.3 释放资源按「创建顺序倒序」destroy避免内存泄漏model_data-destroy();engine-destroy();network-destroy();config-destroy();builder-destroy();printf(Done.\n);return0;}关键解读serialize()把内存中的engine转成二进制数据方便保存到硬盘——这个二进制文件就是TRT的「优化模型文件」后续推理时无需重新构建网络直接加载即可资源释放TRT的所有组件builder、config等都需要手动destroy()不像C普通对象会自动析构漏写会导致内存泄漏保存的engine.trtmodel是「平台相关」的——只能在「编译时的TRT版本、编译时的GPU设备」上最优运行跨版本/跨设备可能运行缓慢甚至报错。四、补充知识解读笔记里的关键坑点显性batch size的重要性新版TRT≥7.0强制推荐createNetworkV2(1)显性0隐性已废弃显性batch size影响推理接口推理时要用enqueueV2隐性用enqueue已废弃。Workspace Size的本质不是「模型占用的内存」而是TRT优化层时的「临时工作内存」TRT为了内存复用不会给每个层单独分配内存而是从workspace里取所以要保证足够大但也不用过大比如超过GPU显存。输入输出数量的对应性addInput调用N次 → 推理时需要传入N个输入数据markOutput调用M次 → 推理时能获取M个输出数据数量不匹配会导致推理时报错。Engine的兼容性「TRT版本兼容」比如用TRT8.6编译的engine在TRT8.2上可能加载失败「设备兼容」用RTX3090编译的engine在RTX2080上能运行但不是最优TRT会针对编译时的GPU架构做优化。五、总结核心要点回顾TensorRT构建模型的核心4步「定义builder/config/network → 设计网络结构 → 生成engine → 序列化保存」关键组件TRTLogger是必须的createNetworkV2(1)要牢记资源必须手动destroy()核心产物engine.trtmodel是TRT优化后的二进制模型文件后续推理的核心依赖——构建模型的过程是「一次性的」推理时直接加载这个文件即可无需重复构建。这个hello案例虽然简单但涵盖了TRT构建模型的全流程吃透它之后你就能理解后续复杂模型比如YOLO的TRT部署核心逻辑——无非是把「全连接层」换成「卷积层/池化层」把简单结构换成复杂结构而已。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询