机器人学习这个圈子里最近大家都在聊RoboTTT。这名字拆开看Robo指机器人TTT一般取Test-Time Training测试时训练的意思合起来就是在机器人策略上做测试时训练。但它更吸引我的点是后半句Context Scaling for Robot Policies直译是面向机器人策略的上下文缩放。这两个词组合在一起刚好戳中了当下具身智能领域一个很尴尬的现状——模型参数越来越大训练数据越来越多但部署到新环境里策略依然很容易失忆。我这一年多试过各种微调方案也踩过不少坑越做越觉得与其每次换个场景就重新调权重不如换条思路把上下文这个东西用起来。RoboTTT的思路正是如此。这篇文章我会从原理到工程实现完整拆一遍这条技术路线也会把复现过程中最容易被忽略的坑一并讲清楚。适合正在做机器人策略部署、做模仿学习或者对具身智能前沿方案感兴趣的研究者和工程师参考。1. 为什么机器人策略卡在了上下文太短1.1 固定长度输入的隐形天花板传统机器人策略的输入设计注意力基本都放在最近发生了什么上。以行为克隆为例一个典型策略接收的观测是最近10帧或20帧图像外加当前关节角度、夹爪状态然后输出一个动作或动作序列。这在简单任务上没问题但一旦任务变长、环境变了固定长度的历史窗口就变成了一道隐形天花板。原因其实不难理解。策略看到的信息只有最近这一小段它不知道这个任务是怎么开始的不知道前面尝试过什么更不知道类似任务在历史演示里是怎么处理的。于是策略只能做一个局部反应器根据眼前的像素和状态猜一个动作。遇到没见过的情况它就只能硬猜。你在仿真里跑得好好的策略换个光照、换个物体颜色成功率立刻下滑很多时候不是模型容量不够而是它手里真正能参考的信息太少了。这种设计本质上是把一个连续决策问题硬生生切成了一个个独立的单步映射。每一步的输入都一样长但这20帧图像背后的语义上下文——比如用户指令、任务进度、此前失败的经历——全都被丢弃了。1.2 从大模型那里借来的上下文概念Transformer架构进入机器人领域后局面发生了很大变化。RT-2、Octo这类工作把语言指令、图像观测、甚至历史动作都串成一个token序列模型本质上变成了一个机器人领域的多模态序列模型。这套做法和LLM高度相似所以顺理成章地引入了context window上下文窗口的概念。上下文窗口决定了模型在预测下一个token时最多能看到多长的历史。RT系列早期模型受限于视觉token数量一条指令加几张图就占掉了大半窗口后来的工作不断把窗口加长但大部分工作的重心仍然放在如何塞进更多观测上而不是如何让策略在推理时动态扩展上下文。这里就出现了一个关键差异LLM面对长文档时可以靠大上下文做检索、类比和推理但机器人策略的大多数训练流程仍然只把上下文当作一堆历史帧的容器并不指望它在部署时能继续往里写东西。换句话说Transformer给机器人策略打开了上下文这扇门但门里的路还没人认真铺。1.3 上下文太短时策略会犯什么错我实际跑过一批长程操作实验最有代表性的一个场景是把物体放进抽屉再关上。固定窗口策略在训练分布里几乎满分但在一个新桌面、新光照、物体起始位置偏移的情况下它经常会做到一半就停下来或者反复去抓同一个位置好像完全忘了这个任务要做到哪一步。问题就出在上下文长度上策略只能看到最近几帧当物体被手抓住后、正在移动的过程中单靠当前帧很难判断这一步是在放置还是在调整姿态。但如果上下文里有任务开头用户说把物体放进抽屉的指令有前几步手已经接近目标区域的记录模型就有足够信息推断当前意图。这其实是机器人策略普遍面临的一个困境训练时上下文有限推理时又没有机制去扩充信息。RoboTTT想解决的就是这两个问题一起解决。2. 从推理时自适应到RoboTTT一条反直觉的路线2.1 测试时训练并不是新东西但机器人场景完全不一样Test-Time Training本身不是新鲜概念。视觉领域早就有人提过模型在测试阶段用自监督任务比如旋转预测、掩码重建更新一部分参数让特征表示适应新分布。语音和自然语言处理里也有类似的做法。核心思想只有一个模型不能永远停在训练时的状态部署时遇到新数据应该现场再学一点。但机器人场景有几个独特难点。第一机器人策略的输入是流式的每个时刻都在产生新观测测试时训练必须在实时控制回路里完成不能像图像分类那样离线慢慢调。第二机器人动作预测对延迟极其敏感你不可能在每一步控制前都跑一遍反向传播。第三机器人数据分布变化往往是结构和因果性的不只是光照变化那么简单任务目标变了、物体位置变了、甚至机械臂末端执行器换了这些都会让特征分布大幅偏移。所以把传统TTT直接搬过来大概率会翻车。这也让我看到RoboTTT这条路线真正的价值它没有一上来就想着改权重而是在上下文层面做文章。2.2 RoboTTT的核心主张权重不动上下文狂涨RoboTTT最抓眼球的表述是Context Scaling也就是上下文缩放。它主张在测试阶段不更新模型权重而是把越来越多的交互上下文写入一个可扩展的上下文缓冲让策略基于这个不断增长的上下文来做决策。粗看反直觉模型还是那个模型凭什么上下文变长就能变强其实这正好符合Transformer的注意力机制特性。注意力最擅长的事情就是让当前预测token去关注输入序列里最相关的部分。你把过去5分钟的交互过程都写进上下文策略在预测动作时就能直接attend到任务开始时的指令3分钟前那次失败的轨迹这些关键节点相当于给策略配了一个外置工作记忆。这和人类翻手册、看笔记做事的逻辑很像。换个角度来看Context Scaling也可以理解成把测试时训练要学的东西从参数搬到了上下文里。传统的微调是把新知识写进权重而RoboTTT是让新知识以token的形式出现在输入侧。这避免了一大堆麻烦不需要计算梯度、不会覆盖旧知识、不会陷入过拟合。2.3 它要解决的两件事快速适应和不遗忘我见过太多微调方案解决了适应却牺牲了遗忘。一个模型在任务A上微调完之后再去任务B任务A的表现往往明显下降这就是灾难性遗忘。尤其机器人策略的数据分布差距大微调次数一多模型几乎变成一个只会做最近任务的专用控制器。RoboTTT用上下文缩放同时处理这两个诉求。适应新任务时策略只需要把新任务的观测、动作、反馈追加到上下文里注意力机制会自动把权重分配到相关位置切换任务时清空或切换上下文缓冲模型自然回到原先的知识体系。整个过程不碰任何权重所以理论上不存在遗忘问题。这意味着RoboTTT特别适合多任务、频繁切换的部署场景。比如一台机械臂白天分拣零件、下午做装配晚上换一条产线做码垛按传统流程每个任务都得重新微调一版模型用RoboTTT的方案你只需要准备对应的演示记忆库和上下文缓冲策略主体完全共享。3. 拆开RoboTTT上下文缩放的核心机制与工程实现3.1 组成框架Context Buffer、Memory Retriever、Policy BackboneRoboTTT这类方案只要拆开看基本绕不开三个核心部件。第一是Context Buffer上下文缓冲它是整个方案的工作台用来管理和拼接测试时不断增长的信息。原始观测、动作执行结果、语言指令、成功或失败的反馈信号都被组织成token序列放进这个缓冲里。它和传统KV缓存不一样的是它需要支持动态追加、截断、摘要压缩。第二是Memory Retriever记忆检索器负责从预先构建的演示库中找出与当前任务最相似的片段。这里可以走文本检索、轨迹相似度检索也可以用学习式的embedding检索。RoboTTT的Context Scaling并不是凭空无限扩展而是有选择地引入历史演示作为参考这样策略面对新情况时能回想起类似场景是怎么处理的。第三是Policy Backbone策略主干它可以是RT-2、OpenVLA这类视觉语言动作模型也可以是一个收敛良好的扩散策略。RoboTTT的理念是策略主干本身不一定要改动关键是训练时要让它习惯把上下文作为决策依据。这三个部件合在一起就构成了一条完整的上下文缩放管线检索器从记忆库中捞参考缓冲把参考和历史观测串成序列策略主干在序列上做动作预测。3.2 推理时的数据流一帧一帧往上下文里喂下面我用伪代码把整个推理循环画一下。这里刻意不做具体框架绑定因为你用PyTorch、JAX或者别的库都能实现同样逻辑。# 初始化加载策略主干和演示记忆库 policy load_policy_backbone() demo_memory load_demo_memory() retriever load_retriever() # 上下文缓冲初始为空或者只包含任务描述token context [] task_description tokenize(把红色方块放到蓝色盒子里) context.append(task_description) # 检索与当前任务相关的演示片段 related_demos retriever.search(task_description, top_k5) for demo in related_demos: context.append(demo.tokens) # 推理循环 while not task_done: obs robot.get_obs() # 当前观测图像/状态 action_hist recent_actions[-10:] # 最近动作记录 context.append(encode_obs(obs)) context.append(encode_actions(action_hist)) # 防止上下文过长做一次压缩/裁剪 context maybe_compress(context, max_budgetMAX_TOKENS) # 策略读取完整上下文输出动作 action policy.predict(context) robot.execute(action) # 把执行结果和反馈追加回上下文 context.append(encode_feedback(action, successNone))这个循环里最关键的一行是maybe_compress。虽然叫Context Scaling但工程上不可能真的让序列无限增长。上下文越长注意力计算量越大而且无关信息太多会稀释注意力权重。所以RoboTTT在推理时会持续做缩放新增信息进入缓冲旧的、不再重要的信息会被摘要、丢弃或压缩成少量token。3.3 上下文压缩与Token预算不能真的无限加这里展开讲讲缩放这个词的真正含义。它不只是单调变长而是一种动态的资源管理策略。我在实验里习惯把上下文分成两层短期工作记忆与长期演化记忆。短期工作记忆保留最近几秒的观测和动作它是策略做精细控制的基础长期演化记忆保存任务层面的关键事件比如第3步成功第一次抓取失败。压缩时优先压缩长期记忆中的重复帧、相似状态用一句文本摘要代替几十个视觉token。比如在2秒到5秒之间连续调整了三次夹爪位置一句话就能代表几十帧图像信息。Token预算也需要根据策略主干的注意力窗口来定。如果主干用的是32k上下文窗口的模型那初始给到的预算可以是16k剩下16k留给新增交互信息如果主干只有4k窗口就得更激进地压缩甚至采用滑动窗口加重要事件锚点的设计方案。我自己的经验是在视觉token占大头的情况下RoPE类位置编码的Transformer对长上下文里夹杂摘要token还是比较友好的但前提是摘要token的语义要和原始信息对齐。这个对齐怎么保证答案在训练阶段。3.4 训练阶段怎么配合模拟长上下文推理如果只在推理时加长上下文而训练时模型的上下文很短模型大概率不知道该怎么利用那些多出来的token。所以RoboTTT的训练流程必须做两件事一是随机构造长上下文训练样本二是训练辅助自监督任务让模型学会利用上下文。长上下文样本可以从完整轨迹里随机截取而不是固定从起始帧截取。这样模型会看到不同阶段的上下文也不至于对上下文总是包含任务开头产生依赖。训练时还会做模拟压缩把部分历史帧替换成文本摘要或者变短的视觉token强制模型在训练阶段就适应压缩后的上下文形态。第二件事尤为重要。RoboTTT会给策略主干加一两个辅助任务比如根据最近上下文预测当前任务进度根据长期记忆预测下一步该执行哪个子任务。这些辅助任务本质上是在教模型从上下文中提取决策依据。如果只是简单地把上下文拼接喂进去模型很可能把所有上下文都当成噪声背景注意力还是集中在最后几帧图——那就白做了。我当时跑的时候发现一个规律辅助任务的设计要让模型必须去关注中间区域的上下文而不是只盯着最后的观测。比如把任务进度做成一个离散label让模型用中间段的演示参考来预测这一招非常有效。4. 与主流机器人策略的同台对比RoboTTT赢在哪里4.1 四种方案的关键差异为了说明RoboTTT的位置我把它和三类常见路线放在一个表里对比。方案适应新环境的方式是否修改权重是否会遗忘样本效率部署延迟固定窗口行为克隆策略不支持直接换场景重训否推理时不学习不适用低低在线强化学习微调与环境交互后更新策略是严重低中参数微调Fine-tuning在新数据上继续训练是高中中RoboTTT推理时扩展上下文并检索演示否理论无高中高这个表能看出一个核心趋势RoboTTT用略高的部署延迟换来了快速适应不遗忘高样本效率的组合这个组合在现在其他方案上很难同时出现。当然表格里的延迟不低主要多出了检索和压缩两个环节。但这两个环节都可以用异步方式优化检索不需要阻塞每一次动作预测可以每隔几秒更新一次压缩也可以放在控制周期之外做。这样一来真正挡住主控制回路的延迟只会略微增加。4.2 为什么检索上下文比重新训练更实用我从实际部署角度做一个成本估算。假设你有一套训练好的策略要适配一条新产线的10个工位。参数微调流程是每个工位采集数据、标注、训练、验证、部署就算全部自动化一个工位也要花几个小时前提还是显存充足、不出现灾难性遗忘。RoboTTT的流程则完全不一样。你只需要把每个工位的演示视频或轨迹整理成演示记忆库接到检索器后面。部署新工位时输入一个任务描述检索器自动找参考片段策略直接开始干活。整个过程可能只需要十几分钟而且之前的工位完全不受影响。这种便利性在服务业机器人和家庭机器人场景更有价值。用户的需求千奇百怪把桌上的马克杯放到厨房水槽里这种描述每个家庭都不一样。你不可能给每个家庭微调一次模型但你可以给每个家庭留一段演示视频。RoboTTT本质上让机器人能够在推理时参考用户提供的演示这就是一种上下文层面的即时学习。4.3 代价是实打实的计算、检索依赖与理论边界说了一堆好处也得说说它的代价。最直接的代价是上下文处理开销。一个长上下文Transformer的自注意力计算复杂度是O(n²)n是token数量。实际工程中能在128k上下文上跑靠的是FlashAttention、稀疏注意力、KV Cache等优化但部署到机器人车载算力上仍然可能吃紧。第二个代价是检索质量直接决定策略上限。如果演示库本身分布偏差很大检索器召回的参考片段和当前任务相关性差策略反而可能被误导。这个和RAG系统遇到的问题同源垃圾进垃圾出。第三个代价是理论边界仍然存在。Context Scaling不可能完全替代物理规律的学习。比如涉及精确力控的任务光靠看上下文里的图像和动作模型很难凭空学会接触力的调整策略。这类任务该上适配器还是得上上下文缩放解决的是高层决策和任务理解层面的泛化不是所有问题。5. 复现与部署时我踩过的那些坑5.1 上下文越长越好是第一个大坑我刚实现第一版RoboTTT思路时下意识把上下文窗口开到接近模型上限幻想着信息越多越好。结果测试时成功率不升反降模型开始在奇怪的地方重复执行动作。后来查注意力热力图才发现当上下文里塞了太多相似的视觉token某些关键token的注意力权重会被严重稀释模型几乎注意不到任务指令。正确的做法是给上下文做分段和分层。第一步把语言指令、演示参考、最近观测这三类token分开第二步在注意力机制中给不同类型的token分配不同的注意力掩码或权重偏置第三步定期压缩重复的视觉token。这样虽然上下文总量看起来小了但决策可用的信息浓度反而更高。这个教训我一直记着上下文缩放的目标不是让序列多长而是让序列里每一段都对当前决策有用。5.2 训练与推理上下文分布不一致直接掉点这是我在消融实验里发现的第二个大问题。训练时我用的上下文主要来自人工截取的完整轨迹推理时系统把实时交互记录检索演示混在一起。结果模型在训练时表现良好一到真机部署就崩。原因其实很简单模型没有见过实时记录这种风格的上下文尤其是我在实时记录里加了成功/失败反馈token训练时根本没有这种输入。后来的解决方案是在训练时显式模拟推理的上下文结构包括随机插入检索片段、随机加入一些模拟失败的反馈token甚至随机打乱某些段落。经过这样对齐之后训练和推理的性能差距才被压缩到很小。这个坑其实很多RAG类方案都会踩。上下文不只是内容集合它有结构、有位置、有格式。你训练时怎么拼推理时就必须怎么拼任何不一致都会表现为诡异的性能下降。5.3 演示库里混入脏数据策略会照单全收RoboTTT的检索器会把相关演示片段当成参考案例。但参考案例本身是有好坏的。如果演示库里有几个错误的、低质量的轨迹恰好和当前任务相似检索器把脏片段召回后策略很可能照着错误示范来一次任务直接失败。我一开始天真地以为演示库只要量够大就行。后来我统计分析了失败案例发现大部分失败都关联到几个特定演示片段——它们的动作抖动、目标位置偏离或者根本没有完成任务。解决脏数据问题没有捷径一是做数据清洗把未完成、抖动过大、标注错误的轨迹全部剔除二是给检索器加置信度低于阈值就不召回宁缺毋滥。这个经验对任何做机器人演示学习的项目都适用。5.4 辅助任务选不好等于给策略添乱前面说训练时要加辅助任务但辅助任务不是随便加的。我试过加一个预测未来第5帧图像的自监督任务结果策略主干大量特征都用来理解未来图像长什么样对动作预测的贡献反而减弱了。更适合RoboTTT的辅助任务应该是那些必须在长上下文上做推理的任务。例如预测当前任务进度是第几步预测下一步该操作哪个物体预测最近一次成功/失败发生在哪一步。这些任务能迫使模型在长上下文里建立时间索引和因果链对动作预测是有正向作用的。如果你在做类似方案我的建议是设计辅助任务前先想清楚这个任务是否需要跨较长时间跨度的信息如果只看最近两帧就能做那它对Context Scaling的训练帮助就非常有限。6. 如果让我在真实任务上试用一套最小落地流程6.1 从仿真单任务开始不要直接上真机任何一个新的策略训练管线我都建议先在仿真里跑通。仿真环境的优势是低成本复现和自动评测。你可以用MuJoCo、Isaac Lab或者他们自家的仿真平台先选一个中等难度的单任务比如抓取并放置到指定位置。第一步先把基础策略训好这一步和普通行为克隆没有区别。第二步再加入RoboTTT的上下文机制从多段轨迹中检索相似片段作为上下文前缀训练策略在上下文条件下预测动作。第三步才是加入测试时动态扩展让策略真正在推理循环里持续追加交互记录。我强烈建议每一步都设置一个明确的性能门槛。比如基础策略在干净环境下成功率要超过90%再加入上下文机制后不应低于这个值如果低于说明上下文构造方式有问题不如先回头查。6.2 数据与基础设施准备演示库、检索模型、上下文缓存演示库是整套系统的地基。每条演示轨迹不只存图像和动作还需要附带语言描述、任务标签、以及关键步骤的时间戳。这样的元数据会让检索器的工作轻松很多。检索模型可以先用现成的多模态embedding模型比如CLIP对每个轨迹片段做embedding运行时用向量的余弦相似度做召回。如果条件允许再进一步微调一个小型的轨迹检索模型专门对齐任务描述-轨迹片段之间的语义。上下文缓存建议单独用一个进程维护。机器人控制频率通常是50Hz到100Hz而检索和压缩这类重操作跑不了那么快。更合理的做法是控制进程只负责读取最新上下文维护进程每隔一段时间异步更新演示参考和压缩摘要。6.3 三个必看的评测指标评测时不要只看最终成功率至少要跟踪三个维度。第一个是任务成功率这个不用说。第二个是首次尝试成功率。很多长上下文策略在失败一次后会从上下文里学到这样不对然后第二次尝试成功。但实际部署中第一次失败就可能让人对机器人失去信心所以首次尝试成功率必须单独统计。第三个是切换任务后的恢复表现用它来衡量遗忘程度做完任务A再切换到任务B再切回任务A成功率是否还能回到原有水平。我在实验中发现RoboTTT在第二个和第三个指标上明显优于参数微调方案但在第一个指标上如果任务本身需要精确力控它可能并不占优。评测时一定要根据自己场景选择主要指标。6.4 一点优化心得先控制延迟再控制效果最后分享一个部署层面的心得。很多人在做这种长上下文策略时一上来就追求最优效果结果延迟超标整个部署失败。我的建议是先把延迟压到规定范围内再开始提效果。具体做法是先量化策略主干的推理耗时然后把检索和压缩都放到异步线程保证主循环延迟稳定再评估上下文在最大长度下是否出现显存溢出如果溢出先做激进压缩保证任务能跑起来最后才去调整检索TopK、上下文预算、压缩频率这些参数来拉高成功率。这个顺序能让你少走很多弯路。我到现在还记得第一次让长上下文策略在仿真里稳定跑完长程任务时的感觉权重完全没有动只是往上下文里塞了更多参考信息策略就从一个单步反应器变成了一个会回头看、会临时学的系统。这种变化让我确信Context Scaling这条路在机器人策略上还有很大的挖掘空间。如果你正在被微调易遗忘、泛化难、上手慢这些问题困扰RoboTTT这条路线值得你投入一个完整的实验周期去验证。