DynaGuide 用自有数据部署指南

点击标题展开/折叠 · 面向"已采集真机数据、想用 DynaGuide 部署"的场景

0. 数据内容:标准 state-action episode 就够了

你采集的数据只要是标准的 state-action episode就够用——每条 episode 是一段轨迹,每个时间步包含:观测(图像 + 本体感知 proprio)+ 对应动作。

两个模型用同一批 episode,但抽取方式不同:

模型用数据的哪部分学什么
扩散策略
(base policy)
(obs_t → action_t)模仿:看到观测生成动作
动态模型
(dynamics model)
(obs_t, action_chunk[t:t+H]) → obs_{t+H} 三元组前向预测:当前观测+动作 → 未来观测的 latent
关键差异:动态模型必须能看到"动作执行后的未来观测",所以它需要完整轨迹(要用到后面的帧)。扩散策略只需要"当前观测→当前动作"。
知识互补设计(可选但重要):若想复现 DynaGuide 的"知识互补"效果,动态模型最好用比 base policy 更广的数据训练(论文用 ABCD split 训 dynamics、D split 训 base policy)。你的数据里,让 dynamics model 见更多样的行为,引导才可能把 policy 推向它没充分学过的行为。

guidance conditions(引导目标)

还需要第三份数据——但不是训练用,是推理时的引导目标:从你的数据里筛出"想引导的目标行为"的成功片段(如 20 条"抓某物体"),DynaGuide 编码它们的末态作为 z+。想避免的行为可作 z-。

1. 概念澄清(先破除误解)

Q: 梯度引导是部署时用,还是后训练时用?

部署(推理)时用。 DynaGuide 的梯度引导(classifier guidance)发生在推理时的 DDIM 去噪循环里,不在任何训练阶段。

Q: 属于"梯度引导式的更新参数"吗?

不是。 这是最容易误解的点。DynaGuide 的梯度是对动作求的,不是对模型参数求的:

g = ∂E(a) / ∂a     ← 对动作 a 求梯度(a 是正在去噪的噪声动作)
不是
g = ∂L / ∂θ        ← 对参数 θ 求梯度(这才是训练/微调)

它不更新任何权重。base policy 和 dynamics model 在部署时全程冻结。梯度只是在采样时把动作往目标方向"推",跟 fine-tuning 完全是两回事。

Q: 需要重新训练吗?

需要,但训练的是两个模型,且都是标准监督训练(这才更新参数),跟"梯度引导"无关:

组件要不要训训练方式部署时状态
Base policy(扩散策略)标准监督(对 θ 反传)冻结
Dynamics model(动态模型)标准监督(DINO latent MSE)冻结
梯度引导不训推理时对动作求梯度
核心结论:DynaGuide 里"训练"和"引导"是两件独立的事。训练 = 更新参数得到两个冻结模型;引导 = 部署时用冻结的 dynamics model 对动作求梯度。没有"梯度引导式的参数更新"这种东西。它既不是预训练也不是后训练,属于第三种范式——inference-time steering(推理时引导)。

2. 关键分叉:你的 base policy 是什么?

这决定整个规划。DynaGuide 原版的 base policy 是 robomimic 的 DDIM 扩散策略,而你真机跑的是 pi0.5(flow matching)。两者引导机制不同:

路线做法难度
A:忠实复现 DynaGuide在你的数据上训一个 robomimic DDIM 扩散策略作 base policy + 训 dynamics model → 部署引导。完全走通,但 base policy 不是 pi0.5。
B:引导 pi0.5用你的 pi0.5 作 base policy → 需把引导从 DDIM 公式改写成 flow matching 的速度场引导。是 VLMGuide 课题的后期目标。
建议先走路线 A——它能让你在自己的数据上完整跑通 DynaGuide 全链路,验证数据质量和引导效果,成本低、风险小。路线 B 留到机制验证之后。

3. 详细规划(路线 A 为主)

Phase 0:数据格式转换

DynaGuide 的 MultiviewDataset 要求 HDF5 格式(数据内容就是标准 episode,只是要转成这个结构):

data/
├── demo_0, demo_1, ...
│   ├── actions:  [T, action_dim]
│   └── obs/
│       ├── third_person: [T, H, W, 3] uint8   ← 至少一个相机
│       ├── eye_in_hand:  [T, H, W, 3] uint8   ← 可选
│       ├── proprio:      [T, proprio_dim]      ← 本体感知
│       └── states:       [T, state_dim]        ← 成功判定用(可选)

把真机数据(LeRobot 或自定义格式)写脚本映射到这个结构。最容易出错处:action 维度、相机命名、图像范围 0-255。

Phase 1:训练 base policy(扩散策略)

python robomimic/scripts/train.py \
  --config configs/diffusion_policy_image_calvin_ddim.json \
  --dataset <你的数据.hdf5> --output <out> --name my_base_policy

改 config 里的 obs keys、action_dim 匹配你的数据。单 3090 约 24-48h。产出:冻结的 base policy checkpoint。

Phase 2:训练 dynamics model

python train_dynaguide.py --exp_dir <out> \
  --train_hdf5 <你的数据.hdf5> --test_hdf5 <验证集.hdf5> \
  --cameras third_person --action_dim <你的维度> \
  --proprio_key proprio --proprio_dim <你的维度> \
  --num_epochs 6000 --action_chunk_length 16 --batch_size 16

DINOv2 冻结,只训 Transformer dynamics head。训练数据 = 你的 demo(成功轨迹即可;论文建议用 base policy 的 rollout 成功+失败混合更好,先用演示数据够)。单 3090 约 24-48h。

Phase 3:准备 guidance conditions

从数据里筛出目标行为的成功片段(如 20 条),存成小 HDF5。DynaGuide 编码其末态为 z+。有负目标也可准备 z-。

Phase 4:部署引导(推理,不训练)

python run_dynaguide.py \
  --agent <base_policy> --guidance <dynamics_model> \
  --exp_setup_config <你的config.json> \
  --scale 1.5 --ss 4 --alpha 30 ...

全程冻结,只在 DDIM 去噪时对动作求梯度引导。这里没有任何参数更新。

训练顺序总览

你的真机数据
   ├─(Phase1 监督训练, 更新参数)→ base policy [冻结]
   └─(Phase2 监督训练, 更新参数)→ dynamics model [冻结]
                                        │
   目标行为片段 ─(Phase3)→ guidance conditions z+/z-
                                        │
   (Phase4 推理时, 对动作求梯度, 不更新参数)→ 引导后的动作

4. 两个提醒

1. 路线 A 的 base policy 是扩散策略,不是 pi0.5。如果你的真机部署栈已绑定 pi0.5,路线 A 训出的 DP 是另一个策略——只能证明"DynaGuide 在你的数据上能引导",不能直接引导现有 pi0.5。要引导 pi0.5 得走路线 B(flow matching 引导),是更大的工程。
2. 你的数据能否训出可用的 base policy 是前提。若数据量/多样性不够,base policy 本身就抓不好,引导也无从谈起——引导只能在 policy 已有能力分布内重加权(此前的 latent 敏感度实验已确认这一点)。