大家好,我是专注于计算机视觉与边缘计算部署的开发者。在实际项目中,我们常常遇到这样的困境:一个训练好的 YOLOv8 模型,在 Python 环境下用 OpenCV 简单推理,帧率(FPS)可能只有个位数,完全无法满足实时性要求。从模型加载、图像预处理、推理到后处理,每一步都可能存在性能瓶颈。
本文将系统性地拆解 YOLOv8 + OpenCV 推理的全链路,分享一套从1.2 FPS 优化到 35 FPS的实战经验。内容涵盖从基础的代码优化、模型量化,到高级的 TensorRT 部署,并提供完整的代码示例和避坑指南。无论你是刚接触模型部署的新手,还是寻求性能突破的进阶开发者,都能从中找到可落地的优化方案。
1. 背景与核心概念:为什么你的 YOLOv8 跑得慢?
在深入优化之前,我们需要理解影响推理速度的关键环节。一个完整的 YOLOv8 推理流程通常包括以下步骤:
- 模型加载:从
.pt或.onnx文件加载模型权重和结构。 - 图像预处理:将输入图像缩放、归一化、转换为模型所需的张量格式(如
BGR to RGB,HWC to CHW,/255归一化)。 - 模型推理:在 CPU 或 GPU 上执行前向传播计算。
- 后处理:解析模型输出,应用非极大值抑制(NMS)过滤冗余框,并将坐标映射回原图尺寸。
性能瓶颈分析:
- Python 循环与操作:在 Python 层面用
for循环逐张处理、使用numpy的不必要拷贝,会引入巨大开销。 - 预处理/后处理:这两步通常由 Python 代码完成,如果实现低效,其耗时可能超过模型推理本身。
- 模型格式与推理引擎:直接使用 PyTorch 的
.pt模型在 CPU 上推理非常慢。未优化的 ONNX 模型也无法发挥硬件最大潜力。 - 硬件利用不足:未启用 GPU,或未使用针对特定硬件(如 NVIDIA GPU)的高性能推理库。
优化目标:我们的目标是将整个流水线“硬化”,减少 Python 解释器的干预,将计算密集型任务转移到高效的、预编译的库中执行。
2. 环境准备与版本说明
为了复现和对比优化效果,请先搭建基础环境。以下版本为本文撰写时的稳定组合,你可以根据你的 CUDA 版本进行调整。
操作系统:Ubuntu 20.04 / Windows 11Python:3.8 - 3.10关键库:
- PyTorch: 2.0.1+cu118
- Ultralytics YOLOv8:
ultralytics>=8.0.0 - OpenCV:
opencv-python>=4.7.0 - ONNX Runtime:
onnxruntime-gpu(用于 GPU 推理) 或onnxruntime(用于 CPU) - TensorRT: 8.5.x+ (需要与 CUDA 版本匹配)
CUDA 与 cuDNN:本文 GPU 优化部分基于 CUDA 11.8 和 cuDNN 8.6。安装 TensorRT 前,请务必确认版本兼容性。
你可以使用以下命令创建环境并安装基础依赖:
# 创建并激活虚拟环境 (可选但推荐) conda create -n yolov8_optim python=3.9 conda activate yolov8_optim # 安装 PyTorch (请根据官网指令选择适合你CUDA版本的命令) pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # 安装 Ultralytics YOLOv8 和 OpenCV pip install ultralytics opencv-python # 安装 ONNX Runtime for GPU pip install onnxruntime-gpu注意:TensorRT 的安装较为复杂,我们将在后续专门章节详细说明。
3. 基准测试:原始低效实现(~1.2 FPS)
让我们从一个最常见、但效率低下的实现开始,并以此作为性能基准。这段代码直接使用ultralytics的 API 进行循环预测。
import cv2 from ultralytics import YOLO import time # 1. 加载模型 (PyTorch格式) model = YOLO('yolov8n.pt') # 使用 Nano 模型做示例 # 2. 打开视频流或摄像头 cap = cv2.VideoCapture('test_video.mp4') # 或 cv2.VideoCapture(0) # 3. 原始循环推理 frame_count = 0 start_time = time.time() while cap.isOpened(): ret, frame = cap.read() if not ret: break # 关键耗时操作:直接调用 predict,内部包含完整的预处理/推理/后处理 results = model(frame, verbose=False) # verbose=False 关闭日志 # 绘制结果 (这里也会消耗时间) annotated_frame = results[0].plot() cv2.imshow('YOLOv8 Inference - Slow', annotated_frame) frame_count += 1 if cv2.waitKey(1) & 0xFF == ord('q'): break # 计算FPS end_time = time.time() total_time = end_time - start_time fps = frame_count / total_time print(f"[基准] 处理总帧数: {frame_count}, 总耗时: {total_time:.2f}s, 平均FPS: {fps:.2f}") cap.release() cv2.destroyAllWindows()为什么慢?
model(frame)每次调用都包含模型初始化检查(虽然不重复加载)。- 预处理和后处理逻辑封装在库内,无法针对特定场景优化。
results[0].plot()绘图操作也在循环内,增加了开销。- 没有利用任何批处理(Batch Processing)能力。
在 Intel i7-12700K CPU 上处理 640x640 的输入,这段代码的 FPS 大约在1.2 - 2.5之间,完全无法实时。
4. 优化阶段一:OpenCV 与预处理优化(提升至 ~8 FPS)
第一步,我们将控制权从高级 API 手中拿回来,手动实现预处理,并消除不必要的操作。
4.1 分离预处理与后处理
YOLOv8 的预处理是固定的:将图像缩放到640x640(或训练尺寸),BGR 转 RGB,归一化(/255),并转换为CHW格式。
import cv2 import numpy as np import time from ultralytics import YOLO def preprocess_image_opencv(image, target_size=640): """ 使用OpenCV和NumPy进行高效的预处理。 参数: image: 原始BGR图像 (H, W, C) target_size: 模型输入尺寸 返回: blob: 预处理后的张量 (1, 3, H, W) ratio: 缩放比例,用于后处理坐标映射 """ # 获取原始尺寸 h, w = image.shape[:2] # 计算缩放比例,保持长宽比 scale = min(target_size / h, target_size / w) new_h, new_w = int(h * scale), int(w * scale) # 使用OpenCV的INTER_LINEAR插值进行缩放 (速度较快) resized = cv2.resize(image, (new_w, new_h), interpolation=cv2.INTER_LINEAR) # 创建画布并填充到 target_size x target_size canvas = np.full((target_size, target_size, 3), 114, dtype=np.uint8) canvas[:new_h, :new_w, :] = resized # BGR -> RGB canvas_rgb = cv2.cvtColor(canvas, cv2.COLOR_BGR2RGB) # HWC -> CHW, 归一化,并添加批次维度 blob = canvas_rgb.transpose(2, 0, 1).astype(np.float32) / 255.0 blob = np.expand_dims(blob, axis=0) # shape: (1, 3, 640, 640) # 计算用于后处理的缩放比例和填充 ratio = (new_w / w, new_h / h) # 宽高的缩放比例 return blob, ratio, (target_size - new_w, target_size - new_h) # 返回填充信息 # 加载模型 model = YOLO('yolov8n.pt') cap = cv2.VideoCapture('test_video.mp4') frame_count = 0 start_time = time.time() while cap.isOpened(): ret, frame = cap.read() if not ret: break # 优化后的预处理 blob, ratio, pad = preprocess_image_opencv(frame) # 推理 - 将NumPy数组转换为PyTorch Tensor import torch inputs = torch.from_numpy(blob).to(model.device) results = model.model(inputs) # 直接调用底层model进行推理 # 注意:results 现在是原始的模型输出,需要手动后处理 # 后处理逻辑较复杂,此处先跳过绘制,仅测量预处理+推理时间 # 我们将在下一步实现后处理 frame_count += 1 # 仅用于测试,不显示图像 if frame_count % 100 == 0: print(f"已处理 {frame_count} 帧") # ... 计算FPS优化点:
- 使用
cv2.resize替代可能存在的内部转换。 - 将连续的
numpy操作向量化,减少中间变量。 - 直接调用
model.model(inputs)进行纯推理,绕过高级API的额外逻辑。
仅此一项,FPS 可能提升至5-8。
4.2 实现高效后处理
后处理的核心是解码模型输出并应用 NMS。YOLOv8 的输出格式需要根据模型版本确定。以下是一个通用性较强的后处理函数:
def postprocess_yolov8(prediction, conf_threshold=0.25, iou_threshold=0.45, input_shape=640, orig_shape=None, ratios=None, pads=None): """ YOLOv8 后处理:解码输出,应用置信度过滤和NMS。 参数: prediction: 模型原始输出 (Tensor或NumPy数组) ... 其他参数 返回: boxes: 检测框 (x1, y1, x2, y2) in original image coordinates scores: 置信度 class_ids: 类别ID """ # 确保 prediction 是 NumPy 数组 if isinstance(prediction, torch.Tensor): prediction = prediction.cpu().detach().numpy() # YOLOv8 输出形状通常为 (1, 84, 8400) 对于 640x640 输入 # 84 = 4 (box) + 80 (coco classes) prediction = prediction[0].T # 转置为 (8400, 84) # 分离框坐标和类别分数 boxes = prediction[:, :4] scores = prediction[:, 4:] # 找到每个预测框的最大类别分数和对应的ID class_ids = np.argmax(scores, axis=1) max_scores = np.max(scores, axis=1) # 根据置信度阈值过滤 mask = max_scores > conf_threshold boxes = boxes[mask] class_ids = class_ids[mask] max_scores = max_scores[mask] # 将中心点格式 (cx, cy, w, h) 转换为角点格式 (x1, y1, x2, y2) x1 = (boxes[:, 0] - boxes[:, 2] / 2) y1 = (boxes[:, 1] - boxes[:, 3] / 2) x2 = (boxes[:, 0] + boxes[:, 2] / 2) y2 = (boxes[:, 1] + boxes[:, 3] / 2) boxes = np.column_stack([x1, y1, x2, y2]) # 应用非极大值抑制 (NMS) # 使用 OpenCV 的 NMS,它比纯 Python 实现快得多 indices = cv2.dnn.NMSBoxes(boxes.tolist(), max_scores.tolist(), conf_threshold, iou_threshold) if len(indices) > 0: indices = indices.flatten() boxes = boxes[indices] class_ids = class_ids[indices] max_scores = max_scores[indices] # 将坐标映射回原始图像尺寸 (如果提供了原始尺寸和缩放信息) if orig_shape is not None and ratios is not None and pads is not None: orig_h, orig_w = orig_shape[:2] ratio_w, ratio_h = ratios pad_w, pad_h = pads # 首先去除填充 boxes[:, [0, 2]] -= pad_w / 2 boxes[:, [1, 3]] -= pad_h / 2 # 然后缩放回原始尺寸 boxes[:, [0, 2]] /= ratio_w boxes[:, [1, 3]] /= ratio_h # 确保坐标不超出图像边界 boxes[:, [0, 2]] = np.clip(boxes[:, [0, 2]], 0, orig_w) boxes[:, [1, 3]] = np.clip(boxes[:, [1, 3]], 0, orig_h) return boxes, max_scores, class_ids现在,将预处理、推理、后处理和绘制整合到主循环中:
# 在主循环内替换推理和后处理部分 blob, ratio, pad = preprocess_image_opencv(frame) inputs = torch.from_numpy(blob).to(model.device) with torch.no_grad(): # 禁用梯度计算,节省内存和计算 predictions = model.model(inputs) boxes, scores, class_ids = postprocess_yolov8( predictions, orig_shape=frame.shape, ratios=(ratio[0], ratio[1]), pads=pad ) # 绘制检测框 (简化版) for box, score, cls_id in zip(boxes, scores, class_ids): x1, y1, x2, y2 = map(int, box) label = f"{model.names[int(cls_id)]} {score:.2f}" cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2) cv2.putText(frame, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2) cv2.imshow('Optimized YOLOv8', frame)经过预处理和后处理的优化,在 CPU 上 FPS 可以稳定达到8-12,提升显著。
5. 优化阶段二:模型格式转换与 ONNX Runtime(提升至 ~15 FPS)
PyTorch 模型在推理时带有动态图开销。转换为 ONNX 格式并使用 ONNX Runtime 推理,能获得更稳定的性能。
5.1 导出 ONNX 模型
使用 Ultralytics 官方命令或脚本导出:
from ultralytics import YOLO # 加载模型 model = YOLO('yolov8n.pt') # 导出为 ONNX success = model.export(format='onnx', imgsz=640, simplify=True, opset=12)关键参数:
imgsz=640: 指定输入尺寸。simplify=True: 启用 ONNX 图简化,移除冗余操作。opset=12: ONNX 算子集版本,建议 >=11。
导出后你会得到yolov8n.onnx文件。
5.2 使用 ONNX Runtime 进行推理
ONNX Runtime 是一个高性能推理引擎,支持 CPU 和 GPU。
import onnxruntime as ort import numpy as np import cv2 import time # 1. 创建ONNX Runtime会话 # 提供者列表,优先使用CUDA,其次是CPU providers = ['CUDAExecutionProvider', 'CPUExecutionProvider'] session = ort.InferenceSession('yolov8n.onnx', providers=providers) # 获取输入输出名称 input_name = session.get_inputs()[0].name output_name = session.get_outputs()[0].name # 2. 复用之前的预处理函数 preprocess_image_opencv def preprocess_for_onnx(image, target_size=640): # 与之前的 preprocess_image_opencv 逻辑完全一致 blob, ratio, pad = preprocess_image_opencv(image, target_size) # ONNX Runtime 需要 float32 类型的 NumPy 数组 return blob.astype(np.float32), ratio, pad # 3. 推理循环 cap = cv2.VideoCapture('test_video.mp4') frame_count = 0 start_time = time.time() while cap.isOpened(): ret, frame = cap.read() if not ret: break # 预处理 blob, ratio, pad = preprocess_for_onnx(frame) # ONNX Runtime 推理 outputs = session.run([output_name], {input_name: blob}) prediction = outputs[0] # 获取第一个输出 # 复用之前的后处理函数 boxes, scores, class_ids = postprocess_yolov8( prediction, orig_shape=frame.shape, ratios=(ratio[0], ratio[1]), pads=pad ) # 绘制... (省略) frame_count += 1 # 计算FPS fps = frame_count / (time.time() - start_time) print(f"[ONNX Runtime] 平均FPS: {fps:.2f}")性能提升:ONNX Runtime 对计算图进行了优化,并且底层由 C++ 实现,避免了 Python 的一些开销。在相同的 CPU 上,FPS 可提升至12-18。如果使用CUDAExecutionProvider,在 GPU 上性能会更高。
6. 优化阶段三:TensorRT 终极加速(冲刺 35+ FPS)
TensorRT 是 NVIDIA 推出的高性能深度学习推理 SDK,它能对模型进行图优化、层融合、精度校准(INT8量化),并生成针对特定 GPU 架构优化的引擎(.engine文件),实现最大吞吐量。
6.1 TensorRT 安装与环境配置
安装 TensorRT 是最大的挑战之一,务必严格遵循版本匹配。
- 检查 CUDA 和 cuDNN:
nvcc --version # 查看 CUDA 版本 cat /usr/local/cuda/include/cudnn_version.h | grep CUDNN_MAJOR -A 2 # Linux查看cuDNN - 下载 TensorRT:从 NVIDIA TensorRT 下载页面 选择与你的 CUDA 版本匹配的 Tar 包。例如,CUDA 11.8 对应 TensorRT 8.5.x。
- 安装 TensorRT(以 Linux Tar 包为例):
tar -xzf TensorRT-8.x.x.x.Linux.x86_64-gnu.cuda-11.8.cudnn8.6.tar.gz cd TensorRT-8.x.x.x # 将库文件路径添加到环境变量 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:`pwd`/lib # 安装 Python wheel cd python pip install tensorrt-*-cp3x-none-linux_x86_64.whl # 选择对应Python版本的whl # 安装其他组件(如 onnx-graphsurgeon) cd ../graphsurgeon pip install graphsurgeon-*.whl cd ../onnx_graphsurgeon pip install onnx_graphsurgeon-*.whl - 安装 PyCUDA(可选,用于自定义插件时):
pip install pycuda
6.2 将 ONNX 模型转换为 TensorRT 引擎
有几种方式构建 TensorRT 引擎:
- trtexec:命令行工具,适合快速测试。
- Python API:更灵活,可以集成到部署脚本中。
这里展示使用trtexec的简单方法:
# 基本命令,生成 FP32 精度的引擎 trtexec --onnx=yolov8n.onnx --saveEngine=yolov8n_fp32.engine --workspace=1024 # 生成 FP16 精度的引擎,通常能提速且精度损失可接受 trtexec --onnx=yolov8n.onnx --saveEngine=yolov8n_fp16.engine --fp16 --workspace=1024 # 生成 INT8 精度的引擎,需要校准数据,速度最快 trtexec --onnx=yolov8n.onnx --saveEngine=yolov8n_int8.engine --int8 --workspace=1024 --calib=<校准缓存文件>注意:INT8 量化需要校准数据集来统计激活值范围,过程稍复杂。初次尝试建议从 FP16 开始。
6.3 使用 TensorRT Python API 进行推理
安装tensorrtPython 包后,可以加载引擎并推理。
import tensorrt as trt import pycuda.driver as cuda import pycuda.autoinit # 初始化CUDA上下文 import numpy as np import cv2 import time class TRTInference: def __init__(self, engine_path): # 1. 加载 TensorRT 引擎 self.logger = trt.Logger(trt.Logger.WARNING) with open(engine_path, 'rb') as f, trt.Runtime(self.logger) as runtime: self.engine = runtime.deserialize_cuda_engine(f.read()) # 2. 创建执行上下文 self.context = self.engine.create_execution_context() # 3. 分配输入输出内存 (Host和Device) self.inputs, self.outputs, self.bindings = [], [], [] self.stream = cuda.Stream() for binding in self.engine: size = trt.volume(self.engine.get_binding_shape(binding)) * self.engine.max_batch_size dtype = trt.nptype(self.engine.get_binding_dtype(binding)) # 分配主机内存 host_mem = cuda.pagelocked_empty(size, dtype) # 分配设备内存 device_mem = cuda.mem_alloc(host_mem.nbytes) # 保存绑定 self.bindings.append(int(device_mem)) # 根据是输入还是输出,保存到不同列表 if self.engine.binding_is_input(binding): self.inputs.append({'host': host_mem, 'device': device_mem}) else: self.outputs.append({'host': host_mem, 'device': device_mem}) def infer(self, input_blob): """ 执行推理。 参数: input_blob: 预处理后的图像数据 (numpy array, shape: [1, 3, H, W]) 返回: output: 模型输出 (numpy array) """ # 将输入数据复制到主机内存 np.copyto(self.inputs[0]['host'], input_blob.ravel()) # 将输入数据从主机内存传输到设备内存 cuda.memcpy_htod_async(self.inputs[0]['device'], self.inputs[0]['host'], self.stream) # 执行推理 self.context.execute_async_v2(bindings=self.bindings, stream_handle=self.stream.handle) # 将输出数据从设备内存传输回主机内存 cuda.memcpy_dtoh_async(self.outputs[0]['host'], self.outputs[0]['device'], self.stream) # 同步流 self.stream.synchronize() # 返回输出数据 return self.outputs[0]['host'].reshape(self.engine.get_binding_shape(1)) # 假设只有一个输出 def __del__(self): # 清理 CUDA 内存 for mem in self.inputs + self.outputs: if 'device' in mem: mem['device'].free() # 使用示例 trt_model = TRTInference('yolov8n_fp16.engine') cap = cv2.VideoCapture('test_video.mp4') frame_count = 0 start_time = time.time() while cap.isOpened(): ret, frame = cap.read() if not ret: break # 预处理 (与ONNX版本相同) blob, ratio, pad = preprocess_for_onnx(frame) # TensorRT 推理 prediction = trt_model.infer(blob) # 后处理 (与之前相同) boxes, scores, class_ids = postprocess_yolov8( prediction, orig_shape=frame.shape, ratios=(ratio[0], ratio[1]), pads=pad ) # 绘制... (省略) frame_count += 1 fps = frame_count / (time.time() - start_time) print(f"[TensorRT FP16] 平均FPS: {fps:.2f}") trt_model = None # 显式释放性能飞跃:在 NVIDIA RTX 3060 GPU 上,使用 TensorRT FP16 引擎,YOLOv8n 处理 640x640 图像的 FPS 可以轻松达到35-50+,相比最初的 1.2 FPS 提升了近 30 倍。
7. 其他关键优化技巧与常见问题
7.1 批处理(Batch Inference)
无论是 ONNX Runtime 还是 TensorRT,都支持批处理。一次性处理多张图像能显著提高 GPU 利用率。
# 伪代码思路 batch_size = 4 batch_frames = [] batch_ratios = [] batch_pads = [] for i in range(batch_size): ret, frame = cap.read() if not ret: break blob, ratio, pad = preprocess(frame) batch_frames.append(blob) batch_ratios.append(ratio) batch_pads.append(pad) if batch_frames: # 将列表堆叠成一个 batch batch_input = np.vstack(batch_frames) # shape: [batch_size, 3, 640, 640] # 进行批推理 batch_output = session.run([output_name], {input_name: batch_input}) # 逐张后处理 for i in range(len(batch_frames)): process_single_result(batch_output, i, batch_ratios[i], batch_pads[i])7.2 使用cv2.dnn模块(纯 OpenCV)
OpenCV 的dnn模块也支持直接加载 ONNX 模型并进行推理,它内部可能使用 Inference Engine (OpenVINO) 或 CUDA 后端,配置简单。
net = cv2.dnn.readNetFromONNX('yolov8n.onnx') net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA) net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA) blob = cv2.dnn.blobFromImage(frame, 1/255.0, (640, 640), swapRB=True, crop=False) net.setInput(blob) outputs = net.forward() # outputs 需要根据 OpenCV 的维度顺序进行调整,然后进行后处理7.3 常见问题与排查
| 问题现象 | 可能原因 | 解决思路 |
|---|---|---|
| ONNX 导出失败 | opset版本不兼容,模型包含不支持算子。 | 尝试opset=12或更高。使用simplify=True。检查 Ultralytics 版本。 |
| TensorRT 构建引擎失败 | ONNX 模型中包含 TensorRT 不支持的层或操作。 | 使用trtexec的--verbose模式查看错误。尝试更新 TensorRT 版本。对于 YOLOv8,确保使用simplify导出的 ONNX。 |
| 推理结果为空或错误 | 预处理/后处理与模型训练配置不匹配。 | 确认预处理是否与model.export()时的设置一致(尺寸、归一化、通道顺序)。使用模型原生的验证脚本检查 ONNX 模型输出是否正确。 |
| FPS 提升不明显 | 瓶颈不在模型推理,而在图像解码(cv2.VideoCapture)或显示(cv2.imshow)。 | 将视频解码移到独立线程。禁用cv2.imshow或降低显示频率进行测试。使用time.time()分段测量各阶段耗时。 |
| GPU 内存不足 | 模型太大,或批处理尺寸过大。 | 换用更小的模型(如 YOLOv8n)。减少批处理大小。尝试 FP16 或 INT8 量化。 |
modulenotfounderror: no module named 'opencv' | OpenCV 未正确安装。 | 使用pip install opencv-python。在虚拟环境中检查安装。 |
8. 最佳实践与工程建议
- 性能剖析:优化前,务必使用工具(如 Python 的
cProfile、line_profiler,或简单的time.time())定位瓶颈。到底是 IO 慢、预处理慢,还是推理慢? - 渐进式优化:不要一开始就上 TensorRT。遵循“原生 PyTorch -> 优化预处理 -> ONNX Runtime -> TensorRT”的路径,每一步都验证正确性和性能提升。
- 精度验证:每次转换格式(PT -> ONNX -> TRT)后,都要在验证集上测试 mAP 或对比几张图片的检测结果,确保精度下降在可接受范围内(特别是 FP16/INT8 量化后)。
- 生产环境考虑:
- 模型版本管理:对
.pt、.onnx、.engine文件进行版本控制。 - 健壮性:添加异常处理(如图像读取失败、推理失败)、日志记录和健康检查。
- 资源管理:TensorRT 引擎加载较慢,应设计为单例或池化,避免频繁创建销毁。
- 动态批处理:对于可变请求率的服务,实现动态批处理以平衡延迟和吞吐量。
- 模型版本管理:对
- 硬件适配:TensorRT 引擎是硬件相关的。为不同的 GPU(如 Jetson、Tesla、GeForce)生成不同的引擎文件。
从 1.2 FPS 到 35 FPS 的旅程,本质上是将计算从低效的 Python 解释器环境,逐步迁移到高度优化的本地代码和专用硬件上的过程。核心思路是:标准化模型格式、最小化数据移动、最大化硬件并行度。
希望这份全链路优化指南能为你带来实质性的帮助。优化无止境,下一步你可以探索更激进的量化(INT8)、模型剪枝、使用 TensorRT 的IInt8EntropyCalibrator2进行校准,或者针对你的特定硬件(如 Jetson、RK3588)进行交叉编译和部署。动手尝试,并根据你的实际场景进行调优,才是提升性能的最佳途径。