tensorRT_Pro
tensorRT_Pro是一个基于TensorRT的高性能推理框架,专为简化AI模型部署而设计。它提供C++和Python的极简接口,让开发者只需几行代码就能运行YOLOv5、YOLOX等主流模型,无需深入处理TensorRT的复杂集成细节。例如,C++只需3行代码完成推理,Python示例也清晰易用。
它解决了传统TensorRT部署门槛高的问题——原本需要大量代码处理插件开发、序列化和精度优化(如FP32/FP16/INT8编译),而tensorRT_Pro已封装这些步骤,让部署效率大幅提升。特别适合AI工程师和嵌入式开发者在服务器或边缘设备上快速部署模型,无需反复调试底层细节。
工具附带丰富教程、Docker镜像和预训练模型示例(如YOLOv5的简单实现、CenterNet转换指南),新手也能轻松上手。核心优势在于“开箱即用”:从模型加载到推理结果输出,全程流畅高效,让高性能推理真正触手可及。
使用场景
某智能安防公司需在NVIDIA Jetson AGX Xavier嵌入式设备上部署YOLOv5行人检测模型,实时分析1080P视频流以实现安防预警,要求推理延迟低于80ms。
没有 tensorRT_Pro 时
- 需手动编写TensorRT引擎创建代码,涉及输入输出绑定、插件注册等底层操作,开发周期长达2周。
- 模型精度优化(FP16/INT8)需反复编译测试,每次调整耗时1小时以上,影响紧急需求迭代。
- 自定义后处理插件(如NMS)实现复杂,调试时频繁出现内存泄漏,导致3次返工。
- 嵌入式部署需单独处理CUDA 11.4、TensorRT 8.4版本依赖,环境配置失败率超40%。
- 性能瓶颈不明确,推理延迟常达120ms,无法满足实时预警要求。
使用 tensorRT_Pro 后
- 仅需3行C++代码加载预编译模型并执行推理,开发周期压缩至2天。
- 内置一键精度优化工具,FP16/INT8切换仅需5分钟,优化效率提升12倍。
- 封装后处理插件序列化机制,NMS逻辑通过API直接调用,调试错误率归零。
- 通过Docker镜像一键部署到Jetson设备,环境配置时间从1天降至10分钟。
- 性能测试报告精准定位瓶颈,优化后平均延迟降至58ms,满足实时性指标。
tensorRT_Pro将复杂的TensorRT部署流程简化为几行代码,让嵌入式AI开发从“技术攻坚”转向“业务创新”。
运行环境要求
- Linux
- Windows
需要 NVIDIA GPU,CUDA 10.2
未说明

快速开始
新闻:
- 🔥 发布了一个简单的实现:https://github.com/shouxieai/infer
- 🔥 增加了对 YOLOv7 的支持。
- 🔥 发布了集成 TensorRT 的硬件解码 Python 解决方案。
- 🔥 Docker 镜像已发布:https://hub.docker.com/r/hopef/tensorrt-pro
- ⚡ 也提供了 tensorRT_Pro_comments_version(协作贡献版本),以获得更好的学习体验。仓库:https://github.com/Guanbin-Huang/tensorRT_Pro_comments
- 🔥 发布了简单的 YOLOv5/YOLOX 实现,简单易用。
- 🔥 支持 YOLOv5 1.0-6.0/master 版本。
- 教程笔记本下载:
- 发布了将 CenterNet 从 PyTorch 导出到 TensorRT 的教程。
教程视频
- 哔哩哔哩:https://www.bilibili.com/video/BV1Xw411f7FW(目前仅提供中文版,英文版即将推出)
- 幻灯片:http://zifuture.com:1556/fs/sxai/tensorRT.pptx(目前仅提供中文版,英文版即将推出)
- 教程文件夹:为初学者提供了一个很好的入门介绍,帮助他们大致了解我们的框架。(中文/英文)
开箱即用的基于 TensorRT 的高性能推理框架,支持 C++/Python
C++ 接口:只需 3 行代码即可运行 YOLOX
// 在 GPU-0 上创建推理引擎 //auto engine = Yolo::create_infer("yolov5m.fp32.trtmodel", Yolo::Type::V5, 0); auto engine = Yolo::create_infer("yolox_m.fp32.trtmodel", Yolo::Type::X, 0); // 加载图像 auto image = cv::imread("1.jpg"); // 进行推理并获取结果 auto box = engine->commit(image).get(); // 返回 Box 向量Python 接口:
import pytrt model = models.resnet18(True).eval().to(device) trt_model = tp.from_torch(model, input) trt_out = trt_model(input)- 简单的 Python YOLO 示例:
import os import cv2 import numpy as np import pytrt as tp engine_file = "yolov5s.fp32.trtmodel" if not os.path.exists(engine_file): tp.compile_onnx_to_file(1, tp.onnx_hub("yolov5s"), engine_file) yolo = tp.Yolo(engine_file, type=tp.YoloType.V5) image = cv2.imread("car.jpg") bboxes = yolo.commit(image).get() print(f"{len(bboxes)} objects") for box in bboxes: left, top, right, bottom = map(int, [box.left, box.top, box.right, box.bottom]) cv2.rectangle(image, (left, top), (right, bottom), tp.random_color(box.class_label), 5) saveto = "yolov5.car.jpg" print(f"Save to {saveto}") cv2.imwrite(saveto, image) cv2.imshow("result", image) cv2.waitKey()
简介
- 提供面向 C++/Python 的高级接口。
- 简化自定义插件的实现,并封装了序列化和反序列化过程,使使用更加便捷。
- 简化 fp32、fp16 和 int8 模型的编译流程,便于在服务器或嵌入式设备上使用 C++/Python 进行部署。
- 提供可直接使用的模型及示例,包括 RetinaFace、SCRFD、YOLOv5、YOLOX、ArcFace、AlphaPose、CenterNet 和 DeepSORT(C++)。
YOLOX与YOLOv5系列模型测试报告
app_yolo.cpp速度测试
- 分辨率(YOLOv5P5、YOLOX)= (640×640),(YOLOv5P6) = (1280×1280)
- 最大批处理大小 = 16
- 预处理 + 推理 + 后处理
- CUDA 10.2,cuDNN 8.2.2.26,TensorRT 8.0.1.6
- RTX 2080 Ti
- 测试次数:取100次结果的平均值,但排除首次预热运行
- 测试日志:workspace/perf.result.std.log
- 测试代码:src/application/app_yolo.cpp
- 测试图像:位于workspace/inference目录下的6张图片
- 分别为810×1080、500×806、1024×684、550×676、1280×720、800×533分辨率
- 测试方法:加载6张图片,对这6张图片进行推理,重复100次。注意每张图片都需要进行预处理和后处理。
| 模型 | 分辨率 | 类型 | 精度 | 耗时(ms) | FPS |
|---|---|---|---|---|---|
| yolox_x | 640×640 | YOLOX | FP32 | 21.879 | 45.71 |
| yolox_l | 640×640 | YOLOX | FP32 | 12.308 | 81.25 |
| yolox_m | 640×640 | YOLOX | FP32 | 6.862 | 145.72 |
| yolox_s | 640×640 | YOLOX | FP32 | 3.088 | 323.81 |
| yolox_x | 640×640 | YOLOX | FP16 | 6.763 | 147.86 |
| yolox_l | 640×640 | YOLOX | FP16 | 3.933 | 254.25 |
| yolox_m | 640×640 | YOLOX | FP16 | 2.515 | 397.55 |
| yolox_s | 640×640 | YOLOX | FP16 | 1.362 | 734.48 |
| yolox_x | 640×640 | YOLOX | INT8 | 4.070 | 245.68 |
| yolox_l | 640×640 | YOLOX | INT8 | 2.444 | 409.21 |
| yolox_m | 640×640 | YOLOX | INT8 | 1.730 | 577.98 |
| yolox_s | 640×640 | YOLOX | INT8 | 1.060 | 943.15 |
| yolov5x6 | 1280×1280 | YOLOv5_P6 | FP32 | 68.022 | 14.70 |
| yolov5l6 | 1280×1280 | YOLOv5_P6 | FP32 | 37.931 | 26.36 |
| yolov5m6 | 1280×1280 | YOLOv5_P6 | FP32 | 20.127 | 49.69 |
| yolov5s6 | 1280×1280 | YOLOv5_P6 | FP32 | 8.715 | 114.75 |
| yolov5x | 640×640 | YOLOv5_P5 | FP32 | 18.480 | 54.11 |
| yolov5l | 640×640 | YOLOv5_P5 | FP32 | 10.110 | 98.91 |
| yolov5m | 640×640 | YOLOv5_P5 | FP32 | 5.639 | 177.33 |
| yolov5s | 640×640 | YOLOv5_P5 | FP32 | 2.578 | 387.92 |
| yolov5x6 | 1280×1280 | YOLOv5_P6 | FP16 | 20.877 | 47.90 |
| yolov5l6 | 1280×1280 | YOLOv5_P6 | FP16 | 10.960 | 91.24 |
| yolov5m6 | 1280×1280 | YOLOv5_P6 | FP16 | 7.236 | 138.20 |
| yolov5s6 | 1280×1280 | YOLOv5_P6 | FP16 | 3.851 | 259.68 |
| yolov5x | 640×640 | YOLOv5_P5 | FP16 | 5.933 | 168.55 |
| yolov5l | 640×640 | YOLOv5_P5 | FP16 | 3.450 | 289.86 |
| yolov5m | 640×640 | YOLOv5_P5 | FP16 | 2.184 | 457.90 |
| yolov5s | 640×640 | YOLOv5_P5 | FP16 | 1.307 | 765.10 |
| yolov5x6 | 1280×1280 | YOLOv5_P6 | INT8 | 12.207 | 81.92 |
| yolov5l6 | 1280×1280 | YOLOv5_P6 | INT8 | 7.221 | 138.49 |
| yolov5m6 | 1280×1280 | YOLOv5_P6 | INT8 | 5.248 | 190.55 |
| yolov5s6 | 1280×1280 | YOLOv5_P6 | INT8 | 3.149 | 317.54 |
| yolov5x | 640×640 | YOLOv5_P5 | INT8 | 3.704 | 269.97 |
| yolov5l | 640×640 | YOLOv5_P5 | INT8 | 2.255 | 443.53 |
| yolov5m | 640×640 | YOLOv5_P5 | INT8 | 1.674 | 597.40 |
| yolov5s | 640×640 | YOLOv5_P5 | INT8 | 1.143 | 874.91 |
app_yolo_fast.cpp速度测试。永不止步,追求更快
- 亮点: 在精度无损的情况下,比上述结果快约0.5毫秒。具体来说,我们移除了Focus层及部分转置节点等,并将其改用CUDA内核函数实现,其余部分保持不变。
- 测试日志: workspace/perf.result.std.log
- 测试代码: src/application/app_yolo_fast.cpp
- 提示: 可以参考下载的ONNX文件进行修改。如有任何疑问,欢迎通过各种方式联系。
- 结论: 本工作的核心思想是优化预处理和后处理流程。若使用YOLOX或YOLOv5的小型版本,该优化可能会有所帮助。
| 模型 | 分辨率 | 类型 | 精度 | 耗时(ms) | FPS |
|---|---|---|---|---|---|
| yolox_x_fast | 640×640 | YOLOX | FP32 | 21.598 | 46.30 |
| yolox_l_fast | 640×640 | YOLOX | FP32 | 12.199 | 81.97 |
| yolox_m_fast | 640×640 | YOLOX | FP32 | 6.819 | 146.65 |
| yolox_s_fast | 640×640 | YOLOX | FP32 | 2.979 | 335.73 |
| yolox_x_fast | 640×640 | YOLOX | FP16 | 6.764 | 147.84 |
| yolox_l_fast | 640×640 | YOLOX | FP16 | 3.866 | 258.64 |
| yolox_m_fast | 640×640 | YOLOX | FP16 | 2.386 | 419.16 |
| yolox_s_fast | 640×640 | YOLOX | FP16 | 1.259 | 794.36 |
| yolox_x_fast | 640×640 | YOLOX | INT8 | 3.918 | 255.26 |
| yolox_l_fast | 640×640 | YOLOX | INT8 | 2.292 | 436.38 |
| yolox_m_fast | 640×640 | YOLOX | INT8 | 1.589 | 629.49 |
| yolox_s_fast | 640×640 | YOLOX | INT8 | 0.954 | 1048.47 |
| yolov5x6_fast | 1280×1280 | YOLOv5_P6 | FP32 | 67.075 | 14.91 |
| yolov5l6_fast | 1280×1280 | YOLOv5_P6 | FP32 | 37.491 | 26.67 |
| yolov5m6_fast | 1280×1280 | YOLOv5_P6 | FP32 | 19.422 | 51.49 |
| yolov5s6_fast | 1280×1280 | YOLOv5_P6 | FP32 | 7.900 | 126.57 |
| yolov5x_fast | 640×640 | YOLOv5_P5 | FP32 | 18.554 | 53.90 |
| yolov5l_fast | 640×640 | YOLOv5_P5 | FP32 | 10.060 | 99.41 |
| yolov5m_fast | 640×640 | YOLOv5_P5 | FP32 | 5.500 | 181.82 |
| yolov5s_fast | 640×640 | YOLOv5_P5 | FP32 | 2.342 | 427.07 |
| yolov5x6_fast | 1280×1280 | YOLOv5_P6 | FP16 | 20.538 | 48.69 |
| yolov5l6_fast | 1280×1280 | YOLOv5_P6 | FP16 | 10.404 | 96.12 |
| yolov5m6_fast | 1280×1280 | YOLOv5_P6 | FP16 | 6.577 | 152.06 |
| yolov5s6_fast | 1280×1280 | YOLOv5_P6 | FP16 | 3.087 | 323.99 |
| yolov5x_fast | 640×640 | YOLOv5_P5 | FP16 | 5.919 | 168.95 |
| yolov5l_fast | 640×640 | YOLOv5_P5 | FP16 | 3.348 | 298.69 |
| yolov5m_fast | 640×640 | YOLOv5_P5 | FP16 | 2.015 | 496.34 |
| yolov5s_fast | 640×640 | YOLOv5_P5 | FP16 | 1.087 | 919.63 |
| yolov5x6_fast | 1280×1280 | YOLOv5_P6 | INT8 | 11.236 | 89.00 |
| yolov5l6_fast | 1280×1280 | YOLOv5_P6 | INT8 | 6.235 | 160.38 |
| yolov5m6_fast | 1280×1280 | YOLOv5_P6 | INT8 | 4.311 | 231.97 |
| yolov5s6_fast | 1280×1280 | YOLOv5_P6 | INT8 | 2.139 | 467.45 |
| yolov5x_fast | 640×640 | YOLOv5_P5 | INT8 | 3.456 | 289.37 |
| yolov5l_fast | 640×640 | YOLOv5_P5 | INT8 | 2.019 | 495.41 |
| yolov5m_fast | 640×640 | YOLOv5_P5 | INT8 | 1.425 | 701.71 |
| yolov5s_fast | 640×640 | YOLOv5_P5 | INT8 | 0.844 | 1185.47 |
设置与配置
Linux
- VSCode(强烈推荐!)
- 配置 cuDNN、CUDA、TensorRT 8.0 和 Protocol Buffers 的路径。
- 在 Makefile 或 CMakeLists.txt 中配置与你的 NVIDIA 显卡匹配的计算能力:
- 例如:
-gencode=arch=compute_75,code=sm_75。如果你使用的是 3080Ti,则应为gencode=arch=compute_86,code=sm_86。 - GPU 计算能力参考表: https://developer.nvidia.com/cuda-gpus#compute
- 例如:
- 在 .vscode/c_cpp_properties.json 中配置库路径。
- CUDA 版本:CUDA 10.2
- cuDNN 版本:cudnn 8.2.2.26。注意需要同时下载开发文件(.h 文件)和运行时文件(.so 文件)。
- TensorRT 版本:tensorRT-8.0.1.6-cuda10.2
- Protocol Buffers 版本(用于 ONNX 解析器):protobuf v3.11.4
- 如果使用其他版本,请参考……
- 下载链接:https://github.com/protocolbuffers/protobuf/tree/v3.11.4
- 下载后编译,并将 Makefile/CMakeLists.txt 中的路径替换为新的 protobuf 3.11.4 路径。
- CMake:
mkdir build && cd buildcmake ..make yolo -j8
- Makefile:
make yolo -j8
Linux:为 Python 编译
- 编译并安装
- Makefile:
- 在 Makefile 中设置
use_python := true
- 在 Makefile 中设置
- CMakeLists.txt:
- 在 CMakeLists.txt 中设置
set(HAS_PYTHON ON)
- 在 CMakeLists.txt 中设置
- 输入
make pyinstall -j8 - 编译后的文件位于
python/pytrt/libpytrtc.so
- Makefile:
Windows
请查看 lean/README.md 以获取详细的依赖项信息。
在 TensorRT.vcxproj 中,将
<Import Project="$(VCTargetsPath)\BuildCustomizations\CUDA 10.0.props" />替换为你自己的 CUDA 路径。在 TensorRT.vcxproj 中,将
<Import Project="$(VCTargetsPath)\BuildCustomizations\CUDA 10.0.targets" />替换为你自己的 CUDA 路径。在 TensorRT.vcxproj 中,将
<CodeGeneration>compute_61,sm_61</CodeGeneration>替换为你自己的计算能力。配置你的依赖项,或将它们下载到 /lean 文件夹中。配置 VC++ 目录(包含目录和引用)。
配置环境变量,在“调试”->“环境”中进行设置。
编译并运行示例,有三种选项可供选择。
Windows:为 Python 编译
- 编译 pytrtc.pyd。在 Visual Studio 中选择 Python 进行编译。
- 复制 dll 文件并执行
python/copy_dll_to_pytrt.bat。 - 在 python 目录下通过
python test_yolov5.py执行示例。
- 如果需要安装,切换到目标环境(例如你的 conda 环境),然后运行
python setup.py install,之后再按照步骤 1 和 2 操作。 - 编译后的文件位于
python/pytrt/libpytrtc.pyd。
其他 Protocol Buffers 版本
- 在 onnx/make_pb.sh 中,将 protoc 的路径
protoc=/data/sxai/lean/protobuf3.11.4/bin/protoc替换为你自己版本的 protoc。
# 在终端中进入 /onnx 路径
cd onnx
# 执行命令生成 pb 文件
bash make_pb.sh
- CMake:
- 将 CMakeLists.txt 中的
set(PROTOBUF_DIR "/data/sxai/lean/protobuf3.11.4")替换为你所用 protoc 的相同路径。
- 将 CMakeLists.txt 中的
mkdir build && cd build
cmake ..
make yolo -j64
- Makefile:
- 将 Makefile 中的
lean_protobuf := /data/sxai/lean/protobuf3.11.4替换为你所用 protoc 的相同路径。
- 将 Makefile 中的
make yolo -j64
TensorRT 7.x 支持
- 默认是 TensorRT 8.x
- 将 onnx_parser_for_7.x/onnx_parser 替换为 src/tensorRT/onnx_parser
bash onnx_parser/use_tensorrt_7.x.sh
- 配置 Makefile/CMakeLists.txt 中指向 TensorRT 7.x 的路径。
- 执行
make yolo -j64
TensorRT 8.x 支持
- 默认是 TensorRT 8.x
- 将 onnx_parser_for_8.x/onnx_parser 替换为 src/tensorRT/onnx_parser
bash onnx_parser/use_tensorrt_8.x.sh
- 配置 Makefile/CMakeLists.txt 中指向 TensorRT 8.x 的路径。
- 执行
make yolo -j64
不同任务/模型支持指南
YoloV5 支持
- 如果 PyTorch ≥ 1.7,且模型为 5.0+,则该框架支持此模型。
- 如果 PyTorch < 1.7 或 YOLOv5 为 2.0、3.0 或 4.0,则需要对 opset 进行小幅修改。
- 如果你想实现低版本 PyTorch 下的推理、动态批次大小以及其他高级设置,请查看我们的 博客(目前为中文),并通过微信扫描二维码加入我们。
- 下载 YOLOv5
git clone git@github.com:ultralytics/yolov5.git
- 修改代码以支持动态批次大小
# yolov5/models/yolo.py 中 forward 函数第 55 行
# bs, _, ny, nx = x[i].shape # x(bs,255,20,20) 转为 x(bs,3,20,20,85)
# x[i] = x[i].view(bs, self.na, self.no, ny, nx).permute(0, 1, 3, 4, 2).contiguous()
# 修改为:
bs, _, ny, nx = x[i].shape # x(bs,255,20,20) 转为 x(bs,3,20,20,85)
bs = -1
ny = int(ny)
nx = int(nx)
x[i] = x[i].view(bs, self.na, self.no, ny, nx).permute(0, 1, 3, 4, 2).contiguous()
# yolov5/models/yolo.py 第 70 行
# z.append(y.view(bs, -1, self.no))
# 修改为:
z.append(y.view(bs, self.na * ny * nx, self.no))
############# 对于 YOLOv5-6.0 #####################
# yolov5/models/yolo.py 第 65 行
# if self.grid[i].shape[2:4] != x[i].shape[2:4] or self.onnx_dynamic:
# self.grid[i], self.anchor_grid[i] = self._make_grid(nx, ny, i)
# 修改为:
if self.grid[i].shape[2:4] != x[i].shape[2:4] or self.onnx_dynamic:
self.grid[i], self.anchor_grid[i] = self._make_grid(nx, ny, i)
# 断开 PyTorch trace 的连接
anchor_grid = (self.anchors[i].clone() * self.stride[i]).view(1, -1, 1, 1, 2)
# yolov5/models/yolo.py 第 70 行
# y[..., 2:4] = (y[..., 2:4] * 2) ** 2 * self.anchor_grid[i] # wh
# 修改为:
y[..., 2:4] = (y[..., 2:4] * 2) ** 2 * anchor_grid # wh
# yolov5/models/yolo.py 第 73 行
# wh = (y[..., 2:4] * 2) ** 2 * self.anchor_grid[i] # wh
# 修改为:
wh = (y[..., 2:4] * 2) ** 2 * anchor_grid # wh
############# 对于 YOLOv5-6.0 #####################
# yolov5/export.py 第 52 行
# torch.onnx.export(dynamic_axes={'images': {0: 'batch', 2: 'height', 3: 'width'}, # 形状(1,3,640,640)
# 'output': {0: 'batch', 1: 'anchors'} # 形状(1,25200,85) 修改为
# 修改为:
torch.onnx.export(dynamic_axes={'images': {0: 'batch'}, # 形状(1,3,640,640)
'output': {0: 'batch'} # 形状(1,25200,85)
- 导出为 ONNX 模型
cd yolov5
python export.py --weights=yolov5s.pt --dynamic --include=onnx --opset=11
- 复制模型并执行
cp yolov5/yolov5s.onnx tensorRT_cpp/workspace/
cd tensorRT_cpp
make yolo -j32
YOLOv7 支持
1. 下载 YOLOv7 和对应的 pth 文件。# 来自 CDN
# 或者使用 wget 下载:https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7.pt
wget https://cdn.githubjs.cf/WongKinYiu/yolov7/releases/download/v0.1/yolov7.pt
git clone git@github.com:WongKinYiu/yolov7.git
- 修改代码以支持动态批次大小
# yolov7/models/yolo.py 中的第45行 forward 函数
# bs, _, ny, nx = x[i].shape # x(bs,255,20,20) 转为 x(bs,3,20,20,85)
# x[i] = x[i].view(bs, self.na, self.no, ny, nx).permute(0, 1, 3, 4, 2).contiguous()
# 修改为:
bs, _, ny, nx = map(int, x[i].shape) # x(bs,255,20,20) 转为 x(bs,3,20,20,85)
bs = -1
x[i] = x[i].view(bs, self.na, self.no, ny, nx).permute(0, 1, 3, 4, 2).contiguous()
# yolov7/models/yolo.py 中的第52行
# y = x[i].sigmoid()
# y[..., 0:2] = (y[..., 0:2] * 2. - 0.5 + self.grid[i]) * self.stride[i] # xy
# y[..., 2:4] = (y[..., 2:4] * 2) ** 2 * self.anchor_grid[i] # wh
# z.append(y.view(bs, -1, self.no))
# 修改为:
y = x[i].sigmoid()
xy = (y[..., 0:2] * 2. - 0.5 + self.grid[i]) * self.stride[i] # xy
wh = (y[..., 2:4] * 2) ** 2 * self.anchor_grid[i].view(1, -1, 1, 1, 2) # wh
classif = y[..., 4:]
y = torch.cat([xy, wh, classif], dim=-1)
z.append(y.view(bs, self.na * ny * nx, self.no))
# yolov7/models/yolo.py 中的第57行
# return x 如果处于训练模式,否则返回 (torch.cat(z, 1), x)
# 修改为:
return x 如果处于训练模式,否则返回 torch.cat(z, 1)
# yolov7/models/export.py 中的第52行
# output_names=['classes', 'boxes'] 如果 y 为空,则为 ['output'],
# dynamic_axes={'images': {0: 'batch', 2: 'height', 3: 'width'}, // 尺寸(1,3,640,640)
# 'output': {0: 'batch', 2: 'y', 3: 'x'}} 如果 opt.dynamic 为真,则设置,否则为 None)
# 修改为:
output_names=['classes', 'boxes'] 如果 y 为空,则为 ['output'],
dynamic_axes={'images': {0: 'batch'}, // 尺寸(1,3,640,640)
'output': {0: 'batch'}} 如果 opt.dynamic 为真,则设置,否则为 None)
- 导出为 ONNX 模型
cd yolov7
python models/export.py --dynamic --grid --weight=yolov7.pt
- 复制模型并执行
cp yolov7/yolov7.onnx tensorRT_cpp/workspace/
cd tensorRT_cpp
make yolo -j32
YoloX 支持
- 下载地址:https://github.com/Megvii-BaseDetection/YOLOX
- 如果不想自己导出 ONNX 文件,可以直接在 Megvii 的仓库中运行。
- 下载 YoloX
git clone git@github.com:Megvii-BaseDetection/YOLOX.git
cd YOLOX
- 修改代码
修改后的代码可以确保成功进行 int8 编译和推理,否则会抛出
Missing scale and zero-point for tensor (Unnamed Layer* 686)错误。
# yolox/models/yolo_head.py 中的第206行 forward 函数。将注释掉的代码替换为未注释的代码
# self.hw = [x.shape[-2:] for x in outputs]
self.hw = [list(map(int, x.shape[-2:])) for x in outputs]
# yolox/models/yolo_head.py 中的第208行 forward 函数。将注释掉的代码替换为未注释的代码
# [batch, n_anchors_all, 85]
# outputs = torch.cat(
# [x.flatten(start_dim=2) for x in outputs], dim=2
# ).permute(0, 2, 1)
proc_view = lambda x: x.view(-1, int(x.size(1)), int(x.size(2) * x.size(3)))
outputs = torch.cat(
[proc_view(x) for x in outputs], dim=2
).permute(0, 2, 1)
# yolox/models/yolo_head.py 中的第253行 decode_output 函数。将注释掉的代码替换为未注释的代码
#outputs[..., :2] = (outputs[..., :2] + grids) * strides
#outputs[..., 2:4] = torch.exp(outputs[..., 2:4]) * strides
#return outputs
xy = (outputs[..., :2] + grids) * strides
wh = torch.exp(outputs[..., 2:4]) * strides
return torch.cat((xy, wh, outputs[..., 4:]), dim=-1)
# tools/export_onnx.py 中的第77行
model.head.decode_in_inference = True
- 导出为 ONNX
# 下载模型
wget https://github.com/Megvii-BaseDetection/YOLOX/releases/download/0.1.1rc0/yolox_m.pth
# 导出
export PYTHONPATH=$PYTHONPATH:.
python tools/export_onnx.py -c yolox_m.pth -f exps/default/yolox_m.py --output-name=yolox_m.onnx --dynamic --no-onnxsim
- 执行命令
cp YOLOX/yolox_m.onnx tensorRT_cpp/workspace/
cd tensorRT_cpp
make yolo -j32
YoloV3 支持
- 如果 PyTorch 版本 ≥ 1.7,且模型版本 ≥ 5.0,则框架本身即可支持该模型。
- 如果 PyTorch 版本 < 1.7 或是 YOLOv3 模型,则需要对 opset 进行小幅调整。
- 若希望在较低版本的 PyTorch 上实现推理,或使用动态批次大小等高级功能,请查看我们的博客(目前为中文),并通过微信扫描二维码加入我们。
- 下载 YOLOv3
git clone git@github.com:ultralytics/yolov3.git
- 修改代码以支持动态批次大小
# yolov3/models/yolo.py 中的第55行 forward 函数
# bs, _, ny, nx = x[i].shape // x(bs,255,20,20) 转为 x(bs,3,20,20,85)
# x[i] = x[i].view(bs, self.na, self.no, ny, nx).permute(0, 1, 3, 4, 2).contiguous()
# 修改为:
bs, _, ny, nx = map(int, x[i].shape) // x(bs,255,20,20) 转为 x(bs,3,20,20,85)
bs = -1
x[i] = x[i].view(bs, self.na, self.no, ny, nx).permute(0, 1, 3, 4, 2).contiguous()
# yolov3/models/yolo.py 中的第70行
# z.append(y.view(bs, -1, self.no))
# 修改为:
z.append(y.view(bs, self.na * ny * nx, self.no))
# yolov3/models/yolo.py 中的第62行
# 如果 self.grid[i].shape[2:4] 不等于 x[i].shape[2:4] 或者 self.onnx_dynamic 为真,
# 则更新 self.grid[i] 和 self.anchor_grid[i] 使用 _make_grid(nx, ny, i) 方法
# 修改为:
如果 self.grid[i].shape[2:4] 不等于 x[i].shape[2:4] 或者 self.onnx_dynamic 为真,
则更新 self.grid[i] 和 self.anchor_grid[i] 使用 _make_grid(nx, ny, i) 方法
anchor_grid = (self.anchors[i].clone() * self.stride[i]).view(1, -1, 1, 1, 2)
# yolov3/models/yolo.py 中的第70行
# y[..., 2:4] = (y[..., 2:4] * 2) ** 2 * self.anchor_grid[i] // wh
# 修改为:
y[..., 2:4] = (y[..., 2:4] * 2) ** 2 * anchor_grid // wh
# yolov3/models/yolo.py 中的第73行
# wh = (y[..., 2:4] * 2) ** 2 * self.anchor_grid[i] // wh
# 修改为:
wh = (y[..., 2:4] * 2) ** 2 * anchor_grid // wh
# yolov3/export.py 中的第52行
# torch.onnx.export(dynamic_axes={'images': {0: 'batch', 2: 'height', 3: 'width'}, // 形状(1,3,640,640)
# 'output': {0: 'batch', 1: 'anchors'} // 形状(1,25200,85)
# 修改为:
torch.onnx.export(dynamic_axes={'images': {0: 'batch'}, // 形状(1,3,640,640)
'output': {0: 'batch'} // 形状(1,25200,85)
- 导出为 ONNX 模型
cd yolov3
python export.py --weights=yolov3.pt --dynamic --include=onnx --opset=11
- 复制模型并执行
cp yolov3/yolov3.onnx tensorRT_cpp/workspace/
cd tensorRT_cpp
# 修改 src/application/app_yolo.cpp: main
# 测试(Yolo::Type::V3, TRT::Mode::FP32, "yolov3");
make yolo -j32
Retinaface支持
- 下载Pytorch_Retinaface仓库
git clone git@github.com:biubug6/Pytorch_Retinaface.git
cd Pytorch_Retinaface
# models/retinaface.py第24行
# return out.view(out.shape[0], -1, 2) 修改为
return out.view(-1, int(out.size(1) * out.size(2) * 2), 2)
# models/retinaface.py第35行
# return out.view(out.shape[0], -1, 4) 修改为
return out.view(-1, int(out.size(1) * out.size(2) * 2), 4)
# models/retinaface.py第46行
# return out.view(out.shape[0], -1, 10) 修改为
return out.view(-1, int(out.size(1) * out.size(2) * 2), 10)
# 下面的修改确保resize节点的输出基于缩放比例而非固定形状,从而实现动态批处理。
# models/net.py第89行
# up3 = F.interpolate(output3, size=[output2.size(2), output2.size(3)], mode="nearest") 修改为
up3 = F.interpolate(output3, scale_factor=2, mode="nearest")
# models/net.py第93行
# up2 = F.interpolate(output2, size=[output1.size(2), output1.size(3)], mode="nearest") 修改为
up2 = F.interpolate(output2, scale_factor=2, mode="nearest")
# 下面的代码移除了softmax(有时会出现问题),同时将输出拼接起来以简化解码过程。
# models/retinaface.py第123行
# if self.phase == 'train':
# output = (bbox_regressions, classifications, ldm_regressions)
# else:
# output = (bbox_regressions, F.softmax(classifications, dim=-1), ldm_regressions)
# return output
# 上述内容修改为:
output = (bbox_regressions, classifications, ldm_regressions)
return torch.cat(output, dim=-1)
# 设置'opset_version=11'以确保导出成功。
# torch_out = torch.onnx._export(net, inputs, output_onnx, export_params=True, verbose=False,
# input_names=input_names, output_names=output_names)
# 修改为:
torch_out = torch.onnx._export(net, inputs, output_onnx, export_params=True, verbose=False, opset_version=11,
input_names=input_names, output_names=output_names)
- 导出为ONNX格式
python convert_to_onnx.py
- 执行
cp FaceDetector.onnx ../tensorRT_cpp/workspace/mb_retinaface.onnx
cd ../tensorRT_cpp
make retinaface -j64
Scrfd支持
- https://github.com/deepinsight/insightface/tree/master/detection/scrfd
- 关于导出为ONNX格式的技术细节即将发布。在正式发布之前,欢迎加入我们进行讨论。
Arcface支持
auto arcface = Arcface::create_infer("arcface_iresnet50.fp32.trtmodel", 0);
auto feature = arcface->commit(make_tuple(face, landmarks)).get();
cout << feature << endl; // 1x512
- 在人脸识别示例中,
workspace/face/library是已注册的人脸集合。 workspace/face/recognize是要识别的人脸集合。- 结果保存在
workspace/face/result和workspace/face/library_draw中。
CenterNet支持
请参阅教程/2.0中的详细说明。
Bert支持(中文分类)
界面简介
Python 接口:更轻松地从 PyTorch 模型获取 ONNX 和 TRT 模型
- 仅需一行代码即可导出 ONNX 和 TRT 模型,并将其保存以供后续使用。
import pytrt
model = models.resnet18(True).eval()
pytrt.from_torch(
model,
dummy_input,
max_batch_size=16,
onnx_save_file="test.onnx",
engine_save_file="engine.trtmodel"
)
Python 接口:TensorRT 推理
- YOLOX TensorRT 推理
import pytrt
yolo = tp.Yolo(engine_file, type=tp.YoloType.X) # engine_file 是 TRT 模型文件
image = cv2.imread("inference/car.jpg")
bboxes = yolo.commit(image).get()
- 从 PyTorch 到 TensorRT 的无缝推理
import pytrt
model = models.resnet18(True).eval().to(device) # PyTorch 模型
trt_model = tp.from_torch(model, input)
trt_out = trt_model(input)
C++ 接口:YOLOX 推理
// 在 GPU 0 上创建推理引擎
auto engine = Yolo::create_infer("yolox_m.fp32.trtmodel", Yolo::Type::X, 0);
// 加载图像
auto image = cv::imread("1.jpg");
// 进行推理并获取结果
auto box = engine->commit(image).get();
C++ 接口:以 FP32/FP16 编译模型
TRT::compile(
TRT::Mode::FP32, // 以 FP32 编译模型
3, // 最大批量大小
"plugin.onnx", // ONNX 文件
"plugin.fp32.trtmodel", // 保存路径
{} // 需要时重新定义输入形状
);
- 对于 FP32 编译,你只需提供一个允许重新定义输入形状的 ONNX 文件。
C++ 接口:以 INT8 编译
- INT8 推理在精度上略逊于 FP32(约下降 5%),但速度却快得惊人。在该框架中,我们提供了 INT8 推理功能。
// 定义 INT8 校准函数,用于读取数据并处理为张量。
auto int8process = [](int current, int count, vector<string>& images, shared_ptr<TRT::Tensor>& tensor){
for(int i = 0; i < images.size(); ++i){
// INT8 编译需要校准。我们读取图像数据并设置归一化矩阵,然后将数据转换为张量。
auto image = cv::imread(images[i]);
cv::resize(image, image, cv::Size(640, 640));
float mean[] = {0, 0, 0};
float std[] = {1, 1, 1};
tensor->set_norm_mat(i, image, mean, std);
}
};
// 指定 TRT::Mode 为 INT8
auto model_file = "yolov5m.int8.trtmodel";
TRT::compile(
TRT::Mode::INT8, // INT8
3, // 最大批量大小
"yolov5m.onnx", // ONNX
model_file, // 保存文件名
{}, // 重新定义输入形状
int8process, // 校准回调函数
".", // 用于校准的图像数据所在目录
"" // 校准数据保存目录(即加载校准数据的地方)
);
- 我们通过整合一个 int8process 函数,避免了 TensorRT 官方实现中可能出现的诸多问题。
C++ 接口:推理
我们引入了 Tensor 类,以便更轻松地进行推理和主机与设备之间的数据传输,从而让用户无需关注底层细节。
Engine 类是另一个便利工具。
// 加载模型并获取共享指针。如果加载失败,则返回 nullptr。
auto engine = TRT::load_infer("yolov5m.fp32.trtmodel");
// 打印模型信息
engine->print();
// 加载图像
auto image = imread("demo.jpg");
// 获取模型的输入和输出节点,可以通过名称或索引访问
auto input = engine->input(0); // 或者 auto input = engine->input("images");
auto output = engine->output(0); // 或者 auto output = engine->output("output");
// 调用 set_norm_mat() 将图像放入输入张量中
float mean[] = {0, 0, 0};
float std[] = {1, 1, 1};
input->set_norm_mat(i, image, mean, std);
// 进行推理。这里 sync(true) 或 async(false) 是可选的
engine->forward(); // engine->forward(true 或 false)
// 获取输出指针,用于访问输出结果
float* output_ptr = output->cpu<float>();
C++ 接口:插件
- 你只需定义核函数和推理过程即可。代码的细节(例如插件的序列化、反序列化和注入等)都由框架自动处理。
- 很容易实现新的 FP32 和 FP16 插件。详情请参阅 HSwish.cu。
template<>
__global__ void HSwishKernel(float* input, float* output, int edge) {
KernelPositionBlock;
float x = input[position];
float a = x + 3;
a = a < 0 ? 0 : (a >= 6 ? 6 : a);
output[position] = x * a / 6;
}
int HSwish::enqueue(const std::vector<GTensor>& inputs, std::vector<GTensor>& outputs, const std::vector<GTensor>& weights, void* workspace, cudaStream_t stream) {
int count = inputs[0].count();
auto grid = CUDATools::grid_dims(count);
auto block = CUDATools::block_dims(count);
HSwishKernel <<<grid, block, 0, stream >>> (inputs[0].ptr<float>(), outputs[0].ptr<float>(), count);
return 0;
}
RegisterPlugin(HSwish);
关于我们
- 我们的博客:http://www.zifuture.com/ (目前仅提供中文版,英文版即将推出)
- 我们的视频频道: https://space.bilibili.com/1413433465 (目前仅提供中文版,英文版即将推出)
版本历史
v1.02021/09/14常见问题
相似工具推荐
stable-diffusion-webui
stable-diffusion-webui 是一个基于 Gradio 构建的网页版操作界面,旨在让用户能够轻松地在本地运行和使用强大的 Stable Diffusion 图像生成模型。它解决了原始模型依赖命令行、操作门槛高且功能分散的痛点,将复杂的 AI 绘图流程整合进一个直观易用的图形化平台。 无论是希望快速上手的普通创作者、需要精细控制画面细节的设计师,还是想要深入探索模型潜力的开发者与研究人员,都能从中获益。其核心亮点在于极高的功能丰富度:不仅支持文生图、图生图、局部重绘(Inpainting)和外绘(Outpainting)等基础模式,还独创了注意力机制调整、提示词矩阵、负向提示词以及“高清修复”等高级功能。此外,它内置了 GFPGAN 和 CodeFormer 等人脸修复工具,支持多种神经网络放大算法,并允许用户通过插件系统无限扩展能力。即使是显存有限的设备,stable-diffusion-webui 也提供了相应的优化选项,让高质量的 AI 艺术创作变得触手可及。
everything-claude-code
everything-claude-code 是一套专为 AI 编程助手(如 Claude Code、Codex、Cursor 等)打造的高性能优化系统。它不仅仅是一组配置文件,而是一个经过长期实战打磨的完整框架,旨在解决 AI 代理在实际开发中面临的效率低下、记忆丢失、安全隐患及缺乏持续学习能力等核心痛点。 通过引入技能模块化、直觉增强、记忆持久化机制以及内置的安全扫描功能,everything-claude-code 能显著提升 AI 在复杂任务中的表现,帮助开发者构建更稳定、更智能的生产级 AI 代理。其独特的“研究优先”开发理念和针对 Token 消耗的优化策略,使得模型响应更快、成本更低,同时有效防御潜在的攻击向量。 这套工具特别适合软件开发者、AI 研究人员以及希望深度定制 AI 工作流的技术团队使用。无论您是在构建大型代码库,还是需要 AI 协助进行安全审计与自动化测试,everything-claude-code 都能提供强大的底层支持。作为一个曾荣获 Anthropic 黑客大奖的开源项目,它融合了多语言支持与丰富的实战钩子(hooks),让 AI 真正成长为懂上
ComfyUI
ComfyUI 是一款功能强大且高度模块化的视觉 AI 引擎,专为设计和执行复杂的 Stable Diffusion 图像生成流程而打造。它摒弃了传统的代码编写模式,采用直观的节点式流程图界面,让用户通过连接不同的功能模块即可构建个性化的生成管线。 这一设计巧妙解决了高级 AI 绘图工作流配置复杂、灵活性不足的痛点。用户无需具备编程背景,也能自由组合模型、调整参数并实时预览效果,轻松实现从基础文生图到多步骤高清修复等各类复杂任务。ComfyUI 拥有极佳的兼容性,不仅支持 Windows、macOS 和 Linux 全平台,还广泛适配 NVIDIA、AMD、Intel 及苹果 Silicon 等多种硬件架构,并率先支持 SDXL、Flux、SD3 等前沿模型。 无论是希望深入探索算法潜力的研究人员和开发者,还是追求极致创作自由度的设计师与资深 AI 绘画爱好者,ComfyUI 都能提供强大的支持。其独特的模块化架构允许社区不断扩展新功能,使其成为当前最灵活、生态最丰富的开源扩散模型工具之一,帮助用户将创意高效转化为现实。
NextChat
NextChat 是一款轻量且极速的 AI 助手,旨在为用户提供流畅、跨平台的大模型交互体验。它完美解决了用户在多设备间切换时难以保持对话连续性,以及面对众多 AI 模型不知如何统一管理的痛点。无论是日常办公、学习辅助还是创意激发,NextChat 都能让用户随时随地通过网页、iOS、Android、Windows、MacOS 或 Linux 端无缝接入智能服务。 这款工具非常适合普通用户、学生、职场人士以及需要私有化部署的企业团队使用。对于开发者而言,它也提供了便捷的自托管方案,支持一键部署到 Vercel 或 Zeabur 等平台。 NextChat 的核心亮点在于其广泛的模型兼容性,原生支持 Claude、DeepSeek、GPT-4 及 Gemini Pro 等主流大模型,让用户在一个界面即可自由切换不同 AI 能力。此外,它还率先支持 MCP(Model Context Protocol)协议,增强了上下文处理能力。针对企业用户,NextChat 提供专业版解决方案,具备品牌定制、细粒度权限控制、内部知识库整合及安全审计等功能,满足公司对数据隐私和个性化管理的高标准要求。
ML-For-Beginners
ML-For-Beginners 是由微软推出的一套系统化机器学习入门课程,旨在帮助零基础用户轻松掌握经典机器学习知识。这套课程将学习路径规划为 12 周,包含 26 节精炼课程和 52 道配套测验,内容涵盖从基础概念到实际应用的完整流程,有效解决了初学者面对庞大知识体系时无从下手、缺乏结构化指导的痛点。 无论是希望转型的开发者、需要补充算法背景的研究人员,还是对人工智能充满好奇的普通爱好者,都能从中受益。课程不仅提供了清晰的理论讲解,还强调动手实践,让用户在循序渐进中建立扎实的技能基础。其独特的亮点在于强大的多语言支持,通过自动化机制提供了包括简体中文在内的 50 多种语言版本,极大地降低了全球不同背景用户的学习门槛。此外,项目采用开源协作模式,社区活跃且内容持续更新,确保学习者能获取前沿且准确的技术资讯。如果你正寻找一条清晰、友好且专业的机器学习入门之路,ML-For-Beginners 将是理想的起点。
ragflow
RAGFlow 是一款领先的开源检索增强生成(RAG)引擎,旨在为大语言模型构建更精准、可靠的上下文层。它巧妙地将前沿的 RAG 技术与智能体(Agent)能力相结合,不仅支持从各类文档中高效提取知识,还能让模型基于这些知识进行逻辑推理和任务执行。 在大模型应用中,幻觉问题和知识滞后是常见痛点。RAGFlow 通过深度解析复杂文档结构(如表格、图表及混合排版),显著提升了信息检索的准确度,从而有效减少模型“胡编乱造”的现象,确保回答既有据可依又具备时效性。其内置的智能体机制更进一步,使系统不仅能回答问题,还能自主规划步骤解决复杂问题。 这款工具特别适合开发者、企业技术团队以及 AI 研究人员使用。无论是希望快速搭建私有知识库问答系统,还是致力于探索大模型在垂直领域落地的创新者,都能从中受益。RAGFlow 提供了可视化的工作流编排界面和灵活的 API 接口,既降低了非算法背景用户的上手门槛,也满足了专业开发者对系统深度定制的需求。作为基于 Apache 2.0 协议开源的项目,它正成为连接通用大模型与行业专有知识之间的重要桥梁。