共计 1711 个字符,预计需要花费 5 分钟才能阅读完成。
背景痛点
在实际项目中,很多团队会选择 PyTorch 训练 YOLO 模型,但生产环境往往需要 C ++ 部署。这个过程中会遇到几个典型问题:

- PyTorch 模型直接导出为 TorchScript 后,在 C ++ 端依赖完整的 LibTorch 库,体积庞大(超过 1GB)
- 不同版本的 CUDA/cuDNN 与推理引擎存在兼容性问题,经常出现版本冲突
- 原生 Python 实现的 NMS 等后处理逻辑需要重写为 C ++,且要保证数值计算一致性
技术选型对比
目前主流的 C ++ 推理方案有三种:
- ONNX Runtime
- 优点:跨平台支持好,API 简单,支持动态输入
-
缺点:性能中等,量化支持有限
-
TensorRT
- 优点:极致性能,支持多种量化(FP16/INT8)
-
缺点:生态封闭,模型转换复杂
-
LibTorch
- 优点:与训练框架无缝对接
- 缺点:依赖庞大,性能较差
对于大多数场景,推荐组合方案:
flowchart LR
PyTorch 训练 --> ONNX 导出 --> TensorRT 优化 --> C++ 部署
核心实现步骤
1. 模型导出 ONNX
使用官方 export.py 脚本时需特别注意动态维度:
# 关键导出参数
torch.onnx.export(
model,
im,
'yolov5s.onnx',
opset_version=12,
input_names=['images'],
output_names=['output'],
dynamic_axes={'images': {0: 'batch'}, # 动态 batch
'output': {0: 'batch'}
}
)
2. C++ 前处理实现
使用 OpenCV 进行高效图像预处理:
// 现代 C ++ 风格的前处理
cv::Mat preprocess(cv::Mat& img, int target_size) {
cv::Mat resized;
cv::resize(img, resized, cv::Size(target_size, target_size));
// 归一化操作 (0- 1 范围)
resized.convertTo(resized, CV_32F, 1.0/255);
// HWC 转 CHW
cv::dnn::blobFromImage(resized, resized);
return resized;
}
3. 后处理优化
手写 CUDA 核函数加速 NMS:
__global__ void nms_kernel(float* boxes, float* scores, ...) {
// 共享内存加速 IO
__shared__ float local_boxes[THREADS_PER_BLOCK * 6];
...
}
性能优化技巧
TensorRT FP16 量化
构建器配置关键参数:
config->setFlag(BuilderFlag::kFP16);
config->setMaxWorkspaceSize(1 << 30);
内存池设计
class MemoryPool {
std::vector<void*> gpu_ptrs_;
cudaStream_t stream_;
public:
void* allocate(size_t size) {
void* ptr;
cudaMallocAsync(&ptr, size, stream_);
gpu_ptrs_.push_back(ptr);
return ptr;
}
~MemoryPool() {for(auto ptr : gpu_ptrs_)
cudaFreeAsync(ptr, stream_);
}
};
避坑指南
- 动态维度问题:ONNX 导出时务必指定 dynamic_axes
- CUDA 兼容性:建议使用 CUDA 11.x + TensorRT 8.x 组合
- 端侧部署 :使用
polygraphy工具裁剪无用算子
性能测试数据
| 设备 | 框架 | FP32 延迟(ms) | FP16 延迟(ms) |
|---|---|---|---|
| Jetson Xavier | ONNX Runtime | 45 | – |
| RTX 3090 | TensorRT | 12 | 6 |
开放性问题
在实际项目中,精度和速度的平衡需要考虑:
1. 业务对误检的容忍度
2. 实时性要求(如视频流需 >25FPS)
3. 硬件成本约束
建议方案:
– 高精度场景:YOLOv5x + FP32
– 平衡场景:YOLOv5s + FP16
– 极速场景:YOLOv5n + INT8
最终还是要通过 A / B 测试确定最适合的方案。
正文完
