资讯动态

树莓派部署YOLO实战:模型转换、量化与实时推理指南

发布时间:2026/10/3 6:02:07 来源:尧图企业网站定制
训练好的YOLO模型要落地到树莓派上听起来像技术大佬的折腾项目但放在毕设和工程原型里这其实是一个非常典型的需求。树莓派加一块USB摄像头再跑一个推理速度尚且能看的YOLO模型就能做口罩识别、火焰检测、人员统计、姿态估计等各类边缘端应用。这篇文章我以树莓派4B为例基于常见的YOLOv5/YOLOv8训练权重完整走一遍从模型转换、环境搭建到摄像头实时推理的部署流程重点讲清楚每一步为什么这么做以及我在实际部署中踩过的坑和测试出来的真实性能数据。如果你手里已经有一个训练好的.pt模型文件但完全没有树莓派部署经验这篇文章能帮你少走至少两天弯路。如果你只是刚接触目标检测也可以用公开的YOLO权重先跑通整个流程再换成自己的模型。整个过程不涉及训练只讲部署你需要的基础是能安装树莓派系统懂一点Python会用OpenCV。下面直接开始。1. 部署思路在树莓派上跑YOLO本质是取舍1.1 树莓派在边缘推理中的定位树莓派不是服务器它更像一个低功耗的“边缘小盒子”。CPU是四核ARM架构算力跟PC上的GPU差距悬殊但这不妨碍它承担原型验证、课堂教学、轻量级工业检测等任务。关键是要想清楚一个问题你部署YOLO到底是为了什么我见过不少同学一上来就在树莓派上装PyTorch、加载训练好的权重然后发现一张640x640的图像推理时间超过5秒内存还经常告警。这类做法不是不行而是没有理解“部署”和“实验”的区别。部署的目标是在目标设备上以最快、最稳的方式跑通模型而不是把训练时的环境原样搬过去。所以部署第一步不是写代码而是先确认你的边界树莓派型号、内存大小、是否接摄像头、目标帧率、允许的最大功耗、是否需要实时检测。这些参数直接决定后面怎么选推理后端、怎么压缩模型、怎么设计后处理。1.2 四条常见部署路线对比从训练环境到树莓派模型文件通常要经过格式转换。我梳理了四条最常用的路线路线描述转换路径推理后端树莓派上实测表现适合场景路线APyTorch直接跑.pt文件直接用PyTorch CPU极慢内存占用高只做功能验证不推荐路线BONNX Runtime.pt→.onnxONNX Runtime较快部署简单大多数项目首选路线COpenCV DNN.pt→.onnxOpenCVcv2.dnn中等依赖少不想引入额外推理框架路线DNCNN.pt→.onnx→.param/.binNCNN通常比ONNX Runtime略快尤其小模型追求极致CPU性能我自己的经验是如果只是毕设展示或短期原型路线B最省心转换工具链成熟问题也容易搜到。如果你的项目需要长期在树莓派上一天跑十几个小时路线D值得考虑NCNN在ARM CPU上做了很多汇编级优化量化支持也更完善。路线C适合只想用一个OpenCV就跑完读取、预处理、推理、画框的项目但不建议用来调性能。1.3 模型选型不是所有的YOLO都适合树莓派“YOLO”现在是一个大家族从YOLOv5到YOLOv8再到YOLO11这里说的“第几代”其实不同的维护组织有自己的版本建设路径。但部署在前端设备上体积和算力是第一优先级。以YOLOv8系列为例YOLOv8n参数量约3.2M模型文件约6MB最适合树莓派。YOLOv8s参数量约11M模型文件约22MB树莓派上勉强能实时。YOLOv8m/l/x参数量大树莓派CPU基本跑不动不推荐。我在树莓派4B上实测输入尺寸640x640时YOLOv8n的推理帧率大约在5到8 FPSYOLOv8s只有2到3 FPS。如果把输入尺寸降到416再把模型转成NCNN量化版本YOLOv8n可以达到15 FPS左右。这就是部署阶段的“取舍”精度、速度、资源三者不可能全都要。2. 硬件与基础环境准备2.1 树莓派型号、内存与散热选择树莓派4B是当前最常用的部署平台2GB内存起步但我强烈建议用4GB或8GB版本。YOLO推理时即使是6MB的轻量模型也需要加载模型参数、中间特征图、图像数据和多级后处理数组2GB内存在边缘情况下很容易触发OOM。树莓派5性能更强但如果你的代码依赖某些老旧的GPIO库或摄像头驱动4B反而兼容性更好。散热是非常容易被忽略的点。树莓派4B在高负载推理时CPU温度会很快冲到80度以上一旦过热触发降频帧率会直接从5FPS掉到2FPS。建议至少装一个带散热片的铝合金外壳或者一个小风扇。不要小看这个成本它直接影响推理稳定性。摄像头方面如果你只想快速跑通检测USB摄像头最省事即插即用OpenCV直接就能读到。CSI接口的摄像头模块比如OV5647成像素质更好但需要在树莓派上额外启用驱动某些老型号摄像头还要用libcamera而不是raspistill配置成本稍高。2.2 系统安装与基础配置系统建议用树莓派官方的 Raspberry Pi OS64位版本。64位系统能更充分利用树莓派4B的ARM处理器某些Python包在64位下也能获得更好的优化。安装系统后第一件事sudo apt update sudo apt upgrade -y如果软件源访问速度不理想可以把系统源换成国内镜像源编辑/etc/apt/sources.list和/etc/apt/sources.list.d/raspi.list这样apt install下载依赖会快很多。这一步不需要额外工具但能节省大量等编译的时间。接下来需要给系统留出足够的磁盘空间。如果是运行官方Imager烧录的系统一般会自动扩容但如果你用的是旧卡或手动分区务必在raspi-config里确认根分区占用了全部TF卡空间。不然模型文件、虚拟环境和依赖包很容易把系统盘塞满。2.3 Python虚拟环境与依赖安装我强烈建议在树莓派上创建虚拟环境来部署不要直接装在系统Python里。因为树莓派系统升级时可能会覆盖pip安装的包虚拟环境可以把所有依赖锁定在固定位置。python -m venv --system-site-packages yolo_env source yolo_env/bin/activate pip install --upgrade pip这里有一个小细节树莓派上的OpenCV最好直接装opencv-python预编译包而不是自己源码编译因为源码编译需要大量时间和内存。如果因为硬件浮点支持问题安装失败可以先升级系统到最新版本再装。需要安装的核心依赖包括pip install numpy opencv-python onnxruntime pyyaml如果你的模型后续要转NCNN还需要ncnn对应的Python包或在PC上编译NCNN工具链。ONNX Runtime在树莓派上可以直接通过pip安装CPU版本的包不需要GPU支持这也是它方便的一个原因。3. 把训练好的模型转换成边缘端能吃的格式3.1 训练端该做什么检查很多人在树莓派上部署失败不是推理代码有问题而是训练完的模型本身就不适合部署。转换前检查三件事。第一模型输入尺寸。如果你的训练尺寸是1280x1280树莓派上很难跑到可用的帧率。我一般建议训练时尽量在精度可接受范围内用小尺寸比如640或416。如果模型已经用1280训练了转换时强行降到320会有较大精度损失。第二类别数量和输出层结构。YOLOv5和YOLOv8的输出格式不同YOLOv8输出的是一个1 x (4 num_classes) x num_anchors的张量YOLOv5输出则是三组不同尺度的特征图拼接后得到的1 x num_anchors x (5 num_classes)。后处理代码一定要跟模型版本对应否则画框位置会乱掉。第三权重文件是否只有模型参数。如果你在训练时加了EMA、优化器状态等建议先提取出纯权重文件或者导出时去掉其余部分。否则在树莓派上加载会多占用内存。3.2 PyTorch权重转ONNXONNX是当前边缘部署的“中间语言”。训练好的.pt文件通过官方脚本导出ONNX格式整个过程在PC上完成即可不需要在树莓派上进行。YOLOv5导出命令python export.py --weights best.pt --include onnx --opset 12 --img 640YOLOv8导出命令yolo export modelbest.pt formatonnx opset12 imgsz640这里有几个参数要特别注意opset 12ONNX算子集的版本。树莓派上的ONNX Runtime版本要是比较新可以用opset 12如果再低的话某些YOLO算子不支持。imgsz 640导出后的模型输入尺寸。想更快就改为416或320但精度会下降。不要开dynamicTrue动态维度。动态输入尺寸会显著增加推理耗时树莓派场景通常固定尺寸就够了。导出后会在相同目录下生成一个.onnx文件。可以用onnx.checker验证一下或者用onnxruntime在PC上先跑一次推理确认输出结果和PyTorch一致再拷贝到树莓派。3.3 ONNX转NCNN更适合ARM的优化路线NCNN是腾讯开源的一款针对手机和嵌入式设备优化的神经网络推理框架。树莓派是ARM架构NCNN有许多ARM Neon汇编优化所以不少场景下比ONNX Runtime更快。转换过程一般也在PC上做。先把YOLO导出成ONNX然后使用NCNN的onnx2ncnn工具转换onnx2ncnn best.onnx best.param best.bin转换后得到两个文件param记录网络结构bin记录权重数据。NCNN还有一个optimize工具可以进一步做算子融合和内存重排ncnnoptimize best.param best.bin best_opt.param best_opt.bin 0这里的0代表FP32存储。如果你在树莓派上内存不够可以试65536fp16存储但要求CPU支持FP16运算树莓派4B的ARM架构对FP16的加速效果有限。NCNN还支持Int8量化但量化需要校准集比较复杂不是无脑开的。3.4 量化从FP32到FP16/INT8的代价与收益模型量化是提升树莓派推理速度最有效的手段之一。但量化不是“导出时加一个参数”就完事它分为两种训练后量化PTQ直接拿训练好的模型用一小批校准图片统计激活值范围再转成INT8。量化感知训练QAT训练阶段就模拟量化误差精度损失更小但需要重新训练。树莓派部署中简单场景用PTQ就够了。不过要注意ONNX Runtime在树莓派上对INT8支持并不如NCNN和TFLite好。如果确实需要量化加速NCNN是更顺手的工具。我在实际测试里YOLOv5s用NCNN FP32在树莓派4B上推理大约4 FPS转成INT8后能到8到10 FPS但精度下降了约2到4个mAP点。如果检测目标本身比较大比如人员、车辆这个精度损失可以接受如果检测细小的缺陷就要谨慎量化。4. 在树莓派上跑推理4.1 用ONNX Runtime加载模型ONNX Runtime在树莓派上安装很简单CPU版本即可不需要额外配置CUDA或TensorRT。加载模型的代码非常直观import onnxruntime as ort sess ort.InferenceSession(best.onnx, providers[CPUExecutionProvider]) input_name sess.get_inputs()[0].name output_names [out.name for out in sess.get_outputs()]这里顺手打印input_name和output_names因为不同版本YOLO导出的ONNX名称可能不同。YOLOv8导出的ONNX输入名通常是images输出名可能是output0。建议你实际确认后再写预处理和后处理。ONNX Runtime默认采用单线程推理但树莓派有四个CPU核心我们可以通过SessionOptions调整线程数options ort.SessionOptions() options.intra_op_num_threads 4 sess ort.InferenceSession(best.onnx, options, providers[CPUExecutionProvider])实测在树莓派4B上开启四线程比单线程快很多但如果模型本身很小线程数开太多反而会因为线程调度增加开销。建议从2线程开始测试。4.2 用OpenCV DNN跑YOLO如果你的项目依赖很少希望只在树莓派上用一个OpenCV就完成所有功能可以用cv2.dnn.readNetFromONNX加载模型。import cv2 net cv2.dnn.readNetFromONNX(best.onnx) net.setPreferableBackend(cv2.dnn.DNN_BACKEND_OPENCV) net.setPreferableTarget(cv2.dnn.DNN_TARGET_CPU)然后需要自己构造blobblob cv2.dnn.blobFromImage(image, 1/255.0, (640, 640), (0, 0, 0), swapRBTrue) net.setInput(blob) outputs net.forward()OpenCV DNN的好处是不需要额外安装ONNX Runtime但缺点是对某些新模型算子支持不够及时。YOLOv8导出ONNX时如果用了比较新的算子OpenCV版本太旧会直接报错。我的建议是能装onnxruntime就用ONNX RuntimeOpenCV DNN作为备选。4.3 摄像头实时目标检测代码结构树莓派部署YOLO最常见需求是实时摄像头检测。整体流程是读取一帧图像 - 预处理letterbox - 模型推理 - 后处理置信度过滤、NMS - 画框显示或存储。我这里给出一个基本的代码骨架基于ONNX Runtime和OpenCVimport cv2 import numpy as np import onnxruntime as ort # 加载模型 sess ort.InferenceSession(best.onnx, providers[CPUExecutionProvider]) input_name sess.get_inputs()[0].name # 摄像头 cap cv2.VideoCapture(0) cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) def letterbox(img, new_shape(640, 640)): shape img.shape[:2] r min(new_shape[0] / shape[0], new_shape[1] / shape[1]) new_unpad (int(round(shape[1] * r)), int(round(shape[0] * r))) img cv2.resize(img, new_unpad, interpolationcv2.INTER_LINEAR) dw (new_shape[1] - new_unpad[0]) / 2 dh (new_shape[0] - new_unpad[1]) / 2 top, bottom int(round(dh - 0.1)), int(round(dh 0.1)) left, right int(round(dw - 0.1)), int(round(dw 0.1)) img cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value(114, 114, 114)) return img while cap.isOpened(): ret, frame cap.read() if not ret: break input_img letterbox(frame) blob cv2.dnn.blobFromImage(input_img, 1/255.0, (640, 640), swapRBTrue) blob np.transpose(blob, (0, 2, 3, 1)) # 根据模型要求调整 outputs sess.run(None, {input_name: blob.astype(np.float32)})[0] # 后续对 outputs 做 NMS 和画框注意不同版本的YOLO导出ONNX后输入张量格式可能不同。YOLOv5导出ONNX后可以直接用blobFromImage的结果YOLOv8则可能需要把NCHW转成NHWC或反过来。建议先用一张固定图片在PC上测试确认输入输出维度。4.4 性能测试与结果我在树莓派4B4GB版本上跑过一组对比测试条件是输入尺寸640x640摄像头分辨率1280x720推理后端ONNX Runtime。模型平均帧率FPS内存占用CPU占用YOLOv8n6.3约450MB四个核心约80%YOLOv8s2.3约720MB四个核心接近100%YOLOv5n6.8约420MB约75%YOLOv5s2.6约690MB约95%这个结果说明树莓派只适合跑“n”级别模型。为了看起来还不错的精度很多人训练时会选s或更大但那是在PC上训练得到的体验真放到树莓派上实时检测基本就见鬼了。5. 性能优化从2 FPS到15 FPS以后5.1 输入尺寸与预处理是最大的隐藏瓶颈很多人只看模型推理时间却忽略了预处理。在树莓派上一张640x640的图cv2.resize和letterbox处理大约需要10到20毫秒如果是1280x720的原始视频帧每帧都要做缩放和边条填充累加起来非常可观。优化手段很直接把摄像头采集分辨率设置低一点比如640x480同时模型输入尺寸用416或320。模型输入越小resize耗时越短推理时间也越短整体帧率往往能提升30%以上。我还试过把letterbox的填充值从(114,114,114)改成(0,0,0)对推理结果影响很小可以忽略。重点是不要对每一帧重新分配大数组尽量复用np.ndarray对象避免频繁内存分配。5.2 推理后端之间到底有多大差距同一份ONNX模型在不同后端上的表现差异非常明显。我在树莓派4B上做过一次横向测试模型是YOLOv8n输入尺寸416推理后端单帧推理耗时毫秒说明ONNX Runtime4线程85较稳定通用性好OpenCV DNN128简单但比较慢NCNN4线程72小模型优化明显NCNN4线程 FP1668有轻微风险需验证支持如果你的项目需要长期稳定运行我建议ONNX Runtime为主NCNN作为后续优化选项。不要在项目初期就绑定某个特定后端因为模型导出、算子版本、后处理这些环节都会影响最终表现。5.3 模型轻量化剪枝、蒸馏与换主干树莓派算力有限最有效的方法是让模型本身变小。除了选择YOLOv8n这类轻量级版本还有几个方向通道剪枝把YOLO中贡献小的卷积通道裁掉模型体积和计算量能减少30%以上。知识蒸馏用大模型训练期间输出作为“软标签”来指导小模型学习小模型精度能接近大模型。更换主干有些YOLO变体把主干网络换成MobileNetV3或ShuffleNetV2推理速度和精度平衡点不同。但是这些操作需要重新训练模型不是部署阶段能完成的。如果训练数据、算力和时间都很紧张最稳妥的办法是直接用YOLOv8n或YOLOv5n做训练然后在部署阶段做量化这样能保证精度和性能兼得。5.4 系统层面的其他优化除了模型树莓派系统本身也有一些可以调整的地方。关闭桌面环境。如果只是做后台检测不接显示器最好在raspi-config里把系统启动模式设置为“Console”省下大量CPU和内存。限制CPU频率避免过热降频。树莓派4B可以通过raspi-config启用“风扇温度控制”或者在/boot/config.txt里设置force_turbo1。关掉不需要的服务比如蓝牙和Wi-Fi管理协议栈。如果摄像头通过网线或本地推流蓝牙用不上就直接关闭。使用更轻的Python解释器或PyPy这一条实际收益不大不建议折腾。我把这些优化统称为“讨要性能”每一项看起来都不起眼但叠加起来可能让最终帧率从4FPS变成7FPS体验完全不同。6. 常见问题与排查技巧实录6.1 模型转换后输出形状和预期不一致这个问题几乎每个人都会遇到。YOLOv8导出的ONNX输出维度是[1, 84, 8400]而很多网上教程写的还是YOLOv5的[1, 25200, 85]。如果你的后处理代码沿用YOLOv5的写法结果自然不对。排查方法很简单在树莓派或PC上先打印模型输出的shape。for out in sess.get_outputs(): print(out.name, out.shape)拿到真实shape后再写NMS代码。YOLOv8的输出需要在第二维和第三维之间做转置变成[1, 8400, 84]然后按行处理。这个转换用一两次numpy.transpose就能解决但必须知道模型输出结构。6.2 推理结果全是背景什么目标都检测不到这个问题多半出在预处理上。第一种可能是图像归一化方式不对YOLO的输入像素需要除以255并且如果是RGB模型不能把通道顺序搞反。OpenCV读取的图像默认是BGR导出模型时如果训练数据是RGB推理前必须swapRBTrue。第二种可能是输入尺寸不对。letterbox时缩放比例算错导致图像被拉伸或填充过多目标形状变化太大置信度自然低。建议在调试阶段把预处理后的图像保存下来肉眼确认显示的目标仍然清晰。第三种可能是置信度阈值设得太高。树莓派上部署时如果模型经过量化输出置信度会比FP32低如果后处理里还沿用0.5的阈值很多目标会被过滤掉。把这个阈值调低到0.25甚至0.15测试往往就有结果了。6.3 树莓派卡死无响应远程连不上这种情况多半是内存不足或CPU过热。模型推理时占用内存过高系统会触发OOM轻则杀掉进程重则整机无响应。我建议在树莓派上部署时先用watch free -h观察内存占用。如果是OOM解决方案有换更小的模型、减小输入尺寸、使用NCNN量化版本、增加交换分区swap。注意SWAP虽然缓解内存不足但TF卡频繁读写会加速损坏仍不建议长期依赖。如果是过热卡死查看vcgencmd measure_temp如果温度超过80度就需要加强散热。树莓派没有SSD时高负载下使用TF卡也会出现IO等待可以考虑用USB固态硬盘引导系统但成本会上升。6.4 摄像头采集失败与帧率忽高忽低USB摄像头在树莓派上最常见的问题是带宽不足尤其是使用USB 2.0接口同时接摄像头和无线网卡容易导致画面掉帧。解决办法是把摄像头插到蓝色USB 3.0接口或者降低采集分辨率。如果使用CSI摄像头需要先启用驱动并安装libcamera工具。OpenCV直接调用CSI摄像头需要配合libcamera的虚拟设备节点配置过程略复杂。在调试时先用系统自带的rpicam-hello确认摄像头能成像再回到OpenCV读取。帧率忽高忽低的原因可能是读取线程和推理线程共用主循环摄像头采集阻塞导致推理不稳定。优化办法是使用单独线程采集图像用队列传给推理线程这样能解决大部分卡顿问题。6.5 踩坑速查表现象最可能原因解决方案加载模型报错提示不支持的算子ONNX Runtime版本低升级onnxruntime或降低opset推理输出shape不对模型版本与后处理写错打印输出的shape按实际格式解析检测框偏到一边letterbox填充后坐标未换算回原图后处理判断框坐标时去掉填充边距帧率极低输入尺寸过大或模型过大改用n系列模型降输入到416CPU温度冲到85度散热不足加装风扇或散热片降低CPU频率摄像头画面黑屏CSI摄像头未启用驱动先运行rpicam-hello工具验证内存持续增长每帧都创建新数组导致GC压力复用大数组减少np.concatenate7. 写在最后的个人项目体会对这个部署流程我最大的感受是树莓派上跑YOLO技术难点不在“跑起来”而在“跑得稳定”。一旦树莓派断电重启摄像头驱动、虚拟环境路径、系统自动挂载这些问题都会冒出来。我建议把部署过程写成shell脚本把模型文件放在固定目录并用systemd设置服务自启这样才有工程化的味道。另外一个实用建议是先在一张图片上验证完整流程再接入摄像头。很多人直接把摄像头和模型一起启动出了问题既不确定是摄像头的问题还是模型后处理的问题排查起来特别痛苦。我在实际项目里会先保存一张图片用脚本单帧跑一遍推理画出结果图确认一切正常后再实施实时检测。如果你也想在树莓派上部署自己的YOLO模型不用急着买各种配件。先用手头的树莓派4B安装系统下载一个官方的YOLOv8n权重把博文里的流程走一遍等理解了整个链路再换上自己的训练权重。这套能力不仅在毕设里用得上放到真实的边缘设备项目里也一样管用。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑