How to?

papers batch 2

May 25, 2026
papers
13 Minutes
2567 Words

ALOE (9): 智元 Rushuai Yang | Maoqing Yao

一句话:bc 预热后在 rollout 过程中训练一个 Q_net(critic) 支持干预,并从replay-buffer(原始数据、人类干预和历史rollout轨迹)中采样一个带奖励的转移 (s, a_chunk, r_chunk, s_next),自举部分则使用 Q_net(current_policy(s_next)),估计悲观奖励 Q_pess 的同时更新 Q_net,随后 Q_net 评估 current_policy 在 s 处的多次采样平均表现. 如果 a_chunk 价值比 s 高则给 a_chunk 整个高权重. demo 装手机还不错.

  • 实际上使用多个 Q_net 取 min 来进行悲观估计.
  • Q_net 这部分看出是 off-policy 的,因为这里 r 来自 replay_buffer 而 a_next = current_policy(s_next) 则来自 current_policy. 这是 off-policy 多种形式中的一种.

GreenVLA (10)

有很多训练 trick,包括5阶段课程学习、质量指标筛选(公开数据集质量表). 然而,demo 没有什么新东西。

GuidedVLA: ybw (11)

一句话:给 pi0 action token 加手工设计的 auxiliary tasks.

  • 让 action tokens 的 q 去 attend depth_proj(depth_enc(img)) 的 kv 得到 y1
  • 从 action tokens 学习新的 q 以及从 concat(image tokens, action tokens) 学习新的 kv 用于:
    • 计算 这里 qk 的 attn score,这个 score 和 GT attn mask patchify 得到 obj_loss (ground truth 由其他 grounding 模型生成)
    • 以及产生 pred_skill(one-hot,类似于 “pick” “place” “hold” 分类),计算额外 skill_loss. 这里也会得到 y2 y3
    • action tokens += linear(concat(y1, y2, y3))
    • (代码中被称为 control_qkv)
  • 以上带门控
  • 以上给 action expert 的指定层去做,代码默认 [9, 10, 11, 12] (pi0 expert 一共 18 层)

关于 control net

1
output = original_attention(x) + # 这里是纯 pi0 的
2
linear(control_attention(x)) # 只不过这里 linear 初始化为 0 防止初始就让老模型乱掉

Interleave-VLA: fcx (12)

1
# 输入包含当前观测图像、交错的图文指令及机器人状态
2
# 使用 <BOI>/<EOI> 特殊 Token 标识指令中的参考图像
3
-instr_tokens = tokenizer.encode("把那个蓝色的带条纹的勺子放到盘子里") # 常规 VLA
4
+instr_tokens = tokenizer.encode(f"把 <BOI>{crop_img}<EOI> 放到盘子里") # 本方法,操作者在GUI手动框选目标
5
obs_tokens = visual_encoder(current_observation)
6
# 将观测、交错指令和本体感受状态拼接为统一序列
7
input_seq = concat(obs_tokens, instr_tokens, robot_state)
8
# VLA 模型直接生成连续动作序列
9
actions = VLA_Model.predict(input_seq)
flowchart TD
    img["Observation Images
(B, n_cam=3, H=224, W=224, C=3)"] --> siglip["PaliGemma Image Encoder(SigLIP)"] instr_img["Instruction Images (Crops/Web/Sketch)
(B, n_imgs, 224, 224, 3)"]:::highlight --> siglip txt["Interleaved Tokens (Text + BOI/EOI)
(B, max_len=N)"]:::highlight --> tok["Gemma Tokenizer + Special Tokens"]:::highlight siglip --> obs_vis["Observation Tokens
(B, 3*256=768, D=2048)"] siglip --> instr_vis["Instruction Visual Tokens
(B, n*256, D=2048)"]:::highlight tok --> textemb["Text Embeddings
(B, N, D=2048)"] instr_vis --> inter_instr["Interleaved Instruction Embeddings
(Text Tokens & Visual Tokens Mix)"]:::highlight textemb --> inter_instr obs_vis --> prefix["Prefix Tokens (Obs + Interleaved Instr)
(B, seq_len, D=2048)"]:::highlight inter_instr --> prefix state["Robot State
(B, action_dim=32)"] --> stateproj["state_proj"] noisy["Noisy Actions x_t
(B, horizon=50, action_dim=32)"] --> actproj["action_in_proj"] time["Flow Time t
(B,)"] --> timemlp["Time Embedding MLP"] stateproj --> statetok["State Token
(B, 1, D=1024)"] actproj --> acttok["Action Tokens
(B, 50, D=1024)"] timemlp --> timetok["Time Tokens
(B, 50, D=1024)"] acttok --> mix["Action + Time Tokens
(B, 50, D=1024)"] timetok --> mix statetok --> suffix["Suffix Tokens
(B, seq_len=51, D=1024)"] mix --> suffix prefix --> pg["PaliGemma / Gemma 2B Expert"] suffix --> ae["Action Expert / Gemma 300M"] pg <--> shared["Shared Masked Self-Attn (qkv dim=256)"] ae <--> shared shared --> actout["action_out_proj"] actout --> vt["Predicted v_t
(B, 50, action_dim=32)"] gt["Target u_t = noise - action
(B, 50, action_dim=32)"] --> loss["Flow Matching Loss"] vt --> loss classDef highlight fill:#ffff00,stroke:#333,stroke-width:2px;

Implicit RDP (13)

一句话:在一个 img 周期内构建高频的短期 wrench kv memory 并在 train-time-only 加入 virtual_target 和 stiffness auxiliary tasks 来强制模型利用力信息,推理时仅需力传感器+位控且并且没有用 admittance control. 例如在插入书本等任务中,如果书本怼到墙壁能快速感知到并反应.

力 reactive + 位控比较适合上述书本插缝的情形,但并不适合套手机壳;后者更需要力控,但力控对于到达目标点的反应却更慢。两者之间存在 tradeoff. 从一个角度考虑, 人手没有编码器实际上不能做位控,机械臂擅长做位控任务,但前者却能实现一系列灵巧操作,到底是怎么控制的?

1
noisy_action[i] ---attend--> noise_action[<=i] & fast_kv[<=i] & slow_kv
2
fast_kv[i] 内部为 GRU,slow_kv 内部为 obs_encoder
1
# Train: 不用随机采样 fast kv length
2
# batch aligned around slow time S, with dense force covering slow history -> action horizon
3
slow_obs = {
4
img: img_slow[:, S-1:S+1], # (B,2,3,360,640), slow history
5
tcp_pose: tcp_slow[:, S-1:S+1], # (B,2,6)
6
}
7
fast_obs = wrench_fast[:, F0:F0+16] # (B,16,6),
8
a0 = action_aug[:, F0:F0+16] # (B,16,13), aug 的意思就是 6 tcp + 6 virtual target + 1 stiffness
9
slow_kv = SlowEncoder(slow_obs) # (B,~100,768), slow cross-attn K/V
10
fast_kv = FastGRU(fast_obs) # (B,16,768), causal fast K/V
11
eps = randn_like(a0); k = randint(0,K,(B,))
12
xk = add_noise(a0, eps, k) # (B,16,13), noisy action tokens / Q source
13
pred = Transformer(xk, k, slow_kv, fast_kv) # (B,16,13), causal: action i sees fast_obs <= i
14
target = eps # or v_target under v-prediction
15
loss = mean((pred - target) ** 2) # diffusion loss over B x 16 x 13

实际上不论是采数据还是 infer-time,原始数据的 img, tcp_pose 和 wrench 都是同步同频率 (e.g 10hz),只是 img, tcp_pose 大部分被忽略了.

1
# Infer: slow #1: step_count % tcp_action_update_interval == 0, default update_interval=6
2
obs = env.get_obs(obs_steps=2) # 同频同步帧: img/tcp_pose/wrench, each length=2
3
slow_kv_1 = SlowEncoder(obs) # conceptually (B,102,768)
4
noise_1 = randn(B,16,13) # cached noisy trajectory for this chunk
5
# infer #1, step_count % 6 == 0
6
N = latency_step + 0 + n_obs_steps # default 2 + 0 + 2 = 4
7
ext_obs = env.get_obs(obs_steps=N) # recent N synchronized wrench frames
8
fast_kv = FastGRU(ext_obs["right_robot_tcp_wrench"]) # (B,4,768)
9
x = DDIM(noise_1[:, :N], slow_kv_1, fast_kv) # (B,4,13)
10
execute(x[:, -1, :6]) # only tcp pose; vt/stiff discarded
11
# infer #2, same slow_kv/noise, step_count % 6 == 1
12
N = latency_step + 1 + n_obs_steps # 5
13
ext_obs = append_one_new_obs_and_keep_last_N(ext_obs) # recent 5 synchronized wrench frames
14
fast_kv = FastGRU(ext_obs["right_robot_tcp_wrench"]) # (B,5,768)
15
x = DDIM(noise_1[:, :N], slow_kv_1, fast_kv) # (B,5,13)
12 collapsed lines
16
execute(x[:, -1, :6])
17
# infer #3 ...
18
N = latency_step + 2 + n_obs_steps # 6
19
fast_kv = FastGRU(recent_sync_wrench[:N]) # (B,6,768)
20
x = DDIM(noise_1[:, :N], slow_kv_1, fast_kv)
21
execute(x[:, -1, :6])
22
# ...
23
# next slow update when step_count % 6 == 0 again
24
25
obs = env.get_obs(obs_steps=2)
26
slow_kv_2 = SlowEncoder(obs)
27
noise_2 = randn(B,16,13)

Adaptive Compliance Policy (14)

预测 virtual target 和 stiffness 从而在纯位控机器人上使用 admittance control

default

VP-VLA: Zixuan wang 港科大 (15)

全程冻结 VLM 和 SAM 并直接在 pixel level 绘制锚点. 并且让 VLA 中的 VLM 对齐外部的 VLM.

Do World… ? (16)

  • ?teacher–student training framework

BORA: czx (17)

本文在离线训练 Q net, V net(仅用于辅助训练 Q_net) 的同时更新 vlm encoder,并在在线阶段冻结 Q,只额外训练一个 MLP 级别的 residual policy. demo 很一般,仅限慢速 pick and place 以及食指大拇指的简单捏握.

Offline RL

flowchart TD
    obs --> vlm[[vlm]] --> z
    z --> value_net[[value_net]] --> V["V[] 数组"] --> v_loss["loss_v =
expectile_loss(Q.detach(), V)"] z --> policy[[consistent_policy]] --> A["A[] 数组"] --> Q[[Q_net]] --> q_loss["loss_q =
bellman_residual(Q, reward, V_next)
这里 V_next = V_net(GT z_(t+1))"] policy --> v[[1~3次去噪]] -->policy A --> loss_act["loss_act =
-ppo_clip(A, advantage(Q, V))
+ λ_bc * bc_loss(A, A_demo)"]
  • expectile_loss: [todo]
    1
    diff = Q.detach() - V
    2
    weight = torch.where(diff > 0, tau, 1 - tau)
    3
    loss_v = torch.mean(weight * (diff**2))
  • bellman_residual:
    1
    y_t = reward + gamma * (1 - done) * V_next
    2
    loss_q = torch.mean((Q - y_t.detach())**2)

Online RL

flowchart TD
    obs --> vlm[[🧊vlm]] --> z
    z --> policy[[🧊consistent_policy]] --> A_base --> Q1[[🧊Q_net]] --> Q_base --> target
    z --> residual[[🔥residual_policy]] --> A_res --> A_final["A = A_base + λ A_res"] --> Q2[["🧊Q_net (同一个)"]] --> Q_final --> target
    policy --> v[[1~3次去噪]] -->policy
    A_base --> A_final
    target["target =
hinge(Q_base + δ - Q_final) - Q_final
"]

递归

  • Q-chunking 就是本文使用的给 action_chunk 的每个位置打分.
  • implicit Q learning ? 就是:
    • 非 implicit 更新 Q_net: target = reward + gamma * max(Q_target(s_next, policy(s_next))). 如果 policy 输出 OOD 的动作,Q 的评分可能虚高,policy 被诱导去选择这些幻觉动作,导致整个评价体系崩溃.
    • implicit 更新 Q_net:
      1
      diff = Q.detach() - V
      2
      weight = where(diff > 0, τ, 1 - τ) # 当 Q > V 时权重为 τ=0.7,当 Q < V 时权重为 1-τ
      3
      # m_t_i 为有效步掩码(处理提前终止的情况)
      4
      loss_V = mean(m_t_i * weight * (diff**2))
      5
      target = reward + gamma * V(s_next)
    • 本文没有直接使用 IQL 而是使用了 IQL-style expectile.

一些概念

  • stiffness: F = K * (x_des - x) + D * (v_des - v),这里的 stiffness 就是 K. K 越大,同样的位置误差会产生越大的修正力/力矩.
  • 力位混合控制:选择一些轴力控,一些轴位控. 如 X, Y 走位,Z 保持 10N 下压力. 力控目标通常是末端[Fx, Fy, Fz, Mx, My, Mz] 扭矩(例如 Mz 可以理解为绕 z 轴转,拧螺丝),控制器内部通过雅可比矩阵 tau = J^T * wrench 转换为各关节扭矩.

Latent Policy Barrier (18)

一句话: 在 diffusion 过程中加入 guidance 项使得下一时刻的潜在观测与最近专家潜在观测的距离尽量小.

具体而言,下一时刻的潜在观测是通过训练的动力学模型 d(z_t, a_(t, chunk)) -> z_(t + tp) 得到的,该模型的训练数据来自专家轨迹 + 早期 ckpt 的 rollout 轨迹,在 infer-time 冻结。而 guidance 要求 d 的参与,而前几个去噪步让 d 难以预测,因此文章在 100 步去噪的最后 10 步才执行 guidance.

cosmos-policy (19)

一句话:使用 video model 直接预测 proprio token, action token 和 value token.

这三者是 minmax 然后直接被广播到 CxHxW 的 image token 形状, 还支持预测 V(s) 从而实现从 rollout 数据中学习以及 model-based planning (1 action -> 3 states -> 15 Q(s, a)). demo: picknplace, 叠衣服, 拉拉链. 注意下图中,设 action chunk len = K,状态 s 所在时间为 t,则 s’ 所在时间是 t + K (即这一整个 action chunk 执行完毕以后). 一个 action chunk (chunk_size, action_dim) 对应一个 latent frame. video backbone 使用的是 cosmos-predict2-2B.

default

Wall-WM (20)

wall-wm train-time 用 event-chunk 替代了 time-chunk,并且提出了一种 infer-time 分层加速解码方式。文章非常长,解释了很多架构设计细节。然而,demo 只展示了泛化的 picknplace. 一些设计细节包括:

  • 多相机 attn mask 做了几何约束.
  • 每 transformer layer 都有 action token 到 state token 的单独 crossattn,不会因为 pi 那样完全 self attn 稀释注意力到 video token.
  • 用 vlm 决定事件对应的 event-chunk 长度 n,然后对 (n + 1) * K_p(每个 video latent 对应 K_p 个 action token) 个带位置编码的噪声去噪.
flowchart TD
    cap(["事件描述 ℓ_i
(event 模式, 变长)"]) --> t5[["T5 文本编码"]] instr(["全局指令 + 历史
(unified 模式)"]) --> qwen[["Qwen3.5-9B VLM 🧊"]] qwen --> stair[["🟢创新: Staircase 解码器
中间层后并行一次性出
几个思考向量, 不逐字生成"]] t5 --> cond(["文本条件 c_ℓ"]) stair --> cond %% ---------- 视频塔 ---------- v0(["当前多视角观测 V0
(B, n_cam=3, H, W, 3)"]) --> vdit cond --> vdit vdit[["🟢创新: 多视角 Video DiT 🧊
跨相机注意力 + Camera RoPE
+ Sight-Cone 只看共视区域
(动作训练阶段冻结)"]] vdit --> vfeat(["逐层视频特征 h^v"]) vdit --> vloss["视频 Flow-Matching Loss"] %% ---------- 动作塔 ---------- state(["机器人状态 s"]) --> ea nact(["噪声动作 a_t
(B, K_p·(1+n) 变长, act_dim)"]) --> ea[["MLP 编码 E_a"]] ea --> adit[["动作 DiT (与视频塔同深度)"]] cond --> adit vfeat -. "🟢创新: 单向耦合
每层 q=动作 / k,v=视频特征" .-> adit state -. "🟢创新: 每层专门 cross-attn 读状态
不被海量视频 token 淹没" .-> adit adit --> vt(["预测 v_t
(B, K_p·(1+n), act_dim)"]) vt --> aloss["动作 Flow-Matching Loss"]
Article title:papers batch 2
Article author:Julyfun
Release time:May 25, 2026
Copyright 2026
Sitemap