最近我们在某自研的多模态大模型底座上做机器人操作实验,遇到了一个很常见但很扎心的问题:模型权重完全冻结,直接零样本推理去执行真实任务,成功率低得让人怀疑人生。试过调 prompt、换数据格式、加规则兜底,最后真正跑通并沉淀下来的方案,就是标题里这个 SenseNova-RoboRSI——一个纯靠“模型外面的系统”把机器人表现顶上去的项目,全程不动大模型权重。
做这件事的缘起很直接:手头这个底座模型在视觉理解、指令跟随上都不错,但一旦接到真实机械臂控制链路里,动作不是发抖就是越界,甚至会在“拿起杯子”的任务里执行了一个“平移半米再放下”的奇怪轨迹。我们最初的直觉是去微调它,但数据、成本、落地环境三个问题同时卡住,最后才转向了“不改权重、只改系统”的路线。这篇文章把整个方案的架构、关键模块、实验数据和我们踩过的坑完整写下来,适合正在被大模型机器人操作困扰的工程师,也适合想搞清楚“冻结模型的增量优化”到底怎么落地的研究同学。
1. 为什么冻结权重反而成了刚需:微调路线的三个死结
先说结论:在机器人操作这个场景里,微调大模型不是不能做,而是绝大多数团队做不起,或者做完之后得不偿失。我们最开始也想走微调路线,但深入评估后,发现了三个绕不开的问题。
1.1 操作数据的数量和异构程度都不支持微调
机器人操作数据比纯文本、纯图像数据难收集得多。一组合法的操作数据至少要包含多视角图像、机械臂关节角、夹爪状态、力觉信息以及对应的任务描述,而且要保证时间轴对齐、坐标系准确。我们团队花了两周时间才收集了几千条有效样本,这个量级对微调一个大模型来说连“热身”都算不上。更麻烦的是异构性:不同机械臂的关节配置不同,夹具型号不同,相机安装位置不同,同一段轨迹换到另一套硬件上基本不能用。即便把数据量凑上去,微调出来的权重也高度绑定当前的硬件配置,换个手臂就要重新来一轮。
1.2 灾难性遗忘会让通用能力快速损失
大模型之所以好用,是因为它在海量通用数据上获得了丰富的先验知识。微调做机器人操作时,梯度更新会把模型往特定任务的分布上拉,与此同时它原本的图像理解、常识推理能力会快速衰退。我们在一个极小规模的测试集上做过验证:微调 2000 步后,目标任务成功率确实涨了,但模型对未见过的指令的响应质量明显下降。对一个面向真实场景的产品来说,这种能力回退是不可接受的——你总不能为了让它会抓杯子,把它的对话和常识能力牺牲掉。
1.3 部署场景要求模型可以在不同机器人之间迁移
我们的目标场景是同一套模型底座适配多台不同构型的机器人设备。如果走微调路线,每一台设备的参数、标定、控制频率都不一样,意味着要维护 N 份权重和 N 套评测流程。这在实际工程里是非常痛苦的。于是我们反过来想:如果模型权重始终保持不变,把任务相关的可调模块全部外置到系统层,那样模型的通用能力保住了,硬件适配也只需要改外围配置,整个链路的复杂度会大幅下降。
这就是 RoboRSI 的出发点。它不是某个单一的算法创新,而是一整套系统设计思路的产物。
2. RoboRSI 的整体思路:权重不动,模型周围的世界动起来
要理解 RoboRSI,可以先做一个类比。假设你招到一个很有天赋、但完全没上过生产线的实习生。他的知识储备足够,缺的是对具体工位的适应能力。微调相当于送他去重新上大学,成本高、周期长,而且学完可能把常识都丢了。RoboRSI 的做法是:不重新培训他,而是给他配一张好的工位操作台、一份清晰的作业流程图,再安排一个经验丰富的师傅在旁边盯着,出问题就及时提醒和纠正。
模型还是那个模型,但模型周围的环境变了,它的表现自然就变了。
2.1 四层结构总览
RoboRSI 整体由四个模块构成,全部工作在模型权重之外:
| 层级 | 模块名称 | 核心职责 | 是否触碰模型权重 |
|---|---|---|---|
| 输入侧 | 感知增强与上下文构造 | 把多模态传感器信息翻译成模型能理解的 prompt 上下文 | 否 |
| 任务侧 | 技能缓存库 | 将高频操作步骤提炼为语义技能模板,引导模型按步骤决策 | 否 |
| 输出侧 | 动作适配层 | 对模型生成的动作意图做安全校验、运动约束和轨迹平滑 | 否 |
| 闭环侧 | 在线自校正 | 根据执行反馈自动切换技能模板或调整提示策略 | 否 |
这四个模块串联起来,就形成了一条完整的“感知 → 规划 → 执行 → 反馈”链路。模型只负责它最擅长的事——理解任务、分解意图、输出语义化的动作描述;而真正和物理世界打交道、保证安全性和稳定性的工作,全部交给外围模块处理。
2.2 设计原则:哪些模块能碰,哪些不能碰
这里有一条硬性边界需要说清楚:任何训练过程都不能反传到基础模型。RoboRSI 里确实存在可学习模块——比如输出侧的动作适配器有一个很轻量的映射网络,它的参数可以更新,但它的输入输出接口夹在“模型输出”和“机械臂控制指令”之间,和基础模型的权重更新路径完全隔离。这样做的理由是:可学习模块越靠近执行端,越容易快速收敛,因为它的学习目标非常明确——把动作映射得准、映射得稳——而且训练数据只需少量真机示范即可。但它的能力上限受制于基础模型的理解质量,一旦基础模型输出的意图本身是错的,外围模块再怎么学也救不回来。
我们后续做实验也证实了这一点:当基础模型对任务语义的理解正确时,外围系统能明显放大它的表现;当模型理解出现原则性错误时,外围系统能做的只有止损,没法逆转结果。
3. 输入侧改造:把机器人本体状态翻译成大模型看得懂的上下文
模型权重不能动,但我们能动的第一个关键点就是“喂给模型什么”。大多数项目直接把一张 RGB 图像和一句自然语言指令拼在一起丢给模型,这是远远不够的。机器人操作场景里,模型需要知道的东西远比一张图要多:当前手臂的姿态、夹爪有没有张到指定开度、末端受力是轻是重、目标物体在工作空间里的精确位置……这些信息如果不进入上下文,模型就只能在“盲猜”状态下输出动作意图。
3.1 多模态信号如何编排进 prompt
以我们团队的第二代实现为例,模型输入由四部分组成:
- 主视觉流:工作台全局视角的图像,分辨率统一到 640×480,每 250ms 刷新一帧。
- 辅助视觉流:安装在机械臂末端的眼部相机画面,用于观察抓取点的局部细节。
- 本体状态描述:关节角度、末端位姿、夹爪开度这些量,经过单位归一化后转成文本块。
- 力觉信息编码:六维力/力矩传感器数据经过符号化后追加在状态文本末尾。
把这四部分拼在一起后,模型实际看到的 prompt 形态大致是下面这个样子:
[Task Instruction] 请将桌面上红色杯子从当前位置移动到托盘中心。 [Scene State] camera_view: top_camera_01 end_effector_pose: x=0.42, y=0.18, z=0.27, roll=1.51, pitch=0.02, yaw=-0.04 gripper_state: open_width=0.075, finger_force=0.0 joint_angles: j1=15.2, j2=-22.8, j3=9.1, j4=1.6, j5=-3.4, j6=12.3 force_sensor: fx=-0.2, fy=0.5, fz=4.7, mx=0.01, my=0.02, mz=0.00 object_detection: target=red_cup, bbox=[320, 210, 450, 287], center=[385, 248] last_action_status: success这个格式是我们调了十几版之后稳定下来的。最初我们尝试过用带 XML 标签的结构,模型也能读懂,但实际推理时偶尔会出现格式混乱。后来改成“键值对 + 语义化前缀”的写法,模型的跟随稳定性明显提升。核心经验是:状态描述越贴近自然语言习惯,模型越不容易在格式解析上出错。
3.2 视角归一化与坐标建模
一个很容易被忽视的细节是坐标系的统一。机械臂的末端位姿默认是在机械臂基座坐标系下描述的,但大模型预训练时见过的空间描述大多以相机视角为参照。如果直接把基座坐标喂进去,模型对“左”“右”“前”“后”这类空间词的理解会和实际执行方向产生偏差。
我们的做法是在输入侧加了一个坐标归一化层:所有相机图像先经过外参标定,把像素坐标投影到机械臂基座坐标系;末端位姿则换算成以当前相机视角为参照的局部坐标描述。这样模型看到的是“物体在我视野的右前方约 0.3 米”,而不是“物体在世界系坐标(0.85,-0.23)”这种冷冰冰的数字。单纯这一项改动,就让模型对空间指令的响应准确率提升了 8% 左右。
3.3 力觉信号的编码细节
力觉信息最开始时我们直接以浮点数数组形式放进去,效果很不好,模型经常忽略这些数值。后来改成阈值符号化,效果立刻好了很多。具体做法是把六维力数据分三个维度处理:
- 重力补偿后的末端合成力大小:分为“无接触(force < 1.5N)”、“轻接触(1.5N ≤ force < 5N)”、“中接触(5N ≤ force < 10N)”、“强接触(force ≥ 10N)”四档。
- 力矩特征:如果 mx、my 的绝对值大于阈值,则标注为“可能发生倾倒或偏心受力”。
- 变化趋势:与上一帧相比,如果力超过 3N 的瞬变,标注为“接触冲击”。
这样编码之后,模型不仅能知道末端当前“碰到了东西”,还能推理出“碰得重不重、是不是垂直受力”。在插拔、推拉这类需要感知接触的任务中,这个信息几乎是决定成败的。
3.4 Prompt 长度与刷新频率的平衡
输入侧还有一个容易被低估的问题:上下文长度。完整的状态描述加两个视角的图像,token 数量并不少。如果每次执行动作、每次状态刷新都把全部信息重新送入,推理延迟会线性上升。
我们的工程做法是:主视觉流以 2.5Hz 的频率更新,辅助视觉流以 5Hz 更新,而本体状态文本每次动作决策前才刷新一次。实际单次决策的端到端延迟从最初的 1.2 秒降到了 380ms 左右,而任务成功率没有明显波动。想让模型在机器人和真实环境上表现稳定,不能只追求“喂得越多越好”,得仔细权衡信息量与实时性之间的关系。
4. 输出侧改造:动作适配层如何兜住模型的“口嗨”
如果说输入侧解决的是“模型看不看得懂”的问题,那么输出侧解决的就是“模型说得对不对、能不能安全执行”的问题。大模型输出的动作天然是“语义化”的,它可能会说“把杯子轻轻向右移动 5 厘米”,但机械臂需要的是具体的关节轨迹或笛卡尔空间位姿增量。如果把这个转换完全交给控制层,一旦模型的语义输出含糊或激进,轻则动作抖动,重则直接把机械臂怼到工件上。
4.1 为什么模型输出不能直接下发
直接下发的典型症状有三个:一是速度突变,模型在某一帧输出“快速靠近”,下一帧又输出“停止”,机械臂会像急刹车一样猛冲猛停;二是越界,模型对工作空间没有概念,会输出一个让末端跑到机械臂物理极限之外的目标点;三是振荡,尤其在接近目标物体时,模型对“接近到什么程度算到位”判断不稳定,会在目标点两侧来回摆动。
RoboRSI 的动作适配层就是在模型输出和执行器之间加一道过滤和转换工序。它不是简单的规则拦截,而是把模型的语义动作映射到受约束的运动空间里。
4.2 安全校验与速度约束
动作适配层的第一道工序是安全校验。模型输出的目标动作会先经过三层检查:
- 笛卡尔工作空间检查:目标点是否在机械臂的可达范围之内。
- 关节限位检查:执行该动作涉及的关节角是否越限。
- 速度/加速度约束:目标速度是否超过硬件允许值。
不满足条件的动作不会被直接丢弃,而是做“降级处理”。比如速度超限时,按最大允许速度等比缩放;目标点超出工作空间时,沿动作向量方向截断到边界内侧并保持姿态不变。这个降级策略非常关键——直接拒绝执行会让模型产生严重的“行为中断感”,而降级执行则能保证任务流不被打断。
4.3 可学习适配器的边界
安全校验是规则层,适配层中还包含一个轻量级可学习模块。这个模块的输入是大模型最后一个隐藏层的动作表征(保留语义信息),输出是笛卡尔空间的位姿增量。训练目标很简单:让输出轨迹逼近人类示教或遥操作采集的参考轨迹。
训练时只更新这个外部小网络,基础模型的梯度完全截断。这个设计的巧妙之处在于:小网络的学习目标非常 narrow,数据量需求很低。我们只用每个任务 100 组左右示教数据,就能让映射误差降低到 1 厘米以下。相比之下,微调基础模型要达到同等水平的控制精度,需要的数据量大两个数量级还不止。
不过要提醒一句:这个可学习模块不能乱加。如果基础模型输出的隐层表征本身不稳定,小网络学到的映射也会失稳。我们做过对比测试,去掉可学习适配器、只保留规则层的情况下,任务成功率会下降 10% 左右;但把可学习模块做得太复杂,收益反而会被训练不稳定抵消。
4.4 轨迹平滑的调参心得
最后一个关键点是轨迹平滑。模型的控制频率和机械臂底层控制频率通常不一致,需要在中间做插值和平滑。我们试过几种方案:
- 简单线性插值:实现容易,但加速度在插值点不连续,末端会有肉眼可见的顿挫感。
- 三次样条插值:轨迹连续且平滑,但容易overshoot,在精密靠近场景下可能冲过目标点。
- 低通滤波 + 速率限制:实际效果最稳定,虽然直观上看轨迹没有那么“优美”,但控制安全性最好。
最终我们采用的是“低通滤波 + 速度斜坡限制”组合。滤波截止频率设在 8Hz,速度变化率限制在 0.6 m/s²。这样既保证了动作流畅,又不会让机械臂出现危险的急加速。
5. 技能缓存库与在线自校正:经验沉淀在模型之外
大模型的强项是理解和泛化,弱项是稳定复现一套精确的动作序列。真实机器人任务恰恰要求后者:同一套抓取-搬运-放置动作,必须每一次都以一致的方式完成。技能缓存库就是为了解决这个问题。
5.1 技能模板:把任务步骤变成检查项而非脚本
我们构建技能模板时踩过一个重要的坑:一开始把技能写成精确的动作脚本,比如“先移动到 A 点,再下降到 B 点,闭合夹爪,抬升到 C 点”。结果模型执行得非常机械,一旦目标物体位置变了哪怕 2 厘米,整套动作就废了。
后来改成“目标条件化”的检查项形式。以 pick 技能为例,模板长这样:
Skill: pick - 前提:目标物体的中心坐标已由视觉检测模块给出,且末端位于物体上方安全高度。 - 执行策略: 1. 将末端移动到目标点上方约 10cm 的安全高度。 2. 竖直下降,直到末端力传感器检测到接触或到达目标高度。 3. 闭合夹爪,确认夹爪开度小于等于物体宽度。 4. 竖直抬升 8cm,保持姿态稳定。 - 自检:抬升后夹爪内物体是否保持,力传感器读数是否正常。这种模板给模型留了决策空间,但同时限定了动作执行的“安全通道”。模型不需要凭空想象“怎么抓一个东西”,它只需要在模板给出的环节里做出参数选择,比如目标坐标、下降速度、夹爪闭合宽度。说人话就是:模型从“编剧本”变成了“跟着台本即兴表演”,自由度小了,稳定性大幅上升。
5.2 在线自校正:失败信号触发技能切换
再强的模板也难免失败。在线自校正模块负责监控执行过程中的状态信号,一旦发现异常,就自动切换技能模板或调整提示词。我们实现了以下几个典型的自校正规则:
| 监测信号 | 异常条件 | 触发动作 |
|---|---|---|
| 力觉冲击 | 接触力瞬间超过 10N | 立即暂停下降,切换到 retract 技能,回退 3cm |
| 位姿偏差 | 末端与目标点偏差连续 1s 超过 3cm | 重新检测目标位置,刷新视觉上下文,重试 pick |
| 夹爪反馈 | 闭合后物体仍滑落 | 切换为 pinch 技能,调整夹爪闭合速度和力度 |
| 速度异常 | 末端速度超过预设阈值的 2 倍 | 强制降速,重新规划轨迹 |
自校正的价值在于它把“失败”从一种不可恢复的状态变成了一种可处理的正常流程。模型输出的决策错了没关系,只要反馈模块检测得快、替代方案切换得准,整体任务成功率仍然可以维持在较高水平。
5.3 一次完整任务流程示例
一个完整的搬运任务在 RoboRSI 下是这样执行的:视觉模块完成目标检测,技能缓存库根据任务指令自动加载 pick-place 技能模板,模型在模板框架内输出动作意图;动作适配层把意图转为安全的轨迹指令下发;执行过程中力觉信号实时反馈到在线自校正模块,出现异常立即切换技能;任务结束后,本次执行的状态序列和技能选择记录被存入缓存库,供后续任务做参考。
这条链路下来,模型只参与了“理解指令、选择技能、给出参数”这一小段决策,其他所有环节都由外部模块接管。权重不动,但整体系统对环境的适应能力大幅提升。
6. 实测效果与关键参数:从 62% 到 89% 背后发生了什么
方案说完得看数据。我们在三组任务上做了系统对比:单一抓取放置、复杂插拔操作、多步骤整理任务。每组任务分别测“裸模型直接推理”和“RoboRSI 完整链路”的成功率,以及动作平滑性和端到端延迟。
6.1 测试任务和评估指标
- 抓取放置任务:从工作台任意位置抓取不同形状的物体,放置到指定托盘区域。
- 插拔操作任务:将 USB 接头插入标准接口,模拟常见的精密装配场景。
- 多步骤整理任务:把散落物品按类别整理到不同容器,要求模型连续执行多步动作。
评估指标包括任务成功率、单次动作的末端最大速度波动、以及从视觉输入到动作指令输出的端到端延迟。
6.2 实验对比
| 任务类别 | 裸模型成功率 | RoboRSI 成功率 | 提升幅度 | 最大速度波动降低 |
|---|---|---|---|---|
| 抓取放置任务 | 58% | 86% | +28% | 近 5 倍 |
| 插拔操作任务 | 31% | 74% | +43% | 近 4 倍 |
| 多步骤整理任务 | 42% | 71% | +29% | 近 5 倍 |
| 综合均值 | 约 44% | 约 77% | +约 33% | 约 4.7 倍 |
这个结果验证了我们最初的两个判断:权重冻结的模型可以通过外部系统获得显著增益;复杂任务对“技能缓存 + 自校正”这类结构化支持的依赖更大,提升幅度也越明显。插拔任务从 31% 提升到 74%,是所有任务里增益最大的,原因就是它最依赖精确的力觉反馈和接触状态判断,这些恰好是外围系统重点加强的部分。
6.3 关键参数与调参注意事项
| 参数 | 推荐值 | 调节方向说明 |
|---|---|---|
| 主视觉流刷新率 | 2.5Hz | 太高会推高延迟,太低会导致目标位置感知滞后 |
| 辅助视觉流刷新率 | 5Hz | 用于抓取点局部确认,可略高于主视角 |
| 力觉轻接触阈值 | 1.5N—5N | 视末端负载和摩擦系数调整,阈值过小会频繁误报 |
| 低通滤波截止频率 | 8Hz | 调低更平滑但响应变钝,调高抖动明显 |
| 速度变化率限制 | 0.6 m/s² | 精密操作可降到 0.3,快速搬运可适当放开 |
| 技能模板数量 | 每类任务 3—5 个 | 太少无法覆盖失败分支,太多会让模型选择困难 |
参数表不是让你照抄,而是提供一个预期范围和调节方向。比如力觉阈值,如果你用的是轻型二指夹爪,接触力普遍偏小,阈值就得适当降低,不然模型永远不会感知到“已经夹住了”。
对了,这套链路跑下来,端到端延迟相对于裸模型只增加了约 8ms。这点开销主要来自状态文本的拼接和低通滤波计算,完全在可控范围内。这也是 RoboRSI 能用于实际部署的关键前提——不是所有提升都必须用延迟换取。
7. 排坑实录:四个坑让我重新理解了系统设计
任何系统都不是一次调通的。RoboRSI 从第一版到最终稳定版本,中间经历过几次差点推翻重来的问题。挑四个最有代表性的坑写出来,供大家参考。
7.1 坑一:适配层把动作“滤没了”
第一批验证时,我们加了非常强的低通滤波,目的是消除机械臂抖动。结果抖动的确没了,但整个动作也变得绵软无力,抓取速度慢了将近一倍,部分任务直接超时失败。排查半天发现问题不在滤波算法本身,而是滤波截止频率设计得过于保守,把模型输出的真实意图变化也一并滤掉了。
后来我们把截止频率调高到 8Hz,并引入运动意图预测:当模型连续两帧输出同一方向的动作时,放宽滤波幅度,快速跟进;当模型输出方向频繁切换时,加强滤波力度,抑制抖动。这样一来,动作既平滑又不拖沓。
7.2 坑二:技能模板太具体,模型反而变傻
第一版技能模板我们写得非常详细,几乎每个动作的每个参数都给定死。结果模型在遇到模板未覆盖的情况时表现极其僵硬。有一次任务要求换一种方式抓取一个异形物体,模板里规定的策略完全不适用,模型竟然强行按模板执行,把物体弄翻了。
后来把模板改成“前提-策略-自检”的检查项结构后,问题基本消失。核心思路是模板负责约束动作的安全边界和关键顺序,参数选择和策略微调交给模型实时决策。一个好的技能模板应该像一个有经验的老师傅画出的流程规范,而不是一份自动化脚本。
7.3 坑三:上下文太长,延迟暴涨
我们把大量传感器历史数据塞进上下文,试图让模型拥有“记忆”,但效果适得其反。token 数量直接翻倍,单次推理延迟从 300ms 涨到 800ms,任务成功率反而下降——因为延迟导致状态信息滞后,模型是在对“过时的世界”做决策。
解决方式是坚决做减法:历史数据不塞,只保留当前状态;多视角图像降为两路;力觉信息转为符号化描述。压缩之后延迟恢复,成功率还略有上升。这个教训很直接:在真实机器人上,上下文信息的新鲜度比数量重要得多。
7.4 坑四:仿真到实机的标定误差
我们在仿真环境里把成功率调到接近 90%,一上真机直接掉到 60%。仔细检查后发现,问题出在相机标定和机械臂运动学参数的微小误差上。仿真环境里模型看到的目标位置和实际执行位置完全一致,真机上则存在 1—2cm 的系统性偏移。
解决方法是给视觉检测的目标坐标加一个在线标定补偿:每次任务开始前,让机械臂末端先触碰几个已知标定点,通过反馈误差实时修正坐标系转换矩阵。这套标定流程只需要几秒钟,但让真机成功率重新回到了仿真水平。
8. 写在最后:这套方案的边界和下一步思路
RoboRSI 给了我们一个很明确的方法论:当模型权重的改进成本过高时,优先考虑系统结构性的优化。感知增强、技能缓存、动作适配、在线校正确实不属于“模型创新”,但它们对真实机器人系统稳定性的贡献,在我们的实验里是实打实的。这个方法也不只适用于大模型机器人的操作场景,任何“强模型 + 弱执行”的组合,理论上都可以借鉴这种外围系统增强的思路。
但说实话,这套方案也有明确的边界。如果基础模型的语义理解能力本身不过关,比如它无法区分“拿起来”和“推过去”,外围系统能做的只是让它稳定地犯错。我们在某个早期模型底座上做过尝试,任务成功率只能恢复到 20% 左右,怎么调外围模块都无济于事。所以我的建议是:先评估基础模型的“语义下限”,再决定是否值得花精力做外围系统。只有当模型大部分指令都理解正确、只是执行层面不稳定时,RoboRSI 这种路线才会给你惊喜。
下一步我们计划把技能缓存库做成自动构建的闭环:从成功执行的任务中自动提炼新的技能模板,同时把失败案例自动转化为自校正规则的候选。这样系统会随着使用逐渐积累经验,而模型权重依然保持不动。这条路我们还在走,跑出阶段性结果后再来分享。