
1. 从一块开发板说起为什么我最终选了 BeagleY-AI第一次拿到 BeagleY-AI 的时候我其实没抱太大期望。市面上能跑 AI 推理的开发板太多了从树莓派加加速棒到各种国产 SoC 方案选择多到让人麻木。但真正上手用了一段时间之后我发现这块板子的定位非常清晰——它不是那种什么都能做但什么都做不精的通用板而是在 AI 推理、Python 开发和硬件扩展这三个方向上做了明确的取舍和优化。BeagleY-AI 的核心是一颗集成了 AI 加速单元的处理器配合足够大的内存和丰富的接口让它能在不依赖云端的情况下完成图像分类、目标检测、语音识别等常见推理任务。对于做嵌入式 AI 项目的开发者来说这意味着你可以把模型直接部署在设备端不用担心网络延迟、数据隐私和持续的网络成本。我写这个系列的目的很简单把我从开箱到跑通第一个 AI 项目、再到接入传感器和外围硬件的完整过程记录下来。市面上很多教程要么只讲软件不讲硬件要么只给代码不讲原理中间踩坑的部分全靠自己摸索。我会尽量把每一步的为什么讲清楚让你不仅知道怎么操作还知道为什么这么做。这篇文章适合几类人一是刚接触嵌入式 AI 的开发者想找一块门槛不高但功能够用的板子入门二是有 Python 基础但没怎么碰过硬件的软件工程师想拓展一下技能边界三是做过一些单片机项目但想往 AI 方向靠的硬件爱好者。不管你属于哪一类只要跟着走一遍应该都能在自己的 BeagleY-AI 上跑出结果。2. 开箱之后别急着上电硬件接口与系统准备的几个关键决策2.1 板载接口的布局逻辑与供电方案选择BeagleY-AI 的接口布局乍一看和常见的单板计算机差不多但仔细看会发现一些针对 AI 和硬件项目的专门设计。板子一侧是标准的 40 针 GPIO 排针兼容常见的传感器和执行器模块另一侧是 USB 接口、以太网口和显示输出。特别值得注意的是它单独引出的 CSI 摄像头接口和 DSI 显示接口这两个接口在 AI 视觉项目里非常关键。供电方面官方推荐使用 5V/3A 的 USB-C 电源。我实测下来如果你只是跑一些轻量级的推理任务5V/2.5A 也能凑合但一旦接上摄像头、显示屏或者多个传感器供电不足的问题就会暴露出来——表现为系统随机重启或者 USB 设备频繁掉线。这不是板子的问题而是电源功率不够导致的电压跌落。所以我的建议是一步到位直接上一个质量靠谱的 5V/3A 电源省得后面排查半天才发现是供电的锅。注意不要用那种十几块钱的廉价电源空载电压可能标称 5V但带载后跌到 4.6V 以下AI 推理时处理器满载运行电流波动很大劣质电源根本扛不住。散热也是容易被忽略的一点。BeagleY-AI 在跑推理任务时处理器温度会明显上升。我建议至少贴一个铝制散热片如果要做持续推理或者放在封闭外壳里最好加一个小风扇。温度过高时处理器会降频推理速度直接打对折这个体验落差非常明显。2.2 系统镜像的选择与烧录别在第一步浪费时间BeagleY-AI 支持从 microSD 卡启动官方提供了基于 Debian 的系统镜像。下载镜像的时候要注意选择对应版本别下成其他板子的镜像了——虽然名字很像但设备树和驱动完全不同烧进去也起不来。烧录工具我用的是 balenaEtcher跨平台操作简单选镜像、选卡、点烧录三步搞定。烧录完成后把卡插回板子接上电源和网线等待系统启动。第一次启动会比较慢因为系统要做一些初始化配置耐心等两三分钟。这里有个小技巧如果你没有显示器可以通过串口或者 SSH 来访问。串口连接需要一根 USB 转 TTL 的线接到板子对应的调试串口引脚上波特率一般是 115200。SSH 的话需要你先知道板子的 IP 地址可以通过路由器的管理界面查看或者用网络扫描工具找一下。提示第一次启动后尽快修改默认密码并配置好 SSH 密钥登录后面用起来会方便很多。系统起来之后第一件事是更新软件源和已安装的包。这一步在国内网络环境下可能需要换源否则下载速度会很慢。换源的方法和普通 Debian 系统一样修改/etc/apt/sources.list文件把官方源替换成国内镜像源即可。换完之后执行sudo apt update sudo apt upgrade把系统更新到最新状态。2.3 Python 环境的隔离为什么我不建议直接用系统 Python系统自带的 Python 版本通常比较旧而且直接在上面装包容易和系统工具产生依赖冲突。我的习惯是用虚拟环境来管理项目依赖这样每个项目有自己独立的包目录互不干扰。创建虚拟环境的命令很简单sudo apt install python3-venv python3-pip python3 -m venv ~/projects/beagley-ai/venv source ~/projects/beagley-ai/venv/bin/activate激活虚拟环境后命令行提示符前面会出现(venv)标识这时候用 pip 安装的包都会装在这个虚拟环境里。退出虚拟环境用deactivate命令。对于 AI 项目来说常用的 Python 包包括 NumPy、OpenCV、Pillow 等。如果你要用到深度学习框架可能还需要安装 ONNX Runtime 或者 TFLite Runtime 的 ARM 版本。这些包在 pip 上都有预编译的 aarch64 版本直接 pip 安装即可不需要自己编译。注意有些包在 ARM 平台上的预编译版本可能不是最新的如果遇到兼容性问题可以尝试指定版本号安装或者从源码编译。源码编译比较耗时建议优先找预编译版本。3. 让板子看见摄像头接入与图像采集的完整链路3.1 CSI 摄像头与 USB 摄像头的取舍BeagleY-AI 支持两种摄像头接入方式CSI 排线接口和 USB 接口。这两种方式各有优劣选择哪种取决于你的具体需求。CSI 摄像头直接连接到处理器的图像处理单元延迟低、带宽高适合需要高帧率或者高分辨率的场景。但 CSI 摄像头的兼容性是个问题不是所有 CSI 摄像头都能直接用需要驱动支持。官方推荐的摄像头模块兼容性最好但价格通常比通用的 USB 摄像头贵一些。USB 摄像头即插即用兼容性好随便一个 UVC 协议的摄像头插上就能用。但 USB 总线的带宽有限高分辨率下帧率会受限而且会占用一个 USB 接口。如果你只是做简单的图像分类或者二维码识别USB 摄像头完全够用。我自己的方案是调试阶段用 USB 摄像头快速验证代码逻辑正式部署时换成 CSI 摄像头获得更好的性能和更整洁的接线。3.2 用 OpenCV 采集图像并验证摄像头工作状态不管用哪种摄像头第一步都是确认系统能识别到设备。对于 USB 摄像头插入后执行ls /dev/video*如果看到/dev/video0之类的设备节点说明系统已经识别到了。对于 CSI 摄像头可能需要加载对应的驱动模块具体操作参考官方文档。确认设备存在后用 OpenCV 写一个最简单的采集程序来验证import cv2 cap cv2.VideoCapture(0) if not cap.isOpened(): print(摄像头打开失败) exit() ret, frame cap.read() if ret: cv2.imwrite(test_frame.jpg, frame) print(f采集成功图像尺寸{frame.shape}) else: print(帧采集失败) cap.release()这段代码做了三件事打开摄像头、读取一帧图像、保存为文件。如果运行后能看到test_frame.jpg文件并且图像内容正常说明摄像头链路是通的。提示如果cv2.VideoCapture(0)打不开可以试试换成cv2.VideoCapture(0, cv2.CAP_V4L2)显式指定使用 V4L2 后端。在 Linux 系统上V4L2 是标准的摄像头接口兼容性最好。采集到图像之后你可以用 OpenCV 做各种预处理缩放、裁剪、颜色空间转换、滤波去噪等等。这些操作在 AI 推理之前通常是必要的因为模型对输入图像的尺寸和格式有特定要求。3.3 图像预处理中的常见坑与性能优化图像预处理看起来简单但实际做项目时很容易在这里翻车。我踩过的几个坑值得说一下。第一个坑是颜色空间搞混。OpenCV 默认用 BGR 顺序读取图像但很多 AI 模型期望的是 RGB 顺序。如果你直接把 OpenCV 读到的图像喂给模型颜色会偏得离谱推理结果自然也不对。解决办法是在预处理阶段做一次cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)转换。第二个坑是归一化参数不一致。不同的模型在训练时用的归一化方式可能不同有的是除以 255有的是减均值除标准差。如果你不确定模型期望的输入格式最稳妥的办法是查模型的文档或者看训练代码。用错了归一化参数模型精度会大幅下降。第三个坑是预处理成了性能瓶颈。在嵌入式设备上CPU 性能有限如果预处理代码写得不够高效可能比模型推理本身还慢。我的经验是尽量用 OpenCV 的向量化操作避免 Python 层面的循环。比如缩放用cv2.resize颜色转换用cv2.cvtColor这些都是底层优化过的比手写循环快得多。如果预处理确实成了瓶颈可以考虑用硬件加速。BeagleY-AI 的处理器通常带有图像处理单元或者 GPU可以通过 OpenCL 或者专用 API 来加速图像操作。不过这部分的配置比较复杂建议先把基础流程跑通再考虑优化。4. 跑通第一个 AI 推理从模型选择到结果解读4.1 在嵌入式设备上选模型的三个原则在 BeagleY-AI 这种嵌入式设备上跑 AI 推理模型选择和在服务器上完全不同。服务器上你可以随便上一个几百兆的大模型推理慢一点无所谓。但在嵌入式设备上内存有限、算力有限模型选不好直接跑不起来。我的选型原则有三条。第一优先选轻量级网络。MobileNet、SqueezeNet、EfficientNet-Lite 这些专为移动端设计的网络参数量小、计算量低在嵌入式设备上跑起来比较流畅。第二优先选量化过的模型。FP32 模型占内存大、计算慢换成 INT8 量化模型后内存占用减少四分之三推理速度也能提升两三倍精度损失通常在可接受范围内。第三优先选有现成部署工具的模型。ONNX Runtime、TFLite、NCNN 这些推理框架都有各自的模型格式和转换工具选一个你熟悉的框架能省很多事。以图像分类为例我推荐从 MobileNetV2 开始。这个网络足够轻量在 BeagleY-AI 上跑单张图片推理大概几十毫秒精度也还不错。等跑通之后再尝试其他模型对比一下速度和精度的权衡。4.2 模型转换与部署ONNX 路线的实操步骤我选择 ONNX 作为模型部署的中间格式因为 ONNX 的生态比较完善从各种训练框架导出的模型都能转成 ONNX然后 ONNX Runtime 在 ARM 平台上的支持也比较好。假设你已经有一个训练好的 PyTorch 模型转换步骤如下import torch import torch.onnx # 加载模型并设置为推理模式 model MyModel() model.load_state_dict(torch.load(model.pth)) model.eval() # 构造一个示例输入 dummy_input torch.randn(1, 3, 224, 224) # 导出为 ONNX torch.onnx.export( model, dummy_input, model.onnx, input_names[input], output_names[output], dynamic_axes{input: {0: batch_size}, output: {0: batch_size}}, opset_version11 )导出之后可以用onnxruntime在 BeagleY-AI 上加载并推理import onnxruntime as ort import numpy as np session ort.InferenceSession(model.onnx) input_name session.get_inputs()[0].name # 构造输入数据 input_data np.random.randn(1, 3, 224, 224).astype(np.float32) # 推理 outputs session.run(None, {input_name: input_data}) print(outputs[0].shape)如果一切正常你会看到输出张量的形状比如(1, 1000)表示 1000 个类别的分类结果。注意ONNX Runtime 在 ARM 平台上默认使用 CPU 推理。如果你的模型比较大推理速度慢可以考虑用 ONNX Runtime 的 OpenVINO 或者 TensorRT 后端但 BeagleY-AI 上是否支持这些后端需要查一下文档。4.3 推理结果的解读与后处理模型输出的原始张量通常不能直接使用需要经过后处理才能得到人类可读的结果。以图像分类为例输出是一个长度为 1000 的向量每个元素对应一个类别的分数。你需要做的是对输出向量做 Softmax 归一化得到每个类别的概率。找出概率最高的几个类别。根据类别索引查标签文件得到类别名称。def softmax(x): exp_x np.exp(x - np.max(x)) return exp_x / exp_x.sum() probs softmax(outputs[0][0]) top5_idx np.argsort(probs)[-5:][::-1] for idx in top5_idx: print(f类别 {idx}: 概率 {probs[idx]:.4f})对于目标检测模型后处理会更复杂一些通常包括解码边界框、非极大值抑制等步骤。这些后处理逻辑在不同的模型之间差异很大建议直接参考模型作者提供的示例代码。后处理也是容易出问题的地方。我遇到过因为坐标缩放比例搞错导致检测框位置完全偏移的情况。排查这类问题的办法是可视化——把检测框画到原图上一眼就能看出对不对。5. 从推理到控制GPIO 与传感器接入的实战细节5.1 GPIO 操作的安全规范与 Python 库选择BeagleY-AI 的 40 针 GPIO 排针兼容常见的传感器模块这为硬件项目提供了很大的便利。但 GPIO 操作有几个必须遵守的安全规范否则可能烧毁引脚甚至整块板子。第一GPIO 引脚的工作电压通常是 3.3V不要直接接 5V 的信号。如果你用的传感器输出是 5V 电平需要加一个电平转换模块。第二每个引脚的输出电流有限制通常不超过 16mA驱动 LED 或者小继电器没问题但驱动电机必须用驱动模块。第三配置引脚功能之前先查清楚引脚定义别把电源引脚当成普通 IO 用了。Python 操作 GPIO 常用的库有gpiod和libgpiod的 Python 绑定。较新的系统推荐用gpiod因为旧的RPi.GPIO库主要是为树莓派设计的在其他板子上兼容性不好。import gpiod from gpiod.line import Direction, Value # 打开 GPIO 芯片 chip gpiod.Chip(/dev/gpiochip0) # 配置引脚为输出模式 line chip.get_line(17) line.request(consumerled, typegpiod.LINE_REQ_DIR_OUT) # 输出高电平 line.set_value(1)这段代码把 17 号引脚配置为输出并置高。实际操作时引脚编号需要根据板子的引脚定义来确定不同板子的编号方式可能不同。5.2 接入温湿度传感器I2C 通信的完整流程I2C 是传感器接入中最常用的协议之一接线简单两根信号线加电源线就能通信。以常见的温湿度传感器为例接入流程如下。首先确认 I2C 总线已经启用。执行ls /dev/i2c-*如果看到/dev/i2c-1之类的设备节点说明 I2C 已经可用。然后用i2cdetect工具扫描总线上的设备sudo apt install i2c-tools sudo i2cdetect -y 1如果传感器连接正常你会看到对应的地址被列出来比如0x44或者0x76。确认设备存在后用 Python 读取数据。我通常用smbus2这个库它比标准的smbus库更好用from smbus2 import SMBus bus SMBus(1) address 0x44 # 发送读取命令 bus.write_byte(address, 0x2C) # 读取 6 个字节的数据 data bus.read_i2c_block_data(address, 0x00, 6) # 解析数据具体解析方式取决于传感器型号 temp_raw (data[0] 8) | data[1] temp -45 175 * temp_raw / 65535 print(f温度{temp:.2f} °C)提示不同传感器的寄存器地址和数据格式不同上面的代码只是示例。实际使用时一定要查传感器的数据手册确认命令字节和数据解析方式。I2C 通信中常见的问题是地址冲突和上拉电阻缺失。如果总线上挂了多个设备地址不能重复。如果通信不稳定可能是上拉电阻没接或者阻值不合适通常 4.7kΩ 到 10kΩ 之间比较合适。5.3 把 AI 推理结果和硬件控制串起来单独跑 AI 推理或者单独控制硬件都不难真正有意思的是把两者结合起来。比如做一个智能垃圾分类项目摄像头采集图像AI 模型识别垃圾类别然后根据识别结果控制舵机把垃圾分到不同的桶里。这个流程的代码结构大概是这样的import cv2 import onnxruntime as ort import gpiod # 初始化摄像头 cap cv2.VideoCapture(0) # 初始化推理会话 session ort.InferenceSession(garbage_classifier.onnx) # 初始化 GPIO chip gpiod.Chip(/dev/gpiochip0) servo_line chip.get_line(18) servo_line.request(consumerservo, typegpiod.LINE_REQ_DIR_OUT) while True: ret, frame cap.read() if not ret: continue # 预处理 input_blob preprocess(frame) # 推理 outputs session.run(None, {input: input_blob}) class_id np.argmax(outputs[0]) # 根据类别控制舵机 if class_id 0: set_servo_angle(servo_line, 0) elif class_id 1: set_servo_angle(servo_line, 90) else: set_servo_angle(servo_line, 180)这个框架可以套用到很多场景智能门禁人脸识别控制电磁锁、智能农业识别病虫害控制喷药、智能家居手势识别控制灯光等等。核心逻辑都是感知-推理-决策-执行这个闭环。实际做项目时实时性是个需要关注的问题。如果推理速度跟不上摄像头帧率就需要跳帧处理或者降低输入图像的分辨率。另外GPIO 操作和推理最好放在不同的线程里避免相互阻塞。6. 调试与优化那些文档里不会写的经验6.1 系统卡顿和推理变慢的排查思路用了一段时间之后你可能会发现系统变慢了推理时间从几十毫秒涨到几百毫秒。这种情况通常有几个原因。最常见的是散热问题。处理器温度过高触发降频性能直接打折。排查方法是查看处理器温度cat /sys/class/thermal/thermal_zone0/temp返回值除以 1000 就是摄氏度。如果超过 80°C就需要加强散热了。第二个原因是内存不足。AI 推理很吃内存如果同时跑了其他占内存的服务系统会频繁使用交换分区速度自然就慢了。用free -h查看内存使用情况如果可用内存很少考虑关掉不必要的服务或者换一块内存更大的板子。第三个原因是后台进程占用 CPU。用top或者htop看看哪个进程在偷跑 CPU把不需要的进程关掉。6.2 模型推理速度优化的几个实用手段如果排查完系统问题推理速度还是不理想可以从模型层面做优化。第一个手段是量化。把 FP32 模型转成 INT8 模型推理速度通常能提升两到三倍模型体积也缩小到四分之一。ONNX Runtime 提供了量化工具操作不算复杂from onnxruntime.quantization import quantize_dynamic, QuantType quantize_dynamic( model.onnx, model_quantized.onnx, weight_typeQuantType.QUInt8 )第二个手段是裁剪输入尺寸。如果你的模型输入是 224x224但实际场景中 128x128 就够用那就把输入改小。计算量通常和输入尺寸的平方成正比从 224 降到 128计算量减少到原来的三分之一左右。第三个手段是使用多线程推理。ONNX Runtime 支持配置线程数options ort.SessionOptions() options.intra_op_num_threads 4 session ort.InferenceSession(model.onnx, options)BeagleY-AI 通常有四个 CPU 核心设置成 4 能充分利用多核性能。但也不是线程越多越好线程太多反而会因为上下文切换开销导致性能下降一般设置成物理核心数就行。6.3 长时间运行项目的稳定性保障做 Demo 和做产品是两回事。Demo 跑几分钟没问题但产品需要连续运行几天甚至几个月不出故障。我在长时间运行的项目中总结了几条经验。第一加看门狗。BeagleY-AI 的处理器通常有硬件看门狗可以在系统卡死时自动重启。配置看门狗需要写内核模块参数或者用systemd的看门狗功能具体操作查一下系统文档。第二日志要写好。程序运行时的关键信息都要记日志出问题时才有据可查。Python 的logging模块就够用了配置好日志级别和输出文件定期清理旧日志避免占满磁盘。第三异常处理要到位。摄像头掉线、传感器读取失败、推理出错这些异常都要捕获并处理不能让程序直接崩溃。我的习惯是在主循环外面包一层try-except出错后记录日志、释放资源、等待几秒后重试。第四定期重启。如果程序有内存泄漏或者资源释放不干净的问题定期重启是最简单有效的解决办法。可以用cron定时任务每天凌晨重启一次服务对大多数项目来说影响可以忽略。提示如果你的项目对可用性要求很高可以考虑双机热备方案一台出问题另一台顶上。不过这会增加成本和复杂度根据实际需求权衡。7. 关于这块板子和这个系列我的一些个人体会BeagleY-AI 给我的感觉是一块务实的板子。它没有堆砌最顶级的硬件参数而是在 AI 推理能力、Python 生态兼容性和硬件扩展性之间找到了一个不错的平衡点。对于想入门嵌入式 AI 的开发者来说它的学习曲线比较平缓社区文档也在逐步完善。这个系列的第一篇主要覆盖了从开箱到跑通 AI 推理加硬件控制的完整链路。后面我计划继续写模型训练和部署的进阶内容、多传感器融合的案例、以及如何把项目从原型变成可以长期运行的产品。如果你跟着这篇文章走了一遍应该已经能在自己的 BeagleY-AI 上跑出一些有意思的东西了。最后分享一个我在嵌入式项目里一直坚持的习惯每做一步都先验证再继续。不要一口气写完所有代码再运行而是写一小段就测一小段。摄像头能出图了再写预处理预处理对了再接模型模型跑通了再加硬件控制。这样出问题时排查范围小定位快整体效率反而比一口气写完再调试高得多。