File size: 5,231 Bytes
ac29381
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# DreamZero 数据准备指南

---

## 1. 数据格式要求

DreamZero 期望每个训练样本包含以下字段:

| 字段 | 类型 | 形状 | 说明 |
|------|------|------|------|
| `video` | uint8 numpy | [T, V, H, W, 3] | T=帧数, V=视角数 |
| `state` | float32 numpy | [state_horizon, max_state_dim] | 机器人状态(需 padding) |
| `action` | float32 numpy | [action_horizon, max_action_dim] | 动作序列(需 padding) |
| `language` | str | - | 任务描述 |

### 参数约束

```
action_horizon / (lat_T - 1) = num_action_per_block / num_frame_per_block
(lat_T - 1) / state_horizon = num_frame_per_block / num_state_per_block
lat_T = num_frames // 4           # Wan2.2 VAE 4x 时间下采样
```

**标准参数**(已验证):
- `num_frames=12, action_horizon=12, state_horizon=1`
- `num_frame_per_block=2, num_action_per_block=12, num_state_per_block=1`
- `max_state_dim=44, max_action_dim=32`

---

## 2. State/Action Padding

State 和 Action 统一 padding 到固定维度:

```python
import numpy as np

MAX_STATE_DIM = 44
MAX_ACTION_DIM = 32

def pad_state(state: np.ndarray) -> np.ndarray:
    """Pad state to MAX_STATE_DIM."""
    d = state.shape[-1]
    padded = np.zeros((MAX_STATE_DIM,), dtype=np.float32)
    padded[:d] = state.astype(np.float32)
    return padded

def pad_action(action_chunk: np.ndarray) -> np.ndarray:
    """Pad action to [horizon, MAX_ACTION_DIM]."""
    d = action_chunk.shape[-1]
    padded = np.zeros((*action_chunk.shape[:-1], MAX_ACTION_DIM), dtype=np.float32)
    padded[..., :d] = action_chunk.astype(np.float32)
    return padded
```

---

## 3. 添加新数据集步骤

### 3.1 创建 Dataset 类

```python
# groot/vla/data/dataset/my_dataset.py
from pathlib import Path
import numpy as np
from groot.vla.model.dreamzero.transform.dreamzero_cotrain import DreamTransform

class MyDataset:
    def __init__(self, dataset_dir, num_frames=12, action_horizon=12,
                 state_horizon=1, num_views=1, ...):
        # 1. 扫描数据文件
        # 2. 构建 episode 列表
        # 3. 创建 DreamTransform 实例
        
        self.transform = DreamTransform(
            default_instruction="Perform the task.",
            max_state_dim=44, max_action_dim=32,
            state_horizon=state_horizon,
            action_horizon=action_horizon,
            num_views=num_views,
            embodiment_tag_mapping={"my_robot": 17},
            tokenizer_path="/path/to/umt5-xxl",
        )
        # 必须设置 metadata
        self.transform.set_metadata(self.merged_metadata["my_robot"])
        self.transform.train()
    
    def __getitem__(self, idx):
        # 返回格式:
        return dict(self.transform({
            "video": video,           # [T, V, H, W, C] uint8
            "state": state,           # [T, D] float32
            "action": action,         # [T, D] float32
            "annotation.human.action.task_description": text,
        }))
```

### 3.2 创建 Hydra 配置

```yaml
# groot/vla/configs/data/dreamzero/my_dataset.yaml
defaults:
  - dreamzero/base_48_wan_fine_aug_relative
  - _self_

my_dataset_dir: /path/to/data

num_frames: 12
action_horizon: 12
state_horizon: 1
num_views: 1
num_frame_per_block: 2
num_action_per_block: 12
num_state_per_block: 1
max_state_dim: 44
max_action_dim: 32
max_chunk_size: 4
image_resolution_height: 160
image_resolution_width: 320
frame_seqlen: 50

train_dataset:
  _target_: groot.vla.data.dataset.my_dataset.MyDataset
  _convert_: object
  dataset_dir: ${my_dataset_dir}
  num_frames: ${num_frames}
  action_horizon: ${action_horizon}
  state_horizon: ${state_horizon}
  num_views: ${num_views}
  video_height: ${image_resolution_height}
  video_width: ${image_resolution_width}
```

### 3.3 训练

```bash
torchrun ... experiment.py \
  data=dreamzero/my_dataset \
  num_frames=12 action_horizon=12 num_views=1
```

---

## 4. Embodiment Tag

每个数据集需要注册一个 embodiment tag(用于识别机器人种类):

```python
# 内置 tag 映射 (部分)
embodiment_tag_mapping = {
    "oxe_droid": 17,   # DROID 机器人
    "libero": 18,      # LIBERO
    "panda": 19,       # Franka Panda
    "manifeel": 20,    # ManiFeel
    "robotwin": 21,    # RoboTwin
}
```

如果不确定用哪个 tag,使用 `"oxe_droid": 17`。

---

## 5. 数据验证

训练前验证数据格式:

```python
# 快速验证
ds = MyDataset(dataset_dir="/path/to/data", max_episodes=3)
sample = ds[0]
print(sample.keys())
for k, v in sample.items():
    if hasattr(v, 'shape'):
        print(f"  {k}: {v.shape}, {v.dtype}")

# 验证 DreamTransform 输出
transformed = dict(ds.transform({
    "video": sample["video"],
    "state": sample["state"],
    "action": sample["action"],
    "annotation.human.action.task_description": "test",
}))
```

---

## 6. 常见数据问题

| 问题 | 原因 | 解决 |
|------|------|------|
| `lat_T = 0` | num_frames < 4 | 设置 num_frames >= 4 |
| `reshape error` | num_frame_per_block 不对齐 | 确保 (lat_T-1) % num_frame_per_block == 0 |
| `InterpolationKeyError` | config 缺少字段 | 检查 YAML 包含所有 `${...}` 引用 |
| VAE dtype error | bf16 vs float32 不匹配 | VAE 加载时用 `dtype=self.dtype` |