vla-sft-code-dreamzero / scripts /train /droid_training_wan22.sh
poet70's picture
Upload folder using huggingface_hub
ac29381 verified
Raw
History Blame Contribute Delete
6.18 kB
#!/bin/bash
# DreamZero DROID Training Script with Wan2.2-TI2V-5B backbone
#
# Usage:
# bash scripts/train/droid_training_wan22.sh
#
# Prerequisites:
# - DROID dataset in LeRobot format at DROID_DATA_ROOT
# Download: huggingface-cli download GEAR-Dreams/DreamZero-DROID-Data --repo-type dataset --local-dir ./data/droid_lerobot
# - Wan2.2-TI2V-5B weights (download from HuggingFace)
# huggingface-cli download Wan-AI/Wan2.2-TI2V-5B --local-dir ./checkpoints/Wan2.2-TI2V-5B
# - Image encoder (CLIP) from Wan2.1 - Wan2.2-TI2V-5B does not include it
# Option A: huggingface-cli download Wan-AI/Wan2.1-I2V-14B-480P --local-dir ./checkpoints/Wan2.1-I2V-14B-480P
# Option B: Set IMAGE_ENCODER_DIR to a path containing models_clip_open-clip-xlm-roberta-large-vit-huge-14.pth
# - umt5-xxl tokenizer (auto-downloaded or pre-downloaded)
# huggingface-cli download google/umt5-xxl --local-dir ./checkpoints/umt5-xxl
export HYDRA_FULL_ERROR=1
# Repo root: must be a directory that contains groot/ (so experiment.py can be found).
# Beaker/weka uses /root/yejink/dreamzero; image has /root/dreamzero; else script location.
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SCRIPT_REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
if [ -n "$DREAMZERO_ROOT" ] && [ -d "$DREAMZERO_ROOT/groot" ]; then
: # keep existing and valid
elif [ -d "/root/yejink/dreamzero/groot" ]; then
DREAMZERO_ROOT=/root/yejink/dreamzero
elif [ -d "/root/dreamzero/groot" ]; then
DREAMZERO_ROOT=/root/dreamzero
elif [ -d "$SCRIPT_REPO_ROOT/groot" ]; then
DREAMZERO_ROOT="$SCRIPT_REPO_ROOT"
else
DREAMZERO_ROOT="${DREAMZERO_ROOT:-/root/yejink/dreamzero}"
fi
if [ ! -d "$DREAMZERO_ROOT/groot" ]; then
echo "ERROR: No groot/ under $DREAMZERO_ROOT. Set DREAMZERO_ROOT to the dreamzero repo root that contains groot/."
exit 1
fi
# ============ USER CONFIGURATION ============
NUM_GPUS=${NUM_GPUS:-8}
DROID_DATA_ROOT=${DROID_DATA_ROOT:-"$DREAMZERO_ROOT/data/droid_lerobot"}
# If env set the old relative default, resolve to repo root (e.g. Beaker image env)
if [ "$DROID_DATA_ROOT" = "./data/droid_lerobot" ]; then
DROID_DATA_ROOT="$DREAMZERO_ROOT/data/droid_lerobot"
fi
OUTPUT_DIR=${OUTPUT_DIR:-"$DREAMZERO_ROOT/checkpoints/dreamzero_droid_wan22_lora"}
# Wan2.2-TI2V-5B checkpoint (contains: diffusion weights, T5, VAE)
WAN22_CKPT_DIR=${WAN22_CKPT_DIR:-"$DREAMZERO_ROOT/checkpoints/Wan2.2-TI2V-5B"}
# Image encoder: Wan2.2-TI2V-5B does NOT include CLIP - use Wan2.1's or standalone
IMAGE_ENCODER_DIR=${IMAGE_ENCODER_DIR:-"$DREAMZERO_ROOT/checkpoints/Wan2.1-I2V-14B-480P"}
TOKENIZER_DIR=${TOKENIZER_DIR:-"$DREAMZERO_ROOT/checkpoints/umt5-xxl"}
# =============================================
# ============ AUTO-DOWNLOAD WEIGHTS ============
if [ ! -d "$WAN22_CKPT_DIR" ] || [ -z "$(ls -A "$WAN22_CKPT_DIR" 2>/dev/null)" ]; then
echo "Wan2.2-TI2V-5B not found at $WAN22_CKPT_DIR. Downloading from HuggingFace..."
huggingface-cli download Wan-AI/Wan2.2-TI2V-5B --local-dir "$WAN22_CKPT_DIR"
fi
if [ ! -d "$TOKENIZER_DIR" ] || [ -z "$(ls -A "$TOKENIZER_DIR" 2>/dev/null)" ]; then
echo "umt5-xxl tokenizer not found at $TOKENIZER_DIR. Downloading from HuggingFace..."
huggingface-cli download google/umt5-xxl --local-dir "$TOKENIZER_DIR"
fi
# Image encoder: download Wan2.1 if not present (only need CLIP from it)
if [ ! -f "$IMAGE_ENCODER_DIR/models_clip_open-clip-xlm-roberta-large-vit-huge-14.pth" ]; then
echo "Image encoder not found. Downloading Wan2.1-I2V-14B-480P (for CLIP only)..."
huggingface-cli download Wan-AI/Wan2.1-I2V-14B-480P --local-dir "$IMAGE_ENCODER_DIR"
fi
# ================================================
# Validate dataset exists
if [ ! -d "$DROID_DATA_ROOT" ]; then
echo "ERROR: DROID dataset not found at $DROID_DATA_ROOT"
echo "Download with: huggingface-cli download GEAR-Dreams/DreamZero-DROID-Data --repo-type dataset --local-dir $DROID_DATA_ROOT"
exit 1
fi
# Use image Python 3.11 when available (Dockerfile installs dreamzero with python3.11 -m pip).
# Absolute path so worker processes open the correct file even if their cwd differs.
EXPERIMENT_PY="$DREAMZERO_ROOT/groot/vla/experiment/experiment.py"
if [ ! -f "$EXPERIMENT_PY" ]; then
echo "ERROR: Not found: $EXPERIMENT_PY"
exit 1
fi
PYTHON_311="/usr/bin/python3.11"
if [ -x "$PYTHON_311" ]; then
if [ -n "${FIX_NUMPY_IN_SCRIPT:-}" ]; then
"$PYTHON_311" -m pip install "numpy==1.26.4" --force-reinstall -q 2>/dev/null || true
fi
RUN_CMD=( "$PYTHON_311" -m torch.distributed.run --nproc_per_node "$NUM_GPUS" --standalone "$EXPERIMENT_PY" )
echo "Using image Python 3.11: $PYTHON_311"
else
RUN_CMD=( python3 -m torch.distributed.run --nproc_per_node "$NUM_GPUS" --standalone "$EXPERIMENT_PY" )
echo "Using: $(command -v python3)"
fi
cd "$DREAMZERO_ROOT"
"${RUN_CMD[@]}" \
report_to=wandb \
data=dreamzero/droid_relative_wan22 \
wandb_project=dreamzero \
train_architecture=lora \
num_frames=33 \
action_horizon=24 \
num_views=3 \
model=dreamzero/vla \
model/dreamzero/action_head=wan_flow_matching_action_tf_wan22 \
model/dreamzero/transform=dreamzero_cotrain \
num_frame_per_block=2 \
num_action_per_block=24 \
num_state_per_block=1 \
seed=42 \
training_args.learning_rate=1e-5 \
training_args.deepspeed="groot/vla/configs/deepspeed/zero2.json" \
save_steps=1000 \
training_args.warmup_ratio=0.05 \
output_dir=$OUTPUT_DIR \
per_device_train_batch_size=1 \
max_steps=100 \
weight_decay=1e-5 \
save_total_limit=10 \
upload_checkpoints=false \
bf16=true \
tf32=true \
eval_bf16=true \
dataloader_pin_memory=false \
dataloader_num_workers=1 \
save_lora_only=true \
max_chunk_size=4 \
save_strategy=no \
droid_data_root=$DROID_DATA_ROOT \
dit_version=$WAN22_CKPT_DIR \
text_encoder_pretrained_path=$WAN22_CKPT_DIR/models_t5_umt5-xxl-enc-bf16.pth \
image_encoder_pretrained_path=$IMAGE_ENCODER_DIR/models_clip_open-clip-xlm-roberta-large-vit-huge-14.pth \
vae_pretrained_path=$WAN22_CKPT_DIR/Wan2.2_VAE.pth \
tokenizer_path=$TOKENIZER_DIR