Skip to content

Commit d5ab046

Browse files
fwd4claude
andcommitted
action DROID recipe: address PR NVIDIA#37 review (ychao-nvidia)
- Cosmos3-DROID dataset naming + HF links; doc restructured (Prerequisites / Inputs You Provide / Recipe / Full Reproduction / Checkpoints). - Launcher: DATASET_PATH + EXTRA_DATASET_CHECK for the Cosmos3-DROID success dir. - State multi-node GB200 validation at 8192 global batch (drop H200-specific notes). - Describe max_samples_per_batch precisely: samples packed into each per-rank batch (num_workers x prefetch_factor workers decode in parallel to feed it); spell out global batch = max_samples_per_batch x world size x grad_accum_iter. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Hao Liang <haolia@nvidia.com>
1 parent c0fde79 commit d5ab046

4 files changed

Lines changed: 48 additions & 50 deletions

File tree

cosmos_framework/configs/base/experiment/action/posttrain_config/action_policy_droid_nano.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@
203203
iterable_shuffle=True, # rank x worker episode-shuffle stream
204204
episode_shuffle_seed=42,
205205
use_image_augmentation=True, # SR boost (random crop+rescale + color jitter)
206-
# Keep-ranges window filter (drops idle/non-task frames). Off by default;
206+
# keep_ranges_1_0_1.json window filter (drops idle/non-task frames). Off by default;
207207
# set use_filter_dict=True + filter_dict_path to enable.
208208
use_filter_dict=False,
209209
filter_dict_path=None,

docs/action_policy_droid_posttrain.md

Lines changed: 40 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
# Cosmos3-Nano-Policy-DROID Post-Training
22

3-
[Cosmos3-Nano-Policy-DROID](https://huggingface.co/nvidia/Cosmos3-Nano-Policy-DROID) is an action policy fine-tuned from [`Cosmos3-Nano`](https://huggingface.co/nvidia/Cosmos3-Nano) (the 8B MoT) on the **DROID LeRobot** dataset, using absolute joint-position actions plus proprioceptive state at 480p. This example reproduces that post-training. The registered `action_policy_droid_nano` experiment, the DROID action dataset class (`joint_pos` 8-D + `use_state`), and the EMA warm-start fix all ship in this package; you supply two external inputs — a prepared DROID LeRobot dataset and a DCP base checkpoint converted from `nvidia/Cosmos3-Nano` (see [Inputs You Provide](#inputs-you-provide)). Validated end-to-end on H200: 1 node / 8 GPU and 2 nodes / 16 ranks (HSDP).
3+
[Cosmos3-Nano-Policy-DROID](https://huggingface.co/nvidia/Cosmos3-Nano-Policy-DROID) is an action policy model post-trained from [Cosmos3-Nano](https://huggingface.co/nvidia/Cosmos3-Nano), a 16B Mixture-of-Transformers model, on the [Cosmos3-DROID](https://huggingface.co/datasets/nvidia/Cosmos3-DROID) dataset. The model predicts absolute joint-position actions conditioned on proprioceptive state and video observations at a resolution of 480p (`640×360`). This example reproduces the post-training procedure used to train the model.
4+
5+
Two external inputs are required: (1) a pre-downloaded Cosmos3-DROID dataset in LeRobotDataset v3.0 format, and (2) a DCP base checkpoint converted from Cosmos3-Nano.
6+
7+
The recipe runs multi-node via HSDP (single node / 8 GPUs and beyond).
48

59
<!--TOC-->
610

711
______________________________________________________________________
812

913
**Table of Contents**
1014

15+
- [Prerequisites](#prerequisites)
1116
- [Inputs You Provide](#inputs-you-provide)
12-
- [Dataset](#dataset)
1317
- [Recipe](#recipe)
1418
- [Full Reproduction](#full-reproduction)
1519
- [Checkpoints](#checkpoints)
@@ -18,13 +22,13 @@ ______________________________________________________________________
1822

1923
<!--TOC-->
2024

21-
Prerequisites:
25+
## Prerequisites
2226

2327
- [Setup](../README.md#setup) — clone the repo, install the training extras (`uv sync --all-extras --group=cu130-train`), and activate the environment.
24-
- [Environment Variables](./environment_variables.md)
25-
- [FAQ](./faq.md) — troubleshooting (OOM during SFT, defaults), common pitfalls.
28+
- [Environment Variables](./environment_variables.md) — set environment variables.
29+
- [FAQ](./faq.md) — troubleshooting (OOM during SFT, defaults) and common pitfalls.
2630

27-
The runnable artifacts (TOML recipe, paired launch shell) live in [`examples/`](../examples/README.md); all commands below run from the repo root with the environment activated.
31+
The runnable artifacts (TOML recipe, paired launch shell) live in [`examples/`](../examples); all commands below run from the repo root with the environment activated.
2832

2933
## Inputs You Provide
3034

@@ -33,53 +37,44 @@ the DROID action dataset class with the recipe knobs (`action_space=joint_pos`,
3337
`concat_view`), and the EMA warm-start in `checkpoint/dcp.py`. Two inputs are external and must
3438
be provided per environment:
3539

36-
1. **Prepared DROID LeRobot v3.0 dataset** — the LeRobot v2.0→v3.0 conversion + success
37-
filtering is run out-of-band (not yet in this repo). Point `DROID_ROOT` at the resulting
38-
`…/droid_lerobot/success` directory (must contain `meta/info.json`).
39-
2. **DCP base checkpoint** — convert `nvidia/Cosmos3-Nano` to DCP and point
40+
1. **[Cosmos3-DROID](https://huggingface.co/datasets/nvidia/Cosmos3-DROID) dataset (in LeRobotDataset v3.0 format)** — pre-download the
41+
dataset and point `DROID_ROOT` at the resulting `…/Cosmos3-DROID/success` directory (must
42+
contain `meta/info.json`).
43+
2. **DCP base checkpoint** — convert [Cosmos3-Nano](https://huggingface.co/nvidia/Cosmos3-Nano) to DCP and point
4044
`BASE_CHECKPOINT_PATH` at it (see [Full Reproduction](#full-reproduction)). Action heads are
4145
not loaded from it (they init fresh).
4246

43-
## Dataset
44-
45-
The **DROID LeRobot** dataset. To be released.
46-
4747
## Recipe
4848

49-
| knob | value |
50-
| ----------------- | ----------------------------------------------------------------------------------------------------- |
51-
| init | `nvidia/Cosmos3-Nano` (public Hugging Face repo) |
52-
| action space | `joint_pos` (absolute joint position, 8-D incl. gripper) |
53-
| state | `use_state=true` (proprioception; valid only with `joint_pos`) |
54-
| task mode | `policy` (single-task; the `joint` multi-task default is avoided) |
55-
| resolution | `480` |
56-
| viewpoint / video | `concat_view` / `video_mode=null` |
57-
| chunk length | `32` (tokenizer `encode_exact_durations=[33]`) |
58-
| sequence packing | `max_num_tokens_after_packing=-1` (full vision sequence per step) |
59-
| shuffle | episode-shuffle stream (decorrelates the per-step global batch) |
60-
| window filter | keep-ranges (`KarlP/droid`) — trains the curated ≈74% window set |
61-
| lr | `2e-4` |
62-
| global batch | `8192` (e.g. 128 samples/rank × 64 ranks; lower per-rank + raise `grad_accum_iter` to fit GPU memory) |
63-
| eval | disabled for the reproduction run |
64-
65-
> The dataset streams an **episode-shuffle** order (decorrelates the per-step global batch — a
66-
> plain sequential read feeds every rank the same overlapping windows → unstable grad-norm). The
67-
> **keep-ranges window filter** drops idle/non-task frames (trains the curated ≈74% window set);
68-
> the reproduction enables it by default — see [Full Reproduction](#full-reproduction).
49+
| knob | value |
50+
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
51+
| init | `Cosmos3-Nano` (public Hugging Face repo) |
52+
| action space | `joint_pos` (absolute joint position, 8-D incl. gripper) |
53+
| state | `use_state=true` (proprioception; valid only with `joint_pos`) |
54+
| task mode | `policy` (single-task; the `joint` multi-task default is avoided) |
55+
| resolution | `480` |
56+
| viewpoint / video | `concat_view` / `video_mode=null` |
57+
| chunk length | `32` (tokenizer `encode_exact_durations=[33]`) |
58+
| sequence packing | `max_num_tokens_after_packing=-1` (full vision sequence per step) |
59+
| shuffle | episode-shuffle stream (decorrelates the per-step global batch) |
60+
| window filter | [keep_ranges_1_0_1.json](https://huggingface.co/KarlP/droid/blob/main/keep_ranges_1_0_1.json) (`KarlP/droid`) — trains the curated ≈74% window set |
61+
| lr | `2e-4` |
62+
| global batch | `8192` = `max_samples_per_batch` × world size × `grad_accum_iter` (e.g. 64 × 128 ranks × 1; reduce `max_samples_per_batch` + raise `grad_accum_iter` to fit GPU memory) |
63+
| eval | disabled for the reproduction run |
6964

7065
## Full Reproduction
7166

7267
The OSS flow mirrors the other recipes (see [docs/training.md](./training.md)):
7368

7469
```shell
75-
# Step 1: prepare DROID LeRobot v3.0 success split -> $DATASET_PATH (see "Inputs You Provide")
70+
# Step 1: prepare Cosmos3-DROID success split -> $DATASET_PATH (see "Inputs You Provide")
7671

7772
# Step 2: convert the base checkpoint -> $BASE_CHECKPOINT_PATH
7873
python -m cosmos_framework.scripts.convert_model_to_dcp \
79-
-o $BASE_CHECKPOINT_PATH \
80-
--checkpoint-path Cosmos3-Nano
74+
--checkpoint-path Cosmos3-Nano \
75+
-o $BASE_CHECKPOINT_PATH
8176

82-
# Step 3: download the keep-ranges window filter (drops idle/non-task frames -> trains
77+
# Step 3: download the keep_ranges_1_0_1.json window filter (drops idle/non-task frames -> trains
8378
# the curated ~74% window set, matching the released model).
8479
hf download KarlP/droid keep_ranges_1_0_1.json --local-dir $FILTER_DIR
8580

@@ -89,21 +84,22 @@ export DATASET_PATH=/path/to/dataset/success
8984
export BASE_CHECKPOINT_PATH=/path/to/base_checkpoint
9085
export WAN_VAE_PATH=/path/to/Wan2.2_VAE.pth
9186
export NPROC_PER_NODE=8
92-
# Enable the keep-ranges filter via EXTRA_TAIL_OVERRIDES (space-separated Hydra
87+
# Enable the keep_ranges_1_0_1.json filter via EXTRA_TAIL_OVERRIDES (space-separated Hydra
9388
# overrides; an exported string survives `bash <wrapper>`).
94-
export EXTRA_TAIL_OVERRIDES="\
95-
dataloader_train.dataloader.datasets.droid.dataset.use_filter_dict=True \
96-
dataloader_train.dataloader.datasets.droid.dataset.filter_dict_path=$FILTER_DIR/keep_ranges_1_0_1.json"
89+
export EXTRA_TAIL_OVERRIDES=" \
90+
dataloader_train.dataloader.datasets.droid.dataset.use_filter_dict=True \
91+
dataloader_train.dataloader.datasets.droid.dataset.filter_dict_path=$FILTER_DIR/keep_ranges_1_0_1.json \
92+
"
9793
bash examples/launch_sft_action_policy_droid.sh
9894
```
9995

100-
The recipe TOML (`examples/toml/sft_config/action_policy_droid_repro.toml`) sets the scalar
96+
The recipe TOML ([`examples/toml/sft_config/action_policy_droid_repro.toml`](../examples/toml/sft_config/action_policy_droid_repro.toml)) sets the scalar
10197
knobs (`max_iter`, `save_iter`, `grad_clip`, parallelism, wandb); the dataset/action knobs
10298
(`joint_pos`, `use_state`, `concat_view`, 480p, chunk 32, count-based batch) live in the
10399
registered `action_policy_droid_nano` experiment per the schema's design. For multi-node HSDP,
104100
set `model.config.parallelism.data_parallel_replicate_degree = <num_nodes>` (intra-node shard stays 8).
105101

106-
The **keep-ranges filter** maps each DROID trajectory key to a list of `[start, end]` frame
102+
The **keep_ranges_1_0_1.json filter** maps each DROID trajectory key to a list of `[start, end]` frame
107103
ranges; only windows whose start falls inside a kept range are trained on (episodes absent from
108104
the dict are dropped). To train on the full window set instead, leave `EXTRA_TAIL_OVERRIDES` unset.
109105

examples/launch_sft_action_policy_droid.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
# docs/action_policy_droid_posttrain.md.
1212
#
1313
# Env vars (override for your filesystem):
14-
# DATASET_PATH DROID LeRobot v3.0 success split (…/droid_lerobot/success)
14+
# DATASET_PATH Cosmos3-DROID success split (…/Cosmos3-DROID/success)
1515
# BASE_CHECKPOINT_PATH DCP of nvidia/Cosmos3-Nano (convert_model_to_dcp; see docs)
1616
# WAN_VAE_PATH Wan2.2 VAE .pth (Wan-AI/Wan2.2-TI2V-5B)
1717
# WANDB_API_KEY for online logging (TOML wandb_mode="online")
@@ -35,7 +35,7 @@ TOML_FILE="examples/toml/sft_config/action_policy_droid_repro.toml"
3535
# The experiment reads ${oc.env:DROID_ROOT}; bridge the launcher's DATASET_PATH to it.
3636
export DROID_ROOT="${DROID_ROOT:-$DATASET_PATH}"
3737

38-
EXTRA_DATASET_CHECK='[[ -f "$DROID_ROOT/meta/info.json" ]] || { echo "ERROR: missing $DROID_ROOT/meta/info.json (prepare DROID LeRobot v3.0 — see docs/action_policy_droid_posttrain.md)" >&2; exit 1; }'
38+
EXTRA_DATASET_CHECK='[[ -f "$DROID_ROOT/meta/info.json" ]] || { echo "ERROR: missing $DROID_ROOT/meta/info.json (prepare Cosmos3-DROID — see docs/action_policy_droid_posttrain.md)" >&2; exit 1; }'
3939

4040
# Extra Hydra overrides from the environment: a space-separated string word-split into
4141
# the TAIL_OVERRIDES array. An exported string survives `bash <wrapper>` (a child

examples/toml/sft_config/action_policy_droid_repro.toml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ wandb_mode = "online"
2727
precision = "bfloat16"
2828

2929
[model.parallelism]
30-
data_parallel_shard_degree = 8 # intra-node (8x H200); set replicate for multi-node HSDP
30+
data_parallel_shard_degree = 8 # 8-GPU model shard; set replicate for multi-node HSDP
3131
data_parallel_replicate_degree = 1
3232

3333
[model.activation_checkpointing]
@@ -48,6 +48,8 @@ logging_iter = 50
4848
load_path = "${oc.env:BASE_CHECKPOINT_PATH}"
4949
save_iter = 1000
5050

51-
# Per-rank batch is 128 in the experiment (res480; matches the reference recipe).
52-
# 128 OOMs on a 139 GiB H200 — override at launch for H200:
51+
# max_samples_per_batch is 128 in the experiment — samples packed into each per-rank batch
52+
# (the num_workers x prefetch_factor workers just decode in parallel to keep it fed); res480,
53+
# reference recipe, validated multi-node on GB200.
54+
# On lower-memory GPUs, reduce it at launch, e.g.:
5355
# --opts dataloader_train.max_samples_per_batch=32

0 commit comments

Comments
 (0)