这个系列代码被封装的非常的精致,对二次开发不太友好,虽然也还是可以做些调节
这里写目录标题
量化
量化需要根据目标运行的机子确定。如果是CPU,就选ONNX,如果是GPU,ONNX是不work的,要用tensorrt
ONNX (自带)
Export
model.export(format='onnx',int8=True)
Predict
from onnxruntime import InferenceSession
import numpy as np
from PIL import Image
from opyv8 import Predictor
import time
session = InferenceSession(path_or_bytes=r"runs\detect\train4\weights\best.onnx")
predictor = Predictor(model=session, names=['red','blue'])
start_time = time.time()
img = Image.open('test2.jpg')
print(predictor.predict(img))
print(time.time()-start_time)
ONNX (torch)
有三种方式试过,都可以导出onnx的模型
1. 用yolov8
源码来自:ultralytics\yolo\engine\exporter.py
(不固定尺寸)
yolo export model=path/to/best.pt format=onnx dynamic=True
2. 用yolov5 里 export.py
但是attempt_load_weights这一步,要用yolo v8
3. 直接用 torch
class Demo(nn.Module):
def __init__(self, model=None):
super(Demo, self).__init__()
self.model = YOUR_PROCESS(model, 0, 255, False)
def forward(self, img):
return self.model(img)[0]
from ultralytics.nn.tasks import attempt_load_weights
model = attempt_load_weights(weights, device=0, inplace=True, fuse=True)
model = Demo(model)
model.to(device).eval()
#......(过程省略)
torch.onnx.export(self.model, img, output_path, verbose=False, opset_version=11, input_names=['images'],
output_names=['output'],
dynamic_axes={
'images': {
0: 'batch', 2: 'height', 3: 'width'}})
- 这里的Demo和YOUR_PROCESS都需要基于
nn.Module
,在YOUR_PROCESS用于包含一些模型额外的处理。- YOUR_PROCESS 中的内容,如果是用于前处理,记得不要进行梯度计算,并对运算过程和整个层做梯度忽略。如下:
with torch.no_grad():
# 在这个代码块中执行的操作不会被记录用于自动求导
output = model(input)
self.conv_xx.eval()
# 对于self.conv_xx层以及与其相关的层,将启用评估模式的行为
output = self.conv_xx(input)
- attempt_load_weights这一步,要用yolo v8的
TensorRT
以下三个libraries是比较重要的
pip install pycuda
pip install cuda-python
pip install tensorrt
一般前两个不会有什么问题,但是第三个会报错ERROR: Could not build wheels for tensorrt, which is required to install pyproject.toml-based projects
- 第一步:更新pip
F:\anaconda3\envs\detection\python.exe -m pip install --upgrade pip setuptools
然后重新尝试pip install tensorrt
- 第二步:
如果你在看这篇po的时候,pip 里面还是没有更新到对应你的 wheel,那么你需要自己来
假设之前,你已经下载了Nvidia 的TensorRT的zip 了(https://developer.nvidia.com/nvidia-tensorrt-8x-download)
好吧,以防万一,你还木有装,我还是说一下吧~ 下载的ZIp 解压到 “C:\Program Files\NVIDIA Corporation” , 解压的地址其实随便啦,但是我喜欢统一将Nvidia的都放这里。接着,我会将以下地址放入到 System’s PATH: C:\Program Files\NVIDIA Corporation\TensorRT\lib
set 完path 后,这个里面有救命的wheel file, tensorrt 配套的都放在 C:\Program Files\NVIDIA Corporation\TensorRT\python
,好滴,找到符合你python version的wheel file,(emmmm…我不是太喜欢Windows 系统,不晓得为啥不能在原地调absolute path 操作。)
好嘛,我copy & paste它们到本地,比如我需要操作: pip install YOLOv8\tensorrt-8.6.1-cp39-none-win_amd64.whl
viola~~ 你的tensorrt 就装好啦,快给我点个👍
- 从onnx导出 tensorrt 的engine format:
C:\Program Files\NVIDIA Corporation\TensorRT/bin/trtexec \
--onnx=yolov8s.onnx \
--saveEngine=yolov8s.engine \
--fp16
咋用呢? inference那一步,用法如果你搞过了ONNX,其实就是大同小异。后处理有点麻烦,暂时先不搞了,思路是到时候调用以下yolov8里后处理的部分,改一下代码就行
- github 上提供了例子:
https://github.com/NVIDIA/TensorRT/blob/main/quickstart/SemanticSegmentation/tutorial-runtime.ipynb
等我有空再续
predict
在预测时,头N个,时间花销要大点,如果测时间,得等它跑几轮,速度才会快起来。比如下面这个,前几轮是2秒,然后是0.06秒
i = 0
while i < 3:
start_time = time.time()
res = model('test2.jpg',save=True,device = 0)
print(time.time()-start_time)
i+=1
start_time = time.time()
img = Image.open('test2.jpg')
res = model('test2.jpg',save=True,device = 0)
print(time.time()-start_time)
multi-scale
def preprocess_batch(self, batch, imgsz_train, gs):
"""
Allows custom preprocessing model inputs and ground truths depending on task type.
"""
sz = random.randrange(int(self.args.imgsz