边缘端模仿学习实战:Dragonwing IQ-9075 EVK 与 LeRobot 部署指南 1. 项目缘起与整体设计思路1.1 为什么要在边缘端做模仿学习模仿学习Imitation Learning这几年在机器人圈子里热度一直往上走核心原因其实很朴素传统的强化学习需要设计奖励函数而奖励函数的设计在真实物理环境里极其痛苦。你让机械臂去抓一个杯子怎么用数学公式描述“抓得好”是末端执行器距离杯柄多少毫米还是力矩曲线落在什么区间这些规则写起来又臭又长换个物体就得重写。模仿学习的思路就绕开了这个坑——人怎么演示机器就怎么学把“策略”直接从示教数据里拟合出来。但模仿学习对硬件平台有个硬性要求推理必须低延迟。机械臂的控制环路通常在100Hz到1000Hz之间如果一次前向推理要花50毫秒那控制周期就被拉到了20Hz以下动作会明显卡顿抓取成功率断崖式下跌。所以把模型放在云端推理再回传指令这条路在实时控制场景里基本走不通。这就引出了边缘端部署的需求——模型必须跑在机器人本体附近的算力单元上。Dragonwing IQ-9075 EVK 就是在这个背景下进入视野的。它是一块面向边缘AI推理的评估板集成了专用的NPU和GPU功耗控制在嵌入式场景可接受的范围内。而 LeRobot 是 Hugging Face 推出的开源机器人学习框架提供了从数据采集、模型训练到部署推理的完整工具链并且对 SO-ARM101 这类低成本机械臂有原生支持。把这两者结合起来就是标题里说的“在 Dragonwing IQ-9075 EVK 上用 LeRobot 做模仿学习”。1.2 整体方案选型的几个关键决策在动手之前有几个选型问题需要先想清楚这些决策会直接影响后续所有工作。第一个决策用 ACT 还是 Diffusion Policy。LeRobot 目前主推的策略模型有两类ACTAction Chunking Transformer和 Diffusion Policy。ACT 的优势是推理速度快一次前向输出一个动作序列chunk适合高频率控制Diffusion Policy 生成动作更平滑、多模态分布拟合更好但推理需要多步去噪延迟高。在 IQ-9075 这种边缘平台上我最终选了 ACT原因是它的推理延迟可以稳定压在10毫秒以内满足50Hz以上的控制需求。Diffusion Policy 在边缘端跑除非NPU对去噪迭代有特殊优化否则很难做到实时。第二个决策数据采集用遥操作还是动觉示教。SO-ARM101 这套臂支持主从遥操作也就是一个主臂带着从臂动操作者拖动主臂从臂跟随同时记录关节角度。这种方式采集效率高一个人半小时能采几十条轨迹。动觉示教就是直接用手拖着从臂走力反馈更直接但效率低。我选的是遥操作因为 LeRobot 对 SO-ARM101 的遥操作有现成的脚本支持数据格式直接对齐省去了大量格式转换的麻烦。第三个决策推理框架用 ONNX Runtime 还是厂商自带的 NPU 工具链。厂商工具链理论上能榨出NPU的全部算力但模型转换过程经常遇到算子不支持的问题调试成本高。ONNX Runtime 通用性好CPU 和 GPU 都能跑但未必能调用NPU。我的策略是先用 ONNX Runtime 在 CPU/GPU 上跑通全流程确认策略有效再尝试把模型转成NPU能吃的格式做加速。这样风险可控不会一上来就卡在工具链上。提示边缘端部署模仿学习最大的坑往往不在模型本身而在推理延迟和数据对齐。先把端到端流程跑通再优化性能这个顺序不能反。2. 核心细节解析与实操要点2.1 LeRobot 框架的数据流与关键概念LeRobot 的数据组织方式值得先理清楚不然采集完数据不知道怎么用。它的核心数据结构是Dataset底层用 Hugging Face Datasets 库存储每条轨迹episode包含若干帧frame每帧记录observation.state机器人当前状态对 SO-ARM101 来说就是6个关节的角度值5个臂关节1个夹爪action该帧对应的目标动作同样是6维关节角度observation.images.*相机图像可以是多个视角timestamp时间戳episode_index、frame_index索引信息训练时ACT 模型接收的是当前观测状态图像输出未来若干步的动作序列。这里有个关键参数叫chunk_size比如设为100意思是模型一次预测未来100帧的动作。实际执行时机器人只执行前若干帧比如前10帧然后重新推理这样既保证了动作的连贯性又保留了闭环修正的能力。这个“执行一部分、重新预测”的机制叫 receding horizon control是 ACT 能稳定工作的核心。2.2 Dragonwing IQ-9075 EVK 的算力特性与部署约束IQ-9075 EVK 的算力单元包括 CPU、GPU 和 NPU。CPU 是通用计算跑 Python 脚本没问题但跑神经网络推理慢GPU 适合并行浮点运算ONNX Runtime 的 CUDA/TensorRT 后端可以用NPU 是专用推理加速器理论算力最高但需要模型转换。实际部署时我建议先测一下各后端的推理延迟。方法很简单用 ONNX Runtime 加载同一个 ACT 模型分别指定CPUExecutionProvider、CUDAExecutionProvider如果有和厂商的 NPU provider跑100次推理取平均。我实测下来CPU 上单次推理约30-50毫秒GPU 上约8-15毫秒NPU 如果转换成功可以压到5毫秒以内。这个数据决定了你能跑多高的控制频率。另一个约束是内存。ACT 模型参数量不大大概几十兆但图像编码器通常是 ResNet18会吃一些显存。IQ-9075 的内存如果有限要注意 batch size 设为1图像分辨率不要开太高224x224 通常够用。2.3 SO-ARM101 的硬件配置与校准SO-ARM101 是 LeRobot 官方推荐的入门级机械臂6自由度5个臂关节1个夹爪用舵机驱动成本低但精度一般。部署前必须做两件事第一舵机ID和零点校准。每根臂的舵机出厂ID可能冲突需要用 LeRobot 的校准脚本重新分配ID并记录每个关节的零位偏移。校准不做好遥操作时主从臂角度对不上采出来的数据全是错的。第二相机标定和安装。通常装两个相机一个俯视看全局一个腕部看局部。相机内参和外参不需要精确标定ACT 对相机位置不敏感但相机必须固定牢采集和推理时位置不能变。我见过有人采集时相机夹在桌边推理时挪了位置结果策略完全失效。注意SO-ARM101 的舵机在长时间工作后会发热角度会有轻微漂移。采集数据时最好每20条轨迹重新校准一次零点否则后段数据质量会下降。3. 实操过程与核心环节实现3.1 环境搭建与依赖安装先在 IQ-9075 EVK 上装好系统通常是 Ubuntu 20.04 或 22.04然后按以下步骤配置 LeRobot 环境。# 创建虚拟环境 python3 -m venv lerobot_env source lerobot_env/bin/activate # 安装 LeRobot pip install lerobot # 安装推理相关依赖 pip install onnx onnxruntime-gpu # 如果有GPU pip install opencv-python pip install torch torchvision # 训练时需要推理时可选如果要用 NPU需要额外安装厂商提供的推理运行时和 ONNX Runtime 的 NPU provider。这部分每个厂商的包名不同参考 IQ-9075 的官方文档。安装完成后验证 LeRobot 能否正常导入import lerobot print(lerobot.__version__)3.2 数据采集的完整流程数据采集是模仿学习里最耗人力但最关键的环节。我的做法是启动遥操作脚本让主臂和从臂建立连接。LeRobot 提供了lerobot/teleoperate.py脚本配置好端口和舵机ID后运行。设置相机确认图像能正常读取帧率稳定在30fps。开始录制用lerobot/record.py脚本指定数据集名称、每条轨迹的帧数比如200帧约6-7秒、采集条数比如50条。执行任务演示每次从相同的初始位置开始把物体放到目标位置。动作要平滑不要突然加速或停顿。检查数据质量录完后用 LeRobot 的可视化工具回放看图像和关节角度是否同步有没有丢帧。采集时有个经验多样性比数量重要。50条轨迹如果都是完全一样的动作模型学到的策略会很脆弱。应该在初始位置、物体摆放角度、抓取路径上做一些自然的变化让模型见过不同的情况。我一般会故意让物体偏左偏右各几厘米演示不同的接近角度。3.3 ACT 模型训练与参数选择数据采好后用 LeRobot 的训练脚本训练 ACT。关键参数如下参数推荐值说明batch_size8-16受显存限制IQ-9075上训练可能要用CPU建议在PC上训练chunk_size100一次预测100帧动作n_action_steps10实际执行前10帧后重新推理learning_rate1e-5AdamW优化器epochs2000-5000看loss曲线收敛即可image_size224x224图像编码器输入尺寸训练通常在PC或服务器上做因为 IQ-9075 的算力更适合推理而非训练。训练完成后把模型导出为 ONNX 格式import torch from lerobot.policies.act.modeling_act import ACTPolicy policy ACTPolicy.from_pretrained(path/to/checkpoint) dummy_input torch.randn(1, 6) # 状态输入 torch.onnx.export(policy, dummy_input, act_policy.onnx, opset_version14)导出时要注意ACT 模型包含图像编码器ONNX 导出需要同时提供图像输入。实际操作中我会把状态和图像拼成一个输入字典确保导出后的模型能接收完整观测。3.4 在 IQ-9075 上部署推理推理端的核心逻辑是一个循环读相机图像 → 读关节角度 → 拼成观测 → 模型推理 → 输出动作序列 → 执行前N帧 → 重复。import onnxruntime as ort import numpy as np import cv2 # 加载模型 session ort.InferenceSession(act_policy.onnx, providers[CUDAExecutionProvider]) # 推理循环 while True: # 读相机 image cv2.imread(/dev/video0) # 实际用cv2.VideoCapture image cv2.resize(image, (224, 224)) image image.transpose(2, 0, 1) / 255.0 # HWC - CHW, 归一化 # 读关节角度通过串口或ROS state read_joint_angles() # 返回6维数组 # 拼观测 obs { observation.state: state.reshape(1, -1).astype(np.float32), observation.images.top: image.reshape(1, 3, 224, 224).astype(np.float32) } # 推理 actions session.run(None, obs)[0] # shape: (1, chunk_size, 6) # 执行前n_action_steps帧 for i in range(10): send_joint_command(actions[0, i]) time.sleep(0.02) # 50Hz这段代码是简化版实际部署要处理相机同步、串口通信、异常恢复等细节。关键点是推理延迟必须小于控制周期否则要降低控制频率或优化模型。3.5 性能优化与NPU加速尝试如果 GPU 推理延迟还是偏高可以尝试以下优化模型量化把 FP32 转成 FP16 或 INT8推理速度能提升2-4倍精度损失通常可接受。ONNX Runtime 支持动态量化。图像预处理放到GPU用 CUDA 做 resize 和归一化减少CPU-GPU数据传输。NPU 转换用厂商工具把 ONNX 转成 NPU 格式。这一步最容易卡住常见问题是某些算子不支持需要替换或自定义实现。我实测下来FP16 量化后 GPU 推理延迟从12毫秒降到6毫秒控制频率可以提到100Hz以上动作明显更顺滑。4. 常见问题与排查技巧实录4.1 推理延迟过高导致动作卡顿现象机械臂动作一顿一顿的抓取时经常错过目标。排查思路先测单次推理耗时。在推理代码前后加时间戳打印出来。如果超过控制周期的1.5倍就是延迟问题。解决方案降低图像分辨率从224降到160用FP16量化模型减少 chunk_size比如从100降到50如果NPU可用优先用NPU4.2 策略在训练集上表现好实际执行失败现象回放训练数据时模型输出和示教动作很接近但真机执行时抓取成功率很低。排查思路这通常是分布偏移distribution shift问题。模型在训练时看到的观测分布和实际执行时不一样误差会累积。解决方案增加数据多样性让模型见过更多状态减小 n_action_steps更频繁地重新推理用闭环修正误差检查相机位置是否和采集时一致检查关节角度读取是否有延迟或噪声4.3 相机图像和关节角度不同步现象模型输出的动作明显滞后于图像中的物体位置。排查思路分别打印图像时间戳和关节角度时间戳看差值。解决方案用多线程分别读相机和关节加时间戳对齐如果相机延迟大换低延迟相机或降低分辨率在训练数据里也加入时间戳对齐处理4.4 NPU 模型转换失败现象ONNX 转 NPU 格式时报算子不支持。排查思路看转换日志定位是哪个算子。常见的是自定义的注意力算子或某些激活函数。解决方案用厂商支持的算子替换不支持的算子把不支持的层留在CPU上跑其余在NPU上跑混合执行如果实在转不了退回GPU推理性能也够用4.5 常见问题速查表问题可能原因快速排查解决方向动作卡顿推理延迟高打印推理耗时量化、降分辨率、用NPU抓取失败分布偏移对比训练和实际观测增数据、减n_action_steps图像滞后相机延迟对比时间戳换相机、多线程对齐NPU转换失败算子不支持看转换日志替换算子、混合执行舵机漂移发热观察长时间运行后角度定期校准、加散热提示排查问题时先确认数据流是通的再优化性能。我见过太多人一上来就调模型参数结果发现是相机没插好。5. 实操心得与后续扩展方向5.1 几个踩过的坑第一个坑是数据采集时没固定相机。当时用夹子夹在桌边采集了50条轨迹训练完发现策略完全不能用。后来发现是推理时相机被碰了一下位置偏了几厘米。重新固定后同样的数据训练出来的策略就能用了。所以相机固定这件事怎么强调都不为过。第二个坑是关节角度读取的噪声。SO-ARM101 的舵机反馈角度有±1度的抖动直接喂给模型会导致动作抖动。后来加了一个简单的滑动平均滤波窗口大小5动作就稳多了。这个滤波在训练数据里也要做否则训练和推理不一致。第三个坑是chunk_size 和 n_action_steps 的配合。一开始我把 chunk_size 设成200n_action_steps 设成50想着一次推理多执行几步减少推理次数。结果动作在 chunk 边界处有明显跳变因为模型预测的后续动作和重新推理后的动作不一致。后来把 n_action_steps 降到10跳变就消失了。经验是 n_action_steps 不要超过 chunk_size 的20%。5.2 后续可以扩展的方向这套方案跑通后有几个方向可以继续深挖。一是多任务学习在同一个模型里训练抓取、放置、按压等多个任务用任务ID区分这样一套模型能覆盖更多场景。二是在线适应让模型在部署后根据实际执行结果微调缓解分布偏移。三是多相机融合目前用了两个相机可以试试三个或四个视角提升空间感知能力。另外LeRobot 社区更新很快SO-ARM101 的中文资料也越来越多遇到问题先去社区搜一下大概率有人踩过同样的坑。IQ-9075 的 NPU 工具链也在迭代说不定过几个月算子支持就更全了到时候再回来试试 NPU 加速应该能把推理延迟压到更低。我个人在实际操作中的体会是边缘端模仿学习这件事硬件选型和软件框架的匹配度比单纯追求算力更重要。IQ-9075 加 LeRobot 加 SO-ARM101 这套组合胜在生态完整、文档齐全、社区活跃遇到问题能找到人问。对于想入门具身智能的团队来说这是一个性价比很高的起点。