-
Notifications
You must be signed in to change notification settings - Fork 788
[Feat] support action forward dynamics finetuning #283
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
WeiChengTseng
wants to merge
3
commits into
NVIDIA:main
Choose a base branch
from
WeiChengTseng:cosmos3-action-fd
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
173 changes: 173 additions & 0 deletions
173
cookbooks/cosmos3/generator/action/finetune/action_fd_droid_posttrain.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,173 @@ | ||
| # Action FD DROID Post-Training | ||
|
|
||
| This document describes how to run the `action_fd_droid_posttrain` experiment. | ||
| It trains Cosmos3-DROID forward dynamics in `cosmos_framework`. | ||
|
|
||
| ## Overview | ||
|
|
||
| | Piece | Value | | ||
| | ------------------------- | ---------------------------------------------------------------------------------------------------------------------- | | ||
| | Experiment | `action_fd_droid_posttrain` | | ||
| | TOML | `toml/sft_config/action_fd_droid_posttrain.toml` | | ||
| | Launch shell | `launch_sft_action_fd_droid_posttrain.sh` | | ||
| | Config module | `cosmos_framework/configs/base/experiment/action/posttrain_config/action_fd_droid_posttrain.py` | | ||
| | Dataset wrapper | `cosmos_framework/data/generator/action/datasets/droid_merged_lerobot_dataset.py` | | ||
| | Dataset root | [Cosmos3-DROID](https://huggingface.co/datasets/nvidia/Cosmos3-DROID) parent root containing `success/` and `failure/` | | ||
| | Task mode | `forward_dynamics` | | ||
| | Action space | `ee_pose`: 10-D `[pos_delta, rot6d_delta, gripper]` | | ||
| | Chunk length / resolution | `16` frames at `480` | | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| - Install cosmos-framework as described in the shared | ||
| [setup instructions](../../../README.md), then activate its | ||
| virtual environment. | ||
| - Authenticate with Hugging Face (`uvx hf@latest auth login` or `HF_TOKEN`) and | ||
| accept the terms for the required model and dataset repositories. | ||
| - The TOML defaults to online Weights & Biases logging. Export `WANDB_API_KEY`, | ||
| or disable it with `EXTRA_TAIL_OVERRIDES="job.wandb_mode=disabled"`. | ||
| - Run commands from `cookbooks/cosmos3/generator/action/finetune/`. | ||
| - In NGC / PyTorch containers, set `LD_LIBRARY_PATH=''` before Python commands. | ||
|
|
||
| ## Inputs You Provide | ||
|
|
||
| This package ships the training stack — the registered `action_fd_droid_posttrain` | ||
| experiment, the dataset class, and the paired TOML/launch shell. Three inputs | ||
| are external and must be provided per environment: | ||
|
|
||
| 1. **[Cosmos3-DROID](https://huggingface.co/datasets/nvidia/Cosmos3-DROID) dataset (in LeRobotDataset v3.0 format)** — pre-download the | ||
| dataset and point `DATASET_PATH` at the | ||
| resulting `.../Cosmos3-DROID` parent directory. This experiment trains on both | ||
| `success/` and `failure/` subsets. | ||
| 2. **DCP base checkpoint** — prepare a base DCP checkpoint and point | ||
| `BASE_CHECKPOINT_PATH` at it. For local smoke runs this can be | ||
| `checkpoints/Cosmos3-Nano`. | ||
| 3. **Wan2.2 VAE** — download `Wan2.2_VAE.pth` from | ||
| [`Wan-AI/Wan2.2-TI2V-5B`](https://huggingface.co/Wan-AI/Wan2.2-TI2V-5B) | ||
| and point `WAN_VAE_PATH` at the file. | ||
|
|
||
| ## Data Layout | ||
|
|
||
| Set `DATASET_PATH` to the Cosmos3-DROID parent directory: | ||
|
|
||
| ```shell | ||
| export DATASET_PATH=/path/to/Cosmos3-DROID | ||
| ``` | ||
|
|
||
| The loader uses both subsets: | ||
|
|
||
| ```text | ||
| $DATASET_PATH/ | ||
| ├── success/ | ||
| │ └── meta/info.json | ||
| └── failure/ | ||
| └── meta/info.json | ||
| ``` | ||
|
|
||
| or institution-sharded split roots: | ||
|
|
||
| ```text | ||
| $DATASET_PATH/ | ||
| ├── success/<institution>/meta/info.json | ||
| └── failure/<institution>/meta/info.json | ||
| ``` | ||
|
|
||
| The launch shell passes `DATASET_PATH` through to the training config. | ||
|
|
||
| ## Full Reproduction | ||
|
|
||
| The flow mirrors the other SFT recipes: | ||
|
|
||
| ```shell | ||
| # Step 1: prepare Cosmos3-DROID -> $DATASET_PATH. | ||
| # If you do not already have the dataset locally, download it from Hugging Face. | ||
| uvx hf@latest download --repo-type dataset nvidia/Cosmos3-DROID \ | ||
| --local-dir data/Cosmos3-DROID --quiet | ||
| export DATASET_PATH=data/Cosmos3-DROID | ||
|
|
||
| # Step 2: prepare the base DCP checkpoint and Wan2.2 VAE. | ||
| python -m cosmos_framework.scripts.convert_model_to_dcp \ | ||
| -o checkpoints/Cosmos3-Nano \ | ||
| --checkpoint-path Cosmos3-Nano | ||
| uvx hf@latest download Wan-AI/Wan2.2-TI2V-5B Wan2.2_VAE.pth \ | ||
| --local-dir checkpoints/wan22_vae | ||
| export BASE_CHECKPOINT_PATH=checkpoints/Cosmos3-Nano | ||
| export WAN_VAE_PATH=checkpoints/wan22_vae/Wan2.2_VAE.pth | ||
|
|
||
| # Step 3: optionally choose the output root and launch. | ||
| export OUTPUT_ROOT=/path/to/output_root | ||
| export LD_LIBRARY_PATH='' | ||
|
|
||
| bash launch_sft_action_fd_droid_posttrain.sh | ||
| ``` | ||
|
|
||
| `BASE_CHECKPOINT_PATH` should point at the base DCP checkpoint. When using the | ||
| paired launch shell, it must be a local directory because the shared launcher | ||
| validates it before starting `torchrun`. | ||
|
|
||
| ## Validate The Config | ||
|
|
||
| Use `--dryrun` before launching workers: | ||
|
|
||
| ```shell | ||
| PYTHONPATH=. python -m cosmos_framework.scripts.train \ | ||
| --sft-toml toml/sft_config/action_fd_droid_posttrain.toml \ | ||
| --dryrun | ||
| ``` | ||
|
|
||
| ## Run Training | ||
|
|
||
| Recommended paired launch shell: | ||
|
|
||
| ```shell | ||
| bash launch_sft_action_fd_droid_posttrain.sh | ||
| ``` | ||
|
|
||
| Pass short smoke-run overrides through `EXTRA_TAIL_OVERRIDES`: | ||
|
|
||
| ```shell | ||
| export EXTRA_TAIL_OVERRIDES="trainer.max_iter=10 checkpoint.save_iter=10" | ||
| bash launch_sft_action_fd_droid_posttrain.sh | ||
| ``` | ||
|
|
||
| Single-node, 8 GPU: | ||
|
|
||
| ```shell | ||
| PYTHONPATH=. torchrun --nproc_per_node=8 -m cosmos_framework.scripts.train \ | ||
| --sft-toml toml/sft_config/action_fd_droid_posttrain.toml | ||
| ``` | ||
|
|
||
| Multi-node HSDP: | ||
|
|
||
| ```shell | ||
| PYTHONPATH=. torchrun --nnodes=$NNODES --node_rank=$NODE_RANK --nproc_per_node=8 \ | ||
| -m cosmos_framework.scripts.train \ | ||
| --sft-toml toml/sft_config/action_fd_droid_posttrain.toml \ | ||
| -- model.parallelism.data_parallel_replicate_degree=$NNODES | ||
| ``` | ||
|
|
||
| Keep `data_parallel_shard_degree=8` and set | ||
| `model.parallelism.data_parallel_replicate_degree` to the number of nodes. | ||
|
|
||
| ## Outputs | ||
|
|
||
| Training outputs land under: | ||
|
|
||
| ```text | ||
| $IMAGINAIRE_OUTPUT_ROOT/cosmos3_action_fd/action_sft/<job.name>/ | ||
| ``` | ||
|
|
||
| DCP checkpoints are saved under: | ||
|
|
||
| ```text | ||
| $RUN_DIR/checkpoints/iter_<N>/ | ||
| ``` | ||
|
|
||
| The run is resumable by relaunching with the same output directory and job name. | ||
|
|
||
| ## Notes | ||
|
|
||
| - This recipe uses `mode="forward_dynamics"`, so actions are conditioning and the | ||
| model trains video prediction from the first frame plus action sequence. | ||
| - `DROIDMergedLeRobotDataset` uses `action_space="ee_pose"` for the 10-D | ||
| end-effector pose action path. |
125 changes: 125 additions & 0 deletions
125
cookbooks/cosmos3/generator/action/finetune/launch_sft_action_fd_droid_posttrain.sh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,125 @@ | ||
| #!/usr/bin/env bash | ||
| # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| # SPDX-License-Identifier: OpenMDW-1.1 | ||
|
|
||
| # ============================================================================ | ||
| # Structured-TOML launch for action_fd_droid_posttrain. | ||
| # | ||
| # This script intentionally does not source _sft_launcher_common.sh. It contains | ||
| # the recipe-specific defaults, input checks, path anchoring, tail overrides, and | ||
| # torchrun invocation in one file. | ||
| # | ||
| # Run with the cosmos-framework venv active (see action_fd_droid_posttrain.md). | ||
| # Training starts from the installed cosmos-framework checkout root so relative | ||
| # model config paths (e.g. Qwen3-VL JSON) resolve correctly. | ||
| # | ||
| # Env vars (override for your filesystem): | ||
| # DATASET_PATH Cosmos3-DROID parent dir (success/ + failure/) | ||
| # BASE_CHECKPOINT_PATH Base DCP checkpoint | ||
| # WAN_VAE_PATH Wan2.2 VAE .pth | ||
| # COSMOS_FRAMEWORK_ROOT Optional override for the framework checkout root | ||
| # NPROC_PER_NODE torchrun --nproc_per_node (default 8) | ||
| # EXTRA_TAIL_OVERRIDES space-separated Hydra overrides | ||
| # MASTER_PORT torchrun --master_port (default 50012) | ||
| # NNODES torchrun --nnodes for multi-node | ||
| # NODE_RANK torchrun --node_rank for multi-node | ||
| # MASTER_ADDR torchrun --master_addr for multi-node | ||
| # OUTPUT_ROOT default output root (default outputs/train) | ||
| # LOG_FILENAME override log filename | ||
| # ============================================================================ | ||
|
|
||
| set -euo pipefail | ||
|
|
||
| # Cookbook recipe directory (TOML, logs, default relative paths). | ||
| COOKBOOK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||
|
|
||
| TOML_FILE="$COOKBOOK_DIR/toml/sft_config/action_fd_droid_posttrain.toml" | ||
|
|
||
| : "${DATASET_PATH:=data/Cosmos3-DROID}" | ||
| : "${BASE_CHECKPOINT_PATH:=checkpoints/Cosmos3-Nano}" | ||
| : "${WAN_VAE_PATH:=checkpoints/wan22_vae/Wan2.2_VAE.pth}" | ||
|
|
||
| [[ "$DATASET_PATH" = /* ]] || DATASET_PATH="$COOKBOOK_DIR/$DATASET_PATH" | ||
| [[ "$BASE_CHECKPOINT_PATH" = /* ]] || BASE_CHECKPOINT_PATH="$COOKBOOK_DIR/$BASE_CHECKPOINT_PATH" | ||
| [[ "$WAN_VAE_PATH" = /* ]] || WAN_VAE_PATH="$COOKBOOK_DIR/$WAN_VAE_PATH" | ||
| export DATASET_PATH BASE_CHECKPOINT_PATH WAN_VAE_PATH | ||
|
|
||
| OUTPUT_ROOT="${OUTPUT_ROOT:-$COOKBOOK_DIR/outputs/train}" | ||
| LOG_DIR="$OUTPUT_ROOT/logs" | ||
| TOML_STEM="$(basename "$TOML_FILE" .toml)" | ||
| LOG_FILE="$LOG_DIR/${LOG_FILENAME:-${TOML_STEM}_sft.log}" | ||
| IMAGINAIRE_OUTPUT_ROOT="${IMAGINAIRE_OUTPUT_ROOT:-$OUTPUT_ROOT}" | ||
| mkdir -p "$LOG_DIR" | ||
|
|
||
| echo ">>> $(date '+%H:%M:%S') Checking inputs..." | ||
| [[ -f "$TOML_FILE" ]] || { echo "ERROR: TOML not found: $TOML_FILE" >&2; exit 1; } | ||
| [[ -d "$DATASET_PATH" ]] || { echo "ERROR: DATASET_PATH not found: $DATASET_PATH" >&2; exit 1; } | ||
| [[ -d "$BASE_CHECKPOINT_PATH" ]] || { echo "ERROR: BASE_CHECKPOINT_PATH not found: $BASE_CHECKPOINT_PATH" >&2; exit 1; } | ||
| [[ -f "$WAN_VAE_PATH" ]] || { echo "ERROR: WAN_VAE_PATH not found: $WAN_VAE_PATH" >&2; exit 1; } | ||
|
|
||
| [[ -f "$DATASET_PATH/success/meta/info.json" || -n "$(compgen -G "$DATASET_PATH/success/*/meta/info.json")" ]] || { | ||
| echo "ERROR: missing Cosmos3-DROID success split under $DATASET_PATH (expected success/meta/info.json or success/*/meta/info.json)" >&2 | ||
| exit 1 | ||
| } | ||
| [[ -f "$DATASET_PATH/failure/meta/info.json" || -n "$(compgen -G "$DATASET_PATH/failure/*/meta/info.json")" ]] || { | ||
| echo "ERROR: missing Cosmos3-DROID failure split under $DATASET_PATH (expected failure/meta/info.json or failure/*/meta/info.json)" >&2 | ||
| exit 1 | ||
| } | ||
|
|
||
| if [[ -n "${COSMOS_FRAMEWORK_ROOT:-}" ]]; then | ||
| FRAMEWORK_ROOT="$(cd "$COSMOS_FRAMEWORK_ROOT" && pwd)" | ||
| else | ||
| FRAMEWORK_ROOT="$( | ||
| python -c 'import pathlib, cosmos_framework; print(pathlib.Path(cosmos_framework.__file__).resolve().parents[1])' | ||
| )" | ||
| fi | ||
|
|
||
| QWEN3_VL_CONFIG="$FRAMEWORK_ROOT/cosmos_framework/model/generator/reasoner/qwen3_vl/configs/Qwen3-VL-8B-Instruct.json" | ||
| [[ -f "$QWEN3_VL_CONFIG" ]] || { | ||
| cat >&2 <<EOF | ||
| ERROR: cannot resolve cosmos-framework model configs under: | ||
| $FRAMEWORK_ROOT | ||
|
|
||
| Expected Qwen3-VL config at: | ||
| $QWEN3_VL_CONFIG | ||
|
|
||
| Activate the cosmos-framework venv, or export COSMOS_FRAMEWORK_ROOT=/path/to/cosmos-framework. | ||
| EOF | ||
| exit 1 | ||
| } | ||
|
|
||
| TAIL_OVERRIDES=( | ||
| "trainer.straggler_detection.enabled=False" | ||
| ) | ||
| if [[ -n "${EXTRA_TAIL_OVERRIDES:-}" ]]; then | ||
| # EXTRA_TAIL_OVERRIDES is intentionally word-split to match the framework launcher UX. | ||
| # shellcheck disable=SC2206 | ||
| EXTRA_OVERRIDES_ARRAY=(${EXTRA_TAIL_OVERRIDES}) | ||
| TAIL_OVERRIDES+=("${EXTRA_OVERRIDES_ARRAY[@]}") | ||
| fi | ||
|
|
||
| TRAILING_ARGS=(-- "${TAIL_OVERRIDES[@]}") | ||
|
|
||
| TORCHRUN_ARGS=(--nproc_per_node="${NPROC_PER_NODE:-8}" --master_port="${MASTER_PORT:-50012}") | ||
| [[ -n "${NNODES:-}" ]] && TORCHRUN_ARGS+=(--nnodes="$NNODES") | ||
| [[ -n "${NODE_RANK:-}" ]] && TORCHRUN_ARGS+=(--node_rank="$NODE_RANK") | ||
| [[ -n "${MASTER_ADDR:-}" ]] && TORCHRUN_ARGS+=(--master_addr="$MASTER_ADDR") | ||
|
|
||
| cd "$FRAMEWORK_ROOT" | ||
| echo ">>> $(date '+%H:%M:%S') cookbook: $COOKBOOK_DIR" | ||
| echo ">>> $(date '+%H:%M:%S') framework: $FRAMEWORK_ROOT" | ||
| echo ">>> $(date '+%H:%M:%S') TOML: $TOML_FILE" | ||
| echo ">>> $(date '+%H:%M:%S') dataset: $DATASET_PATH" | ||
| echo ">>> $(date '+%H:%M:%S') checkpoint: $BASE_CHECKPOINT_PATH" | ||
| echo ">>> $(date '+%H:%M:%S') log: $LOG_FILE" | ||
|
|
||
| IMAGINAIRE_OUTPUT_ROOT="$IMAGINAIRE_OUTPUT_ROOT" \ | ||
| PYTHONPATH="${FRAMEWORK_ROOT}${PYTHONPATH:+:$PYTHONPATH}" \ | ||
| torchrun "${TORCHRUN_ARGS[@]}" -m cosmos_framework.scripts.train \ | ||
| --sft-toml="$TOML_FILE" \ | ||
| "${TRAILING_ARGS[@]}" \ | ||
| 2>&1 | tee "$LOG_FILE" | ||
|
|
||
| EXIT_CODE=${PIPESTATUS[0]} | ||
| echo ">>> $(date '+%H:%M:%S') Done (exit $EXIT_CODE)" | ||
| exit $EXIT_CODE |
47 changes: 47 additions & 0 deletions
47
cookbooks/cosmos3/generator/action/finetune/toml/sft_config/action_fd_droid_posttrain.toml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| # SPDX-License-Identifier: OpenMDW-1.1 | ||
|
|
||
| # ============================================================================ | ||
| # DROID-Merged LeRobot forward-dynamics post-training. | ||
| # | ||
| # Env required: | ||
| # DATASET_PATH=/path/to/Cosmos3-DROID | ||
| # BASE_CHECKPOINT_PATH=<base DCP dir or object-store path> | ||
| # WAN_VAE_PATH=<Wan2.2_VAE.pth> | ||
| # IMAGINAIRE_OUTPUT_ROOT=/path/to/output_root | ||
| # | ||
| # The registered experiment owns dataset mode/action-space wiring: | ||
| # mode="forward_dynamics", action_space="ee_pose", chunk_length=16, res480. | ||
| # ============================================================================ | ||
|
|
||
| [job] | ||
| task = "vfm" | ||
| experiment = "action_fd_droid_posttrain" | ||
| project = "cosmos3_action_fd" | ||
| group = "action_sft" | ||
| name = "action_fd_droid_posttrain" | ||
| wandb_mode = "online" | ||
|
|
||
| [model] | ||
| precision = "bfloat16" | ||
|
|
||
| [model.parallelism] | ||
| data_parallel_shard_degree = 8 | ||
| data_parallel_replicate_degree = 1 | ||
|
|
||
| [model.activation_checkpointing] | ||
| mode = "selective" | ||
|
|
||
| [model.tokenizer] | ||
| vae_path = "${oc.env:WAN_VAE_PATH}" | ||
|
|
||
| [scheduler] | ||
| cycle_lengths = [20000] | ||
|
|
||
| [trainer] | ||
| max_iter = 20000 | ||
| logging_iter = 50 | ||
|
|
||
| [checkpoint] | ||
| load_path = "${oc.env:BASE_CHECKPOINT_PATH}" | ||
| save_iter = 250 | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not blocking, but since these are not in yet, we have a merge order dependency with cosmos-framework#85.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@WeiChengTseng can you get NVIDIA/cosmos-framework#85 merged too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’m waiting for the review of that PR.