
把工位上的检测主机换成树莓派5之前我一直以为这是件很轻松的事。开发机上YOLOv5模型跑得好好的精度也够搬到ARM板上无非是换个环境跑推理而已。结果从开机到稳定运行前后折腾了一个多月硬生生卡在了六件事上系统选型、模型迁移、推理性能、供电散热、产线通信、长期运行可靠性。这篇不是正经教程就是一次“树莓派5进车间”的项目复盘。我会把每个卡点怎么出现、怎么排查、最后怎么解决的都写清楚。打算把自训练的YOLOv5模型部署到树莓派5边缘设备上的朋友尤其是要在工业现场跑长期任务的这篇文章里的坑你大概率会踩到。1. 系统底座Ubuntu 装是装上了可驱动世界塌了半边1.1 为什么一上来就选 Ubuntu 而不是官方系统开发环境是Ubuntu云端训练也是Ubuntu所以给树莓派5装系统时第一反应就是装Ubuntu。当时树莓派5安装Ubuntu确实很顺官方Imager里直接选Ubuntu 24.04 LTS镜像写入SD卡开机就能进系统。桌面能用网口能通那一刻我还觉得这波稳了。稳了大概半天问题开始往外冒。树莓派5的官方系统Raspberry Pi OS Bookworm和Ubuntu在硬件支持上差得不是一点半点。Bookworm里出厂就打磨好的东西在Ubuntu下经常要自己动手甚至动手都没用。比如GPIO树莓派5的引脚控制方式改了很多老的RPi.GPIO代码在Ubuntu上跑不起来要用libgpiod那一套。再比如硬件视频编码树叶派5的H.264编码器在Ubuntu下的V4L2接口行为跟官方系统不一致做视频录像审计的时候就卡住了。还有GPU算力树莓派5的VideoCore VII在官方系统里对Vulkan支持是现成的Ubuntu上得自己折腾驱动。卡到第三天我做了一个后来被证明极其正确的决定宿主机换成Raspberry Pi OS Bookworm再用Docker跑一个Ubuntu 24.04容器作为开发环境。所有依赖装在容器里宿主机负责摄像头、GPIO、串口这些硬件资源通过--device /dev/video0:/dev/video0把设备映射进容器。这样既保留了Ubuntu的软件生态又不丢官方系统的硬件支持。一句话系统底座的正确打开方式不是二选一而是“官方系统兜底容器凑生态”。1.2 ARM架构下的依赖地狱树莓派5安装Ubuntu之后不管是直接跑还是容器跑装深度学习那套依赖都会遇到一个现实很多pip包没有aarch64平台的预编译wheel需要现场源码编译。YOLOv5系列涉及PyTorch、OpenCV、NumPy、pandas如果版本选得太新光编译就能让你等上几个小时。我的实际做法是锁版本。PyTorch用官方在Linux aarch64有预编译wheel的版本ONNX Runtime同样找aarch64的发布版OpenCV用apt装系统的发行版而不是pip死磕。另外给pip配了piwheels源虽然piwheels主要面向树莓派官方系统但纯ARM架构的预编译包能省不少编译时间。这期间最大的教训是别在树莓派上追求“最新”。开发机上最新版能跑板子上不一定有对应包板子上有对应包不一定能编过就算编过了下次环境重装又要再来一遍。车间设备要的是可复现不是新潮。2. 自训 YOLOv5 搬上 ARM没死在模型死在了依赖上2.1 导出链路pt 到 onnx 只是表面顺利我的模型是自己在工业数据集上从头训练的YOLOv5s类别有划痕、脏污和异物总共三类。在开发机上验证没问题后第一步导出ONNXpython export.py --weights best.pt --include onnx --opset 12这个命令在PC上几秒钟就跑完了拷到树莓派上也顺利加载但后处理开始出幺蛾子。YOLOv5的ONNX输出不止一个头原始输出是一大串reshape后的数组需要自己解析成三个尺度的feature map再自己写NMS。当时图省事试过带端到端NMS的导出方式结果ONNX Runtime在aarch64平台上对那个自定义NMS算子的支持不完善推理报错。折腾一下午之后我老老实实写了一个纯Python的后处理函数解析输出、按置信度过滤、NMS去重。这块的教训是边缘部署的后处理代码越简单越通用越好。别迷信框架自带的端到端方案尤其在ARM平台上算子兼容性永远是隐形的坑。2.2 推理库选型与性能基线树莓派5上推理库我测了三条路PyTorch直接推理、ONNX Runtime CPU推理、OpenCV DNN推理。PyTorch最重但兼容性最好缺点是启动慢、内存占用高、推理帧率低。OpenCV DNN快但YOLOv5的某些层支持不完整后处理更麻烦。最后选定ONNX Runtime原因很简单aarch64有官方wheelCPU优化做得比PyTorch直接跑好部署时还能动态量化。实测基线树莓派5 8GB默认散热yolov5s输入640x640FP32PyTorch直接推理2.1 FPSONNX Runtime CPU推理4.3 FPS加上图像预处理和后处理NMS端到端约3.5 FPS这个速度对静态检测勉强够用但产线上稍微快一点传送带每秒移动30厘米就会出现漏检。测完这个基线我才意识到后面专门要给性能开一个专题。2.3 量化那条路我半路放弃了ONNX Runtime支持动态量化FP32模型压到INT8体积小一半多CPU推理速度能再快一倍。可测试下来小目标漏检率明显上升尤其是划痕这类低对比度缺陷。车间检测最怕的不是慢是漏。漏一次就是残次品流到客户手里。所以最终方案很简单粗暴保留FP32精度牺牲部分帧率用输入尺寸和管线架构把速度找回来。这个取舍越到后面越觉得值。3. 性能不够不是算力的问题是取舍的问题3.1 别对树莓派5的 GPU 抱幻想树莓派5刚到手时我也研究过用GPU加速推理。VideoCore VII确实支持Vulkan网上也有人成功用NCNN在树莓派5上跑YOLOv5。但我实测下来这条路在工业场景里不现实。第一树莓派5的GPU算力有限跑YOLOv5s这类模型收益远不如预期。第二Vulkan/NCNN生态的部署链路不成熟量化和后处理都要自己调风险大。第三GPU推理的驱动依赖和系统绑定很深换个环境可能就废了。我的结论是树莓派5的GPU不是给你跑深度学习用的把CPU优化做足已经能覆盖很多场景。3.2 当场能做的三件优化第一个优化是换轻量模型。YOLOv5s换成YOLOv5n参数少了近一半精度降低一点但推理帧率直接翻倍。如果是检测明显的工件或大缺陷YOLOv5n完全够用。第二个优化是降输入分辨率。640降到416推理时间减少大概50%。但这里有个前提你的缺陷尺寸不能太小。我拿实际数据集测过320分辨率下一个小划痕可能只有几个像素直接漏检。所以我的建议是输入尺寸要根据最小目标像素数来定先算理论边界再动手降。第三个优化才是核心把多线程/多进程管线和推理解耦。我的架构分三个进程相机采集进程、推理进程、结果上传进程。进程之间用队列通信而不是在同一个进程里串行执行。这样采集和推理可以重叠端到端吞吐量从3.5 FPS提到6 FPS左右。代码层面ONNX Runtime的线程配置也很讲究import onnxruntime as ort sess_options ort.SessionOptions() sess_options.intra_op_num_threads 4 sess_options.inter_op_num_threads 1 sess ort.InferenceSession(best.onnx, sess_options, providers[CPUExecutionProvider])同时设环境变量OMP_NUM_THREADS4别让线程调度打架。3.3 真正解决性能问题的是 PCIe 外接 NPUCPU优化做得再狠yolov5s在树莓派5上也就是个位数的FPS。产线节拍一紧我最终上了树莓派5最有价值的外设接口PCIe。树莓派5提供PCIe Gen3 x1接一块M.2 HAT转接板就能插NVMe SSD或NPU加速卡。我用的是Hailo-8加速卡标称算力26 TOPSYOLOv5模型走它的工具链做量化编译后推理帧率直接跳到50 FPS以上而且功耗远低于CPU满载。部署自训练的YOLOv5模型这件事最后的生产方案变成了树莓派5仅做IO调度和协议处理模型推理全部交给NPUCPU负载保持在20%以下温度稳定帧率富余。说实话如果早两周把PCIe这条路想明白能少踩很多坑。4. 车间第一道物理关供电、散热与接线隔离4.1 5V/5A 不是够不够的事是电压稳不稳的事树莓派5的供电协议比4代挑剔得多。官方要求5V/5A也就是27W左右的USB-C PD输入。我一开始用一个标称5V/3A的电源短时间跑没问题一旦推理负载上去USB相机偶尔掉线NVMe盘还可能直接消失。查dmesg满屏的bcm2835-power电压欠压警告。树莓派检测到输入电压低于阈值会主动限制USB外设的电流这就是外设掉线的根因。车间供电环境比办公室恶劣隔壁就是电机和变频器电压波动是常态。解决办法是给树莓派单独配了一路导轨电源DC 5V输出容量按5A以上选不跟其他设备共用一个开关电源。如果是布点位置不方便接插头可以用PoE HAT一根网线同时解决供电和网络注意别同时插USB电源和PoE电源冲突会出问题。4.2 散热不解决推理性能自动打七折树莓派5满负载时CPU温度升得非常快一旦到85℃就开始降频推理帧率从4 FPS掉到2.5 FPS这是硬件自己认怂不做任何提示。车间环境夏天轻松到40℃装风扇是必然的。我用的是铝制散热片加4020风扇温度控制到65℃以下。别忘了留维护口车间粉尘大风扇半年就堵到时候吹出来的风全是热的散热效果大打折扣。正常维护周期我定在三个月清一次灰。高温还会加速SD卡损耗。这也是我后来把系统迁移到NVMe SSD上的重要原因。树莓派5通过M.2 HAT接了一块NVMe硬盘系统、模型、日志全放NVMeSD卡只保留引导分区。速度提升了耐用性也提升了SD卡再也不怕写坏了。4.3 24V 与 3.3V 之间隔着一层光耦树莓派的GPIO是3.3V电平车间的接近开关、继电器输出大多是24V电平直接对接非常危险。我第一次接感应开关时因为没注意NPN/PNP类型烧了一块GPIO扩展板几十块钱倒是小事耽误两天调试才是大事。正确的做法是中间加光耦隔离模块24V信号转3.3V信号再接树莓派。输出方向树莓派3.3V信号也要通过固态继电器或光耦去驱动24V负载绝对不能直接驱动PLC的外部继电器。车间线缆用带磁环的USB线尽量走独立线槽跟电机动力线保持距离不然干扰会导致视频流掉帧。5. 和产线设备对话比训练模型更磨人5.1 模型输出不等于产线事件卡在这一步时模型精度已经不是瓶颈了。我花了三天时间把检测模型的准确率从87%调到92%结果跟PLC联调了一天发现对方根本不关心你的框画得准不准只关心三件事现在是好件还是坏件坏件是什么类型坏件位置在哪。所以协议设计必须往前放放在模型部署之前。我用的是一组Modbus寄存器树莓派作为Modbus TCP客户端周期性写入PLC的保持寄存器区寄存器1状态0空闲、1检测中、2良品、3不良品寄存器2缺陷类型编号1划痕、2脏污、3异物寄存器3-4缺陷中心X坐标寄存器5-6缺陷中心Y坐标就这么点东西写代码只花了一个小时但定义协议和跟PLC工程师对参数对齐用了大半天。车间设备的对接从来不是技术难题而是沟通和约定谁来做状态机的问题。5.2 Modbus TCP 和 RS485两条腿都要会走老一点的生产设备没有网口只有RS485串口跑Modbus RTU协议。树莓派5的串口设置也有个坑默认的UART可能被系统console占用需要在/boot/firmware/config.txt里关掉console接管enable_uart1 dtoverlayuart0串口外接RS485电平转换芯片比如MAX3485再接设备。接线时A/B别接反终端电阻要不要加看距离。Modbus RTU和Modbus TCP的字节序、帧格式都不同我这里就吃过亏TCP模式下坐标乱跳排查半天发现是PLC和树莓派对寄存器的高低字节解释不一致。总线协议这种东西最好写一个单独的小工具先连通再跑业务逻辑。5.3 触发时序谁给谁发信号这是个状态机问题最开始我打算让树莓派同时负责触发信号采集和视觉检测接近开关直接接GPIO触发后立刻拍照推理。听起来顺理成章实际跑起来各种乱。原因是Python不是实时系统从GPIO电平变化到后端推理线程响应延迟不可控。产线节拍50毫秒级时这种延迟会导致漏拍。最终架构是把触发逻辑从树莓派上剥出去改由PLC统一负责时序PLC收到接近开关信号后通过Modbus寄存器通知树莓派“开始拍一张”树莓派推理完把结果写回寄存器PLC读到结果后执行分拣动作。树莓派只做视觉不碰实时控制。隔离职责之后系统稳定多了。5.4 检测数据必须留档车间设备最怕扯皮。产品到底有没有经过检测检测结果是什么必须能回溯。我每天生成一个CSV日志记录时间戳、结果、坐标、置信度图片按小时归档到NVMe本地盘定期拷贝到公司共享存储。有一次客户投诉说某批产品有缺陷流出。查系统日志发现那个批次确实有一帧漏检原因是我们设置的置信度阈值偏高模型对某类缺陷输出只有0.49被过滤掉了。没有数据留档这种问题会变成“供应商与客户”之间无休止的争论。有了留档问题三分钟定位。6. 七天不间断服务自愈、看门狗与远程维护6.1 SD卡怕断电那就把系统做成“断电也不怕”车间意外断电很常见。树莓派如果直接跑在SD卡上断电几次ext4文件系统损坏起不来的概率非常高。我一开始用的树莓派5安装Ubuntu方案SD卡被我拔电测试拔坏过两张。后来把系统迁移到NVMe SSDSD卡只做引导分区问题基本消失。进一步增强根文件系统以只读模式挂载临时文件和运行状态放到tmpfs内存盘程序更新时再重新挂载为读写。这样就算被一把拉断电文件系统也是干净的开机几秒钟恢复工作。日志方面用了log2ram方案把/var/log放到内存里定期同步到磁盘减少写操作。知道的人会觉得这是洁癖但在工业现场多扛一次断电就少一次出勤维护。6.2 systemd 服务自启 看门狗推理程序不能只做python main.py就完事必须变成系统服务[Service] ExecStart/usr/bin/python3 /opt/vis_app/main.py Restartalways RestartSec5 WatchdogSec10Restartalways保证程序崩溃自动拉起WatchdogSec10配合systemd的看门狗机制程序定期sd_notify心跳喂狗超过10秒没喂systemd强制重启服务。系统层面也挂看门狗。树莓派5没有独立外部看门狗芯片但可以用Linux内核的softdog模块加载后出现/dev/watchdog设备再在/etc/systemd/system.conf里设置RuntimeWatchdogSec30内核定期写狗。系统一旦假死硬件重启。程序内部还要有业务看门狗连续5秒没拿到新的检测结果自动记录错误并重启推理服务。这个逻辑比系统看门狗更重要因为系统没死但业务卡死了产线上照样是废品。6.3 远程维护老老实实走局域网车间工位不可能放显示器键盘。我的维护方式很简单树莓派固定IP同一车间网络内SSH登录需要看图形界面就用VNC。但不要依赖什么花哨的远程穿透方案车间网络安全要求通常不允许设备随便外联外部网络。我的做法是给树莓派只分配内网IP所有对外通信只有Modbus TCP到PLC的端口。维护时通过公司已有的远程办公系统接入内网再SSH。另外定期把/etc和/opt/vis_app打包备份到共享存储系统挂了直接重新烧录半小时恢复工位。机械设备修理讲究工装这种“烧录备份”就是软件工装。最后说个真实体会树莓派5进车间这件事如果只是实验工位、节拍松、检测目标又大那它完全能胜任如果要对齐严格产线节拍一定把供电、散热、通信、可靠性当性能一样对待。我卡了一个多月绝大多数时间不是在调模型而是在解决这些“不性感”的现场问题。现在这套方案已经在车间连续跑了两个多月一次死机都没出现过。折腾的人是我希望后来者少折腾几天。