
这台树莓派5我在工位上跑得好好的。跑YOLOv5推理、刷Ubuntu、连屏调参手感丝滑。结果真把它装进车间设备柜连续踩了一整天的坑。重启、掉帧、断连、掉系统每一步都卡得人头疼。这篇文章就把我在车间里被卡住的六件事完整写一遍。供电、散热、系统选型、模型部署、远程运维、掉电恢复每件事我都会把排查过程、原理分析和最终的解决配置贴出来。不管你是打算把树莓派5搬进产线做视觉质检还是只是想在一个恶劣环境里稳定跑AI推理这篇都值得从头到尾看一遍。尤其是“自训YOLOv5模型部署”和“Ubuntu安装”这两块是我实际折腾了两轮才顺手的路线网上说法很多实操细节我一次性给全。1. 供电不稳是第一道坎车间老旧线路下的反复重启1.1 故障现象与第一轮误判设备装好系统起来摄像头画面正常YOLOv5开始推理。大约跑了十分钟板子突然重启。我第一反应是系统问题检查内核日志发现根本没有正常关机记录——不是软重启是硬件级掉电复位。说实话第一次遇到这种情况我整整浪费了一个下午在错误的方向上。刷系统、换镜像、关掉一些服务全都没用。问题还是一样负载一上来就重启。后来换了个思路直接怀疑供电。树莓派5和前几代不太一样它对电源质量敏感得多。官方要求5V/5A的电源但“功率够”和“电压稳”是两码事。车间里的老插座旁边还接着电焊机和大功率电机这些设备一启动电网电压会瞬时跌落。手机用的PD快充头在这种环境里根本顶不住。1.2 用数据定位欠压故障判断欠压最直接的办法看系统自己的状态记录。树莓派启动后执行vcgencmd get_throttled返回一个十六进制值按位表示发生过的故障状态。0x1表示发生过欠压0x2表示当前正在欠压0x4表示CPU频率曾被限制0x8表示当前正在降频。我读到的值几乎每周都有欠压标志满载推理时用电表直接测板端USB-C口的电压已经跌到4.6V左右远低于稳定工作需要的5V±5%范围。这里的原理也很好理解。树莓派5在高负载时瞬时电流能冲到3-5A经过USB线、连接器和电路板走线每一段都会产生压降。算笔账一条1米长的普通USB-C线双线电阻约0.1Ω在5A电流下就有0.5V的压降。电源输出5.1V到板端只剩4.6V正好卡在欠压阈值附近。负载一抖直接复位。1.3 电源选型与线材计算换掉PD快充头换成工业级明纬电源输出5V/5A带接线端子。线材也换了截面积更粗的20AWG USB线长度控制在0.5米以内。接线端子方案在车间更实用直接压接到电源端不用频繁插拔USB头。替换之后我用以下命令连续监控半小时watch -n 5 vcgencmd get_throttled vcgencmd measure_volts coreget_throttled返回值全程为0核心电压稳定在0.9V左右这是PMIC给核心供电的电压不是输入电压设备再没重启过。这里有个经验别迷信“65W快充”这类参数快充头设计目标是给手机充电瞬态响应未必适合树莓派这种动态负载。车间环境里源端稳定比额定功率更重要。2. 散热跟不上性能被温度“锁”住的教训2.1 高温降频带来的帧率雪崩供电问题解决之后系统稳定运行了但我很快发现另一个问题——推理速度越跑越慢。刚启动时YOLOv5推理大约每秒8帧跑了二十分钟后掉到每秒3帧。我还以为模型转换出了问题结果一看CPU温度92°C。树莓派5用的Cortex-A76核心在高负载下发热量不可小看。芯片内部有温度保护机制超过85°C就会主动降频把主频从2.4GHz一步步压下来。性能不是你感觉慢而是处理器自己砍自己的频率。温度监控命令vcgencmd measure_temp cat /sys/class/thermal/thermal_zone0/temp当时整个设备装在一个密闭的配电柜里柜内没有通风加上车间本身环境温度就不低原装散热器根本压不住。2.2 车间粉尘环境下的散热方案取舍先说结论靠原装被动散热器在车间密闭柜里跑AI负载不现实。我最终用的是组合方案板子装进带大面积散热鳍片的金属外壳CPU位置涂好导热硅脂外壳顶部再加一个5V温控风扇向外排风。风扇不直接吹板子而是把密闭柜内的热空气排出形成对流。这样做的好处是灰尘不会直接吹进板卡内部散热效率也比纯被动式高很多。实测数据供参考开放环境下原装散热器能把满载温度压在70°C左右换金属壳加顶排风扇之后即使在密闭柜内满载温度也稳定在65-70°C之间降频再也没有触发过。这里有一个细节值得注意树莓派5的风扇接口支持PWM调速。不要一直全速转吵且吸灰用系统自带的fancontrol配置温度曲线就好。2.3 温度监控与性能校准设备装完后不要直接上线。先做一个20分钟的满载压测同时记录温度和帧率。我写了个简单循环每10秒记录一次while true; do date /tmp/thermal.log; vcgencmd measure_temp /tmp/thermal.log; vcgencmd get_throttled /tmp/thermal.log; sleep 10; done跑完看温度曲线是否平稳有没有降频标志。这一步特别重要因为车间的环境温度跟你工位上是两回事。我见过不少项目在空调房里调好了一进车间就歇菜绝大部分都是散热和供电这两件“小事”。3. 系统选型来回折腾Ubuntu才是YOLOv5的最佳搭档3.1 先装了树莓派OS为什么又换第一次刷系统我理所当然选了Raspberry Pi OS毕竟是官方正统对树莓派5的支持最及时。但在实际部署YOLOv5的过程中我越来越别扭。最痛的一点是软件生态。现在大量AI部署工具、容器镜像、ONNX Runtime的预编译wheel都是优先服务Ubuntu。树莓派OS虽然基于Debian但不少依赖包和文档教程对不上号遇到问题搜解决方案十有八九是Ubuntu的路径。为了省这几分钟装机时间后面多花了两天查兼容性问题不划算。3.2 Ubuntu 24.04的配置差异换到Ubuntu 24.04 LTS之后整个过程顺滑太多。下载Raspberry Pi Imager选择Ubuntu 24.04 LTS预装镜像直接写卡。开机后默认用户和密码是ubuntu/ubuntu系统会强制让你改密码。有几个配置差异需要特别留意树莓派OS的配置文件在/boot/config.txtUbuntu下变成了/boot/firmware/config.txt。启用I2C、SPI或者摄像头CSI口修改的位置不一样。默认没有预装raspi-config工具需要自己装sudo apt install raspi-configGPIO权限问题要处理。Ubuntu下默认用户ubuntu没有直接操作GPIO的权限需要把用户加入gpio组sudo usermod -aG gpio ubuntu之后重启Python直接import RPi.GPIO或者使用libgpiod就不会报权限错误。3.3 什么情况下应该老实留在树莓派OS虽然我最后选了Ubuntu但必须说清楚边界。如果你这个项目主要跑PLC通信、Modbus、大量底层GPIO控制或者依赖wiringPi这类老牌库树莓派OS会更省心。官方源的库更全内核和固件匹配度更高一些底层的DMA接口在Ubuntu下可能需要折腾。我的最终划分是以视觉检测和Python生态为核心的项目无脑选Ubuntu以电子控制、传感器采集为核心的项目留在树莓派OS。两者没有高下之分只是侧重点不一样。4. 把自训YOLOv5模型搬进树莓派5导出、转换、部署4.1 模型导出从PyTorch到ONNX在PC上用YOLOv5训练好的模型是best.pt格式是PyTorch权重。直接放到树莓派上跑PyTorch也可以但内存占用高、速度慢。我实际测试时PyTorch跑640×640输入大概只有5 FPS树莓派5的4GB/8GB内存版本都会有些吃紧。更合理的路线是先导出ONNX然后用推理框架加载。YOLOv5自带导出脚本关键参数如下python export.py --weights best.pt --img 320 --batch 1 --include onnx --opset 12 --simplify这里我把输入尺寸从默认的640改成了320后面会细说原因。opset指定为12兼容性和算子支持比较稳。加上--simplify做图优化能去掉一些冗余算子。导出完成后在树莓派上安装ONNX Runtimepip install onnxruntime注意树莓派5是arm64架构pip会自动安装对应架构的wheel不用自己编译。4.2 ONNX Runtime与NCNN的实测对比为了找到最合适在树莓派5上跑的方式我把PyTorch、ONNX Runtime和NCNN都试了一遍。结果整理成表格推理方案输入尺寸实测帧率内存占用备注PyTorch FP32640×640约5 FPS较高部署简单性能最低ONNX Runtime640×640约8 FPS中等导出后直用最省事NCNN CPU640×640约10-11 FPS较低需要额外转换步骤ONNX Runtime320×320约16-18 FPS中等检测精度需验证数据来源是我自己的8GB树莓派5实测散热状态良好时测得供参考。不同模型、不同温度环境下会有浮动。ONNX Runtime的优点是省心导出即用NCNN速度确实更快但需要把ONNX再转成NCNN格式onnx2ncnn best.onnx best.param best.bin转换过程会提示一些不支持的算子但YOLOv5比较友好基本都能转。NCNN的CPU推理在ARM架构上有针对性的优化内存也小特别适合嵌入式。4.3 推理脚本与输入尺寸的取舍不管用哪个框架推理脚本的核心逻辑都一样图像预处理时做letterbox缩放保持宽高比并填充到指定尺寸推理后对输出做NMS非极大值抑制过滤重复框。我以ONNX Runtime为例贴一个最小可运行的推理骨架import cv2 import numpy as np import onnxruntime as ort session ort.InferenceSession(best.onnx, providers[CPUExecutionProvider]) input_name session.get_inputs()[0].name input_shape session.get_inputs()[0].shape # [1,3,320,320] 或 [1,3,640,640] def letterbox(img, size320): h, w img.shape[:2] scale min(size / w, size / h) nw, nh int(w * scale), int(h * scale) resized cv2.resize(img, (nw, nh)) canvas np.full((size, size, 3), 114, dtypenp.uint8) canvas[(size - nh) // 2:(size - nh) // 2 nh, (size - nw) // 2:(size - nw) // 2 nw] resized return canvas frame cv2.imread(test.jpg) inp letterbox(frame, 320).transpose(2, 0, 1)[None].astype(np.float32) / 255.0 output session.run(None, {input_name: inp})[0] # 后处理根据模型输出格式做NMS输入尺寸的选择是这个环节最重要的取舍。640×640和320×320帧率相差一倍多。如果检测目标在画面中占比较大、不需要太高的分辨率320完全够用。我做了几百张测试图对比漏检率只上升了一个百分点左右但帧率从8FPS提升到16FPS以上对实时性要求高的场景非常关键。至于FP16量化或者INT8量化我在这个项目上没有一上来就做。FP16在树莓派5的CPU上不一定有加速效果反而可能在部分算子引入精度损失INT8需要准备校准数据集且YOLOv5这类检测模型量化后的精度抖动比较大不是首版就该碰的东西。5. 没有显示器的车间远程运维与网络排障5.1 配网与第一次无头启动车间设备柜旁边没有显示器我也没有给树莓派5配屏幕。无头部署的关键是第一次启动就能拿到设备地址。用Raspberry Pi Imager烧录时在设置界面直接预填Wi-Fi的SSID和密码开启SSH服务设置好用户名和密码。Ubuntu的镜像预装的是cloud-init机制同样可以在烧录时注入用户数据和网络配置。如果是树莓派OS传统方法是烧录完成后在boot分区放一个名为ssh的空文件再放一个userconf.txt文件来设置默认用户密码。Ubuntu镜像支持更完整的user-data可以把时区、升级策略、SSH公钥都写进去。5.2 Wi-Fi不稳的排查链路第一次部署用的是Wi-Fi连接结果问题不断。典型症状SSH刚连上没问题过十几分钟就断必须重启网络服务才能恢复。排查过程是这样的先看无线网卡的省电模式iwconfig wlan0输出里如果看到Power Management: on那基本可以确定是罪魁祸首之一。Wi-Fi省电模式在有数据流量时会频繁切换收发状态树莓派和很多家用路由器配合不好表现就是间歇性断连。关闭它sudo iw dev wlan0 set power_save off同时检查路由器设置。车间里那台民用路由器2.4GHz频段干扰非常严重周围还有蓝牙、微波炉、各种工控设备。我直接把板子切到5GHz频段断连问题明显减少。但说实话Wi-Fi在车间里终归不是长久之计。金属机柜对无线信号衰减很厉害门一关信号直接掉一半。最终我把树莓派5的Wi-Fi当作调试通道主要的网络路径换成了有线网线。树莓派5自带千兆以太网口稳定性和带宽都远好于无线。5.3 PoE供电与远程管理的组合方案这里必须提一下树莓派5的PoE HAT。官方出了支持802.3af的PoE HAT通过一根网线同时实现供电和网络对车间部署来说简直是量身定做的方案。一根网线既解决了我前面说的供电不稳问题——PoE供电模块有标准的电压输出和过流保护不像变压器直接插墙上那样受电网波动影响——又解决了网络稳定问题。配一台PoE交换机板子接线非常简单。远程管理配置方面几个细节值得记下来给设备分配固定IP在路由器里做DHCP保留避免IP变化导致运维找不到设备。启用SSH密钥登录同时禁止密码登录车间环境虽然相对封闭但安全习惯不能省。电脑上浏览器的web终端、代码仓库的自动部署钩子都可以配合使用。我自己的流程是本地git推送代码板子上通过systemd服务定时拉取更新并重启进程基本不用摸到设备本体。还有一个兜底方案树莓派5的GPIO串口可以接USB转串口模块万一网络彻底断了通过串口还是能进系统排查。6. 突然断电和SD卡损坏可靠性问题的最后一道坎6.1 SD卡为何成为软肋第六个坑也是车间项目最容易翻车的地方——异常断电。车间里设备启停频繁总开关被拉闸的情况时有发生。树莓派5用SD卡启动时一次突然断电就可能让文件系统损坏症状是重启后系统进不去或者在启动过程中挂载分区失败SD卡变成只读。SD卡本身的硬件特性决定它对掉电很敏感。控制器内部的FTL映射表和缓存没有完整的掉电保护写操作正在执行时断电轻则数据丢失重则整个分区表损坏。在工位上你可能一年都遇不到一次异常断电在车间里可能是每周一次。6.2 NVMe SSD 只读挂载的组合我用两步把这个问题的风险降到最低。第一步把系统从SD卡迁移到NVMe SSD。树莓派5正式支持NVMe启动通过PCIe接口接一块M.2 HAT和NVMe固态盘系统镜像写入SSD从SSD引导。SSD同样依赖缓存的写入理论上也会损坏但有断电保护机制的固态盘比SD卡可靠得多。实测同样异常断电十次的情况下SD卡出现文件系统错误的概率远高于NVMe盘。需要注意的是NVMe SSD的功耗比SD卡高供电方案必须同步升级。我用的5V/5A工业电源完全能带起来但没有冗余余量的电源方案在接入SSD后容易踩第1章的坑。第二步软件层面把写入降到最低。针对只读挂载需求把一些频繁写入的目录放到内存比如日志sudo systemctl edit systemd-journald配置Storagevolatile后系统日志只写入内存tmpfs减少SSD的写擦除次数。还有Python运行时的字节码缓存文件在systemd服务环境里设PYTHONDONTWRITEBYTECODE1也能减少垃圾写入。外置根文件系统如果觉得必要还可以用overlay模式把系统分区做成只读把可写层放在内存或另一个分区。这个配置稍微复杂一些适合要求系统长期运行不产生任何写操作的场景。6.3 开机自启与硬件看门狗系统稳定之后还要保证程序本身可靠运行。我用systemd把YOLOv5推理程序做成服务配置开机自启程序崩溃自动重启[Unit] DescriptionYOLOv5 Detector Afternetwork-online.target Wantsnetwork-online.target [Service] Userubuntu WorkingDirectory/home/ubuntu/deploy ExecStart/home/ubuntu/deploy/venv/bin/python /home/ubuntu/deploy/run.py Restartalways RestartSec5 EnvironmentPYTHONDONTWRITEBYTECODE1 [Install] WantedBymulti-user.target写成/etc/systemd/system/ai-detector.service后sudo systemctl daemon-reload sudo systemctl enable ai-detector sudo systemctl start ai-detector这里加了Afternetwork-online.target确保网络就绪后再启动程序避免程序起来后因为依赖的MQTT或数据库连接失败退出。硬件看门狗也不可少。树莓派5有硬件看门狗模块启用后如果系统或者核心进程卡死看门狗会自动重启板子。在Ubuntu下启用systemd的看门狗sudo sed -i s/#RuntimeWatchdogSec0/RuntimeWatchdogSec10/ /etc/systemd/system.conf重启后执行wdctl可以看到/dev/watchdog设备。有了硬件看门狗遇到程序死循环、内存泄漏这类故障系统会在10秒内自动复位不用人工去车间重启设备。这一套组合跑下来我的设备在车间连续运行了几个月没有再因为掉电和SD卡问题返工。回想整个过程六件事没有一件是“高深技术”全是基础环境问题。但恰恰是这些基础问题决定了一个开发板项目能不能真正在车间里站住脚。每次有人问我树莓派5能不能上产线我都会说能前提是你把供电、散热、系统、存储和自恢复这五件事先想清楚第六件事才是把模型跑起来。