hackhackhack66666 commited on
Commit
d1bdf32
·
verified ·
1 Parent(s): 2ffb236

Add experiment journal (dense visual memory run)

Browse files
Files changed (1) hide show
  1. experiment_log_dense_visual_memory.md +313 -0
experiment_log_dense_visual_memory.md ADDED
@@ -0,0 +1,313 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Experiment log: Dense Visual Memory for OAT (LIBERO)
2
+
3
+ Живой журнал эксперимента для научрука / статьи (ablation section).
4
+ Репозиторий: `BLT-OAT` (fork OAT). Бенчмарк: **LIBERO-10**, `N500` demos.
5
+
6
+ **Последнее обновление:** 2026-05-30 (UTC+3)
7
+
8
+ ---
9
+
10
+ ## 1. Гипотеза и смысл изменения
11
+
12
+ **Исходный OAT** подаёт в cross-attention короткую memory: pooled RGB-векторы (+ state в fused obs), длина порядка `n_obs_steps` (обычно **2 токена**). Пространственная структура кадра сжата в один вектор на timestep.
13
+
14
+ **Наша ветка (`use_dense_visual_memory=true`)** подаёт в тот же cross-attention decoder **длинную spatial memory**:
15
+ - patch-токены с каждой RGB-камеры на каждый obs-step;
16
+ - `time_embed` / `camera_embed`;
17
+ - опционально state-токены через MLP `state_to_memory`.
18
+
19
+ Мы **буквально льём в трансформер больше conditioning-токенов** (сотни вместо единиц). Это не «больше пикселей на входе», а **меньше сжатое** представление для attention.
20
+
21
+ **Ожидание:** модель может точнее локализовать объекты/гриппер → потенциально выше `success_rate`.
22
+ **Риск:** оптимизация сложнее; в начале обучению «может поплохеть» (loss выше, медленнее сходимость, SR ниже), пока cross-attn и encoders не научатся отбирать релевантные patch’и.
23
+
24
+ ---
25
+
26
+ ## 2. Что изменили в архитектуре (vs default OAT)
27
+
28
+ | Компонент | Default OAT | Dense OAT (наш) |
29
+ |-----------|-------------|-----------------|
30
+ | RGB encoder | `RobomimicRgbEncoder` + global pool | `DenseRgbEncoder`: ResNet18 до `layer3`, **без** SpatialSoftmax/pool |
31
+ | Проекция в `d_model` | внутри pooled pipeline | `1×1 Conv` + `LayerNorm` на feature map |
32
+ | Memory length | `To` (≈2) | `2 камеры × To × L_patch + state_tokens` (L≈64 при 128×128) |
33
+ | State | в fused obs vector | отдельные memory-токены (`state_to_memory`) |
34
+ | Позиции memory | `cond_pos_emb` + `cond_emb` | dense: `memory_pos_emb` (`max_memory_len=1024`), `memory_is_embedded=True` |
35
+ | Cross-attn blocks | есть | **не меняли** |
36
+ | Action tokenizer (`OATTok`) | frozen | **не меняли** |
37
+ | Loss | CE по action tokens | **тот же** |
38
+
39
+ Ключевые файлы:
40
+ - `oat/perception/robomimic_vision_encoder.py` — `DenseRgbEncoder`
41
+ - `oat/policy/oatpolicy.py` — `get_dense_memory`, флаги абляций
42
+ - `oat/model/autoregressive/transformer_cache.py` — `_encode_memory`, `memory_pos_emb`
43
+ - `oat/config/train_oatpolicy.yaml` — hydra-флаги
44
+
45
+ Флаги абляций:
46
+ - `policy.use_dense_visual_memory` (alias: `use_cross_attn`)
47
+ - `policy.use_state_memory_tokens`
48
+ - `policy.use_task_uid_in_state_tokens`
49
+
50
+ ---
51
+
52
+ ## 3. Почему больший loss / MSE — не всегда «хуже»
53
+
54
+ Замечание научрука (A. Malinin): для dense-ветки **абсолютный train/val loss может быть выше**, чем у pooled OAT — это не обязательно регрессия.
55
+
56
+ Причины:
57
+ 1. Другая размерность и статистика входа в decoder (длинная memory, другие pos emb).
58
+ 2. Более богатое представление ≠ тот же CE-ландшафт, что у 2-токенного baseline.
59
+ 3. **Целевая метрика проекта — `mean_success_rate` (rollout), не `reconst_mse` / `val_loss`.**
60
+ MSE/loss — sanity-check («учится / не взрывается»), финальное решение — SR на LIBERO eval.
61
+
62
+ ---
63
+
64
+ ## 4. Протокол валидации (короткий)
65
+
66
+ 1. **Smoke / arch:** forward, backward, KV-cache dense vs legacy, shapes.
67
+ 2. **Short A/B (N32, 1k steps):** legacy vs dense-варианты, одинаковый lr/batch.
68
+ 3. **Long-run (N500):** полный датасет, `rollout_every=200`, best ckpt по `mean_success_rate`.
69
+
70
+ GO для long-run (short-run): dense **не хуже** legacy по val/reconst на стабильной конфигурации (допуск ~3–5%) **или** явно лучше по раннему mini-rollout.
71
+
72
+ ---
73
+
74
+ ## 5. Short A/B результаты (`libero10_N32_smoke`, 1k steps, 5 epochs)
75
+
76
+ | Конфиг | `val_loss` (final) | `test_reconst_mse` (final) | Комментарий |
77
+ |--------|-------------------:|---------------------------:|-------------|
78
+ | **legacy** (pooled) | 6.477 | 0.0132 | baseline |
79
+ | **dense + state + task_uid** | 7.531 | 0.1648 | сильная дегра��ация |
80
+ | **dense_visual_only** (state off) | 6.848 | 0.0297 | лучше full dense+uid, хуже legacy |
81
+ | **dense + state, `task_uid` off** | **6.369** | **0.0133** | ≈ legacy по short metrics |
82
+
83
+ **Вывод short A/B:** проблема локализована в **`task_uid` в state memory**, не в dense visual tokens как таковых.
84
+
85
+ Run dirs (cluster): `output/smoke/ab_legacy_1k_r2`, `ab_dense_visual_only_1k`, `ab_dense_state_no_uid_1k`, `ab_dense_state_uid_1k_r2`.
86
+
87
+ ---
88
+
89
+ ## 6. Long-run (текущий)
90
+
91
+ **Активный run (dense + task_uid):** `oat_dense_with_uid_long_0530_220204`
92
+
93
+ | Поле | Значение |
94
+ |------|----------|
95
+ | Сессия tmux | `oat_dense_with_uid_long_0530_220204` |
96
+ | Train | stopped @ ~ep 804 for SR ladder eval |
97
+ | Checkpoints local | `ep-0300`, `ep-0500`, `ep-0700`, `latest.ckpt` |
98
+
99
+ | Поле (старый run без uid) | Значение |
100
+ |------|----------|
101
+ | Сессия tmux | `oat_dense_no_uid_long_0530_213112` |
102
+ | Конфиг | `dense + state`, `use_task_uid_in_state_tokens=false` |
103
+ | Датасет | `libero10_N500.zarr` (`training.num_demo=500`) |
104
+ | WandB | `logging.mode=disabled` (первый запуск упал: `No API key configured`) |
105
+ | Лог | `output/long/oat_dense_no_uid_long_0530_213112.log` |
106
+ | Hydra run | `output/long/oat_dense_no_uid_long_0530_213112/` |
107
+
108
+ **Снимок метрик (2026-05-30, во время обучения):**
109
+ - `global_step` ≈ 3136, `epoch` ≈ 6
110
+ - `train_loss` ≈ 4.96 (снижается с ~7 на старте)
111
+ - `val_loss` (epoch 0): 6.595 — ранняя точка, не финал
112
+ - `mean_success_rate`: **ещё нет** (первый rollout на `epoch % 200 == 0`)
113
+
114
+ Предыдущая tmux-сессия `oat_dense_no_uid_long_0530_212603` — упала на init wandb.
115
+
116
+ ---
117
+
118
+ ## 7. Если `success_rate` сильно просядет — шаблон для ablation (статья / тикет)
119
+
120
+ Ниже — **готовые причины**, которые можно вставить в Discussion/Ablation, если dense < baseline OAT по SR после полного обучения.
121
+
122
+ ### 7.1. Усложнение optimization (главная гипотеза)
123
+
124
+ - Cross-attention получает **~200–300+ memory tokens** вместо 2; effective capacity растёт, но gradient signal размазывается по patch’ам.
125
+ - Новые модули (`DenseRgbEncoder`, `memory_pos_emb`, time/camera embed) учатся с нуля при frozen tokenizer → дольше «сходимость» closed-loop политики.
126
+ - На ранних эпохах политика может вести себя хуже baseline при нормальном или даже падающем train loss.
127
+
128
+ ### 7.2. Несопоставимость offline-метрик
129
+
130
+ - `reconst_mse` / `val_loss` слабо коррелируют с `success_rate` (особенно при смене conditioning).
131
+ - Возможен сценарий: loss ≈ baseline, SR ниже — или loss выше, SR сопоставим (как отмечал научрук).
132
+
133
+ ### 7.3. `task_uid` в memory (подтверждено абляцией)
134
+
135
+ - Включение `task_uid` embedding в state tokens резко ухудшило short-run (`mse` 0.013 → 0.165).
136
+ - Возможные механизмы: неверный id range/семантика, конфликт с state MLP, переобучение на spurious task signal.
137
+ - Long-run идёт **без** `task_uid`; если SR всё равно низкий — причина не только в uid.
138
+
139
+ ### 7.4. Inductive bias pooled OAT
140
+
141
+ - Global pooling даёт компактный, устойчивый вектор — для некоторых LIBERO задач этого может хватать.
142
+ - Dense memory полезен, когда нужна пространственная привязка; если baseline уже «выдавливает» SR из pool, выигрыш может быть < overhead.
143
+
144
+ ### 7.5. Compute / eval budget
145
+
146
+ - Меньше эффективных «эпох» на единицу wall-clock (тяжелее forward).
147
+ - Редкий rollout (`rollout_every=200`) → поздняя обратная связь по SR; best checkpoint по SR может не совпасть с best по loss.
148
+
149
+ ### 7.6. Гиперпараметры не перенастроены
150
+
151
+ - Те же `policy_lr`, `obs_enc_lr`, batch=256, что у pooled baseline — для длинной memory может быть suboptimal (нужен отдельный sweep).
152
+
153
+ **Формулировка для тикета (кратко):**
154
+ > Dense memory увеличивает информационную ёмкость conditioning, но усложняет обучение cross-attention. Наблюдаемый/ожидаемый провал SR не обязательно означает ошибку реализации: он может следовать из optimization difficulty, слабой корреляции offline-метрик с SR, и подтверждённой деградации от `task_uid` (исключена в production run). Финальная оценка — только paired rollout на LIBERO-10 с теми же seeds и eval protocol, что baseline.
155
+
156
+ ---
157
+
158
+ ## 8. Git / деплой
159
+
160
+ | Commit | Описание |
161
+ |--------|----------|
162
+ | (ранние) | DenseRgbEncoder, OATPolicy memory, decoder `memory_pos_emb` |
163
+ | `9c305cd` | fix `lr_scheduler` imports (diffusers) |
164
+ | `020f63d` | `use_state_memory_tokens` |
165
+ | `9481ae0` | `use_task_uid_in_state_tokens` |
166
+
167
+ Синк на кластер: `rsync` в `~/OAT-RoboMimic-Fine-tune/BLT-OAT/`, **exclude `data/`**.
168
+
169
+ Docker: `oat_robomimic_askhabaliev_gs`.
170
+ Tokenizer ckpt: `tokenizer_ep-0950_mse-0.002.ckpt` (HF Mirageinv/oat) — **без изменений**.
171
+
172
+ ---
173
+
174
+ ## 9. Как обновлять этот лог и анализировать все run'ы
175
+
176
+ Каждый Hydra-run пишет в свою папку:
177
+ - `logs.json` — train_loss, val_loss, test_reconst_mse, mean_success_rate (на rollout-эпохах)
178
+ - `.hydra/overrides.yaml` — конфиг (embed_dim, task_uid, …)
179
+ - `checkpoints/` — ckpt для eval и attention viz
180
+ - `*.log` — tee-лог в `output/long/`
181
+
182
+ **Манифест всех run'ов:** `output/long/RUN_MANIFEST.md` (append при sweep)
183
+
184
+ **Сводка по всем run'ам:**
185
+ ```bash
186
+ python scripts/summarize_training_runs.py --root output/long
187
+ # -> output/long/summary/all_runs_summary.csv + .md
188
+ ```
189
+
190
+ **Графики loss / MSE / SR:**
191
+ ```bash
192
+ python scripts/plot_training_runs.py \
193
+ output/long/oat_dense_with_uid_long_0530_220204 \
194
+ output/long/dense_emb128_with_uid_* \
195
+ --out output/long/summary/plots
196
+ ```
197
+
198
+ **Rollout eval (success rate) из checkpoint:**
199
+ ```bash
200
+ python scripts/eval_policy_sim.py \
201
+ -c output/long/<run>/checkpoints/latest.ckpt \
202
+ -o eval/<run_name>
203
+
204
+ # Ladder 300/500/700 (paired SR): docs/plans/libero_sr_eval_ladder_300_500_700.md
205
+ # PHASE=A bash scripts/cluster/run_ladder_sr_eval.sh
206
+ ```
207
+
208
+ **Cross-attention heatmaps:**
209
+ ```python
210
+ from oat.common.attention_viz import visualize_cross_attention
211
+ # policy from checkpoint + sample batch -> overlay on RGB
212
+ ```
213
+
214
+ Команды мониторинга (cluster):
215
+
216
+ ```bash
217
+ tmux ls
218
+ tmux attach -t oat_dense_no_uid_long_0530_213112
219
+ tail -f ~/OAT-RoboMimic-Fine-tune/BLT-OAT/output/long/oat_dense_no_uid_long_0530_213112.log
220
+ python3 -c "
221
+ import json; from pathlib import Path
222
+ p=Path('~/OAT-RoboMimic-Fine-tune/BLT-OAT/output/long/oat_dense_no_uid_long_0530_213112/logs.json').expanduser()
223
+ rows=[json.loads(l) for l in p.read_text().splitlines() if l.strip()]
224
+ for k in ['mean_success_rate','val_loss','train_loss']:
225
+ r=[x for x in rows if k in x]
226
+ if r: print(k, r[-1])
227
+ "
228
+ ```
229
+
230
+ ---
231
+
232
+ ## 10. Changelog
233
+
234
+ ### 2026-05-31 — HF checkpoint upload watcher (epochs 300 & 500, train continues)
235
+ - Script: `scripts/watch_hf_checkpoint_upload.py`
236
+ - Launcher: `scripts/cluster/launch_hf_upload_tmux.sh`
237
+ - Default repo: `hackhackhack66666/OAT-BLT-LIBERO-300` (hub API; git-xet fallback)
238
+ - Checkpoint ladder HF repos:
239
+ - 300 → `hackhackhack66666/OAT-BLT-LIBERO-300` ✅
240
+ - 500 → `hackhackhack66666/OAT-BLT-LIBERO-500` ✅
241
+ - 700 → `hackhackhack66666/OAT-BLT-Libero-700` ✅
242
+ - 900, 1100 → TBD (`OAT-BLT-Libero-900`, `OAT-BLT-Libero-1100`)
243
+ - Each HF repo: `README.md` (EN) + `training_metrics_dashboard.png` + this experiment log
244
+ - SR eval plan: `docs/plans/libero_sr_eval_ladder_300_500_700.md` (sim eval; ckpts kept on disk until done)
245
+ - `--target-epochs` + `--epoch-repo EPOCH=REPO` per snapshot; train continues
246
+ - Trigger when `epoch > target` (so ep-N ckpt exists); train not stopped
247
+ - Requires `HF_TOKEN`; logs: `hf_upload_report.jsonl`, `hf_upload_watch.log`
248
+
249
+ ### 2026-05-31 — Counterfactual early-stop watcher (no real stop)
250
+ - Добавлен CPU-only watcher: `scripts/watch_early_stop_report.py`.
251
+ - Добавлен launcher: `scripts/cluster/launch_early_stop_watch_tmux.sh`.
252
+ - Watcher проверяет с `epoch >= 0` (ранние ep помечаются как noisy в отчёте), каждый час, пишет:
253
+ - `early_stop_report.jsonl` (история проверок),
254
+ - `early_stop_report.md` (сводка для статьи).
255
+ - Важно: watcher **не останавливает** обучение, только пишет где **был бы** стоп.
256
+
257
+ ### 2026-05-30 — Sweep relaunch + post-hoc tooling
258
+ - Скрипты: `summarize_training_runs.py`, `plot_training_runs.py`, `RUN_MANIFEST.md`.
259
+ - Sweep на GPU1 в tmux, `USE_TASK_UID=true` (как основной run).
260
+
261
+ ### 2026-05-30 — Перезапуск с `task_uid`
262
+ - Остановлен long-run без uid (~epoch 15) и embed-dim sweep.
263
+ - Новый long-run: `dense + state + task_uid=true`, N500, tmux `oat_dense_with_uid_long_*`.
264
+
265
+ ### 2026-05-30 — Overnight embed-dim sweep (GPU1)
266
+ - Запущен последовательный sweep `embed_dim` ∈ {128, 384, 512} на свободной GPU1.
267
+ - Baseline 256 остаётся на GPU0 (`oat_dense_no_uid_long_0530_213112`).
268
+ - Скрипт: `scripts/cluster/overnight_dense_embed_dim_sweep.sh`, tmux: `oat_dense_embed_sweep_night`.
269
+
270
+ ### 2026-05-30 — Short A/B завершён, long-run запущен
271
+ - Реализованы dense memory + абляционные флаги.
272
+ - Short A/B: стабильная конфигурация **`dense + state, без task_uid`**.
273
+ - Long-run N500 в tmux `oat_dense_no_uid_long_0530_213112`, wandb off.
274
+ - Train идёт: к ~epoch 6 `train_loss` ~4.96; SR rollout ещё не было.
275
+ - Создан этот experiment log для статьи/тикета.
276
+
277
+ ### 2026-05-30 — Первый long-run упал
278
+ - tmux `oat_dense_no_uid_long_0530_212603`: `wandb.errors.UsageError: No API key`.
279
+ - Перезапуск с `logging.mode=disabled`.
280
+
281
+ ---
282
+
283
+ ## 11. Overnight sweep: `embed_dim` / `dense_feature_dim`
284
+
285
+ **Мотивация:** при фиксированной spatial resolution (L patch’ей) меняется только ширина token embedding — влияет на ёмкость visual memory и нагрузку на cross-attn.
286
+
287
+ **Ограничение кода:** `dense_feature_dim` должен совпадать с `policy.embed_dim` (иначе `dense memory expects cond dim {n_emb}`).
288
+
289
+ | GPU | Задача | `embed_dim` | batch |
290
+ |-----|--------|------------:|------:|
291
+ | 0 | основной long-run | 256 | 256 |
292
+ | 1 | sweep (последовательно) | 128 → 384 → 512 | 256 / 192 / 128 |
293
+
294
+ Скрипт: `scripts/cluster/overnight_dense_embed_dim_sweep.sh`
295
+ tmux (cluster): `oat_dense_embed_sweep_night`
296
+ Конфиг как у основного run: dense + state, **без** `task_uid`, `logging.mode=disabled`.
297
+
298
+ ---
299
+
300
+ ## 12. Открытые вопросы
301
+
302
+ 1. Финальный **SR dense vs legacy** на N500 после `rollout_every`.
303
+ 2. Какой `embed_dim` лучше по SR / sample efficiency (sweep 128/256/384/512)?
304
+ 3. Нужен ли отдельный sweep lr / warmup для dense encoders?
305
+ 4. Как корректно вернуть `task_uid` (mapping id, gating, не в state MLP)?
306
+ 5. Attention viz на лучшем ckpt — куда смотрит policy на успехе/провале?
307
+
308
+ ---
309
+
310
+ ## 13. Ссылки
311
+
312
+ - План реализации: [`docs/plans/cross-attn_dense_oat.md`](plans/cross-attn_dense_oat.md)
313
+ - Attention viz: `oat/common/attention_viz.py`