1. 项目概述从零训练一个机器人“大脑”最近在机器人学习社区里LeRobot这个开源框架的热度是肉眼可见地高。它把那些听起来高大上的模仿学习、强化学习算法打包成了相对容易上手的工具让更多研究者和工程师能快速验证自己的想法。我这次折腾的项目核心就是利用LeRobot给一个名为SO-101的机器人训练一个ACT策略。你可能要问ACT是什么简单来说它就像一个机器人的“条件反射”或“肌肉记忆”。想象一下你教一个孩子拿水杯你不会告诉他每个关节要转多少度你只是示范“伸手、握住、拿起来”这个动作序列。ACTAction Chunking with Transformers策略干的就是类似的事它通过观察人类的演示数据比如遥操作机器人完成某个任务学习到一连串动作一个“动作块”然后当它再次看到类似场景时就能自动复现这一串动作。SO-101机器人从名字和社区讨论来看很可能是一个用于灵巧操作研究的机械臂平台比如类似Franka Emika Panda或者UR5e这类带有力控和末端执行器适合做抓取、装配等精细活。所以这个项目的目标非常明确在LeRobot框架下使用SO-101机器人的数据很可能是仿真环境下的示教数据从头开始训练一个能够完成特定任务的ACT策略模型。这不仅仅是跑通一个教程更是理解如何将前沿的模仿学习算法落地到一个具体的机器人硬件仿真环境中的全过程。无论你是机器人方向的学生想复现顶会论文还是工程师想为自家机械臂快速开发一个演示学习功能这个过程都极具参考价值。2. 核心思路与工具选型为什么是LeRobot ACT在动手之前我们得先搞清楚“武器库”里有什么以及为什么这么选。这决定了后续所有工作的效率和天花板。2.1 LeRobot框架机器人学习的“瑞士军刀”LeRobot并不是某一个算法而是一个PyTorch生态下的开源库它的野心是成为机器人学习的“Hugging Face”。它提供了几个关键价值标准化数据集接口它内置或适配了多个机器人数据集如Bridge、RoboNet、以及各种仿真环境数据统一了数据加载和预处理流程。对于SO-101我们很可能需要使用或制作符合其标准的数据集。即插即用的模型实现像ACT、Diffusion Policy、IBC等当前流行的策略学习算法LeRobot都提供了官方实现和预训练配置省去了我们从论文到代码复现的巨量时间。训练与评估流水线它封装了标准的训练循环、日志记录如Weights Biases、模型检查点保存和策略评估流程。这意味着我们可以更专注于任务定义和调参而不是重复造轮子。仿真与实机部署支持虽然核心是算法但LeRobot也考虑了与仿真器如MuJoCo、Isaac Gym的对接以及将训练好的策略部署到真实机器人的工具链。选择LeRobot意味着我们站在了一个比较高的起点上避开了底层基础设施的坑能直接切入核心问题如何为SO-101这个特定机器人形态和任务准备好数据并调优ACT模型。2.2 ACT策略原理让机器人学会“一连串”动作ACT的核心思想非常直观但实现很巧妙。它主要解决模仿学习中的一个经典难题动作序列的时序依赖和误差累积。传统的行为克隆Behavior Cloning就像让机器人一帧一帧地模仿图片当前帧只根据当前观测决定一个动作。这容易导致“复合误差”第一步有一点点偏差后续步骤的观测就变了模型就会在它没见过的状态下做出错误决策误差像滚雪球一样越来越大最终任务失败。ACT的解决方案是“块预测”动作块Action Chunk模型不是预测下一个瞬间的动作而是直接预测未来一段时间比如未来10个控制周期的一连串动作。这个“块”的长度是一个超参数。Transformer编码器它接收当前的观测比如机械臂关节角度、末端位置、相机图像等作为输入。Transformer擅长捕捉序列中的长距离依赖关系能很好地理解当前观测的上下文。Transformer解码器它以编码器的输出为条件自回归地生成整个动作块。注意这里“自回归”指的是在训练时用于预测下一个动作token时会用到之前预测的动作token以学习动作间的时序关系但在推理部署时给定一个观测模型是一次性输出整个动作块的这保证了执行效率。动作执行与刷新机器人执行这个动作块比如10步。执行完后用新的观测再次输入模型预测下一个动作块如此循环。由于每次预测都基于最新的观测并且一次规划多步策略的稳定性大大增强。对于SO-101机器人执行插孔、旋钮这类需要连续、协调动作的任务ACT的这种“瞻前顾后”的特性非常合适。它让机器人学会的不是一个静态的姿势而是一段动态的技能。2.3 环境与任务定义SO-101在模拟什么“Train from Scratch”意味着我们通常从仿真环境开始。SO-101很可能对应一个特定的MuJoCo或PyBulit仿真模型文件.xml或.urdf。这个模型定义了机器人的连杆、关节、质量、惯性等物理属性以及任务场景比如一张桌子桌子上有一个方块和一个目标位置。在LeRobot的语境下我们需要明确观测空间Observation Space策略模型能看到什么通常包括** proprioception本体感知**机器人的关节角度、关节速度、末端执行器夹爪的开合状态。** 任务相关特征**目标物体的位置可能是通过额外传感器或已知的或者更常见的来自相机的图像。动作空间Action Space策略模型能控制什么对于SO-101这类机械臂通常是末端执行器的相对位姿增量delta position delta rotation加上夹爪的开合指令。也可能是直接的关节扭矩或位置控制但增量控制更常见、更稳定。奖励函数/成功条件在模仿学习中我们通常不显式设计奖励函数而是通过演示数据隐式学习。评估时我们看的是任务完成率例如“方块是否被成功移动到目标区域内并保持一段时间”。我们的工作就是要在LeRobot的框架下配置好这个针对SO-101仿真环境的数据加载器和任务评估器。3. 实操准备搭建训练流水线理论清晰后我们进入实战环节。假设我们已经有了SO-101在某个任务例如“拾放方块”下的演示数据集。这些数据可能是通过人工遥操作、运动规划算法录制或者从其他来源转换而来。3.1 数据准备喂养模型的“粮食”数据是训练成功的基石。LeRobot期望的数据格式通常是hdf5文件里面存储了多条轨迹episode。每条轨迹包含了一系列时间步的字典数据。一个典型的数据条目需要包含{ “observation”: { “image”: np.array([H, W, 3]), # 主相机RGB图像 “agent_pos”: np.array([7]), # 机械臂7个关节的角度假设是7自由度 “end_effector_pos”: np.array([3]), # 末端执行器三维位置 # ... 其他自定义观测 }, “action”: np.array([8]), # 动作向量例如 [dx, dy, dz, droll, dpitch, dyaw, gripper] “done”: bool, # 是否回合结束 “info”: { ... } # 可选元信息 }关键步骤与注意事项数据同步确保观测和动作在时间上是严格对齐的。相机图像可能有延迟需要与关节数据精确同步。一个常见错误是动作t对应的是观测t而实际上动作t执行后才产生观测t1。需要根据你的控制频率和感知频率仔细处理。数据预处理图像通常需要下采样到固定的分辨率如224x224并进行归一化像素值缩放到[0,1]或[-1,1]。状态数据对关节角度、位置等进行归一化。一个稳健的做法是计算数据集中每个维度的均值和标准差然后进行标准化减去均值除以标准差。这能加速模型收敛提高数值稳定性。动作数据同样需要归一化。特别注意如果动作空间包含位姿增量和夹爪指令它们的量纲和范围差异巨大最好分别进行归一化。数据集划分将数据按8:1:1或类似比例划分为训练集、验证集和测试集。验证集用于在训练过程中监控过拟合测试集用于最终评估策略性能。创建LeRobot数据集你需要编写一个继承自torch.utils.data.Dataset的类或者使用LeRobot提供的工具将你的hdf5数据包装成其标准格式。这个类需要实现__getitem__方法返回处理后的观测和动作。实操心得在数据准备阶段多花一倍时间能在训练阶段节省十倍的时间。务必写脚本可视化你的数据随机播放几条轨迹将图像和机器人的动作动画显示出来确保数据是“干净”的没有错位、缺失或明显的错误演示。对于ACT还需要检查动作序列是否平滑连续剧烈的抖动会影响模型学习。3.2 模型配置定义ACT的“骨架”LeRobot通过配置文件通常是yaml文件来管理模型、训练和数据的超参数。这是项目的核心配置文件。我们需要重点关注ACT模型部分的配置policy: name: “act” # 指定使用ACT算法 network: type: “ACT” # 网络类型 # 观测编码器配置 encoder: rgb: type: “ResNet18” # 处理图像的编码器常用ResNet pretrained: true # 使用ImageNet预训练权重能加速收敛 freeze: false # 通常不冻结一起微调 proprio: type: “MLP” # 处理本体感知状态的编码器 hidden_dims: [256, 256] # 动作解码器配置 decoder: type: “MLP” hidden_dims: [256, 256] # ACT关键参数 chunk_size: 10 # 预测未来多少步的动作 latent_dim: 512 # Transformer内部的特征维度 num_encoder_layers: 4 # Transformer编码器层数 num_decoder_layers: 4 # Transformer解码器层数 nheads: 8 # 注意力头数 action_dim: 8 # 动作空间的维度必须与数据中的action维度一致参数选择逻辑chunk_size这是最重要的参数之一。太小如2-5规划视野短可能不足以完成连贯动作太大如30-50则预测难度剧增训练不稳定且推理时延迟变高。对于SO-101的拾放类任务10-20是一个不错的起点。你需要根据控制频率如20Hz和任务典型时长来估算。例如10步在20Hz下对应0.5秒对于一次快速的抓取可能够用。latent_dim,num_layers,nheads这些决定了模型的容量。更大的模型能学习更复杂的映射但也需要更多数据和更长的训练时间。对于中等复杂度的任务latent_dim512,6层8个头是一个平衡的选择。如果任务非常简单或数据量很少可以适当减小。观测编码器ResNet18对于224x224的图像是经典选择。如果你的图像分辨率不同或计算资源有限可以考虑更小的网络如ResNet10或CNN。对于本体感知数据一个2-3层的MLP通常足够。3.3 训练循环配置控制学习的“节奏”训练配置决定了模型如何从数据中学习。train: batch_size: 16 # 根据GPU内存调整。ACT由于使用Transformer对内存要求较高。 num_epochs: 200 # 训练轮数 learning_rate: 1e-4 # 学习率Transformer常用较小的值 weight_decay: 1e-4 # 权重衰减防止过拟合 lr_scheduler: name: “CosineAnnealingLR” # 余弦退火调度器学习率先慢后快再慢有助于收敛 optimizer: name: “AdamW” # Adam的改进版通常与Transformer搭配效果更好 grad_clip: 1.0 # 梯度裁剪防止训练爆炸对Transformer尤其重要 # 数据增强对视觉输入至关重要 augmentation: rgb: random_crop: # 随机裁剪模拟相机视角微小变化 scale: [0.9, 1.0] random_color_jitter: # 随机颜色抖动增强光照鲁棒性 brightness: 0.2 contrast: 0.2 saturation: 0.2 hue: 0.1训练技巧学习率预热Warmup在训练开始时用一个很小的学习率如1e-6训练几个epoch然后逐渐增加到预设值1e-4。这能让模型参数平稳地进入优化过程避免初期震荡。虽然配置中没直接写但很多训练脚本会实现它。梯度累积如果你的batch_size由于GPU内存限制无法设得很大可以使用梯度累积。例如设置batch_size4但每4个batch才更新一次参数等效于batch_size16。这能稳定训练。验证集监控不仅要看训练损失下降更要关注验证集上的损失。如果验证损失很早就停止下降甚至上升说明可能过拟合了需要增加数据增强强度、使用Dropout或减少模型容量。4. 训练执行与监控配置好一切后就可以启动训练了。通常命令类似于python lerobot/scripts/train.py \ --config-path path/to/your_so101_act_config.yaml \ --dataset-path path/to/your_so101_dataset.hdf5 \ --output-dir runs/so101_act_experiment_14.1 训练过程观察点训练开始后不能只是干等着。你需要密切关注几个指标训练损失Train Loss通常是动作预测的均方误差MSE或平滑L1损失。它应该随着训练轮数平稳下降。如果出现剧烈波动或NaN可能是学习率太高、数据有异常值或梯度爆炸。验证损失Val Loss这是判断模型泛化能力的金标准。理想情况下它随着训练损失一起下降但最终会高于训练损失。如果两者差距迅速拉大就是过拟合的明确信号。可视化预测这是最最重要的调试手段。定期比如每10个epoch用验证集的一条轨迹做推理将模型预测的动作序列与真实演示的动作序列进行对比可视化。关节空间对比绘制每个关节角度随时间变化的曲线对比预测值线和真实值点。末端轨迹对比在三维空间中绘制末端执行器的预测路径和真实路径。图像空间预测如果可用对于一些高级模型甚至可以可视化模型“注意力”在了图像的哪个区域。如果发现预测动作在轨迹初期还比较准确但后期严重偏离那很可能是chunk_size设得太小或者模型没有学好长序列的依赖。如果预测动作整体幅度偏小机器人动作“绵软无力”可能是动作数据归一化时压缩了范围或者损失函数权重需要调整。4.2 常见训练问题与排查损失不下降Plateau检查数据首先确认数据加载是否正确。随机取几个batch打印观测和动作的shape和值范围。检查学习率尝试增大学习率如3e-4或使用学习率预热。简化问题用一个极小的模型如latent_dim1281层Transformer在少量数据上过拟合。如果能快速过拟合训练损失降到接近0说明流程基本正确问题可能在模型容量或数据质量。如果不能则代码可能有bug。梯度检查检查模型参数的梯度是否正常不为0也不为NaN。过拟合Overfitting增强数据增加数据增强的强度特别是对于图像数据随机裁剪、遮挡、颜色抖动非常有效。正则化增加weight_decay或在MLP层中加入Dropout。早停Early Stopping当验证损失连续多个epoch不再改善时停止训练并回滚到验证损失最低的模型 checkpoint。训练不稳定Loss NaN/Exploding梯度裁剪Grad Clipping确保配置中设置了梯度裁剪如grad_clip: 1.0这对Transformer模型是标配。检查数据归一化确保输入数据的每个维度都在合理的范围内例如标准化后大致在[-3, 3]之间。异常值会导致梯度爆炸。降低学习率这是最直接的稳定训练的方法。5. 策略评估与仿真测试训练完成后我们得到了一个模型文件.ckpt或.pth。接下来要在仿真环境中测试它的实际表现。5.1 加载策略并创建推理循环在LeRobot中通常会有一个Policy类来封装训练好的模型。推理循环的伪代码如下import torch from lerobot.common.policies import ACTPolicy from your_so101_sim_env import SO101SimEnv # 1. 加载配置和模型 config load_config(“path/to/config.yaml”) policy ACTPolicy.load_from_checkpoint(“path/to/checkpoint.ckpt”, config) policy.eval() # 切换到评估模式 # 2. 初始化仿真环境 env SO101SimEnv(render_mode“human”) # 开启渲染以便观察 obs, info env.reset() # 3. 推理循环 for step in range(max_steps): # 预处理观测使其符合模型输入格式如转换为Tensor归一化 processed_obs preprocess(obs) with torch.no_grad(): # 禁用梯度计算加速推理 action_chunk policy(processed_obs) # 模型预测一个动作块 # 通常只取动作块的第一个动作执行或者按顺序执行整个块 # 这里假设我们采用“执行-刷新”模式执行第一步然后重新观测 action_to_execute action_chunk[0].cpu().numpy() # 反归一化动作如果训练时归一化了 denorm_action denormalize_action(action_to_execute, stats) # 环境执行一步 obs, reward, done, truncated, info env.step(denorm_action) if done or truncated: break env.close()5.2 评估指标在仿真中测试时不能只看“好像成功了”。需要定义量化的评估指标任务成功率运行N次如50次从不同的初始状态开始计算成功完成任务的次数比例。这是核心指标。轨迹效率平均完成一个任务需要多少时间步或多少秒。一个笨拙但能成功的策略可能步数很多。动作平滑度计算动作的加速度二阶差分的均值或最大值。一个抖动剧烈的策略在实际机器人上可能引发振动甚至不稳定。鲁棒性在环境中加入轻微扰动如目标物体位置微小偏移、桌面颜色纹理变化看成功率下降多少。5.3 从仿真到实机的鸿沟如果你最终目标是部署到真实的SO-101机器人上必须意识到“仿真到实机”Sim2Real的差距。仿真中的物理参数摩擦、质量、阻尼和传感器完美的相机图像、无噪声的关节编码器与现实世界不同。缩小差距的常用技巧领域随机化Domain Randomization在仿真训练时随机化各种物理参数如物体质量、摩擦系数、关节阻尼、相机视角、光照、纹理颜色。这迫使策略学习更本质的特征而不是过拟合到仿真的特定参数上。LeRobot可能支持在环境配置中设置这些随机化范围。数据增广的扩展对图像进行更激进的数据增强模拟现实中的模糊、噪声、亮度变化等。动作延迟与滤波在仿真中模拟真实系统的控制延迟并对模型输出的动作进行低通滤波使动作更平滑。在线微调如果安全可行在真实机器人上收集少量新数据需要非常小心防止损坏对仿真训练好的策略进行微调。训练一个ACT策略远不止是调通代码。从数据管道的构建、模型超参数的理解、训练过程的监控与调试到最终的仿真验证和实机部署考量每一步都充满了工程细节和权衡。这个过程最能体现机器人学习“算法”和“系统”结合的特点。最大的收获往往不是最终那个能完成任务的策略而是在解决上述每一个小问题时对数据、模型、机器人系统之间相互作用加深的理解。当你看到SO-101机械臂第一次颤颤巍巍但成功地用你训练的“大脑”完成抓取时那种成就感就是驱动我们不断折腾下去的动力。