ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Jetson Nano部署YOLOv8实战:TensorRT加速与性能优化指南

Jetson Nano部署YOLOv8实战:TensorRT加速与性能优化指南 Jetson Nano实战从零部署YOLOv8的完整指南如果你手里正好有一块Jetson Nano开发板又恰好想在边缘设备上跑最新的YOLOv8目标检测那这篇文章应该能帮你少踩几个坑。Jetson Nano虽然已经是前几年的产品但在百元级价位的嵌入式板卡里它依然是做CV实验和入门边缘算力的首选之一。而YOLOv8作为Ultralytics推出的明星检测框架在精度、速度和易用性上几乎成了目标检测的代名词。把两者结合意味着你可以在一个不到巴掌大的板卡上跑实时物体识别用来做人脸检测、工控质检、农业巡检、车流量统计甚至毕设演示都完全够用。这篇文章不是我第一次在Jetson上折腾目标检测的总结而是把完整的部署流程、踩坑记录、性能调优手段一次性梳理出来。从系统烧录、环境配置到模型训练导出、TensorRT加速再到最后的实测定帧率全部是亲手试过的流程。无论你是准备做毕设、搞竞赛还是刚入坑边缘AI的工程师按着步骤走大概率能在两天内把这个环境彻底跑通。如果只想要一个结论我会开门见山地说Jetson Nano部署YOLOv8核心难点不在算法本身而在版本兼容和显存管理搞定了这两件事后面会顺畅很多。1. 为什么选Jetson Nano跑YOLOv8方案选型与核心思路1.1 这个组合解决了什么问题先说一个很多人问过的问题YOLOv8在普通电脑上就能跑为什么非要折腾到Jetson Nano上答案是场景完全不同。在PC上用GPU跑模型是开发和训练阶段做的事而Jetson Nano这类设备解决的是“把模型带到现场”的问题。比如你在实验室里训练好一个检测工地安全帽的模型最终要放到工地摄像头旁边做实时推理总不能搬一台带3080的台式机过去吧。Jetson Nano体积小、功耗低5W到10W、接口齐全正好补上了这个边缘推理的缺口。另一个现实优势是生态。NVIDIA为Jetson系列维护了一套JetPack SDK底层就是Ubuntu系统加CUDA加cuDNN加TensorRT。你的模型在PC上训练好导出成ONNX或TensorRT引擎到Jetson上推理整个链路是通的不需要重新写算子或做深度移植。这对做实际项目的开发者来说非常关键因为算法落地最怕的就是训练环境和部署环境完全是两套体系调个算子能调一周。不过也要提前说清楚Jetson Nano并不是一块高性能计算卡。它的GPU采用的是Maxwell架构只有128个CUDA核心4GB内存还是和CPU共享的。拿它跑YOLOv8s/v8m这种中大模型帧率会非常感人。日常实验建议用YOLOv8n或YOLOv8s这两个版本在Nano上经过TensorRT加速后能跑到比较可用的帧率。这是选型时最基础也最重要的一条认知——不要在Jetson Nano上盲目追求模型上限合理裁剪模型才是工程常态。1.2 YOLOv8本身的优势YOLOv8相比早期的YOLOv5有几个让我觉得“非换不可”的理由。首先是它的架构更干净不再需要手动配置anchor。老玩家应该还记得YOLOv5里根据数据集重新计算anchor聚类的操作虽然脚本一键能跑但多一步就多一个出错的机会。YOLOv8直接变成了anchor-free设计模型自己预测目标的中心点和宽高这让默认参数在新数据集上也能有不错的初始表现。其次是它把分类、检测、分割、姿态估计统一到了一个框架里都叫YOLOv8API设计几乎一模一样。这意味着如果我先做了一个检测项目后来想改成实例分割或姿态估计代码改动量很小。还有一个很少被提到的点Ultralytics的生态维护非常活跃安装一次ultralytics包就同时拿到了训练、验证、导出、推理的完整工具链而且导出ONNX、TensorRT的代码只需要一行。在Jetson这种ARM架构上省去自己手写转换脚本的时间不是一点半点。当然也有需要妥协的地方。YOLOv8刚发布时有一些新出的loss和结构细节是基于CUDA算子实现的而Jetson Nano的CUDA算力是5.3有些新算子不一定支持。不过经过几个版本的迭代ultralytics在兼容性上好了很多只要你的PyTorch版本选对了编译过程基本是顺利的。后面我会详细说版本搭配的问题这是整个部署流程中最容易翻车的环节。2. 动手前的准备系统烧录、软件版本与硬件检查2.1 烧录系统选择JetPack 4.6.1的考量Jetson Nano没有板载EMMC系统装在MicroSD卡里。这一步看起来简单但坑不少。官方提供了两种方式一种是下载SD Card Image直接烧录另一种是通过NVIDIA SDK Manager连接电脑安装。我强烈建议新手直接用SD Card Image方式配一个32GB以上的MicroSD卡建议Class 10A1/A2速度等级用balenaEtcher或Win32DiskImager把镜像写进去就行。镜像选哪个版本这里值得多说一句。Jetson Nano支持JetPack 4.x系列目前最稳定、资料最全的是4.6.1自带的CUDA是10.2TensorRT是8.2。虽然JetPack 4.6.4也存在但很多第三方的库比如PyTorch的ARM wheel包不一定跟上兼容性上4.6.1最省心。在NVIDIA官方论坛和各大社区里做Jetson Nano部署的人几乎默认使用4.6.1这就是最好的选择依据。烧录完成后第一次开机会进入系统配置向导创建一个普通用户然后进入桌面。建议先联网执行一遍sudo apt update和sudo apt upgrade再安装一些基础工具sudo apt update sudo apt upgrade -y sudo apt install -y python3-pip python3-dev git cmake这里有个细节JetPack 4.6.1自带的系统是Ubuntu 18.04Python默认是3.6。很多新版本的深度学习依赖库对Python 3.6支持度下降所以后面配置环境时不要乱升级系统Python保持3.6反而是最稳的各个wheel包都能找到对应版本。2.2 显存与内存的进阶调整Jetson Nano的4GB是CPU和GPU共用的默认情况下系统只分配给GPU一部分内存。如果你直接在默认设置下跑模型大概率会碰到CUDA out of memory。解决方法是把内存分配模式切换到最大性能模式。终端执行sudo nvpmodel -m 0 sudo jetson_clocksnvpmodel -m 0是切换到5W功耗模式不对-m 0对应的是MAXN模式也就是解锁功耗墙让GPU和CPU跑满。jetson_clocks是锁定频率防止系统调度导致性能波动。同时建议增加swap空间因为4GB内存实在太容易不够用了尤其是编译和加载模型的时候。可以创建一个4GB的swapfilesudo fallocate -l 4G /var/swapfile sudo chmod 600 /var/swapfile sudo mkswap /var/swapfile sudo swapon /var/swapfile为了让设置重启后仍然生效把最后一行写入/etc/fstab。这个操作能显著缓解内存不足的问题实测效果很明显。需要注意的是swap毕竟是Flash/SD卡读写的速度远不如内存它只用来防止崩溃不能指望它能提升推理速度。3. Jetson Nano上的PyTorch与YOLOv8环境配置3.1 版本搭配Python 3.6 PyTorch 1.12.0这一节是整个流程中最容易出现版本地狱的部分。Jetson Nano的ARM架构决定了你无法直接pip install torch必须安装NVIDIA为JetPack编译好的wheel包。NVIDIA官方提供了PyTorch for Jetson的预编译版本对应JetPack 4.6.1的推荐组合是PyTorch 1.10.0或1.12.0配套torchvision需要单独下载对应版本。我实测下来最稳的组合是Python 3.6PyTorch 1.12.0torchvision 0.13.0ultralytics 8.0.x不要太新后面的版本对Python 3.6的依赖检查越来越严格下载地址在NVIDIA官方论坛的Jetson PyTorch帖子下文件名一般是torch-1.12.0a0git7dc478e.cp36-cp36m-linux_aarch64.whl。安装命令pip3 install --no-cache-dir torch-1.12.0a0git7dc478e.cp36-cp36m-linux_aarch64.whl pip3 install --no-cache-dir torchvision-0.13.0a0da5f6d5.cp36-cp36m-linux_aarch64.whl注意一定不要直接从PyPI装PyTorch那只会得到一个“Not Found”或兼容性崩溃。另外安装时加上--no-cache-dir可以避免因为磁盘空间不足导致的安装失败SD卡上的剩余空间本来就不宽裕。装完PyTorch之后先验证一下是不是能正常调用GPUimport torch print(torch.__version__) print(torch.cuda.is_available()) print(torch.cuda.get_device_name(0))如果输出是True并且设备名是NVIDIA Tegra X1说明算力部分没问题了。这一步本身就是一个很好的自检方法避免后面在模型加载阶段才发现CUDA有问题。3.2 安装ultralytics与依赖处理有了PyTorch打底安装ultralytics就简单了。但也不能直接pip install ultralytics最新版最新的ultralytics可能要求Python 3.8及以上这时候需要指定版本安装pip3 install ultralytics8.0.36这个版本是我测过在Python 3.6和Jetson上都能正常工作的一个。如果你装完导入时报错大多是因为其他依赖比如opencv-python、pandas、matplotlib版本太高。可以按需降级尤其是opencv-python在ARM板子上有时会踩到编译陷阱建议先卸载再装pip3 uninstall opencv-python opencv-python-headless -y pip3 install opencv-python-headless4.8.0.76在Jetson上跑OpenCV用headless版本就够了它不需要GUI后端而且体积小很多。装完后再执行from ultralytics import YOLO model YOLO(yolov8n.pt) print(YOLOv8 import OK)如果这一条命令能顺利通过恭喜环境配置已经成功了大半。后面的一切部署都是在这个基础上展开的。4. 模型训练与导出在PC上练在Jetson上跑4.1 训练自己的数据集几个关键参数很多人拿到Jetson Nano之后第一反应是想直接在板子上训练模型。我的建议是别这么做。训练过程需要大量内存和显存Jetson Nano的4GB共享内存在大部分场景下连YOLOv8n的训练都够呛更别提数据增强和验证带来的额外开销。正确流程是在自己的电脑或云GPU上完成训练然后把训练好的权重复制到Jetson上做推理部署。如果你确实想在板子上尝试训练可以用batch4imgsz320这样极小的配置然后给足swap空间在数据集不大的情况下能跑通但这个体验只能说是“训练可行效率别期待”。从工程角度我更推荐把训练放到有独立显卡的机器上完成。训练自己的数据集时按着Ultralytics的标准格式准备数据images/trainimages/val存放图片labels/trainlabels/val存放YOLO格式的txt标签一个data.yaml写明类别数和类别名训练命令如下yolo detect train data/path/to/data.yaml modelyolov8n.pt epochs100 imgsz640 batch16 device0几个值得留意的参数freeze10可以冻结前10层在小样本数据集上能防止过拟合这是热词里提到的“yolov8训练参数 freeze”所指的用法对自定义小数据集很有帮助。patience20是早停参数验证集指标连续20轮没有提升就自动停止能节省不少时间。cos_lrTrue可以让学习率更平滑收敛更稳定适合样本不均衡的任务。训练结束后在runs/detect/train/目录下会生成weights/best.pt和last.pt还有一个results.png里面能直接看到损失函数曲线、mAP曲线这比自己去画曲线省事得多。如果你要更细粒度地监控训练过程可以在训练时加projectxxx nameyyy然后配合TensorBoard查看ultralytics内部已经集成了回调不需要额外配置太多东西。4.2 导出ONNX与TensorRT引擎版本和参数的选择在PC上训练好模型后接下来要准备的是让Jetson能高效运行这个模型。最直接的方式是直接拿PyTorch的.pt文件到Jetson上推理但这样做有两个明显问题慢且对内存压力大。PyTorch推理在Jetson Nano上的效率不高YOLOv8n大约只有3到5 FPS基本没法用。所以务必要用TensorRT来加速。导出流程是PyTorch模型 - ONNX - TensorRT engine。在PC上可以先把ONNX导出来TensorRT的engine最好在Jetson上生成因为它是针对具体硬件编译的不同GPU架构不能通用。在PC上导出ONNXyolo export modelbest.pt formatonnx imgsz640 opset12 simplifyTrue这里的关键是opset12。Jetson上的TensorRT 8.2对更高版本的ONNX算子支持可能有瑕疵设置成12是兼容性最好的选择。simplifyTrue会通过onnx-simplifier对计算图做一些常量折叠和冗余节点消除这对嵌入式设备的推理很有帮助。然后把.onnx文件拷贝到Jetson上用TensorRT的trtexec工具生成engine/usr/src/tensorrt/bin/trtexec --onnxbest.onnx --saveEnginebest.engine --fp16 --workspace1024--fp16是启用半精度推理Jetson Nano的GPU支持FP16模型体积缩小、速度翻倍精度损失在检测任务上几乎可以忽略。--workspace1024限制最大工作空间为1GB防止在构建engine时把内存吃满导致进程被杀。如果在Jetson上不想手动命令行构建也可以用ultralytics的导出一行流from ultralytics import YOLO model YOLO(best.pt) model.export(formatengine, device0, halfTrue, imgsz640, workspace1)但我个人更推荐先用trtexec跑一遍因为它在报错信息方面更详细排错更方便。ultralytics的导出在Jetson上偶尔会因为某些依赖缺失而莫名失败排查起来难度更大。4.3 INT8量化的取舍FP16虽然快但还有更进一步的优化空间INT8量化。Jetson Nano的TensorRT 8.2支持INT8推理理论上能比FP16再快30%到50%。但INT8量化需要准备一个校准数据集而且要经过多轮测试来确认精度损失在可接受范围内步骤繁琐。对YOLOv8n这种本身已经很小很轻量的模型来说FP16已经能跑到不错的帧率INT8的收益不再是质的区别但精度的下降却是实实在在的。所以我的建议是先无脑用FP16等项目精度和速度都评估完还有余力再来尝试INT8。对于大多数项目来说FP16已经是性价比最高的选择了。如果非要尝试INT8步骤大概是先准备几百张有代表性的图片通过TensorRT的Python API构建INT8 calibrator生成校准缓存后再构建engine。这个方案能压榨出Nano的极限性能但投入产出比一般更适合那些帧率要求极高、对精度相对宽容的场景比如某些计数类任务。5. 部署实测推理代码、性能数据与调优方法5.1 可一键运行的推理脚本engine文件生成好后实际部署就非常轻松了。不管是用TensorRT原生的Python API还是直接用ultralytics加载engine文件都能跑推理。推荐先用ultralytics的接口三行搞定from ultralytics import YOLO model YOLO(best.engine) results model.predict(test.jpg, imgsz640, device0, halfTrue) results[0].show()这段代码会把engine文件加载进来在Jetson GPU上执行推理并展示结果。halfTrue是确保输入数据是FP16格式与engine匹配。如果用device0报显存错误可以试试devicecpu——但毫无意义还是不推荐。如果想做摄像头实时推理可以用下面的循环import cv2 from ultralytics import YOLO model YOLO(best.engine, taskdetect) cap cv2.VideoCapture(0) while True: ret, frame cap.read() if not ret: break results model(frame, imgsz640, device0, halfTrue) annotated results[0].plot() cv2.imshow(YOLOv8 on Jetson Nano, annotated) if cv2.waitKey(1) 0xFF ord(q): break cap.release() cv2.destroyAllWindows()如果接的是USB摄像头VideoCapture(0)一般没问题。如果使用CSI摄像头需要改用cv2.VideoCapture(0, cv2.CAP_GSTREAMER)并确保系统里装了gstreamer插件这块配置稍微麻烦一点但网上资料很多照着做就行。5.2 实测性能不同模型的帧率对比我在Jetson Nano上分别测试了YOLOv8n、YOLOv8s以及用TensorRT FP16优化后的速度结果。所有测试都在MAXN模式下进行输入尺寸为640×640使用USB摄像头画面原始权重是从Ultralytics官方模型转换而来。模型推理方式平均帧率YOLOv8nPyTorch直接推理3~5 FPSYOLOv8nTensorRT FP1618~25 FPSYOLOv8sTensorRT FP1610~13 FPSYOLOv8nTensorRT INT825~30 FPS从数据可以明显看出TensorRT的加速效果非常显著YOLOv8n从不可用的3 FPS提升到了接近实时的20 FPS左右。YOLOv8s在Nano上也能跑到10 FPS以上做简单的检测任务够用了但略有卡顿。如果你的项目对帧率有硬性要求降低输入分辨率是最直接的作弊手段。把imgsz从640改到416YOLOv8n的帧率可以再提升一截代价是远距离小目标的检测能力下降。对于近距离的物体识别比如人脸、安全帽、PCB板缺陷416甚至320都是可接受的。这个“分辨率换速度”的思路在嵌入式AI里非常常用值得养成习惯。5.3 性能调优三板斧除了换模型和调分辨率还有几个项目实战中能实际提升性能的手段。第一个是批量推理。如果你的场景是离线分析一批图片/视频帧不要一张一张去推理而是攒一批比如batch8再送入模型。TensorRT对batch处理做了深度优化批量推理的吞吐量会显著高于单张推理。Jetson Nano的显存有限batch不能太大但batch4或8一般是安全的。第二个是锁频与散热。前面提到过jetson_clocks会把CPU/GPU抬到最高频率但随之而来的是发热加剧。Jetson Nano的被动散热版本如果在高温环境下长时间运行会触发降频保护导致性能断崖式下跌。我强烈建议加装主动散热风扇并且在项目上线前跑一个20分钟的持续压力测试比如连续推理视频流观察有没有掉帧或降频。这台板子对散热的需求被很多人低估了。第三个是精简预处理。如果你用ultralytics的model.predict()它内部自带letterbox、归一化、BGR转RGB等步骤省心但不够快。在帧率敏感的实时场景里可以自己用OpenCV完成预处理再把数据直接转成TensorRT的输入格式减少不必要的副本拷贝。这个优化能减少单帧2到5ms的处理开销在Nano这种性能紧张的平台上积少成多。6. 常见问题与排查技巧实录6.1 CUDA out of memory万物之源Jetson Nano上最常见的报错就是CUDA out of memory。很多人以为是模型太大但其实很多时候是后台其他进程占用了显存或者是swap空间不足导致的内存分配异常。排查步骤是sudo nvtop查看当前CPU/GPU占用和内存使用情况如果发现某个Python进程残留在后台直接kill掉。另外建议在推理代码中加入torch.cuda.empty_cache()每次推理后清一下缓存尤其是要做长时间视频流处理时这个调用有奇效。内存碎片化在共享内存平台上比独立显存平台更容易触发OOM定期清缓存能大幅提高稳定性。6.2 TensorRT engine构建失败用trtexec构建engine时如果报错大多数原因是ONNX模型里有TensorRT不支持的算子。常见的报错信息包括“op not supported”或“Unsupported ONNX node”。排查方法是把--fp16去掉先用FP32构建一次。如果FP32能成功而FP16失败说明模型里有对FP16敏感的计算层可以尝试在导出ONNX时设置simplifyTrue或者升级一下TensorRT到8.2.3的补丁版。如果模型里包含自定义层或者特殊算子TensorRT 8.2不一定认识那就只能退回用ONNX Runtime的CUDA EP或者换更基础的模型。但就YOLOv8而言导出ONNX时只要opset不超过12一般不会碰到算子兼容问题这也是我反复强调opset版本的原因。6.3 启动后黑屏常见硬件坑热词里有一条“jetson orin nano 启动后黑屏”其实Jetson Nano同样会碰到。大多数黑屏的原因是SD卡烧录不完整镜像一次性写入没成功检查烧录工具的日志、电源功率不足Nano必须使用5V/4A的DC电源部分劣质电源在负载波动时电压跌落、HDMI线与显示器兼容性差。排查思路很简单先换一张卡重新烧录再换一个电源最后换一条HDMI线。这三个问题几乎覆盖了90%的启动黑屏案例。如果是刚开机的短暂黑屏然后进入系统那是正常的JetPack第一次启动需要初始化很多服务不要急着判断失败。6.4 训练时报Segmentation fault这个报错在Jetson上训练自定义数据时比较常见根源多半是数据加载线程数过多导致内存爆掉。解决方案是在训练时设置workers2甚至workers0使用主线程加载数据配合小batch和小imgsz能够有效规避崩溃。别小看这个参数workers默认是8在Jetson Nano上开着默认值训练几乎是必崩。6.5 部署后中文标签乱码如果你的数据集包含中文类别名称在推理结果上显示时会乱码原因是OpenCV和ultralytics的绘图代码默认字体不支持中文。最简单的方案是模型训练时类别名用拼音或英文比如hard_hat而不是“安全帽”绘制结果后再在业务代码里映射成中文。这个绕路方法不优雅但在嵌入式平台上是最省力的。7. 更进一步在Jetson Orin Nano上的迁移与扩展如果你手头不是Jetson Nano而是新款的Jetson Orin Nano热词里也频繁出现大部分流程依然适用只是细节略有不同。Orin Nano的算力远强于Nano显存到了8GB性能大约有5到10倍的提升跑YOLOv8s的TensorRT FP16可以轻松跑到30 FPS以上甚至能跑一些轻量级大模型和视觉语言模型比如热词里提到的qwen部署的推理实验。但要注意Orin Nano使用的是JetPack 5.x甚至6.x系列自带Python 3.8以上PyTorch的安装方式和wheel版本跟Jetson Nano完全不一样。不要直接把面向JetPack 4.6.1的这套流程硬套到Orin上否则会碰到各种兼容性问题。迁移步骤上核心的模型导出和推理逻辑是完全通用的变的只是环境安装细节。在部署新板子之前先去NVIDIA官网查清楚对应的PyTorch wheel版本和TensorRT版本再动手能省下大量试错时间。至于热词里提到的RK3588则是另一套完全不同的技术栈。RK3588支持NPU加速推理YOLOv8通常用RKNN工具链做模型转换流程和NVIDIA平台有很大区别。如果你正打算在RK3588上部署YOLOv8建议单独找RKNN的教程不要跟NVIDIA的TensorRT流程混着看两者的模型量化、算子支持、工具接口都不一致很容易被绕晕。我自己的体会是在边缘AI这个领域平台绑定的知识非常严重换一块板卡基本等于重学一遍部署流程但底层对模型结构、数据流和性能瓶颈的理解是相通的。当你成功把YOLOv8部署到Jetson Nano上之后下一步可以试着把engine文件嵌入到自己的服务里比如写一个简单的Flask API让局域网内的设备都能请求检测接口。或者再接上舵机和云台做一个简单的目标跟踪小车。这些扩展方向能玩出很多花样也能让你对整条AI落地链路有更深的理解。最后补一个小技巧在Jetson Nano上维护多套Python环境时建议直接用virtualenv或condaMiniForge支持ARM架构来隔离项目依赖。这能避免不同项目之间相互污染导致的环境崩溃。我曾经因为装了一个新版本NumPy导致某天早上起来YOLOv8推理结果全部变成0个目标排查了半天才发现是依赖冲突。从那之后所有嵌入式部署项目我都会先创建一个独立虚拟环境这个习惯值得每个做嵌入式AI的人养成。
返回列表