Buckets:
| # Resume on a new GPU | |
| Stopped cleanly at **step 25280 / 60000** on 2026-07-27, right after `checkpoint-25000.pt` | |
| was written — so nothing meaningful was lost. Nothing is running. | |
| ## Restart training exactly where it stopped | |
| ```bash | |
| cd /mnt/data/sftp/data/hunght23/quangpt3_data/masked-visual-actions/Ctrl-World | |
| PYTHONNOUSERSITE=1 ABLATION=+flow FLOW_DROPOUT_PROB=0.2 \ | |
| DATASET_NAMES=droid_std \ | |
| DATASET_META_INFO_PATH=dataset_meta_info/droid_std_causalready \ | |
| CKPT_PATH=model_ckpt/causal_droidstd/checkpoint-25000.pt \ | |
| TRAIN_BATCH_SIZE=1 GRADIENT_ACCUMULATION_STEPS=4 \ | |
| MAX_TRAIN_STEPS=35000 WARMUP_NEW_PARAMS_STEPS=0 \ | |
| LOG_EVERY_STEPS=50 VALIDATION_STEPS=-1 CHECKPOINTING_STEPS=5000 \ | |
| NUM_WORKERS=4 TAG=causal_droidstd OUTPUT_DIR=model_ckpt/causal_droidstd \ | |
| LOG_FILE=model_ckpt/causal_droidstd/train.log \ | |
| bash scripts/train_causal.sh | |
| ``` | |
| `WARMUP_NEW_PARAMS_STEPS=0` because the conv_in/conv_out warmup already finished at step | |
| 1000. `MAX_TRAIN_STEPS` is the number of **remaining** steps. The checkpoint is already | |
| 24-channel so `train_wm.py` loads it directly without re-widening. | |
| Auto eval + upload (memory-gated; waits when the GPU is busy): | |
| ```bash | |
| OUTDIR=model_ckpt/causal_droidstd VAL_ID=199 \ | |
| VAL_DATASET_DIR=dataset_example/droid_std TAG=causal_droidstd \ | |
| MAX_STEPS=60000 MIN_FREE_MIB=8000 POLL=120 \ | |
| nohup bash scripts/eval_upload_watcher.sh >> model_ckpt/causal_droidstd/watcher.log 2>&1 & | |
| ``` | |
| If the new GPU is free, `TRAIN_BATCH_SIZE=2 GRADIENT_ACCUMULATION_STEPS=2` roughly halves | |
| wall-clock (measured ~44 GiB peak; batch 1 was chosen only to leave room for evals on a | |
| shared card). | |
| ## Data is done — do not re-extract | |
| `droid_std` causal artefacts are complete: **387 train + 4 val** trajectories with | |
| `latent_videos_{phi,ra,rb}` and `causal_aux`, filtered meta at | |
| `dataset_meta_info/droid_std_causalready/`. 9 trajectories were dropped on purpose (all three | |
| views had `cameraMatrix: null`). The 5-stage extraction (`scripts/extract_droid_std.sh`) is | |
| resumable and would just skip everything. | |
| ## State of the evidence | |
| | | | | |
| |---|---| | |
| | PSNR, causal ck20000, 4 val | 16.92 / 16.86 / 18.42 / 15.22 — mean **16.9** | | |
| | PSNR, base Ctrl-World, same 4 | 19.28 / 20.68 / 23.05 / 16.92 — mean **20.0** | | |
| | VAE round-trip ceiling | **33.9 dB** | | |
| | Rollout stability | drops over ~5 frames then **flat for 85** — no divergence | | |
| | 3-branch guidance | runs (2.35x cost), changes 58% of pixels **on edges**, PSNR moves 0.05 dB | | |
| Everything is mirrored to `hf://buckets/twanghcmut/intract-wm/FlowWM/causal_droidstd/` | |
| (`step_*`, `ck20000_4val`, `base_vs_causal`, `guidance_sweep`), each with a README. | |
| ## The two things worth doing next, in order | |
| 1. **A metric that measures what this project is for.** PSNR rewards the blurry conditional | |
| mean, is blind to the sharpening that guidance demonstrably does, and barely penalises an | |
| object ending up in the wrong place — which is the entire thesis. Score instead whether | |
| the object is displaced the way the action implies (e.g. flow/position of the object | |
| region after N chunks). Until that exists, the base-vs-causal gap cannot be interpreted. | |
| 2. **Run the `baseline` ablation row — it has never been run.** Fine-tune stock Ctrl-World on | |
| these same 387 trajectories with `lambda_flow=0`. That is the only way to separate "the Phi | |
| branch costs appearance" from "fine-tuning on a 200x narrower corpus costs appearance" | |
| (catastrophic forgetting). Right now those two explanations are indistinguishable. | |
| `ABLATION=baseline bash scripts/train_causal.sh` with the same data flags. | |
| ## Bugs already found and fixed (do not re-hit) | |
| * **Phi bootstrap latent** — Phi's "no motion" is the zeros/**grey** image, not the colour | |
| wheel's white. Using `zero_flow_latent.pt` for a causal model costs ~2 dB and drifts the | |
| rollout. Fixed; `config.py:zero_phi_latent_path` now points at `zero_phi_latent.pt`. | |
| * **depth stage env** — `oscar-droid/.venv` gets numpy from `~/.local`, so it needs | |
| `env -u PYTHONNOUSERSITE` while the conda stages need `PYTHONNOUSERSITE=1`. | |
| * **rollout on droid_std** — that dataset has no pre-decimated `joints` key; it is rebuilt | |
| from `joint_position` + `gripper_position` (verified bit-identical on droid_subset). | |
| * **`flow_max`** — shipped latents were built with **20.0**, but | |
| `extract_flow_latent.py::resolve_flow_max` prefers `flow_max_calibration.json` (121.70). | |
| Regenerating flow latents without `--flow_max 20.0` silently yields an incompatible dataset. | |
| * The `COLLAPSE RISK` line in the train log is unreliable whenever `zero_phi_latent_path` is | |
| unset — it then compares raw latent norms, which separate moving from static by only 1.03x | |
| even on ground truth. | |
Xet Storage Details
- Size:
- 4.73 kB
- Xet hash:
- dfe81c5184e5583865da7c32f04333b325cb95559638d3c2c4e124f9c6675c33
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.