nvcc --version
、dpkg -l | grep TensorRT
检查是否安装确保你已经安装了 Python 3.8+,然后执行:
pip install ultralytics onnx onnxruntime onnx-simplifier tensorrt pycuda numpy opencv-python
首先,我们需要将 YOLOv8 PyTorch 模型(.pt)转换为 ONNX,因为 TensorRT 不支持直接加载 .pt
文件。
from ultralytics import YOLO # 1️⃣ 加载 YOLOv8n 预训练模型
model = YOLO("yolov8n.pt") # 2️⃣ 导出为 ONNX(动态 batch-size)
model.export(format="onnx", dynamic=True)
运行后会生成 yolov8n.onnx
文件。
为了避免 TensorRT 解析错误,我们对 ONNX 进行 简化。
import onnx
import onnxsim
# 1️⃣ 加载 ONNX 模型
onnx_model = onnx.load("yolov8n.onnx")
# 2️⃣ 进行模型简化
simplified_model, check = onnxsim.simplify(onnx_model)
# 3️⃣ 保存优化后的模型
onnx.save(simplified_model, "yolov8n_sim.onnx")
print("ONNX Simplified:", check)
✅ 生成 yolov8n_sim.onnx
,用于 TensorRT 转换。
我们使用 trtexec
工具将 ONNX 转换为 TensorRT 引擎(.trt)。
trtexec --onnx=yolov8n_sim.onnx --saveEngine=yolov8n.trt --fp16
--onnx=yolov8n_sim.onnx
:输入 ONNX 模型--saveEngine=yolov8n.trt
:输出 TensorRT 引擎--fp16
:启用 FP16 加速(如果硬件支持)--int8
:启用 INT8 量化(需要额外校准) 运行后会生成 yolov8n.trt
,这个就是我们 可以直接推理的模型!
现在,我们可以 用 Python 运行 TensorRT 推理!
import tensorrt as trt
import pycuda.driver as cuda
import pycuda.autoinit
import numpy as np
import cv2
# TensorRT 日志
TRT_LOGGER = trt.Logger()
def load_engine(trt_file):
with open(trt_file, "rb") as f, trt.Runtime(TRT_LOGGER) as runtime:
return runtime.deserialize_cuda_engine(f.read())
engine = load_engine("yolov8n.trt")
context = engine.create_execution_context()
# 获取输入 & 输出索引
input_idx = engine.get_binding_index("images")
output_idx = engine.get_binding_index("output0")
# 分配 GPU 内存
input_shape = engine.get_binding_shape(input_idx)
output_shape = engine.get_binding_shape(output_idx)
d_input = cuda.mem_alloc(np.prod(input_shape) * np.dtype(np.float32).itemsize)
d_output = cuda.mem_alloc(np.prod(output_shape) * np.dtype(np.float32).itemsize)
# 创建 CUDA 流
stream = cuda.Stream()
YOLOv8 需要 640×640 RGB 格式,所以我们需要处理图片:
def preprocess_image(image_path, input_size=640):
image = cv2.imread(image_path)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image = cv2.resize(image, (input_size, input_size))
image = image.astype(np.float32) / 255.0
image = np.transpose(image, (2, 0, 1)) # HWC -> CHW
image = np.expand_dims(image, axis=0) # 添加 batch 维度
return np.ascontiguousarray(image)
input_image = preprocess_image("test.jpg")
# 1️⃣ 传输数据到 GPU
cuda.memcpy_htod_async(d_input, input_image, stream)
# 2️⃣ 运行 TensorRT 推理
context.execute_async_v2([int(d_input), int(d_output)], stream.handle, None)
# 3️⃣ 读取输出结果
output = np.empty(output_shape, dtype=np.float32)
cuda.memcpy_dtoh_async(output, d_output, stream)
stream.synchronize()
print("推理结果:", output)
YOLOv8 输出是 num_detections × 6
,包含:
[x1, y1, x2, y2, conf, cls]
import torch
def nms(detections, conf_thres=0.5, iou_thres=0.5):
detections = torch.tensor(detections)
boxes = detections[:, :4]
scores = detections[:, 4]
classes = detections[:, 5]
keep = torch.ops.torchvision.nms(boxes, scores, iou_thres)
return detections[keep]
filtered_detections = nms(output, conf_thres=0.5)
print("过滤后的目标:", filtered_detections)
def draw_boxes(image_path, detections):
image = cv2.imread(image_path)
for det in detections:
x1, y1, x2, y2, conf, cls = map(int, det)
label = f"{cls}: {conf:.2f}"
cv2.rectangle(image, (x1, y1), (x2, y2), (0, 255, 0), 2)
cv2.putText(image, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
cv2.imshow("Detections", image)
cv2.waitKey(0)
draw_boxes("test.jpg", filtered_detections)
设备 | PyTorch FPS | ONNX Runtime FPS | TensorRT FPS |
---|---|---|---|
NVIDIA RTX 3090 | 45 FPS | 110 FPS | 300+ FPS |
Jetson Orin NX | 10 FPS | 25 FPS | 80+ FPS |
RK3588 | 3 FPS | 7 FPS | 25+ FPS |
✅ 完整流程:
.pt
为 .onnx
trtexec
生成 TensorRT 引擎 性能提升:TensorRT 比 PyTorch 快 5-10 倍!
建议: