从零到一:在Jetson Nano上实现自定义YOLOv5模型的TensorRT推理与DeepStream集成
1. 环境准备与数据集制作在Jetson Nano上部署自定义YOLOv5模型前我们需要先准备好开发环境。我建议使用JetPack 4.6.1作为基础系统这是目前最稳定的版本。安装完成后记得执行sudo apt update sudo apt upgrade更新所有软件包。数据集制作是项目中最耗时的环节之一。以鸭子和马桶抽为例我建议至少准备500张标注图片。使用LabelImg工具标注时有几点经验分享标注框要尽量贴近物体边缘对于遮挡物体只标注可见部分保持标注一致性避免同一物体在不同图片中有不同标注方式标注完成后我们需要将VOC格式转换为YOLO格式。这里有个实用脚本可以帮你自动完成转换import xml.etree.ElementTree as ET import os def convert(size, box): dw 1./size[0] dh 1./size[1] x (box[0] box[1])/2.0 y (box[2] box[3])/2.0 w box[1] - box[0] h box[3] - box[2] x x*dw w w*dw y y*dh h h*dh return (x,y,w,h) def convert_annotation(xml_file, txt_file, classes): tree ET.parse(xml_file) root tree.getroot() size root.find(size) w int(size.find(width).text) h int(size.find(height).text) with open(txt_file, w) as f: for obj in root.iter(object): cls obj.find(name).text if cls not in classes: continue cls_id classes.index(cls) xmlbox obj.find(bndbox) b (float(xmlbox.find(xmin).text), float(xmlbox.find(xmax).text), float(xmlbox.find(ymin).text), float(xmlbox.find(ymax).text)) bb convert((w,h), b) f.write(str(cls_id) .join([str(a) for a in bb]) \n)2. 模型训练与优化在主机端训练YOLOv5模型时我强烈建议使用预训练权重。实测发现使用预训练权重可以提升10-15%的准确率同时减少约30%的训练时间。训练命令如下python train.py --img 640 --batch 16 --epochs 100 --data dataset.yaml --cfg yolov5s.yaml --weights yolov5s.pt --device 0这里有几个关键参数需要注意--img 640输入图像尺寸Jetson Nano上建议保持640x640--batch 16根据显存大小调整RTX 2080Ti可以设置到32--epochs 100对于小数据集100-150个epoch通常足够训练完成后使用detect.py测试模型效果时我发现一个实用技巧添加--augment参数可以启用测试时数据增强这能更全面地评估模型性能python detect.py --weights runs/train/exp/weights/best.pt --source test_images/ --augment3. TensorRT模型转换将PyTorch模型转换为TensorRT引擎是提升推理速度的关键。我推荐使用tensorrtx项目进行转换这是目前最稳定的方案。转换过程分为三步生成.wts中间文件python gen_wts.py yolov5s.pt在Jetson Nano上编译tensorrtxmkdir build cd build cmake .. make生成TensorRT引擎./yolov5 -s yolov5s.wts yolov5s.engine s这里有个坑要注意Jetson Nano的内存有限如果转换大模型如yolov5x可能会失败。我的经验是在Nano上最好使用yolov5s或yolov5n这类轻量模型。4. DeepStream集成实战DeepStream是NVIDIA专为视频分析优化的框架。集成YOLOv5模型时需要修改几个关键文件修改nvdsparsebbox_Yolo.cpp中的类别数static const int NUM_CLASSES_YOLO 2; // 修改为你的类别数配置config_infer_primary_yoloV5.txt[property] ... model-engine-fileyolov5s.engine num-detected-classes2 ...创建labels.txt文件duck sucker启动DeepStream应用的命令如下LD_PRELOAD./libmyplugins.so deepstream-app -c deepstream_app_config_yoloV5.txt在实际部署中我发现通过调整DeepStream的流媒体配置可以显著提升性能。例如将[streammux]部分的width和height设置为实际视频分辨率的1/2可以减少30%的GPU负载同时保持不错的识别精度。5. 性能优化技巧经过多次实践我总结出几个提升Jetson Nano推理性能的关键技巧启用持久模式这可以减少内核启动开销sudo nvpmodel -m 0 sudo jetson_clocks调整电源模式设置为MAXN模式可获得最佳性能sudo nvpmodel -m 0使用TensorRT的FP16模式在生成引擎时添加-d 16参数./yolov5 -s yolov5s.wts yolov5s.engine s -d 16优化DeepStream配置在deepstream_app_config_yoloV5.txt中[streammux] batch-size1 # Nano上建议设为1实测下来经过这些优化后我的鸭子检测模型在Jetson Nano上达到了18FPS完全满足实时检测需求。对于更复杂的场景可以考虑使用TensorRT的INT8量化虽然会损失一些精度但能进一步提升速度。6. 常见问题解决在项目实践中我遇到过几个典型问题及解决方案内存不足错误症状转换大模型时出现out of memory解决方案改用更小的模型或尝试在主机上转换后传输到Nano类别不匹配症状检测结果标签错误解决方案检查所有配置文件中类别数是否一致特别是nvdsparsebbox_Yolo.cpp和config_infer_primary_yoloV5.txt低帧率问题症状推理速度远低于预期解决方案检查是否启用了持久模式尝试降低输入分辨率模型不加载症状DeepStream无法加载TensorRT引擎解决方案确保生成引擎的TensorRT版本与JetPack中的版本一致记得每次修改配置后都要重新编译相关组件。我在一个项目中曾花了3小时debug最后发现只是忘了重新make。