
车间里做视觉检测传统方案是工控机加大功率电源占地方又娇贵。我一直想试试用树莓派 5 这种板卡把推理放到产线边缘省掉视频流绕一圈的延迟。树莓派 5 发布后性能数字确实漂亮四核 A76、主频 2.4GHz、支持 PCIe跑个自己训练的 YOLOv5 模型理论上完全够用。但真正从调试台搬进车间我前后卡了将近半个月问题一个接一个供电、系统、依赖编译、散热、摄像头、掉电恢复每一个都是看着不起眼、实测让人抓狂的坑。这篇文章就把这六件事完整记录下来给打算把树莓派 5 放进工业现场的朋友做参考。全文基于我的实际踩坑经历部分方案是我最终采用的通用做法可以直接抄作业。1. 供电问题暴露得最早也最让人意外1.1 树莓派 5 的胃口和老一代完全不同树莓派 4 时代我习惯用一个 5V/3A 的普通电源就把它喂饱最多在负载高的时候看一眼电压警告。但树莓派 5 不一样官方明确要求 5V/5A也就是 25W 的供电能力。刚开始我没当回事觉得峰值电流只是理论值结果用旧电源一接画面直接出现雷电符号警告系统日志里刷满了 under-voltage 记录推理时 CPU 频率从 2.4GHz 掉到 1.2GHzYOLOv5 的推理帧率直接腰斩。这背后的原因不复杂树莓派 5 的 SoC 在满载时瞬时电流可以拉到 4A 以上加上外接 USB 设备、摄像头、风扇的电流总需求轻松超过 20W。而车间里常用的开关电源虽然标称电流够大但纹波和瞬态响应远不如专用电源USB-C 线材如果细一点、长一点后端电压很容易落到 4.8V 以下。树莓派的电源管理芯片检测到电压过低不会断电而是强制降频保护。1.2 我给车间环境做的供电改造最终方案分两层第一层换用官方原装 27W 电源或同等质量的 5V/5A 适配器线材控制在 1 米以内避免长线压降。第二层加了一块 5V 输出的工业级 DC-DC 稳压模块输入接产线上的 24V 直流电输出稳定在 5.1V、最大 6A。为什么不用开关电源直连因为产线上的 24V 本身就有波动电机启停瞬间电压跌得厉害只有稳压模块能兜住这种瞬时变化。实测下来这块稳压模块让树莓派 5 在满载推理时电压始终稳定在 5.0V 以上24 小时运行没有再出现降频。另外一个小细节树莓派 5 的 USB-C 接口支持 PD 协议但我不建议在车间里用 PD 诱骗线因为非标准 PD 线材和电源的组合很容易握手失败出现“明明插着电但系统不识别充电器”的怪问题到时候排查更费劲。提示判断电源是否足够不要只看系统右上角有没有雷电图标。在终端执行vcgencmd get_throttled返回值是十六进制掩码bit0 和 bit1 分别表示出现了欠压和欠压恢复。这个命令能在无头环境下精确判断供电问题比看图标可靠得多。2. 在树莓派 5 上装 Ubuntu路线选对了能省一半时间2.1 为什么不用 Raspberry Pi OSRaspberry Pi OS 当然能用但跑 YOLOv5 推理时我遇到一个绕不过去的问题系统自带的 Python 是系统版本依赖管理一多就乱而且 libcamera 栈和 OpenCV 之间的兼容性在 Debian 系上时不时抽风。我做视觉推理需要干净的 Python 环境和可预测的包管理行为所以一开始就决定上 Ubuntu Server 24.04 LTS。不过这里有个 2024 年上半年容易踩的坑树莓派 5 刚发布时树莓派官方镜像里是没有 Ubuntu 的要等 Ubuntu 官方镜像适配或者先用 Raspberry Pi OS 再手动迁移。如果你拿到板卡的时间比较早最稳妥的做法是去 Ubuntu 官网下载针对树莓派 5 的预装镜像不要用通用 ARM64 镜像硬刷那些镜像缺内核和固件启动到一半会卡死在彩虹屏。2.2 最小化安装的关键步骤我采用的标准安装流程是用 Raspberry Pi Imager 把 Ubuntu Server 24.04 镜像写入 64GB 工业级 TF 卡第一次启动前直接插入 HDMI 显示器和键鼠完成设置配置静态 IP 和 SSH 后再搬到车间。为什么不在车间里做首启配置因为首启要写大量配置、可能要下载更新包车间里网络环境不一定给力而且无头模式下出问题还得来回插显示器非常耽误事。装完系统后我做的第一件事是禁用 snap 的自动更新这是 Ubuntu Server 上一个容易忽略的坑。snapd 会偷偷在后台刷新说不好什么时候碰上一个新版导致 Python 相关的运行时被替换你的推理程序半夜重启后就在奇怪的地方报错。我直接停掉了 snapd 服务把它标记为 hold 状态。车间环境里稳定的版本比最新特性重要得多。2.3 内核升级引发的兼容性回退还有一次差点把我劝退系统装好第二天我执行apt upgrade升级内核重启后发现 GPU 驱动和 V4L2 摄像头节点全部失效ls /dev/video0直接报不存在。查了半天才发现是 Ubuntu 的 HWE 内核和树莓派 5 的固件版本不匹配。解决办法是回退到初始内核版本并把linux-generic-hwe-24.04这类包设置成不要自动升级。教训就一句话树莓派 5 的固件和内核是绑着走的Ubuntu 这边不像树莓派官方系统那样深度适配升级前务必确认固件兼容性否则系统能启动但外设全哑。3. YOLOv5 部署编译依赖和模型加载的两道坎3.1 ARM64 上的依赖轮子没有想象中全把训练好的 YOLOv5 模型搬到树莓派 5听起来只是 pip install 一把梭实际操作起来ARM64 架构的坑立刻出现。PyTorch 官方对 aarch64 有预编译轮子直接pip install torch torchvision没问题但很多配套库没有 ARM64 版本opencv-python 官方有 aarch64 的 manylinux 轮子能装上但编译时默认不带 GPU 加速这倒无所谓反正是 CPU 推理。真正麻烦的是 YOLOv5 的某些组件比如用 torch.hub 加载模型时会去克隆 GitHub 仓库车间网络不稳定就拉取失败。我把仓库下载好之后放在本地然后torch.hub.set_dir(/opt/yolov5-hub)指向本地缓存彻底规避了联网问题。还有 NMS 这类用 C/CUDA 写的扩展在纯 CPU 环境下 npms 是纯 Python 实现速度会慢一点但能跑。如果你用的 YOLOv5 版本比较老依赖pycocotools这个库在 ARM64 上经常需要从源码编译编译前记得先装gcc和python3-dev。注意YOLOv5 作者会定期发新 tagv6.0 和 v7.0 的模型结构差异不小。你在训练时用的什么版本部署端就要严格使用同一 tag 的源码否则加载权重时会出现Missing key(s) in state_dict的报错。我一开始没注意训练环境里的 YOLOv5 是 v6.1树莓派上装的是最新的 master 分支结果模型能加载但输出结果误差极大排查了半天才发现是版本结构不匹配。这个问题极其隐蔽建议你在训练完导出权重时就把训练环境的requirements.txt和 git 版本号一并记录下来部署时对照还原。3.2 推理性能的完整实测数据部署完成后很多资料会说树莓派 5 能把 YOLOv5s 跑到 10FPS 以上但我在车间环境下的实测没那么乐观。我这里给一份真实数据用的是 640x640 输入、自己训练的 YOLOv5s 模型、纯 CPU 推理、树莓派 5 主动散热片推理方式单帧耗时换算FPS备注纯 PyTorch 推理210ms约 4.8最省事但帧率偏低PyTorch bfloat16180ms约 5.6树莓派 5 支持 bf16但提升有限ONNX Runtime CPU all146ms约 6.8模型导出为 ONNX用 ort 推理ONNX Runtime NNAPI无法启用无法启用树莓派 5 没有 NNAPI 可用这说明一个很关键的问题树莓派 5 的 CPU 性能虽然强但 640 输入的 YOLOv5s 也就稳定在 5-7FPS如果产线上的目标是 15FPS 以上的实时检测必须考虑模型量化或改小输入尺寸或者换边缘 NPU 设备。YOLOv5s 在 320 输入下推理耗时能降到大约 60ms帧率可以到 16FPS但小目标检测率会明显下降。车间场景里如果检测的是大件瑕疵320 输入勉强能用如果是小瑕疵我建议你还是接受 7FPS 的底线或者把运算挪到边上。3.3 自训练模型的类名映射问题一个容易被忽视的细节用自己的数据训练的 YOLOv5 模型部署端要把类名列表写对。我训练的模型有 5 个类别划痕、凹坑、毛刺、异物、正常部署代码里如果只用model.names在 torch.hub 模式下没问题但导出成 ONNX 后用 onnxruntime 推理需要自己维护类的顺序和索引。ONNX 模型只输出检测框的 class index你得把索引映射到正确的名称否则检测结果对不上——字段顺序一旦错了画面里明明是一个凹坑程序输出却是划痕这个错误在调试端几乎不可能发现。4. 性能压榨与散热平衡热降频是隐性杀手4.1 温度墙是怎么让推理变慢的树莓派 5 的 SoC 在被动散热片状态下满载跑 YOLOv5 推理大约 3 分钟温度就冲到 85°C一旦超过 80°C系统就会触发降频保护。我实测过降频后的推理速度从 210ms 一帧涨到 300ms 甚至更多而且温度越高、降频越积极整个推理过程变得极其不稳定。最坑的是这种性能劣化不会在日志里报错你只会看到 FPS 曲线往下掉还以为是自己代码写的问题。这其实是一个热设计问题树莓派 5 的功耗相比 4 代提升了接近一倍但板卡本身的散热设计依然是高档嵌入式单板的标准不主动散热就是不行。在车间这种环境里环境温度可能比办公室高 5-10°C再加上设备柜体密封、周围有发热机器热问题会被进一步放大。4.2 我采用的散热组合方案最终我选了主动散热风扇加铝制散热片的组合。风扇是 5V 的 PWM 温控风扇接在 GPIO 上通过cooling_cpu或pwm_config控制转速。系统温度低于 60°C 时风扇低速运转超过 70°C 时全速。散热片用了带鳍片的铝散热片而不是普通的铜片因为铜的比热容小瞬时能拉住温度但持续高负载下铝鳍片的散热面积优势更明显。装好之后实测环境温度约 28°C 的环境下满载推理 30 分钟温度稳定在 66°C 左右没有再触发降频推理速度保持在稳定水平。这里有一个关键点散热片和 SoC 之间的导热介质一定要用导热硅脂或高质量的导热垫片别用硅胶垫。硅胶垫虽然方便但导热系数低SoC 的热量根本没传出来这是在车间反复测试后得的教训。另外风扇要选带轴承的静音扇不要图便宜买含油轴承的。车间粉尘大含油轴承风扇一两个月就会咔咔响甚至停转而风扇一旦停转散热能力瞬间下降热降频立刻回来。防尘设计也尽量加一层细目防尘网在进风口我后来的设备柜体里加了一片冰箱用的防尘网粉尘确实少了很多。4.3 推理侧的替代优化思路散热解决后FPS 还是不够用的话可以考虑把 YOLOv5 换成 ncnn 或者 TensorRT 编译版本。ncnn 是腾讯开源的神经网络推理框架ARM CPU 上有比较成熟的优化YOLOv5 的 ncnn 移植方法在项目里直接有 Python 封装实测速度比 ONNX Runtime 还能再快 15%-20% 左右。不过需要修改模型导出格式从 .pt 转成 .param 和 .bin调试成本也不小而且要注意 ncnn 对 YOLOv5 的某些层比如 Focus 层需要手动修改网络结构。这个优化做不做取决于产线对帧率的要求是不是真的紧。5. 摄像头接入的三条路CSI、USB 与 RTSP 的兼容性折腾5.1 CSI 摄像头的接口变化与排线陷阱树莓派 5 的摄像头接口从两个变成了两个 CSI 口但官方 Camera Module 3 的排线方向和老款不一样插反了会物理损坏接口。我第一次接树莓派官方 Camera Module 3 时没注意排线 goldfinger 的朝向插进去之后libcamera-hello完全识别不到设备折腾了半小时才发现是排线方向反了。另外树莓派 5 的两个 CSI 口分别对应不同的通道如果接了多个摄像头要记得通过libcamera配置不同的-n编号。在车间环境下CSI 排线本身就是个不稳定因素长距离走线阻抗大振动环境下容易松动。我只在实验室调试时用了 CSI 摄像头放进车间时换成了 USB 工业摄像头就是考虑到排线可靠性的问题。如果你也想用 CSI一定要加排线固定座最好用带锁扣的排线。5.2 USB 工业摄像头在推理负载下的丢帧问题产线上常用的国产工业 USB 摄像头在树莓派 5 上接入后第一个问题是 USB 3.0 端口供电不足。USB 摄像头初始画面一卡一卡日志里出现大量Failed to queue buffer的提示。根因是树莓派 5 的 USB 口总电流有限摄像头加上风扇、无线网卡等外设后电流还是紧张。解决办法是给摄像头单独供电用带外置供电的 USB Hub 接摄像头另一路接树莓派。丢帧问题还有一个隐藏变量GStreamer 管道和 OpenCV 直接读摄像头的优先级不同。我一开始用cv2.VideoCapture(0)直接读 USB 摄像头CPU 占用高帧率不稳定而且丢帧后 OpenCV 会自动跳帧导致追踪逻辑完全错乱。后来我改用 GStreamer 管道底层调用 V4L2做了一个缓冲队列再喂给 YOLOv5帧率和稳定性明显改善。代码大致是这样import cv2 PIPELINE ( v4l2src device/dev/video0 ! video/x-raw,width640,height480,framerate30/1 ! videoconvert ! appsink drop1 ) cap cv2.VideoCapture(PIPELINE, cv2.CAP_GSTREAMER) while True: ret, frame cap.read() if not ret: continue # 送入你自己的 infer 函数 results infer(frame)这个管道开启了drop1也就是允许在推理赶不上采集速度时丢弃旧帧保证始终处理的是最新画面在产线检测场景下比排队等帧要合理得多。5.3 RTSP 工业相机的接入延迟和断流如果是用产线现成的 RTSP 网络相机海康或大华接入简单但有两个坑。第一是延迟RTSP 从相机到树莓派经过网络编解码多一层 100-300ms 不等的延迟如果检测结果要触发剔除动作这个延迟可能影响判断。第二是断流车间网络如果和办公网共用广播风暴或带宽占满时 RTSP 流会断OpenCV 的cap.read()会在断流后持续返回空帧得写重连逻辑。我的做法是把 RTSP 的tcp传输设为优先并将网络单独划分 VLAN 隔离确保相机和树莓派之间是独占链路。重连逻辑也必须在主循环里加超时判断否则设备在无人值守时卡在空帧状态都不知道。6. 无头运行的稳定性设计让设备在车间自己活下去6.1 断电恢复与时间同步问题车间里最考验设备的就是断电。树莓派本身没有 RTC实时时钟断电后重启系统时间是错的日志记录的时间轴完全错乱还会导致 HTTPS 请求失败、证书验证不通过。树莓派 5 新增了一个 RTC 电池接口可以把 CR2032 纽扣电池接上去时间在断电后依然能维持。但还有一层更简单可靠的方案在/etc/systemd/timesyncd里配置车间局域网内的 NTP 服务器让树莓派开机后第一时间同步时间。如果 RTC 电池没备好至少保证逻辑层的时间正确。断电恢复还有一层程序必须在开机后没有人为干预的情况下自动运行。我用 systemd 服务做了自启动服务单元文件里写清楚启动顺序、用户、环境变量和依赖关系同时刻定了Restartalways和RestartSec3s。但要注意如果程序启动时依赖摄像头或网络而这些设备在开机后需要 5-10 秒才能 ready服务就要设置Afternetwork-online.target和Wantsnetwork-online.target否则程序起得太早把自己跑挂了白白增加重启次数。6.2 进程守护与看门狗防止推理程序悄然崩溃光靠 systemd 还不够。树莓派上跑 YOLOv5 推理如果模型输入异常或摄像头断流Python 进程会抛异常直接退出systemd 会原地重启但如果在重启间隙有瑕疵品流过产线就是漏检事故。我后来写了一个轻量级的守护脚本把推理逻辑封装成线程主线程监控心跳推理线程每处理完一帧就把一个全局时间戳更新为当前时间。守护线程每隔 3 秒检查时间戳如果发现 15 秒内没有更新就判定推理线程卡死直接调用os._exit(1)让 systemd 重启整个服务。每次重启前把最近的日志和帧结果写入独立目录方便事后排查。这套方案虽然土但在无人值守场景里非常稳。比复杂的内置看门狗更直观也更容易调试。硬件级别还可以用树莓派 5 的硬件看门狗需要手动加载bcm2835_wdt模块配置/etc/systemd/system.conf里的RuntimeWatchdogSec开机启用后内核级看门狗会在系统长时间无响应时强制重启对解决内核死机、驱动卡死这类硬问题更有效。6.3 存储保护与日志轮转防止 TF 卡在车间早逝最后一个容易被低估的问题是存储。TF 卡在持续写入场景下寿命很短尤其是推理程序如果每分钟都写日志和画面TF 卡的写入放大效应会很严重。我的做法有两层第一层是把日志目录和推理缓存目录挂到内存盘tmpfs里树莓派给 tmpfs 默认大小有限我用fstab额外挂载一个 256MB 的 tmpfs 到/var/log/custom日志定期同步到远程服务器不在本地落盘。第二层是关掉不必要的系统日志比如 journald 默认会把所有内核日志写盘我把Storagevolatile改成只在内存保留 24 小时减少持续写入。TF 卡的选择也重要普通消费级 TF 卡在连续写入场景下几个月就可能掉速、坏块。工业级或者高耐久 TF 卡贵一点但和产线停机成本相比这点钱完全不值一提。还有一点尽量不要在树莓派运行时直接拔电哪怕有断电恢复频繁的突然断电也会让 TF 卡文件系统损坏的概率显著上升有条件就接上前面说的 24V 转 5V 稳压模块配合产线的 UPS 一起用。真到这一步设备才算是能在车间里自己活下去。7. 实际体会到的一些补充上面六件事是落地过程中最想写下来的部分。如果让我总结一句经验那就是树莓派 5 的运算能力确实能满足边缘视觉检测的基本需求但它不是工业级设备把消费级板卡放进车间本质上是在做系统工程供电、散热、存储、自动恢复这些环节任何一个没有兜底都会变成产线上的不确定性。我最后再做一次复盘有几个细节供你参考先选好摄像头的类型接入方向再定软件框架。我一开始先写检测算法后面才考虑摄像头通道结果算法调好了摄像头兼容性的坑反而耽误更多时间。散热测试要在环境温度接近车间真实环境的条件下做办公室空调房测出来的温度曲线参考意义不大。不要在部署当天直接上线先空跑 72 小时把断电、断网、摄像头断流这几种故障场景都模拟一遍确认自动恢复机制真正生效再连到产线主流程上。这个方案目前在我们的产线上已经连续运行了一个多月除了有一次风扇轴承异响被巡检发现更换没有再出过大的幺蛾子。后面我还想尝试用 ncnn 替换 ONNX Runtime 把推理帧率再往上拉一拉顺便把树莓派 5 的 PCIe 接口利用起来外接一张便宜的 neural compute 卡试试如果成功我会再来更新这篇经验。