动作表示选型指南:从连续控制到离散Token与Action Chunk 📅 发布时间:2026/9/9 11:12:59 👁 浏览次数: 1. 从“会想”到“会动”为什么动作表示是机器人基础模型的命门这两年机器人行业最热闹的词,莫过于“机器人基础模型”(Robot Foundation Model)。大家看到一个很明显的趋势以前我们做机器人,习惯“感知→规划→控制”三段式,每个模块单独调,像流水线一样。现在不一样了,大家希望用一个大的端到端模型,输入传感器信息,直接输出动作,省去中间层层手工设计的环节。这条路能不能走通,有一个绕不开的底层问题——动作表示(Action Representation)。说白了,就是模型最终要用什么形式把“下一步该怎么做”表达出来。别小看这个选择,它直接决定了模型怎么训练、推理速度快不快、能不能泛化到新任务、机械臂和灵巧手能不能真正动起来。我在过去两年的实际项目里,试过连续控制、离散 Token、各种 Action Chunk 的策略,踩了不少坑,也攒了不少一手经验。这篇博文就把这些经验摊开讲,聊透“动作表示”这个看似基础、实则致命的设计决策。在展开之前,先给新入坑的朋友画个像:这篇文章适合已经在做模仿学习、行为克隆、多模态大模型 机器人方向的研究者,也适合准备从传统控制转学习方法的工程师。如果你刚接触这个领域,建议先把基础的逆运动学、Transformer 结构过一遍,再回来读,会顺手很多。2. 动作表示的光谱:从连续数值到离散符号2.1 连续控制:最直觉、也最“自然”的选择连续控制,通俗讲就是让模型直接输出一组实数值,比如机械臂末端的目标位置(x, y, z, 四元数),或者各关节的角度增量。这是模仿学习里最常见的形式。早期的 Behaviour Cloning 工作基本都是这么干的用一个小型 MLP 或者 LSTM,输入图像和状态,输出动作的均值,然后配合高斯分布去采样。连续表示的好处很直接——它与真实物理世界是零距离对齐的。你输出一个 0.35 弧度的关节角,伺服驱动器就能直接跟踪,不需要额外的解码过程。控制周期可以做得很快,10Hz、20Hz 甚至 100Hz 都不是问题。对于需要高频反馈的任务,比如力控插拔、动态抓取,连续输出几乎是唯一选择。但连续控制有个让做学习的人非常头疼的问题:多峰性(Multimodality)。同一个观察状态下,最优动作不止一个。比如桌面上一杯水,我可以从左边够到,也可以从右边够到,两个轨迹都是成功的。用连续高斯分布去拟合这种多峰分布,学到的结果往往是所有可行动作的“平均”——伸手到杯子和桌子之间的某个地方,然后失败。这就是所谓的“均值塌缩”问题。2.2 离散 Token:把动作“翻译”成语言离散 Token 的思路,是借鉴大语言模型的做法把连续动作空间切成一个个网格,或者用向量量化(VQ-VAE)把动作编码成有限的“词表”。模型本质上是在做“下一个动作词”的预测。这样一来,动作就变成了序列,可以无缝接入标准的 Transformer 自回归框架。我印象最深的是 RT-2 那个方向的工作。它其实没有用物理上的真实关节角,而是用“末端执行器移动到 (x, y)”这种文本化的离散命令。再比如一些工作直接用 VQ 的方式把 7 自由度的机械臂动作压成 512 或 1024 个 Token,模型每次输出一个索引,再解码回连续动作。离散化的核心优势在于天然支持多峰分布。类别分布能表达“要么从左边伸手,要么从右边伸手”,而不是一个折中的结果。而且离散 Token 可以用语言模型成熟的那套训练技巧,包括 teacher forcing、KV Cache 加速、top-k 采样等。但代价也很大——精度损失。你切分的粒度再细,离散化这一步本身就在丟信息。对于一些高精度装配任务,毫米级的误差可能就让插头插不进插座。另外,Token 序列的长度受限于词表大小和上下文,高频精细控制会比较吃力。2.3 Action Chunk:给动作加上时间维度Action Chunk(动作分块、动作块)并不是一种独立的数值表示方式,而是对“时间步长”的一种重新定义。传统做法是每一步预测一个动作,执行一步,再重新预测。Action Chunk 的做法是:一次预测未来 H 步的动作序列,然后在执行端一次性或逐段执行。为什么需要它?因为单步预测有一个“累积误差”和“反应性震荡”的问题。你每一步都用最新观测重新规划,模型容易被噪声干扰,动作变成高频抖动。而且单步预测非常短视,它看不到“下一步会不会撞到阻碍”。一次预测未来 10~20 步甚至更长的动作块,能迫使模型做更长的推理,动作自然变得更平滑、更连贯。Action Chunking Transformers(ACT)这个工作把这种思想推到了一个新高度。它用 CVAE 做条件变分自编码器,在推演未来动作时引入一个风格的隐变量 z,再把 z 和当前的观测一起作为条件,生成 H 步的动作序列。注意,它输出的动作依然可以是连续值,也可以离散化。所以 Action Chunk 和连续/离散并不是互斥的,而是交叉的维度。3. 我选连续还是离散?四个维度的硬核评测3.1 精度视角:连续当仁不让如果你做的任务对毫米/毫弧度级别的精度有要求,不用犹豫,连续动作是基础。不管是装配、插拔、外科手术还是精密打磨,连续数值在分辨率上拥有天然优势。理论上,只要数值精度足够,你在动作空间里有无限粒度。离散方案受限于词表大小。词表从 256 涨到 4096,映射的分辨率确实在提升,但这是指数级增加的训练代价。而且,离散编码的高频细节损失,在真实物理系统中会被放大——你模型预测的 token 明明是 128,解码出来的速度却可能是 127.5,伺服系统就会产生微小抖动。3.2 推理效率视角:离散 KV Cache 完胜这是我觉得离散 Token 最“能打”的地方。现代主流的端到端策略,都逃不开 Transformer 这个骨架。对 Transformer 来说,离散序列有一个连续输出无法比拟的优势——缓存友好。自回归推理时,Token 序列逐个生成,历史注意力可以用 KV Cache 存下来,避免了重复计算。而连续输出通常需要一次性生成整个动作向量,如果把它看作序列,长度很短,缓存收益不明显。我自己实测,用 GPT 风格的策略头 离散 Token,在 A100 上推理 10Hz 控制频率毫无压力;但用连续回归头,虽然单步更轻,但为了保证控制平滑,经常需要堆更深的 MLP,延迟反而上来了。所以“离散一定更慢”是刻板印象,实际工程中未必如此。3.3 数据效率视角:看你的数据规模说话如果你的演示数据有几十万条、上百万条,离散 Token 配合语言模型的预训练范式,泛化潜力巨大。因为离散动作可以像词元一样做自监督预训练,用大量无标签轨迹来学习动作的“语法”。这是连续输出很难做到的——你对连续值做自回归预测,loss 一般就是 MSE,很难从海量无标签数据里学到有效的世界模型。但反过来,如果你只有几万条演示,离散 Token 的收敛速度通常不如连续控制。原因是离散化等于把问题先变成分类,再变成回归,多了一层需要学习映射的负担。小数据下,连续回归头往往直接、高效得多。3.4 泛化与扩展视角:离散更适合跨本体迁移这里说的跨本体,是指从仿真迁移到真实机器人,或者从 7 自由度机械臂迁移到 6 自由度机械臂。连续动作是和具体机械结构强绑定的,关节角、速度、力矩,换个构型就完全失效。离散 Token 如果设计得当——比如不直接表征关节角,而是表征任务级别的语义动作(如“向右移动 3cm”),那就有更强的迁移性。我有个自己试过的例子。用同样的离散动作空间,做“桌面抓取方块”任务,在仿真里训练完直接放到真实机械臂上,不用微调就能跑出八成以上的成功率。但换回连续动作,仿真到真实的 gap 就非常明显,sim-to-real 的差距全暴露在关节角度上。这也解释了为什么越来越多的人往“语义动作”方向靠。维度 连续控制 离散 Token 推荐场景 精度 高 中(受词表限制) 高精度装配、力控操作 推理效率 中高 高(配合KV Cache) 高频在线决策 数据需求 低 高 小数据场景选连续 跨本体迁移 差 好 仿真到实物、多机械构型4. 实操过程与细节:从选型到调参的一手流程4.1 连续控制策略头的实操笔记连续控制实现起来门槛最低,但想让动作不抖、不平滑,有几个细节值得注意。第一,输出头要分模块。不要用一个全连接层直接输出所有关节的(x,y,z,四元数,wangle,速度)。我一般把末端位置、姿态、夹爪开度拆成三个独立的输出头,因为它们的数值尺度和物理单位完全不同,混在一起会让 loss 不稳定。第二,四元数的归一化一定要在损失函数之后做。我在早期版本里踩过一个坑:模型输出的四元数没归一化,直接拿去算 FK,导致旋转分量出现尺度漂移,机械臂动作越走越离谱。解决方案很简单,在 loss 计算里对四元数做单位化,或者在网络输出后加一个 LayerNorm 后再做单位化,都能解决。第三,连续控制里经常用到GMM(Gaussian Mixture Model) 做输出分布。MOJO 那个系列的工作就验证了,用 5 个高斯分量拟合动作,能很大程度上缓解均值塌缩。实操中,我会给每个分量预测一个 log_std,并加上一定的正则(比如鼓励 std 不能太小),避免某个分量退化成一个尖峰,丧失多样性。这是很多论文里没提到的坑。4.2 VQ-VAE 离散动作的实操流程如果你决定走离散 Token 路线,第一步是训练一个动作编码器(通常用 VQ-VAE 或 VQGAN 的变体)。这个编码器的输入是连续动作序列(比如 7 维关节角 × 10 步的历史窗),输出是离散索引。训练完它之后,会把动作转换成 Token 序列,再去训练策略 Transformer。实操中有三个关键决策:词表大小: 我踩过的合理区间是 256~4096。太小了动作精度惨不忍睹,太大了训练代价高、稀疏问题严重。默认 512 起步。注意力窗口: 动作 Token 序列不像文本那么长,一般 256 以内就够。但如果结合图像 Token,需要再仔细做长度预算。码本对齐机制: VQ-VAE 最常见的 failure 是“码本崩溃”——很多 Token 索引对应到几乎一样的动作,表达力下降。我解决的方法是引入残差量化或优化器共享(shared embeddings),能让码本的利用率大幅提升。我在实际操作中,会把机器人动作(位置、旋转、夹爪)拆成三个独立的 VQ 码本,而不是一个。因为它们的尺寸和语义差别太大,混在一个码本里,会让模型优先应付位置分量,而忽略夹爪的状态。三个码本在推理时分别解码,再合成最终动作,体感上抓取成功率能提升 5%~10%。4.3 Action Chunk 的长度选择与执行策略严格来说,Action Chunk 里的“chunk size” H 是全局最重要的超参数,它直接决定了网络接收的观测范围和预测的未来长度。H 太小,失去了“未来规划”的意义;H 太大,一旦环境发生剧烈变化,模型预测的动作序列可能严重过时,执行起来会很别扭。从我项目经验和相关验证来看,存在一个H 的“甜点区间”。关键任务是桌面操作、简单抓取这类的,实践起来高控制频率任务在 H 取 10~15 左右比较稳;而一些慢速、需要长时间推理的任务,H 可以拉长到 30~50。但如果超过 50,变分推理的稳定性明显下降,而且对于需要即时反应的动态场景,长 chunk 会导致响应迟钝。在执行端,我强烈推荐“执行一半、重新预测”的策略,也叫receding horizon。比如 chunk 长度是 20,我先执行前 10 步,然后用最新观测重新预测一个新的 20 步 chunk。这样既保留 chunk 的长时规划能力,又不至于太迟钝。ACT 原始实现里也有类似机制,但很多人抄代码时没注意,默认执行完整个 chunk,效果就打折扣了。4.4 一份可直接参考的消融实验模板如果你想要快速搭建一套验证动作表示效果的框架,我建议用下面的最小消融组合:基线1:连续控制 MLP(早期行为克隆)基线2:连续控制 Transformer action chunk(H10)基线3:离散 token Transformer(自回归)基线4:离散 token Transformer action chunk(H10)在同一个数据集(比如 ALOHA 双臂或单臂操作数据的开源版本)上训练,统一用 roll-out 成功率做评价。一定要记录部署时的控制频率,因为这个指标在实际任务里跟成功率同等重要。我的测试结果经常是基线2 比基线4 差,但基线3 又会因为 token 精度不足,成功率不如基线2。所以最终选择的往往是在基线4的模式上,把“动作解码”阶段的连续化做细——即模型用离散 token 做高层规划,解码时用连续的 residual 修正。这种离散 连续残差的混合结构,是我目前最推荐的工程方案。5. 常见问题与排查技巧实录5.1 训练时 loss 掉了但 rollout 一塌糊涂这种情况十有八九出在“分布漂移”上——训练时用 teacher forcing,模型每一步都能看到真实动作作为条件,到了部署时输入的是自生成的带误差动作,误差越滚越大,策略就崩了。排查看两个点。第一,你的测试环境里是不是有很强的随机初始条件?如果有,考虑加 domain randomization,别让策略过度依赖固定初始状态。第二,检查你是否用了DAgger式的交互式训练。如果没法做交互式,那就退一步执行 action chunk 的部分执行策略,能明显减小误差累积。5.2 离散 Token 的码本利用率低,大量 token 闲置先用 t-SNE 或 PCA 可视化一下码本向量的分布,大概率是一堆向量挤成一团、只有少数几个分散开。解决思路还是那两条:一是加大commitment loss的权重(我一般从 0.25 调到 0.5~1.0),二是把“提特征”和“查码本”之间加上残差连接,逼着每个码本向量学习到更独特的语义。另外,可以检查一下 pre-trained 编码器的输入是否做了标准化。动作数据的量纲问题(比如关节角在 ±3rad,末端速度在 ±0.5m/s)如果不归一化,VQ 向量很难学到稳定的分布。5.3 Action Chunk 训练后动作不连贯,断点处跳变明显这个很典型。如果使用“执行一半再重新预测”的 receding horizon,前后两个 chunk 之间在动作空间里可能出现大跳变。我试过的最有效的缓解方法叫平滑混合:在窗口重叠区域(比如重复预测最后 5 步),用指数加权平均把旧 chunk 的尾部和新的 chunk 的头部融合起来。实现成本极低,但平滑效果立竿见影。如果还是跳,那往往说明模型学到的基本动力学就不对,可能是训练轨迹里本身就存在不连续,比如演示数据里的急刹、碰撞。先把数据集里的 jump 清理掉,再调平滑。5.4 多峰动作场景下,模型总是挑一种动作做连续控制遇到这个问题,用 GMM 能缓解,但 GMM 也有个毛病——训练到后期,模型会倾向于“贪心”地把概率集中到其中一个峰上,导致多样性退化。我建议用最大熵正则或者CVAE 的 KL 项来维持多样性,效果比单纯调 GMM 的组件数更稳定。在离散模型里这种情况相对少见,因为类别分布天然支持多峰。但如果你发现模型生成的动作经常出现“左手和右手一起伸”这种奇怪混合——那说明离散的粒度太大了,一个 token 实际上对应了多个不同的动作模式,需要增大码表或者拆开不同关节组。6. 经验总结与我的最终建议前端时间我跟朋友聊起这个领域,他问了一个很直接的问题:“你们折腾了这么多动作表示,到底哪种最好?”我的回答是:没有“最好”,只有“最合适”。如果项目周期很紧、数据量又不大,连续控制配合 action chunk 是能保证项目存活的最稳选择。如果团队有较强的数据积累和算力,想做真正具备泛化能力的模型,离散 Token 代表的是更可扩展的方向。从行业整体走势来看,大模型范式正在加速席卷机器人领域。但我始终觉得,机器人基础模型和纯文本大模型有个本质区别:机器人必须落到物理世界,动作表示不是一个纯学习问题,它同时是控制工程问题。这也意味着,谁能在“表示能力”与“物理可执行性”之间找到平衡,谁就能真正把基础模型做到能用、好用。最后送大家一个我在多次折腾后总结的口诀:先连续保底,再离散扩展,chunk 永远是催化剂。不管选哪条路,一定记得把“执行器物理约束”放在考察列表的最前面。没有哪篇论文会告诉你,某个 token 映射出来的关节角,可能导致机械臂穿过桌面——这些都得靠从仿真和实物联调中一点点积累。希望这篇文章能让后来者少走几个我走过的弯路,把更多时间花在真正有意思的决策与泛化问题上。