跳转至

动作表示与策略头

VLA 最难的桥梁是:语言和图像是离散/语义的,机器人控制却是连续、实时、受约束的。动作表示决定了模型能不能把“理解”变成稳定动作。


1. 机器人动作到底是什么?

在不同系统中,“动作”可能表示不同控制接口:

动作接口 例子 特点
末端位姿增量 \(\Delta x,\Delta y,\Delta z,\Delta r,\Delta p,\Delta y\) 操作任务常用,跨机器人相对容易
关节位置 \(q_1,\ldots,q_n\) 和具体机器人强绑定
关节速度 \(\dot{q}_1,\ldots,\dot{q}_n\) 适合连续控制,但要注意积分漂移
力矩/力控制 \(\tau_1,\ldots,\tau_n\) 最底层,学习难度和安全风险高
夹爪命令 open/close 或连续开合度 常作为独立维度

VLA 论文里常见的是“末端位姿增量 + 夹爪 + 终止信号”。例如每一步输出:

\[ a_t = [\Delta x,\Delta y,\Delta z,\Delta roll,\Delta pitch,\Delta yaw,g,e] \]

其中 \(g\) 是夹爪命令,\(e\) 是是否结束当前动作段。

1.1 先确定控制层级

设计动作空间前,先问:模型输出给谁?

VLA -> 高层动作 -> IK/轨迹规划 -> 关节控制器 -> 电机

或:

VLA -> 关节目标 -> 关节控制器 -> 电机

一般建议:

阶段 推荐动作空间 原因
新手桌面抓取 末端位姿增量 + 夹爪 最直观,跨机械臂较容易
固定机械臂项目 关节位置/速度 与底层控制接口一致
灵巧手 手指关节目标或低维手势 latent 自由度高,直接末端表示不够
移动机器人 线速度/角速度 与底盘控制天然一致
人形机器人 分层动作:高层任务 + 局部控制器 全身自由度太高,端到端难度大

不要一开始就让 VLA 输出力矩

力矩控制最接近物理底层,但对模型、数据、安全要求都高。新手更适合从位置或速度接口开始。

1.2 姿态怎么表示?

机械臂末端动作常包含姿态变化。常见表示:

表示 维度 优点 缺点
Euler 角 3 直观 有万向节锁,角度跳变
轴角 3 紧凑,适合小旋转增量 大角度时不直观
四元数 4 平滑,无万向节锁 需要单位化,双覆盖
6D rotation 6 神经网络训练稳定 需要转换回旋转矩阵

桌面操作里经常使用“小姿态增量”:

\[ [\Delta roll,\Delta pitch,\Delta yaw] \]

如果任务需要大范围旋转或连续姿态插值,四元数或 6D rotation 会更稳。


2. 坐标系选择

同一个动作可以放在不同坐标系中表达:

坐标系 含义 适用场景
世界坐标系 相对桌面/房间不动 固定工作站、相机外参稳定
机器人基座坐标系 相对 base_link 机械臂操作常用
末端坐标系 相对当前手爪方向 精细接近、插入、擦拭
相机坐标系 相对视觉观测 视觉伺服、多相机任务

坐标系不一致会直接毁掉训练

数据集中动作如果有的在世界系,有的在末端系,模型会看到同样画面对应完全不同的动作。训练前必须统一坐标系、单位、方向和动作尺度。


3. 离散动作 Tokenization

RT-2、OpenVLA 这类模型把连续动作变成 token,让模型像生成文字一样生成动作。

3.1 Binning

假设某个动作维度 \(x \in [-1,1]\),把它均匀切成 256 个 bin:

\[ \text{bin}(x) = \left\lfloor \frac{x - x_{\min}}{x_{\max} - x_{\min}} \cdot (N - 1) \right\rceil \]

其中 \(N=256\)。模型输出 bin id 后,再反量化回连续值:

\[ \hat{x} = x_{\min} + \frac{\text{bin}}{N - 1}(x_{\max} - x_{\min}) \]

直觉上就是:

-1.0 ---------------- 0.0 ---------------- +1.0
  0        ...        128       ...        255

3.2 数值例子

假设某一维末端增量 \(\Delta x\) 的范围是 \([-0.05, 0.05]\) 米,也就是每步最多移动 5cm。现在专家动作是:

\[ \Delta x = 0.01 \]

用 256 个 bin:

\[ \text{bin}(0.01)= \left\lfloor \frac{0.01 - (-0.05)}{0.05 - (-0.05)} \cdot 255 \right\rceil =153 \]

模型输出 token 153 后,反量化:

\[ \hat{x}=-0.05+\frac{153}{255}\times 0.1\approx 0.01 \]

这说明动作 token 不是“文字”,而是“被离散化后的控制数值”。

3.3 多维动作如何变成 Token 序列?

如果动作是 7 维:

\[ a_t=[\Delta x,\Delta y,\Delta z,\Delta r,\Delta p,\Delta y,g] \]

每一维都可以单独量化成一个 token:

<act_x_153> <act_y_120> <act_z_131> <act_roll_128> ... <gripper_close>

如果一次预测未来 4 步 action chunk,序列会变成:

step1: 7 tokens
step2: 7 tokens
step3: 7 tokens
step4: 7 tokens

也就是 28 个动作 token。自由度越高、chunk 越长,自回归输出越慢,这也是连续动作头和 FAST 这类方法重要的原因。

3.4 优点

  • 可以复用 LLM 的自回归训练方式。
  • 动作 token 能和文本 token 放在同一个序列里。
  • 实现简单,便于大模型微调。

3.5 缺点

  • 量化会损失精度。
  • 高频动作会产生很长 token 序列,推理慢。
  • 每个维度独立分箱,可能忽略动作维度之间的相关性。
  • 对灵巧手、双臂、全身控制这类高自由度系统不够优雅。

4. Action Chunking

逐步输出动作会遇到延迟问题。Action chunking 的做法是一次预测未来 \(H\) 步:

\[ a_{t:t+H} = [a_t, a_{t+1}, \ldots, a_{t+H}] \]

执行时可以滚动预测:

观测 o_t -> 预测未来 8 步 -> 执行前 1~4 步 -> 获取新观测 -> 再预测

优点:

  • 减少高层模型调用频率。
  • 动作更平滑。
  • 适合较慢的大模型推理。

风险:

  • 如果中途环境变化,后面几步可能过期。
  • chunk 太长会降低反应速度。
  • chunk 太短则无法解决延迟问题。

5. 连续动作头:Diffusion 与 Flow

现代 VLA 越来越常用连续动作头,尤其是需要高频、平滑、灵巧控制的任务。

这里的“连续动作头”可以先理解成:视觉语言模型负责理解图像和指令,动作头负责把这种理解变成一段实数动作。

图像 + 语言指令 -> VLM backbone -> 条件特征 z
条件特征 z -> action head -> 连续动作块 a_{t:t+H}

其中动作块通常不是一个动作,而是未来一小段轨迹:

\[ a_{t:t+H} = \begin{bmatrix} a_t \\ a_{t+1} \\ \cdots \\ a_{t+H} \end{bmatrix} \in \mathbb{R}^{H \times D} \]

\(H\) 是 chunk 长度,\(D\) 是每一步动作维度。例如末端位姿增量加夹爪可能是 \(D=7\),如果一次预测 8 步,就是一个 \(8 \times 7\) 的连续矩阵。

为什么不直接用一个 MLP 回归这个矩阵?

普通回归通常学的是“平均动作”。如果同一个状态下有多种合理做法,例如从杯子左侧绕过去或从右侧绕过去,MSE 会倾向于预测两条轨迹的平均值。这个平均值在数学上可能 loss 很低,但在物理上可能正好撞到杯子。

Diffusion 和 Flow 的核心动机就是:不要只预测一个平均答案,而是学习一个动作分布。

              Robot Policy
       Observation → Action Chunk
       ┌───────────┼───────────┐
       │           │           │
 Diffusion     Flow Matching   Autoregressive
       │           │           │
 去噪生成       速度场生成      Token生成
       │           │           │
Continuous     Continuous       FAST
 Action         Action           │
                        Action Tokenizer

5.1 Diffusion Policy

扩散策略把动作序列看成要生成的数据。它和图像生成里的 diffusion 很像,只不过生成对象不是图片像素,而是机器人未来几步动作。

假设专家数据里有真实动作块 \(a^0\)。训练时,我们随机选一个噪声等级 \(k\),往真实动作上加噪声:

\[ a^k = \sqrt{\bar{\alpha}_k}a^0 + \sqrt{1-\bar{\alpha}_k}\epsilon \]

其中:

  • \(a^0\) 是干净的专家动作块。
  • \(a^k\) 是被污染后的动作块。
  • \(\epsilon\) 是高斯噪声。
  • \(k\) 表示扩散步数,\(k\) 越大,动作越接近纯噪声。
  • \(o,l\) 分别表示视觉观测和语言指令。

模型学习的问题是:给你一个带噪声的动作块、当前观测、语言指令和噪声等级,请你把噪声找出来。

\[ \epsilon_\theta(a^k, o, l, k) \approx \epsilon \]

训练 loss 常写成:

\[ \mathcal{L} = \left\| \epsilon - \epsilon_\theta(a^k, o, l, k) \right\|^2 \]

直觉上,它不是直接问模型“正确动作是什么”,而是问:

这个动作块现在有点乱,你能看出里面混进去了多少噪声吗?

推理时没有专家动作,所以从一个纯噪声动作块开始:

随机动作噪声 -> 去噪一步 -> 更像动作 -> 再去噪 -> ... -> 可执行动作块

每一步都用当前图像和语言指令作为条件。最后得到的不是 token 序列,而是一整段连续控制轨迹。

5.1.1 一个抓取例子

假设任务是“拿起桌上的红色积木”,真实动作块可能长这样:

step 1: 向红色积木靠近
step 2: 继续靠近并微调姿态
step 3: 下降
step 4: 闭合夹爪
step 5: 抬起

Diffusion 训练时会把这 5 步动作整体加噪声,让模型学习如何把“乱七八糟的 5 步动作”恢复成“接近、下降、夹取、抬起”的轨迹。

这点很重要:它生成的是动作序列的整体形状,而不是每一步孤立预测。

5.1.2 为什么 Diffusion 适合机器人?

机器人动作经常有多峰性:

同一个目标:
- 可以从左侧绕过去抓
- 可以从右侧绕过去抓
- 可以先抬高手爪再下探
- 也可以贴着桌面慢慢接近

这些都可能是合理专家动作。普通 MSE 回归容易把它们平均掉;diffusion 更像是在条件分布中采样一条完整轨迹,所以更适合表示“多种都对”的情况。

优点:

  • 适合多峰动作分布,例如同一个目标可以从左边或右边抓。
  • 输出连续轨迹,动作平滑。
  • 在机器人模仿学习中效果很好。
  • 可以和 action chunking 自然结合,一次生成未来多步。

缺点:

  • 多步去噪会增加推理成本。
  • 实时控制时要优化采样步数。
  • 采样步数太少时动作质量可能下降。
  • 模型还需要低层控制器处理限幅、碰撞和安全问题。

5.2 Flow Matching

Flow matching 学习从简单分布到动作分布的连续变换。\(\pi_0\)、SmolVLA 等模型使用这类思路来生成连续动作。

如果说 diffusion 像是“从噪声里一步步擦出动作”,flow matching 更像是“学习一条把噪声搬运成动作的速度场”。

先定义两个点:

  • \(x_0\):从简单分布采样的噪声动作块。
  • \(x_1\):数据里的真实专家动作块。

然后在它们之间取一个中间时刻 \(\tau \in [0,1]\)

\[ x_\tau = (1-\tau)x_0 + \tau x_1 \]

\(\tau=0\) 时,\(x_\tau\) 是噪声;当 \(\tau=1\) 时,\(x_\tau\) 是真实动作。模型要学的是在中间任意位置,应该朝哪个方向流动:

\[ v_\theta(x_\tau, o, l, \tau) \approx x_1 - x_0 \]

也就是:

你现在在“噪声动作”和“真实动作”之间的某个位置。
下一小步应该往哪里走,才能更接近真实动作分布?

推理时,从随机噪声动作块 \(x_0\) 出发,沿着模型预测的速度场积分:

\[ \frac{dx}{d\tau} = v_\theta(x_\tau, o, l, \tau) \]

最后到 \(\tau=1\) 附近,就得到一个可执行的连续动作块。

5.2.1 Diffusion 和 Flow 的关系

两者都在做“从简单分布到动作分布”的生成,只是学习目标不同:

方法 学什么 推理直觉
Diffusion 学怎么去掉噪声 从纯噪声开始反复去噪
Flow Matching 学速度场/流方向 从噪声沿着路径流到动作

Flow matching 常被认为采样路径更直接,工程上可能用更少的步数生成动作。但它仍然需要多步积分,所以并不是完全没有推理成本。

5.2.2 为什么 VLA 喜欢 Flow?

VLA 的 backbone 往往已经很大,如果动作头也需要很多自回归 token 或很多 diffusion steps,实时性会很吃紧。Flow 类方法的吸引力在于:

  • 输出是连续动作,不需要逐维离散化。
  • 能生成一整段 action chunk。
  • 比普通 MLP 更能表达复杂动作分布。
  • 采样过程通常比长 token 序列更适合高频控制。

可以把它理解成介于“简单连续回归”和“复杂扩散采样”之间的一类生成式动作头。

5.3 FAST

FAST(Frequency-space Action Sequence Tokenization)严格说不是 diffusion/flow 这种连续动作头,而是“更聪明的动作 tokenization”。它放在这里,是因为它解决的也是高频动作序列难生成的问题。

控制频率越高,平滑信号相邻 timestep 的变化越小,相邻 action token 的相关性越强,next-token objective 中新增信息量下降;模型甚至可能落入“复制最近动作”的差局部最优。

普通动作 tokenization 是逐时间步、逐维度离散化:

step1_x, step1_y, step1_z, ...
step2_x, step2_y, step2_z, ...
step3_x, step3_y, step3_z, ...

问题是动作序列很长,而且相邻时间步高度相关。比如一段平滑接近动作:

0.01, 0.012, 0.013, 0.014, 0.015

逐点 tokenization 会把每个数都单独编码,但其实这段轨迹主要表达的是“缓慢向前移动”。

FAST 的思路是:先把时间序列从时域变到频域。频域里不直接描述“每一帧动作是多少”,而是描述:

这段动作的整体趋势是什么?
有没有快速抖动?
高频细节有多少?

常用工具是离散余弦变换(DCT)。对一个动作 chunk 做 DCT 后,会得到一组频率系数:

原始动作序列 -> DCT -> 低频系数 + 高频系数

低频系数控制整体形状,例如向前、下降、抬起;高频系数控制快速变化,例如手指细微调整、灵巧手接触瞬间的动作变化。

然后再对这些频率系数做 tokenization。这样模型不必一个时间点一个时间点地拼动作,而是在更压缩的频域里生成整段动作。

总结:先把整个动作序列压缩成“运动频率结构”,再 Token 化。

5.3.1 一个直觉例子

假设某一维动作是“夹爪逐渐闭合”:

0.0, 0.1, 0.2, 0.3, 0.4, 0.5

它的主要信息是一个平滑上升趋势。频域表示可以用少量低频系数表达这个趋势。

如果动作是“接触物体时快速抖了一下”:

0.0, 0.1, 0.2, 0.45, 0.25, 0.5

那就需要更多高频系数来描述这个突然变化。

这就是为什么 FAST 对灵巧动作有意义:灵巧手和双臂协作里经常既有整体运动,又有局部高频细节。

5.3.2 FAST 和普通动作 token 的区别

方法 编码对象 优点 代价
普通 tokenization 每个时间步的每个动作维度 简单直观 序列长,重建高频动作困难
FAST 动作 chunk 的频率系数 更压缩,更适合长 chunk 需要频域变换和反变换

推理时,模型生成的不是直接动作值,而是频域 token。系统需要先把 token 还原成频率系数,再通过逆 DCT 还原成时域动作序列。

生成频域 token -> 反量化为频率系数 -> 逆 DCT -> 连续动作 chunk

所以 FAST 的关键不是“动作变连续了”,而是“用更适合序列压缩的方式离散化动作”。

怎么选动作头?

如果你主要读 OpenVLA/RT-2,先学离散 token;如果你要做平滑操作、双臂或灵巧手,尽早学习 diffusion/flow;如果你关心大模型自回归和高频动作的结合,就看 FAST。

可以用一个简单判断:

需求 更适合的动作头
复用 LLM 生成范式,方便微调 离散动作 token
动作维度低,任务简单 连续 MLP 回归
同一状态有多种合理动作 Diffusion / Flow
需要平滑、高频、长 chunk 控制 Diffusion / Flow / FAST
想在自回归模型里更高效地产生长动作序列 FAST

6. 动作头的训练损失

不同动作表示对应不同 loss:

动作头 输出 常用 loss 直觉
离散 token 每一维的 bin/token Cross Entropy 预测正确 token
连续回归 实数动作 MSE / L1 让动作数值接近专家
Gaussian policy 均值和方差 Negative Log Likelihood 学动作分布和不确定性
Diffusion Policy 去噪动作序列 diffusion denoising loss 从噪声恢复专家轨迹
Flow Matching 速度场/流 flow matching loss 学从噪声到动作的连续变换

低 loss 不等于能执行

离线 loss 低,只说明模型在数据分布上像专家。真正执行时,模型自己的动作会改变下一帧观测,状态分布可能偏离专家轨迹,这就是行为克隆的复合误差。


7. 低层控制器仍然重要

VLA 输出的动作通常不是直接打到电机力矩上,而是送到低层控制器:

graph LR
    A[VLA 输出末端增量] --> B[运动学/限幅/滤波]
    B --> C[IK 或轨迹生成]
    C --> D[关节位置/速度控制器]
    D --> E[电机驱动]

必须处理:

  • 关节限位
  • 速度和加速度限幅
  • 碰撞检测
  • 奇异位形
  • 夹爪力限制
  • 急停和人工接管

端到端学习不等于把安全交给神经网络。真正上机器人时,传统控制层是最后一道边界。


8. 实践检查清单

训练或调试 VLA 前,先确认:

  • 动作单位统一:米、弧度、秒。
  • 坐标系统一:base、world、eef、camera 不混用。
  • 动作范围合理:不要让极端值主导归一化。
  • 夹爪命令清晰:开/合/保持是否可区分。
  • 控制频率匹配:模型频率、数据频率、底层控制频率一致或可重采样。
  • 有限幅和安全层:模型输出异常时不会撞机。
  • 姿态表示连续:避免 Euler 角在边界附近跳变。
  • 反归一化正确:模型输出 token/归一化动作后能还原到底层控制单位。