DriveDreamer-Policy: A Geometry-Grounded World–Action Model for Unified Generation and Planning
- [05/2026] Code and model weights released!
- [04/2026] Paper draft released on arXiv.
- Setup
- Data Preparation
- Model Weights
- Add World & Action Tokens
- Inference
- Evaluation
- Training
- Project Structure
- Citation
- Acknowledgements
- License
We use Python 3.10, PyTorch 2.5.1, and CUDA 12.4.
conda create -n vla python=3.10
conda activate vla
pip install torch==2.5.1 torchvision==0.20.1 torchaudio==2.5.1 \
--index-url https://download.pytorch.org/whl/cu124The repository bundles two NAVSIM versions:
| Directory | Version | Used for | Conda env |
|---|---|---|---|
navsim/ |
v2 | Training data + v2 evaluation | vla |
navsim_v1.1/navsim/ |
v1.1 | NAVSIM v1.1 leaderboard evaluation only | navsim_v1.1 |
Install NAVSIM v2 (required for training and v2 evaluation):
cd navsim
pip install -e .
cd ..Install NAVSIM v1.1 (only needed for NAVSIM v1.1 leaderboard evaluation):
NAVSIM v1.1 has different dependencies from v2, so it requires a separate conda environment:
conda create --name navsim_v1.1 --clone vla
conda activate navsim_v1.1
pip uninstall navsim -y
cd navsim_v1.1/navsim
pip install -e .
cd ../..For full installation details and dataset download instructions, refer to the official NAVSIM install guide.
Depth map generation requires a separate conda environment with Depth-Anything-3 installed:
conda create -n <your-da3-env> python=3.10
conda activate <your-da3-env>
cd depth_process/Depth-Anything-3
pip install -e .
cd ../..Our training framework is built on top of starVLA v1.0.1. Install the additional packages:
pip install -r requirements_vla.txtFill in your paths in env.sh and source it before running any pipeline script:
vim env.sh
source env.shKey variables:
| Variable | Description |
|---|---|
CUDA_HOME |
Path to your CUDA 12.4 installation |
HF_HOME |
HuggingFace model cache directory |
NUPLAN_MAPS_ROOT |
Path to nuPlan map files |
OPENSCENE_DATA_ROOT |
Root of the NAVSIM/OpenScene dataset |
NAVSIM_EXP_ROOT |
Where training experiments are saved |
BASE_VLM |
Path to the base Qwen3-VL-2B-WorldAction checkpoint |
WANDB_API_KEY |
Your Weights & Biases API key (optional) |
We convert raw NAVSIM sensor logs into our own unified training format. The complete processing logic is in navsim_data_process/make_data.py.
Dataset notes:
- For planning only, the standard
navtrainsplit is sufficient. - For video generation (2D world head), you additionally need the
trainvalRGB sensor data (lidar is not required). See the NAVSIM splits guide for download instructions.
Run the numbered scripts in order after sourcing your env file:
bash 0-process_data.shEdit SPLIT and DATA_ROOT at the top of the script to match your setup. Add --make_video to the python call to also generate video clips; omit it to skip and significantly speed up processing (recommended for planning-only runs).
Writes one pickle file per scene:
navsim_dataset/
└── meta/
└── {split}/
└── {token}.pkl # one file per scene
Each pickle contains ego poses, velocities, accelerations, driving commands, and per-camera image paths / calibration for all 8 views over T=13 frames.
When --make_video is passed, MP4 clips for the 3 front-facing cameras are also written to navsim_dataset/navsim_video/{split}/.
bash 1-gen_data_meta_list.shScans navsim_dataset/meta/{split}/ and writes a shuffled token list:
{split}_meta.json → ["token_a", "token_b", ...]
This file is passed to the dataloader via --datasets.vla_data.datalist_path.
Requires a conda environment with Depth-Anything-3 installed (see Section 1.3):
conda activate <your-da3-env>
bash 2-gen_depth.shUses the local Depth-Anything-3 copy under depth_process/, loaded offline. Generates metric depth for the 3 front-facing cameras and writes results alongside scene pickles as {token}.pkl-depth.pkl.
bash 3-stat_data.shComputes per-channel trajectory statistics (mean, std) over the training split. Re-run this step and update the normalisation constants in starVLA/dataloader/navsim_dataset.py if you change the training split or mix in other datasets.
| Model | Role | Link |
|---|---|---|
Qwen3-VL-2B-Instruct |
Vision-language backbone | HuggingFace |
Wan2.1-Fun-V1.1-1.3B-InP |
2D video generation head | HuggingFace |
Pixel-Perfect Depth (PPD) |
3D depth head | GitHub |
Depth-Anything-V2 ViT-L |
Semantic encoder for PPD | HuggingFace |
After downloading, place the depth model checkpoints in the depth_model_ckpts/ directory at the project root:
depth_model_ckpts/
├── ppd.pth # Pixel-Perfect Depth checkpoint
└── depth_anything_v2_vitl.pth # Depth-Anything-V2 ViT-L weights
| Checkpoint | Description | Link |
|---|---|---|
DriveDreamer-Policy |
Full trained model (action + video + depth heads) | HuggingFace |
The base Qwen3-VL-2B-Instruct vocabulary must be extended with special tokens for world generation and action prediction (e.g. <2d_world_*>, <robot_action_*>). Run once before inference or training:
source env.sh
bash 7-add_token.shAfter it finishes, update BASE_VLM in env.sh to point to the new extended model:
export BASE_VLM=/path/to/Qwen3-VL-2B-WorldAction # TARGET_VLM from 7-add_token.shAlso set VIDEO_MODEL in 8-train.sh / debug.sh to your local Wan2.1 model root directory.
Set MODEL_DIR at the top of 4-infer.sh to your checkpoint directory, then run:
source env.sh
bash 4-infer.shThe script writes one .npy trajectory file per scene token under navsim_planning_results/<run_id>/<split>/.
You can also call infer.py directly:
python infer.py \
--ckpt_dir /path/to/checkpoint \
--datalist_path {split}_meta.json \
--out_dir navsim_planning_results/ \
--split test \
--batch_size 8 \
--num_workers 7Evaluation requires a pre-computed metric cache. If you do not have one, run the caching script first (commented out at the top of each eval script).
source env.sh
bash 6-eval_v2.shUses the PDM-Score evaluator from the NAVSIM v2 devkit (navsim/). Set PRED_DIR and METRIC_CACHE_PATH at the top of 6-eval_v2.sh.
conda activate navsim_v1.1
source env.sh
bash 5-eval_v1.shUses the PDM-Score evaluator from the NAVSIM v1.1 devkit (navsim_v1.1/navsim/). Requires the separate navsim_v1.1 conda environment (see Section 1.2). Set PRED_DIR and METRIC_CACHE_PATH at the top of 5-eval_v1.sh.
source env.sh
bash 8-train.shLaunches DeepSpeed ZeRO-2 training across 8 GPUs with all three heads active (1D action + 2D video + 3D depth). Set VIDEO_MODEL, VIDEO_CONFIG, VIDEO_DATA_DIR, and BASE_VLM (extended model from Section 4) at the top of 8-train.sh. The run ID is auto-timestamped; checkpoints are saved to $NAVSIM_EXP_ROOT/<run_id>/.
source env.sh
bash debug.shSet GPU and PORT at the top of debug.sh to match an available GPU. Runs a single forward + backward pass on the mini split to verify model loading, data loading, and gradient flow before a full training run.
| Parameter | Default | Description |
|---|---|---|
bz |
4 | Per-device batch size |
num_processes |
8 | Number of GPUs |
act_fm_size |
1536 | Action DiT hidden size |
act_fm_layer |
24 | Action DiT depth |
fm_repeat |
8 | Repeated diffusion steps |
trainer.learning_rate.base |
1e-5 | Base learning rate |
trainer.max_train_steps |
100 000 | Total optimisation steps |
Default values live in starVLA/config/training/cfg_yaw_1225.yaml; variables declared at the top of each shell script override specific values. You generally only need to change the path variables and SPLIT.
DriveDreamer-Policy/
├── starVLA/ # Core model package
│ ├── model/
│ │ ├── framework/ # Model wrappers (QwenOFT, …)
│ │ └── modules/
│ │ ├── action_model/ # Flow-matching DiT action head
│ │ ├── video_model/ # WAN-based 2D video generation head
│ │ ├── depth_model/ # Pixel-Perfect Depth adapter (3D head)
│ │ └── vlm/ # Qwen3-VL backbone utilities
│ ├── dataloader/
│ │ └── navsim_dataset.py # NAVSIM dataset class
│ ├── training/
│ │ └── train_starvla.py # Training entry point
│ └── config/
│ ├── deepseeds/ # DeepSpeed ZeRO configs
│ └── training/ # YAML training configs
├── navsim_data_process/ # Data processing scripts
│ ├── make_data.py # Step 0: process raw NAVSIM data
│ ├── data_list.py # Step 1: generate meta-list JSON
│ └── data_stat.py # Step 3: dataset statistics
├── depth_process/ # Depth generation (Depth-Anything-3)
├── navsim/ # NAVSIM v2 devkit
├── navsim_v1.1/ # NAVSIM v1.1 devkit
├── infer.py # Inference entry point
├── env.sh # Environment variable template
├── 0-process_data.sh # Pipeline step 0: process NAVSIM data
├── 1-gen_data_meta_list.sh # Pipeline step 1: generate meta-list JSON
├── 2-gen_depth.sh # Pipeline step 2: generate depth maps
├── 3-stat_data.sh # Pipeline step 3: dataset statistics
├── 4-infer.sh # Inference
├── 5-eval_v1.sh # NAVSIM v1.1 evaluation (conda: navsim_v1.1)
├── 6-eval_v2.sh # NAVSIM v2 evaluation (conda: vla)
├── 7-add_token.sh # Extend VLM vocabulary (run once before training)
├── 8-train.sh # Full training (8 GPUs)
└── debug.sh # Single-GPU debug run
If you use DriveDreamer-Policy in your research, please cite:
@misc{zhou2026drivedreamerpolicy,
title={DriveDreamer-Policy: A Geometry-Grounded World-Action Model for Unified Generation and Planning},
author={Yang Zhou and Xiaofeng Wang and Hao Shao and Letian Wang and Guosheng Zhao and Jiangnan Shao and Jiagang Zhu and Tingdong Yu and Zheng Zhu and Guan Huang and Steven L. Waslander},
year={2026},
eprint={2604.01765},
archivePrefix={arXiv},
primaryClass={cs.CV},
url={https://arxiv.org/abs/2604.01765},
}This repository is built upon the following open-source projects. We sincerely thank their authors for making their work publicly available:
- starVLA — training framework and model architecture
- Qwen3-VL — vision-language backbone
- VideoX-Fun — video generation modules
- Pixel-Perfect Depth (PPD) — metric depth estimation head
- Depth-Anything — monocular depth foundation model
- NAVSIM — autonomous driving simulation and evaluation
All code in this repository is released under the Apache License 2.0.
The bundled NAVSIM devkit retains its original licence; please refer to navsim/LICENSE.
