六. 部署分类器-trt-engine-explorer

目录

    • 前言
    • 0. 简述
    • 1. 案例运行
    • 2. 补充说明
    • 3. engine分析
    • 结语
    • 下载链接
    • 参考

前言

自动驾驶之心推出的 《CUDA与TensorRT部署实战课程》,链接。记录下个人学习笔记,仅供自己参考

本次课程我们来学习课程第六章—部署分类器,一起来学习 trt-engine-explorer 工具的使用

课程大纲可以看下面的思维导图

在这里插入图片描述

0. 简述

本小节目标:学习如何使用 trt-engine-explorer 工具

这个小节的案例代码与 C++ 没有多大的关系,它更多的是对我们生成的 trt-engine 模型的分析,用 python 脚本把 engine 的模型架构进行可视化

下面我们开始本次课程的学习🤗

1. 案例运行

在正式开始课程之前,博主先带大家跑通 6.4-trt-engine-inspector 这个小节的案例🤗

源代码获取地址:https://github.com/kalfazed/tensorrt_starter

首先大家需要把 tensorrt_starter 这个项目给 clone 下来,指令如下:

git clone https://github.com/kalfazed/tensorrt_starter.git

也可手动点击下载,点击右上角的 Code 按键,将代码下载下来。至此整个项目就已经准备好了。也可以点击 here 下载博主准备好的源代码(注意代码下载于 2024/7/14 日,若有改动请参考最新

整个项目后续需要使用的软件主要有 CUDA、cuDNN、TensorRT、OpenCV,大家可以参考 Ubuntu20.04软件安装大全 进行相应软件的安装,博主这里不再赘述

下面我们要创建一个虚拟环境来安装 trt-engine-explorer 工具,博主这里准备了一个可以运行本小节案例代码的虚拟环境,大家可以按照这个环境来,也可以参考 trt-engine-explorer 官方文档 进行安装,指令如下:

conda create -n env_trex python=3.9
conda activate env_trex
git clone https://github.com/NVIDIA/TensorRT.git
cd TensorRT/tools/experimental/trt-engine-explorer
python3 -m pip install -e.
pip install werkzeug==3.0.0 Flask==3.0.0
sudo apt-get --yes install graphviz

安装完成后大家可以通过 pip 指令查看安装好的 trex 工具,如下图所示:

在这里插入图片描述

假设你的项目、环境准备完成,下面我们一起来运行下 6.4-trt-engine-inspector 小节案例代码

首先我们需要准备一个 engine 模型文件供 trt-engine-explorer 工具分析,这里我们直接拿上个小节生成的 resnet50-int8.engine 过来

下面我们需要利用脚本文件生成分析文件,指令如下:

# 将已有的分析文件全部删除
cd tensorrt_starter/chapter6-deploy-classification-and-inference-design/6.4-trt-engine-inspector/
rm -rf result/resnet50/*
# 将上小节创建好的 engine 拷贝过来
cp ../6.3-in8-calibration/models/engine/resnet50-int8.engine ./result/resnet50/
cd src/python
conda env_trex
python process_engine.py ../../result/resnet50/resnet50-int8.engine ../../result/resnet50 --profile-engine

输出如下图所示:

在这里插入图片描述

同时在 results/resnet50 目录下生成了一系列的文件,如下图所示:

在这里插入图片描述

我们主要关注 resnet50-int8.engine.graph.json 文件,它将 engine 各个 layer 的详细信息都保存下来了,包括 layer 的 name、dimensions、format 以及 data type 等等,其他的文件例如 profile.json、timing.json 则是一些 layer 执行时间的信息,profile.log 则是 trtexec 执行输出的日志信息

我们生成 resnet50-int8.engine.graph.json 文件后可以绘制出其网络结构,执行指令如下:

python draw_engine.py ../../result/resnet50/resnet50-int8.engine.graph.json

你可能会遇到如下的问题:

在这里插入图片描述

这个问题主要是因为 TensorRT 前段时间 10.0 版本发布时相关代码进行了修改,所以这里韩军老师提供的 draw_engine.py 脚本文件的 API 发生了变化

我们直接从目前 TensorRT 官网下的 draw_engine.py 替换当前的内容,如下所示:

#!/usr/bin/env python3
#
# SPDX-FileCopyrightText: Copyright (c) 1993-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#"""
This script generates an SVG diagram of the input engine graph SVG file.Note: this script requires graphviz which can be installed manually:$ sudo apt-get --yes install graphviz$ python3 -m pip install graphviz
"""import warnings
import argparse
import shutil
import trex.graphing
import trex.engine_plandef draw_engine(engine_json_fname: str, profiling_json_fname: str=None, **kwargs):graphviz_is_installed = shutil.which("dot") is not Noneif not graphviz_is_installed:print("graphviz is required but it is not installed.\n")print("To install on Ubuntu:")print("sudo apt --yes install graphviz")exit()try:if kwargs["display_constants"] and not kwargs["display_regions"]:warnings.warn("Ignoring argument --display_constants because it requires --display_regions.")except KeyError:passplan = trex.engine_plan.EnginePlan(engine_json_fname, profiling_file=profiling_json_fname)layer_node_formatter = trex.graphing.layer_type_formattergraph = trex.graphing.to_dot(plan, layer_node_formatter, **kwargs)trex.graphing.render_dot(graph, engine_json_fname, "svg")def make_subcmd_parser(subparsers):draw = lambda args: draw_engine(engine_json_fname=args.input,profiling_json_fname=args.profiling_json,display_regions=args.display_regions,display_layer_names=not args.no_layer_names,display_constants=args.display_constant,)draw_parser = subparsers.add_parser("draw", help="Draw a TensorRT engine.")draw_parser.set_defaults(func=draw)_make_parser(draw_parser)def _make_parser(parser):parser.add_argument("input", help="name of engine JSON file to draw.")parser.add_argument("--profiling_json", "-pj",default=None, help="name of engine JSON file to draw")parser.add_argument("--display_regions", "-dr",action='store_true', help="render memory regions as graph nodes.")parser.add_argument("--display_constant", "-dc",action='store_true', help="render constant input tensors.")parser.add_argument("--no_layer_names", "-no_ln",action='store_true', help="render constants.")if __name__ == "__main__":parser = argparse.ArgumentParser()args = parser.parse_args(_make_parser(parser))draw_engine(engine_json_fname=args.input,profiling_json_fname=args.profiling_json,display_regions=True,expand_layer_details=False,display_latency=True,)

再次执行该脚本,输出如下:

在这里插入图片描述

执行成功后会生成一个 .svg 的图片格式文件,我们可以在浏览器中打开 .svg 的结构图,如下图所示:

在这里插入图片描述

如果大家能够看到上述输出结果,那就说明本小节案例已经跑通,下面我们就来看看具体的 engine 结构变化

2. 补充说明

在分析具体结构变化之前我们先来看下韩君老师在这小节中写的 README 文档

trt-engine-explorer 是 NVIDIA 官方提供的分析 TensorRT 优化后的推理引擎架构的工具包,可以在 TensorRT 官方的 git repository 中找打,具体细节大家可以参考:trt-engine-explorer

在这里插入图片描述

大家参考官方提供的 README.md 把环境搭建起来之后,我们可以尝试分析下我们的 engine 模型。为了方便,在 6.4 小节案例代码中的 src/python 目录下放置了一些官方提供的案例文件可以使用,比如:

通过 TensorRT 优化的推理引擎获取各个 layer 的信息,以 json 形式保存

python process_engine.py ../../result/resnet50/resnet50.engine ../../result/resnet50/resnet50.engine --profile-engine

通过保存得到的 json 信息,绘制出 TensorRT 优化后的网络模型架构,以 SVG 格式保存成图片

python draw_engine.py ../../result/resnet50/resnet50.engine.graph.json

通过 jupyter 在浏览器里打开 SVG 模式下的结构图

jupyter-notebook --ip=0.0.0.0 --no-browser

大家这里可以仔细比较一下各个模型的 .onnx 架构和 .engine 架构的不同,以及同一个模型的不同精度的 .engine 的不同。观察 TensorRT 优化后哪些层被融合了,哪些层是新添加的,大家感兴趣的还可以了解下 reformatter 节点是什么,其实 reformatter 非常重要,因为它涉及到了 TensorRT 的各个 layer 所支持的 data layout,如果想要把部署优化做到极致,理解 data layout 是必须要做的。

3. engine分析

我们对比着看下 resnet50.onnx 模型和 resnet50-int8.engine 引擎的结构变化

在这里插入图片描述

上图中左边是 onnx 右边是 engine,首先在 engine 中 input0 后面的 Reformat 是新添加的节点,接着有一个虚线框,这个代表着之前 onnx 中存在的节点但是现在经过 tensorRT 优化后不存在了。我们可以清晰的看到 onnx 模型中的 Conv、Relu 和 MaxPool 在 engine 中变成了一个 ConvActPool 节点,这个就是 TensorRT 做的层融合后的效果

Note:Engine 中的 Reformat 节点是什么呢?我们是不是应该尽量避免它的产生?

在 TensorRT 的引擎中,Reformat 节点用于在不同层之间处理数据格式的转换。这些节点通常出现在需要更改数据布局(例如从 NCHW 到 NHWC)或调整数据类型(如 FP32、FP16 和 INT8 之间的转换)时,这些转换是必要的,因为引擎中的不同层或操作可能偏好活需要不同的数据格式或精度,以实现性能优化。

通常来说,Reformat 节点越少越好,因为每次格式转换操作都会引入额外的开销,影响引擎的性能。过多的 Reformat 操作会减慢推理速度,因为这需要额外的内存操作

在进行 INT8 量化时,我们最好确保校准过程在各层之间是一致的,一致的量化可以减少在具有不同量化参数的层之间进行 Reformat 的需求

在这里插入图片描述

我们往后看可以发现 ONNX 中的 Relu 节点都不存在了,都变成了虚线框,resnet50 模型比较简单,所以整个 engine 架构还是比较好看的,没有添加什么冗余的东西

在这里插入图片描述

我们在生成 engine 的时候指定的精度是 INT8,那是不是意味着我们所有的节点都是 INT8 的呢,那当然不是,像 Convolution 这种密集型的计算大部分都是 INT8 精度的,但是像上图中的 SoftMax 节点的输入输出都是 FP32 精度

在这里插入图片描述

还有一个点大家需要注意,大家可以看到我们前面的数据都是 NCHW 这种格式,这个大家比较熟悉,但是经过 ConvActPool 之后就变成了 NC/32HW32 这种格式,那这个其实是 TensorRT 内部自定义的一种数据格式,更多细节大家可以看官方文档:data-format-desc

resnet 相对来说比较简单,这里大家可以再看看其他的模型例如 MobileNet 模型 engine 等等,像我们下一个章节要讲的 YOLO 模型,它的 INT8 engine 可能就没有这么好看,它的模型结构相对比较复杂,量化后会存在很多的 reformat 节点

在 tools 文件夹中有一个 build.sh 脚本文件,通过 trtexec 生成 engine,我们可以利用它来生成 mobilenet 的 int8 engine 模型,在此之前我们需要在该脚本文件中添加 --int8 参数,如下图所示:

在这里插入图片描述

接着执行如下指令:

bash tools/build.sh result/mobilnet/mobilenetV2.onnx int8

输出如下:

在这里插入图片描述

同时在当前目录会生成 .engine 和一系列日志文件,如下图所示:

在这里插入图片描述

那大家可能有所疑问为什么可以直接生成 INT8 的 engine 呢?难道不需要 calibration 吗?那其实 trtexec 提供了 --int8 参数运行我们生成 INT8 量化的 engine,如果你不提供 calibration_table,不提供各个 layer 的 dynamic range,那它量化出来的效果非常差,但是我们这里只是查看 mobilenet 的 engine 的结构,所以没有问题

下面我们就如法炮制,跟 resnet50 一样利用 trt-engine-explorer 去生成 engine 的 .svg 图片,这里博主就不再展示了,mobilenetV2-int8.engine 的结构如下图所示:

在这里插入图片描述

结语

本次课程我们学习了 trt-engine-explore 工具的使用,将 TensorRT 优化好的 engine 的结构绘制成 .svg 图片可视化出来。这个工具在做 QAT 量化时可能使用得更多,因为在 QAT 的过程中,模型的各个层之间经常会出现数据格式和精度不匹配的情况,导致 TensorRT 在构建引擎时插入 Reformat 节点。另外可以查看 QAT 模型中哪些层并没有按照我们期望的做 INT8,利用该工具可以有助我们优化模型结构,减少额外的转换操作,检查关键层的量化精度等等

OK,以上就是 6.4 小节案例的全部内容了,下节开始我们进入第七章节的学习,敬请期待😄

下载链接

  • tensorrt_starter源码
  • 6.4-trt-engine-inspector案例文件

参考

  • Ubuntu20.04软件安装大全
  • https://github.com/kalfazed/tensorrt_starter
  • https://github.com/NVIDIA/TensorRT/tools/trt-engine-explorer
  • https://docs.nvidia.com/deeplearning/tensorrt/developer-guide/index.html#data-format-desc

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/414504.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

更新RK3588开发板的rknn_server和librknnrt.so【这篇文章是RKNPU2从入门到实践 --- 【5】的配套文章】

作者使用的平台有: 一台装有Windows系统的宿主机,在该宿主机上装有Ubuntu 20.04虚拟系统; 瑞芯微RK3588开发板,开发板上的系统为Ubuntu22.04系统; 更新板子的 rknn_server 和 librknnrt.so,rknn_server 和…

借鉴腾讯系统架构从小到大的过程 - 如何做好一个系统设计?不限于(慧哥)慧知开源充电桩平台

推荐一套企业级开源充电桩平台:完整代码包含多租户、硬件模拟器、多运营商、多小程序,汽车 电动自行车、云快充协议;——(慧哥)慧知开源充电桩平台;https://liwenhui.blog.csdn.net/article/details/134773779?spm1001.2014.3001…

倒计时1天!每日一题,零基础入门FPGA

近年来,FPGA工程师凭借着远高于传统软件开发工程师的薪酬,吸引了越来越多的人转行。 然而,入门FPGA并非易事。你需要有清晰的学习路线,包括它的基本组成(如可编程逻辑块CLB、输入输出块IOB、内部连线资源等&#xff0…

JS设计模式之“分即是合” - 建造者模式

引言 当我们在进行软件编程时,常常会遇到需要创建复杂对象的情况。这些对象可能有多个属性,属性之间存在依赖关系,或需要按照特定的骤来创建。在这种情况下,使用建造者模式(Builder Pattern)可以提供一种活…

selenium启动总报错 WebDriverManager总是异常

我的环境用这个自动管理驱动的工具 WebDriverManager 总是报错 尝试过很多方法都没有,只好手动指定浏览器的位置 System.setProperty("webdriver.chrome.driver", "C:\\Users\\27224\\.cache\\selenium\\chromedriver\\win64\\128.0.6613.84\\chrome…

HTTP 协议详解

0x01:HTTP 协议简介 HTTP(HyperTextTransferProtocol,超文本传输协议),是一个工作在应用层的协议,它通常运行在 TCP 之上,它指定了客户端以什么样的格式发送信息,以及得到什么样的响…

uniapp微信小程序开发测试获取手机号码

先申请测试号 注意认证但是没有完全认证不要试测试号解密如下 总结我自己的两大坑 1.官网的WXBizDataCrypt需要导入crypto要提前下载但是试了很多次没有效果重新编写这个。将crypto库换成crypto-js库 2.我一直在尝试用下有下面这个界面的测试号不行获取不到用户的code还是啥忘记…

基于SpringBoot+Vue+MySQL的社区维修平台

系统背景 系统管理也都将通过计算机进行整体智能化操作,对于社区维修平台所牵扯的管理及数据保存都是非常多的,例如住户管理、社区公告管理、维修工管理、维修订单管理、接单信息管理、订单信息管理、在线沟通管理、举报信息管理、留言板管理、系统管理等…

记Spring HTTP Invoker远程调用的使用(二)基于Servlet方式,配置servlet映射url-pattern实现

目录 前言 一、概念 二、代码实现 1. 服务端实现 2. 客户端实现 前言 本篇接上一篇记Spring HTTP Invoker远程调用的使用(一)基于Url映射方式,DispatcherServlet统一处理实现-CSDN博客https://blog.csdn.net/u011529483/article/details/141…

搭建高可用OpenStack(Queen版)集群(九)之部署nova计算节点

一、搭建高可用OpenStack(Queen版)集群之部署计算节点 一、部署nova 1、安装nova-compute 在全部计算节点安装nova-compute服务 yum install python-openstackclient openstack-utils openstack-selinux -y yum install openstack-nova-compute -y 若yu…

【如何在MacOS升级ruby版本】

🎥博主:程序员不想YY啊 💫CSDN优质创作者,CSDN实力新星,CSDN博客专家 🤗点赞🎈收藏⭐再看💫养成习惯 ✨希望本文对您有所裨益,如有不足之处,欢迎在评论区提出…

OpenAI Whisper API (InvalidRequestError)

题意: OpenAI Whisper API(无效请求错误) 问题背景: Im trying to use OpenAI Whisper API to transcribe my audio files. When I run it by opening my local audio files from disk, it worked perfectly. Now Im developing a FastAPI e…

【超音速 专利 CN116109587A】一种复杂环境下密封钉焊缝质量检测方法

申请号CN202310066309.X公开号(公开)CN116109587A申请日2023.01.12申请人(公开)超音速人工智能科技股份有限公司(833753)发明人(公开)张俊峰(总); 陈炯标 原文摘要 本发明公开了一种复杂环境下密封钉焊缝…

如何在手机上设置国内代理IP地址:详细指南

在某些情况下,我们可能需要在手机上设置国内代理IP地址,以便访问特定的网络服务或提高网络连接的稳定性。本文将详细介绍如何在Android和iOS设备上设置代理IP地址。 在Android设备上设置代理IP地址 在Android设备上设置代理IP地址非常简单,只…

每日一练1:数字统计(含链接)

链接&#xff1a; [NOIP2010]数字统计_牛客题霸_牛客网 代码&#xff1a; #include <iostream> using namespace std;int main() {int a, b;int count 0;cin >> a >> b;for(int i a; a < b; a){i a;while(i>0){if(i%10 2) count;i / 10;}}cout…

asp.net Temporary ASP.NET Files修改为其他位置

Temporary ASP.NET Files这个文件夹是编译期间用于临时文件存储的目录。当请求一个新页面时ASP.NET会分析aspx页面并为其生成一个.cs文件&#xff0c;然后JIT编译器会编译这个cs生成一个dll&#xff0c;这些过程都是在这个目录里面进行的。其中还放了你在项目中引用的Assembly的…

线性代数|机器学习-P32循环矩阵的特征向量-傅里叶矩阵

文章目录 1. 大纲2. 循环矩阵2.1 移位矩阵P2.2 P的特征值和特征向量2.3 循环卷积矩阵2.4 循环卷积计算 3. 傅里叶矩阵 1. 大纲 循环矩阵在机器学习&#xff0c;图像处理中的应用循环卷积矩阵的特征值&#xff0c;特征向量&#xff0c;卷积规则循环卷积矩阵多项式表达&#xff…

小琳Python课堂:Python优先级队列深入解析:`PriorityQueue`类的使用与原理

小琳Python课堂开讲啦&#xff01;今天我们来深入解析Python中的PriorityQueue类&#xff0c;这个类在 多任务处理和数据优先级管理 中非常有用哦&#xff01;&#x1f31f; 在Python中&#xff0c;PriorityQueue类是queue模块的一部分&#xff0c;用于实现一个优先级队列。优先…

详解JavaScript

目录 JavaScript 引入样式 基础语法 变量 数据类型 运算符 JavaScript对象 数组 数组定义 数组操作 函数 语法格式 关于参数个数 函数表达式 对象 JQuery 语法 选择器 事件 常见的事件 操作元素 获取/设置元素内容 获取/设置元素属性 获取/设置CSS属性 …

【Spring Boot 3】【Web】返回图片

【Spring Boot 3】【Web】返回图片 背景介绍开发环境开发步骤及源码工程目录结构 背景 软件开发是一门实践性科学&#xff0c;对大多数人来说&#xff0c;学习一种新技术不是一开始就去深究其原理&#xff0c;而是先从做出一个可工作的DEMO入手。但在我个人学习和工作经历中&a…