renesas/causaldrivebench

An open benchmark and evaluation framework for causal reasoning and decision-making in autonomous driving systems, designed to assess robustness, interpretability, and generalization across diverse driving scenarios.

Python

0

4 commits

updated Oct 12, 2026

See the code

README

CausalDriveBench pixel-art banner

CausalDriveBench

Evaluating Causal Reasoning in Vision-Language-Action Models for Autonomous Driving
NeurIPS 2026

arXiv Hugging Face dataset NeurIPS 2026 Code license: BSD-3-Clause Data license: CC BY-NC-SA 4.0 Python 3.11

πŸ“„ Paper Β Β·Β  πŸ€— Dataset Β Β·Β  πŸ—‚οΈ Code & Doc Index Β Β·Β  πŸ§ͺ Evaluation Framework Β Β·Β  πŸ“‘ Citation


CausalDriveBench tests whether driving vision-language-action (VLA) models reason causally: can they explain why the ego vehicle brakes, yields or proceeds, and predict what it would do if the scene were different? Grounded in Pearl's Causal Hierarchy, it combines structured causal visual question answering with counterfactual trajectory prediction on real nuScenes driving scenes. Each scene is backed by a causal scene graph that separates active, dormant and distractor entities.

This repository contains the full code for building the benchmark (records β†’ causal scene graphs β†’ QA β†’ counterfactual trajectories) and for evaluating VLAs / VLMs on it.

The banner shows the idea in miniature: the red light is an active cause of the ego car's behaviour (red, dotted), the pedestrian on the kerb is a dormant cause (amber, dashed), and the parked car is a distractor (no arrow).

Contents


Highlights

  • 🧭 Pearl's Causal Hierarchy, made concrete for driving. Questions span association, intervention and counterfactual rungs. They are generated from causal scene graphs whose edges are labelled active-sustaining, active-triggering or dormant, and the graphs also list distractors.
  • πŸ“¦ 7,285 verified causal QA pairs and 1,000 counterfactual trajectories on nuScenes.
  • πŸ€– 13 models evaluated: 10 driving-specific VLAs and 3 general-purpose VLMs.
  • πŸ“‰ Causal reasoning remains hard. The best model reaches 70.6 % QA accuracy, and 4 of 13 models score below random chance.
  • πŸ” Driving fine-tuning costs causal reasoning. Compared with the general-purpose VLM that shares its backbone, a driving fine-tune loses 2–34 percentage points on causal QA.
  • πŸ”€ Language and action are decoupled. Causal-QA accuracy and trajectory accuracy are statistically uncorrelated.

"Neither fluent rationales nor accurate observed-scene trajectories constitute evidence of causal understanding."


Benchmark overview

flowchart LR
    subgraph Build["Benchmark construction (scripts/)"]
        direction TB
        A[Raw driving logs<br/>nuScenes Β· OpenScene Β· AV2] --> B[Unified records<br/>4 timesteps Β· cameras Β· BEV Β· state]
        B --> C[Causal scene graph<br/>VLM, Batch API]
        C --> D[Pruning +<br/>human verification]
        D --> E[Diversity<br/>clustering]
        E --> F[Causal QA<br/>active Β· dormant Β· distractor]
        E --> G[Counterfactual<br/>trajectories]
    end
    subgraph Eval["Evaluation (evaluation/)"]
        direction TB
        H[Dataloader] --> I[Model inference<br/>Docker per model] --> J[Post-processing<br/>accuracy Β· ADE Β· LLM judge]
        J --> K[JSON + HTML reports]
    end
    Build ==>|released benchmark| Eval

What a model is asked to do

TaskSource in graphWhat it probes
Active QA (Causal Ladder)Active ego edgesAssociation β†’ intervention β†’ counterfactual questions about entities that currently drive ego behaviour (rungs R0–R3).
Dormant QADormant ego edgesEntities that would affect the ego under a small change (e.g. a pedestrian approaching the kerb).
Distractor QADistractor listRecognising entities with no causal influence on the ego.
BTE: baseline trajectoryObserved scenePredict the ego's future waypoints in the real scene.
CTE-R2 / CTE-R3: counterfactual trajectoryIntervened scenePredict the ego's trajectory after an intervention (R2) or in an alternate history (R3).

Causal scene graph schema: 5 node types (TRAFFIC_CONTROL, ROAD_OBSTACLE, OTHER_AGENT, ENVIRONMENT, EGO). 5 ego-edge effects (CONSTRAINS_LONGITUDINAL, CONSTRAINS_LATERAL, INHIBITS_PROCEED, GRANTS_PROCEED, DEGRADES). 2 inter-node edges (AFFECTS, CONFOUNDED_BY). 3 causal statuses (active_sustaining, active_triggering, dormant). A distractors list with rejection reasons.


Dataset

The released benchmark is hosted on Hugging Face: causaldrivebench/CausalDriveBench.

from datasets import load_dataset

qa = load_dataset("causaldrivebench/CausalDriveBench", "qa", split="test")
print(qa)          # question, options, correct_answer, reasoning, rung, category, difficulty, ...

Each QA row has the question, answer options, correct answer and reasoning, plus metadata: rung, category, difficulty, graph structure, counterfactual frame and spatial context. The per-sample release layout produced by scripts/release/package_samples.py is:

<dataset>/<scene>/<SAMPLED_N>/
β”œβ”€β”€ meta.json          # scene metadata (token, log, location, timestamp)
β”œβ”€β”€ state.json         # ego + agent states at T=0 (ego-local coordinates)
β”œβ”€β”€ calib.json         # camera intrinsics + extrinsics
β”œβ”€β”€ frames.json        # paths to the original raw sensor images per timestep (Tm1p5 … Tp0p0)
β”œβ”€β”€ graph.json         # verified causal scene graph
└── qa/
    β”œβ”€β”€ active_qa.json
    β”œβ”€β”€ dormant_qa.json
    └── distractor_qa.json

A small sample in this exact format ships with the repo under evaluation/sample_data/, so you can try the pipeline without downloading anything.

Raw imagery is not redistributed. frames.json points into the original datasets, which you must obtain separately under their own terms (nuScenes, OpenScene / NAVSIM, Argoverse 2).


Repository structure

causaldrivebench/
β”œβ”€β”€ scripts/                  # Benchmark construction pipeline
β”‚   β”œβ”€β”€ build_records/        #   raw logs β†’ unified records (nuScenes, OpenScene, AV2)
β”‚   β”œβ”€β”€ batch_processing/     #   ⭐ run_batch_pipeline.sh: graph β†’ QA β†’ trajectories via Batch API
β”‚   β”œβ”€β”€ causal_graph_extraction/  # pruning, subgraph extraction & statistics
β”‚   β”œβ”€β”€ graph_postprocessing/ #   post-review clean-up β†’ *_verified.json
β”‚   β”œβ”€β”€ graph_filtering/      #   diversity clustering & subset selection
β”‚   β”œβ”€β”€ question_answers/     #   QA balancing & statistics
β”‚   β”œβ”€β”€ counterfactual_trajectory/  # CF / agent-intervention trajectories
β”‚   β”œβ”€β”€ rendering/            #   interactive D3 HTML viewers + review editor
β”‚   β”œβ”€β”€ release/              #   release packaging
β”‚   └── download/             #   dataset download helpers
β”œβ”€β”€ prompts/                  # All VLM prompt templates (graph, QA, trajectories, verification)
β”œβ”€β”€ evaluation/               # Containerised multi-model evaluation framework
β”‚   β”œβ”€β”€ common/               #   base classes, metrics, trajectory eval, LLM judge, reports
β”‚   β”œβ”€β”€ models/               #   one folder per evaluated model (+ _template)
β”‚   β”œβ”€β”€ docs/                 #   architecture, data formats, adding a model, …
β”‚   └── sample_data/ Β· sample_outputs/ Β· sample_reports/   # runnable examples
β”œβ”€β”€ driving_rules/            # Driving-rule knowledge base (generic, Singapore, California)
β”œβ”€β”€ docs/                     # Project overview & design specs
β”œβ”€β”€ config.yaml.example       # Pipeline configuration template
└── environment.yaml          # Conda environment

πŸ‘‰ See INDEX.md for a file-by-file index of all code and documentation.


Installation

git clone https://github.com/renesas/causaldrivebench.git
cd causaldrivebench

# Benchmark-construction environment
conda env create -f environment.yaml
conda activate causal_graph

# Graph PNG rendering
sudo apt install graphviz

# Pipeline configuration (paths, provider, API keys); config.yaml is git-ignored
cp config.yaml.example config.yaml

Evaluation runs each model in its own Docker container, so you need Docker with the NVIDIA Container Toolkit for GPU models. See evaluation/docs/docker_operations.md.


Quick start: evaluate a model

1. Try it on bundled sample data (no GPU, no download)

# From the repo root, in any Python β‰₯ 3.10 env with numpy, pillow, tqdm
export PYTHONPATH="$PYTHONPATH:$(pwd)"

# Simulate a full run (dataloader β†’ synthetic outputs β†’ 4-tier reports)
python evaluation/generate_sample_outputs.py

# Re-run post-processing on the simulated run
python evaluation/models/alpamayo_1_0/postprocess.py \
    --run-dir   evaluation/sample_outputs/<run_dir> \
    --bench-dir evaluation/sample_data/causal_nuscenes \
    --mode single --scene nuscenes-scene-0072

An example of the generated static HTML report is in evaluation/sample_reports/ (open index.html locally in a browser).

2. Evaluate a real model (Docker)

cd evaluation/models/<model>/            # e.g. alpamayo_1_5, recogdrive, orion, …

cp dev.env.example dev.env               # set data paths, HF token, GPU, …
docker compose build
docker compose --profile setup run --rm weight-downloader

# Smoke-test on one scene, then drop MODE/SCENE for the full benchmark
MODE=single SCENE=nuscenes-scene-0001 docker compose run --rm inference
MODE=single SCENE=nuscenes-scene-0001 docker compose --profile postprocess run --rm postprocess

Docker-based model folders have a commands.md cheat-sheet with their exact commands. Post-processing can also score reasoning quality with an LLM judge: four dimensions, 0–2 each. See evaluation/docs/llm_judge.md.

3. Evaluate several models at once

python evaluation/orchestrate.py \
    --models alpamayo_1_0,alpamayo_1_5 \
    --dataset nuscenes --mode subset --subset-size 50 \
    --output-dir evaluation/outputs --report-dir evaluation/reports

Adding your own model? Copy evaluation/models/_template/, implement the dataloader, inference and post-processor, then follow evaluation/docs/adding_a_model.md.


Supported models

Integrations live in evaluation/models/. Each one wraps the upstream model behind the same dataloader β†’ inference β†’ postprocess interface.

FolderUpstream modelType
alpamayo_1_0NVIDIA Alpamayo-R1-10B (reference implementation)Driving VLA
alpamayo_1_5NVIDIA Alpamayo-1.5-10BDriving VLA
doeDoe-1Driving world model
impromptu_vlaImpromptu-VLA 3BDriving VLA
omnidriveNVlabs OmniDriveDriving VLA
opendrivevlaOpenDriveVLA-0.5BDriving VLA
orionORIONDriving VLA
recogdriveReCogDrive-8B-RLDriving VLA
safeautoSafeAutoDriving VLA
simlingoSimLingoDriving VLA
gemma4Google Gemma 4 (E2B / E4B / 26B-A4B / 31B)General VLM
qwen25vlQwen2.5-VL-3B / 7B-InstructGeneral VLM
_templateStarting point for new integrations–

Results

The official results tables (per-rung and per-QA-type accuracy, BTE / CTE trajectory ADE) are in the paper. In short:

  • The best model reaches 70.6 % causal-QA accuracy. 4 of 13 models fall below random chance.
  • Driving-specific fine-tuning reduces causal-QA accuracy by 2–34 pp relative to the matching general-purpose backbone.
  • Causal-QA accuracy and trajectory accuracy are statistically uncorrelated: a model can plan well in the observed scene without understanding why.

To reproduce, run the evaluation framework above on the Hugging Face release. evaluation/sanity_check.py verifies run completeness, and evaluation/scripts/reorganize_and_report.py builds Markdown / LaTeX tables.


Regenerating the benchmark

The released dataset is all you need for evaluation. The sections below are for rebuilding or extending the benchmark from raw driving logs. Click a section to expand it.

Raw data β†’ Records β†’ Stage 1: causal graph β†’ Pruning β†’ Stage 3a/3b/3c: QA β†’ Stage 4cf / 5: counterfactual trajectories β†’ HTML / release
1. Data acquisition
  • nuScenes: download from https://www.nuscenes.org/: the full dataset (v1.0-trainval: metadata + camera images) and the map expansion pack.
  • OpenScene (NAVSIM): use the helper scripts:
    bash scripts/download/download_openscene_metadata.sh <LOGS_DIR>
    bash scripts/download/download_openscene_sensor.sh
    bash scripts/download/download_nuplan_maps.sh
    
  • Argoverse 2: download the sensor split (train and/or val) from https://www.argoverse.org/av2.html.
2. Record building

Record building converts each raw dataset into one unified record format that every downstream step consumes:

<RECORDS>/<scene_name>/SAMPLED_N/
β”œβ”€β”€ meta.json
β”œβ”€β”€ Tm1p5/  Tm1p0/  Tm0p5/        # T = -1.5 s, -1.0 s, -0.5 s: bev.png + cameras
└── Tp0p0/                        # T = 0 (present)
    β”œβ”€β”€ bev.png                   # 1536Γ—1536 BEV with heading arrows
    β”œβ”€β”€ cam_front.jpg …           # cameras annotated with 2D boxes + labels
    β”œβ”€β”€ state.json                # ego + agent states (ego-local coordinates)
    β”œβ”€β”€ calib.json                # camera intrinsics + extrinsics
    └── uuid_map.json             # short labels (car_1) β†’ dataset UUIDs

The record builders apply these rules:

  • Temporal BEVs: 4 frames, all in the T=0 ego frame.
  • Agent radius: 30 m for vehicles, 25 m for pedestrians.
  • Visibility filter (nuScenes): vehicles at least 40 % visible, pedestrians at least 60 %.
  • Occlusion filter: multi-ray 3D raycast.
  • Argoverse 2: uses 5 cameras.
  • Large images: anything over 2000 px is resized when batches are prepared.
conda activate causal_graph

# nuScenes
python scripts/build_records/build_nuscenes_records.py \
  --data /path/to/nuscenes --maps /path/to/maps/expansion \
  --records /path/to/records/nuscenes --num-scenes 120

# OpenScene (quartile sampling, 4 samples per scene)
python scripts/build_records/build_openscene_records.py \
  --logs /path/to/navsim_logs --blobs /path/to/openscene --maps /path/to/openscene/maps \
  --records /path/to/records/openscene --num-scenes 100 --max-samples 4

# Argoverse 2 (5 cameras); --split train | val | both
python scripts/build_records/build_argoverse2_records.py \
  --data /path/to/argoverse2/sensor --split val \
  --records /path/to/records/argoverse2 --num-scenes 133

The builders skip existing scenes unless you pass --force. Other useful flags:

  • --scenes …: build specific scenes only.
  • --samples-file: build specific scene/SAMPLED_N pairs.
  • --workers N: number of parallel workers (default 4).
3. Batch pipeline (graphs β†’ QA β†’ trajectories)

scripts/batch_processing/run_batch_pipeline.sh drives every generation stage through a provider's Batch API (Claude by default).

StageNameDescription
1GeneratorImages + state.json β†’ raw causal scene graph
prunePruningReverse-BFS reachability; nodes with no causal path to ego β†’ distractors
3aCausal Ladder QAActive edges β†’ active_qa.json
3bDormant QADormant edges β†’ dormant_qa.json
3cDistractor QADistractors β†’ distractor_qa.json
4cfCF trajectoriesQA items with trajectory_changes=true β†’ routed (below)
5LLM ego trajectoryAgent interventions (remove / reposition / speed change) β†’ LLM-predicted ego response (--nuplan uses the nuPlan simulator instead, stage 4np)

Stage 4cf routing:

RouteConditionPromptsOutput
nuplan_configentity_type=agentprompts/nuplan_config/Agent intervention config β†’ consumed by stage 5 / 4np
llm_t0infrastructure, anchor t0prompts/alternate_trajectories/Intervention_*8 future ego waypoints
llm_obs_windowinfrastructure, anchor observation_windowprompts/alternate_trajectories/CounterFactual_*4 alternate-history ego waypoints
# Full pipeline for one dataset (nuscenes | openscene | argoverse2)
bash scripts/batch_processing/run_batch_pipeline.sh nuscenes \
  --provider claude \
  --records-dir /path/to/records/nuscenes \
  --output-dir  /path/to/outputs/nuscenes \
  --batch-dir   /path/to/batch_jobs

# Stop early / resume
bash scripts/batch_processing/run_batch_pipeline.sh nuscenes ... --stop-after 1     # graphs only
bash scripts/batch_processing/run_batch_pipeline.sh nuscenes ... --stop-after 3c    # through QA
bash scripts/batch_processing/run_batch_pipeline.sh nuscenes ... --resume 3a        # graphs already exist
FlagDescription
--providerclaude (default), openai, gemini
--model, --reasoningOverride model; reasoning effort none (default, recommended) / low / medium / high
--records-dir, --output-dir, --batch-dirOverride paths from config.yaml (use a fresh --batch-dir per run)
--stop-after <stage>, --resume <stage>Run a sub-range of stages (1, prune, 3a–3c, 4cf, 5)
--graph-prompt-version, --qa-prompt-versionPrompt versions (default v5)
--nuplanUse the nuPlan simulator for agent interventions (stage 4np) instead of the LLM (stage 5)
--max-samples N, --filter, --dry-run, --skip-downloadLimit / filter samples, preview batches, reuse downloaded results

Prompt versions:

  • prompts/causal_scene_graph/v5 and prompts/causal_qas/v5 are the defaults. v6 is the newest graph schema and is opt-in.
  • v1–v4 are kept for reference.
  • All datasets share the same templates. The Argoverse 2 differences (camera count, names, image order) are injected at load time.
4. Graph pruning

After stage 1, prune_graphs.py reverses every edge (CONFOUNDED_BY becomes bidirectional) and runs a BFS from the ego. Any node it does not reach has no causal influence on the ego and moves to distractors. This takes O(V + E) per graph, parallelised across files. It runs automatically in the batch pipeline, or standalone:

python scripts/causal_graph_extraction/prune_graphs.py /path/to/outputs/nuscenes --dry-run   # preview
python scripts/causal_graph_extraction/prune_graphs.py /path/to/outputs/nuscenes --workers 8 # writes *_pruned.json
5. Graph post-processing (after human review)

The scripts in scripts/graph_postprocessing/ turn human-reviewed graphs into the canonical {scene_id}_verified.json, which downstream QA, trajectory and release steps consume.

# 1. Work on a copy; never modify the originals
cp -r outputs/nuscenes_full_edit/ outputs/nuscenes_full_edit_backup/

# 2. Rule-based edge / node clean-up (remove --dry-run to apply)
python scripts/graph_postprocessing/fix_causal_graphs.py \
  --input-dir outputs/nuscenes_full_edit_backup/ --edits-dir edits/ --dry-run

# 3. Align scene descriptions with the remaining active edges
#    test: real-time on a few scenes, writes side-by-side comparisons
python scripts/graph_postprocessing/align_scene_description.py test \
  --input-dir outputs/nuscenes_full_edit_backup/ --edits-dir edits/ \
  --records-dir records/nuscenes_full/ --out-dir /path/to/comparison_output/
#    run: submit batch, poll, and apply β†’ writes {scene_id}_verified.json
python scripts/graph_postprocessing/align_scene_description.py run \
  --input-dir outputs/nuscenes_full_edit_backup/ --edits-dir edits/ \
  --records-dir records/nuscenes_full/

Graph review itself happens in the Flask editor scripts/rendering/editor_server.py.

6. HTML visualisation

render_causal_graph.py renders an interactive page per sample: a D3 causal graph, the camera images, the BEV and QA cards. Each page has an Original / Pruned toggle and a JSON viewer.

# Paths are read from config.yaml for the given dataset
python scripts/rendering/render_causal_graph.py --dataset nuscenes \
  --html --index --root-index --serve 9888

# Non-canonical output folder
python scripts/rendering/render_causal_graph.py --dataset nuscenes \
  --output-dir /path/to/outputs/nuscenes_50 --records-dir /path/to/records/nuscenes_50 \
  --html --index --force

# Counterfactual BEV / camera overlays
python scripts/rendering/regenerate_cf_bevs.py \
  --outputs /path/to/outputs/nuscenes --records /path/to/records/nuscenes

The server serves from the parent of the outputs directory, so the relative image paths into records/ resolve.

7. Release packaging
python scripts/release/package_samples.py --dataset nuscenes      # nuscenes | openscene | argoverse2
#   --records / --outputs / --download   override paths from config.yaml

This assembles the release layout and writes a root manifest.json that flags any samples with missing graph or QA files. frames.json lists the original raw sensor image paths, relative to data_root, not the annotated copies in the records.


Data formats

state.json: ego + agent states
{
  "t_rel_s": 0.0,
  "nav_command": "GO STRAIGHT",
  "ego": {
    "speed": 4.058,
    "history": [{"t": -1.5, "x": -6.82, "y": -0.27, "speed": 4.53}],
    "future":  [{"t": 0.5,  "x": 2.07,  "y": -0.03, "speed": 4.14}]
  },
  "agents": {
    "car_1": {
      "category": "vehicle.car",
      "position": {"x": 12.5, "y": -11.3, "yaw": 1.65},
      "speed": 0.0,
      "history": [{"t": -1.5, "x": 12.66, "y": -11.33, "speed": 0.11}]
    }
  }
}

Coordinates are ego-local at T=0: +x is forward, +y is left, and the ego is at the origin. History has 3 steps (t = βˆ’1.5, βˆ’1.0, βˆ’0.5 s). Future has 6 steps (t = 0.5 … 3.0 s).

Causal scene graph (graph.json)
{
  "scene_id": "...",
  "scene_context": {"road_geometry": "...", "navigation_intent": "..."},
  "ego_state": {"speed_mps": "4.0", "inferred_acceleration": "...", "behavior_explanation": "..."},
  "nodes": [
    {"id": "ego", "type": "EGO"},
    {"id": "n1", "type": "TRAFFIC_CONTROL", "label": "Green signal"}
  ],
  "ego_edges": [
    {"source": "n1", "target": "ego", "effect_type": "GRANTS_PROCEED",
     "active": true, "causal_status": "active_sustaining", "justification": "..."}
  ],
  "inter_node_edges": [],
  "distractors": [{"id": "car_2", "rejection_reason": "..."}]
}

The full schema is in the stage-1 prompt, prompts/causal_scene_graph/v5/system_prompt.md. Evaluation-side formats (prompts.jsonl, outputs.jsonl, reports) are documented in evaluation/docs/data_formats.md.


Troubleshooting

Common issues
ProblemCauseSolution
Truncated JSON (max_tokens hit)Response too longmax_tokens is set in scripts/common/llm_provider.py
Image dimensions exceed 2000 pxAV2 cameras are 2048Γ—1550Images are auto-resized at batch preparation (scene_utils.py)
Old batch results reprocessedRe-used batch directoryUse a fresh / empty --batch-dir for every run
No Causal Ladder (active) questionsAll ego edges dormantCheck graph quality; active QA needs active edges
No dormant questionsAll ego edges activeExpected: dormant QA needs dormant edges
_pruned.json not found by QA stagesPruning not runpython scripts/causal_graph_extraction/prune_graphs.py <output_dir>
Empty BEV (no lanes / roads)--maps not providedRebuild records with the map path
Missing heading arrows in temporal BEVsStale recordsRebuild records
OpenScene IDs rejected by the batch APIDots in custom_idHandled automatically (dots β†’ -)
Docker / GPU / evaluation issues–See evaluation/docs/docker_operations.md

Citation

If you find CausalDriveBench useful, please cite:

@article{chembu2026causaldrivebench,
  title   = {CausalDriveBench: Evaluating Causal Reasoning in Vision-Language-Action Models for Autonomous Driving},
  author  = {Chembu, Narendiran and Rao, Navvrat and Kodate, Shreedhar Shreeshail and Banda, Gayatri Srujana and Sarkar, Arko and Khanna, Abhinav and Das, Rajarshee and Kanala, Umesh and Khandelwal, Siddarth and Aman, Kumar and Dubey, Aish and Beedkar, Kaustubh and Jain, Arjun},
  journal = {arXiv preprint arXiv:2609.32157},
  year    = {2026},
  doi     = {10.48550/arXiv.2609.32157},
  url     = {https://arxiv.org/abs/2609.32157}
}

License

  • Code: BSD 3-Clause, Β© 2026 Renesas Electronics.
  • Dataset (annotations, graphs, QA, trajectories on Hugging Face): CC BY-NC-SA 4.0.
  • Underlying sensor data (nuScenes, OpenScene / NAVSIM / nuPlan, Argoverse 2) remains under each dataset's own license and terms of use.

Acknowledgements

CausalDriveBench builds on nuScenes, OpenScene / NAVSIM, nuPlan and Argoverse 2. We thank the authors of all the evaluated models for releasing their code and weights.

renesas/causaldrivebench

An open benchmark and evaluation framework for causal reasoning and decision-making in autonomous driving systems, designed to assess robustness, interpretability, and generalization across diverse driving scenarios.

Python

0

4 commits

updated Oct 12, 2026

See the code

README

CausalDriveBench pixel-art banner

CausalDriveBench

Evaluating Causal Reasoning in Vision-Language-Action Models for Autonomous Driving
NeurIPS 2026

arXiv Hugging Face dataset NeurIPS 2026 Code license: BSD-3-Clause Data license: CC BY-NC-SA 4.0 Python 3.11

πŸ“„ Paper Β Β·Β  πŸ€— Dataset Β Β·Β  πŸ—‚οΈ Code & Doc Index Β Β·Β  πŸ§ͺ Evaluation Framework Β Β·Β  πŸ“‘ Citation


CausalDriveBench tests whether driving vision-language-action (VLA) models reason causally: can they explain why the ego vehicle brakes, yields or proceeds, and predict what it would do if the scene were different? Grounded in Pearl's Causal Hierarchy, it combines structured causal visual question answering with counterfactual trajectory prediction on real nuScenes driving scenes. Each scene is backed by a causal scene graph that separates active, dormant and distractor entities.

This repository contains the full code for building the benchmark (records β†’ causal scene graphs β†’ QA β†’ counterfactual trajectories) and for evaluating VLAs / VLMs on it.

The banner shows the idea in miniature: the red light is an active cause of the ego car's behaviour (red, dotted), the pedestrian on the kerb is a dormant cause (amber, dashed), and the parked car is a distractor (no arrow).

Contents


Highlights

  • 🧭 Pearl's Causal Hierarchy, made concrete for driving. Questions span association, intervention and counterfactual rungs. They are generated from causal scene graphs whose edges are labelled active-sustaining, active-triggering or dormant, and the graphs also list distractors.
  • πŸ“¦ 7,285 verified causal QA pairs and 1,000 counterfactual trajectories on nuScenes.
  • πŸ€– 13 models evaluated: 10 driving-specific VLAs and 3 general-purpose VLMs.
  • πŸ“‰ Causal reasoning remains hard. The best model reaches 70.6 % QA accuracy, and 4 of 13 models score below random chance.
  • πŸ” Driving fine-tuning costs causal reasoning. Compared with the general-purpose VLM that shares its backbone, a driving fine-tune loses 2–34 percentage points on causal QA.
  • πŸ”€ Language and action are decoupled. Causal-QA accuracy and trajectory accuracy are statistically uncorrelated.

"Neither fluent rationales nor accurate observed-scene trajectories constitute evidence of causal understanding."


Benchmark overview

flowchart LR
    subgraph Build["Benchmark construction (scripts/)"]
        direction TB
        A[Raw driving logs<br/>nuScenes Β· OpenScene Β· AV2] --> B[Unified records<br/>4 timesteps Β· cameras Β· BEV Β· state]
        B --> C[Causal scene graph<br/>VLM, Batch API]
        C --> D[Pruning +<br/>human verification]
        D --> E[Diversity<br/>clustering]
        E --> F[Causal QA<br/>active Β· dormant Β· distractor]
        E --> G[Counterfactual<br/>trajectories]
    end
    subgraph Eval["Evaluation (evaluation/)"]
        direction TB
        H[Dataloader] --> I[Model inference<br/>Docker per model] --> J[Post-processing<br/>accuracy Β· ADE Β· LLM judge]
        J --> K[JSON + HTML reports]
    end
    Build ==>|released benchmark| Eval

What a model is asked to do

TaskSource in graphWhat it probes
Active QA (Causal Ladder)Active ego edgesAssociation β†’ intervention β†’ counterfactual questions about entities that currently drive ego behaviour (rungs R0–R3).
Dormant QADormant ego edgesEntities that would affect the ego under a small change (e.g. a pedestrian approaching the kerb).
Distractor QADistractor listRecognising entities with no causal influence on the ego.
BTE: baseline trajectoryObserved scenePredict the ego's future waypoints in the real scene.
CTE-R2 / CTE-R3: counterfactual trajectoryIntervened scenePredict the ego's trajectory after an intervention (R2) or in an alternate history (R3).

Causal scene graph schema: 5 node types (TRAFFIC_CONTROL, ROAD_OBSTACLE, OTHER_AGENT, ENVIRONMENT, EGO). 5 ego-edge effects (CONSTRAINS_LONGITUDINAL, CONSTRAINS_LATERAL, INHIBITS_PROCEED, GRANTS_PROCEED, DEGRADES). 2 inter-node edges (AFFECTS, CONFOUNDED_BY). 3 causal statuses (active_sustaining, active_triggering, dormant). A distractors list with rejection reasons.


Dataset

The released benchmark is hosted on Hugging Face: causaldrivebench/CausalDriveBench.

from datasets import load_dataset

qa = load_dataset("causaldrivebench/CausalDriveBench", "qa", split="test")
print(qa)          # question, options, correct_answer, reasoning, rung, category, difficulty, ...

Each QA row has the question, answer options, correct answer and reasoning, plus metadata: rung, category, difficulty, graph structure, counterfactual frame and spatial context. The per-sample release layout produced by scripts/release/package_samples.py is:

<dataset>/<scene>/<SAMPLED_N>/
β”œβ”€β”€ meta.json          # scene metadata (token, log, location, timestamp)
β”œβ”€β”€ state.json         # ego + agent states at T=0 (ego-local coordinates)
β”œβ”€β”€ calib.json         # camera intrinsics + extrinsics
β”œβ”€β”€ frames.json        # paths to the original raw sensor images per timestep (Tm1p5 … Tp0p0)
β”œβ”€β”€ graph.json         # verified causal scene graph
└── qa/
    β”œβ”€β”€ active_qa.json
    β”œβ”€β”€ dormant_qa.json
    └── distractor_qa.json

A small sample in this exact format ships with the repo under evaluation/sample_data/, so you can try the pipeline without downloading anything.

Raw imagery is not redistributed. frames.json points into the original datasets, which you must obtain separately under their own terms (nuScenes, OpenScene / NAVSIM, Argoverse 2).


Repository structure

causaldrivebench/
β”œβ”€β”€ scripts/                  # Benchmark construction pipeline
β”‚   β”œβ”€β”€ build_records/        #   raw logs β†’ unified records (nuScenes, OpenScene, AV2)
β”‚   β”œβ”€β”€ batch_processing/     #   ⭐ run_batch_pipeline.sh: graph β†’ QA β†’ trajectories via Batch API
β”‚   β”œβ”€β”€ causal_graph_extraction/  # pruning, subgraph extraction & statistics
β”‚   β”œβ”€β”€ graph_postprocessing/ #   post-review clean-up β†’ *_verified.json
β”‚   β”œβ”€β”€ graph_filtering/      #   diversity clustering & subset selection
β”‚   β”œβ”€β”€ question_answers/     #   QA balancing & statistics
β”‚   β”œβ”€β”€ counterfactual_trajectory/  # CF / agent-intervention trajectories
β”‚   β”œβ”€β”€ rendering/            #   interactive D3 HTML viewers + review editor
β”‚   β”œβ”€β”€ release/              #   release packaging
β”‚   └── download/             #   dataset download helpers
β”œβ”€β”€ prompts/                  # All VLM prompt templates (graph, QA, trajectories, verification)
β”œβ”€β”€ evaluation/               # Containerised multi-model evaluation framework
β”‚   β”œβ”€β”€ common/               #   base classes, metrics, trajectory eval, LLM judge, reports
β”‚   β”œβ”€β”€ models/               #   one folder per evaluated model (+ _template)
β”‚   β”œβ”€β”€ docs/                 #   architecture, data formats, adding a model, …
β”‚   └── sample_data/ Β· sample_outputs/ Β· sample_reports/   # runnable examples
β”œβ”€β”€ driving_rules/            # Driving-rule knowledge base (generic, Singapore, California)
β”œβ”€β”€ docs/                     # Project overview & design specs
β”œβ”€β”€ config.yaml.example       # Pipeline configuration template
└── environment.yaml          # Conda environment

πŸ‘‰ See INDEX.md for a file-by-file index of all code and documentation.


Installation

git clone https://github.com/renesas/causaldrivebench.git
cd causaldrivebench

# Benchmark-construction environment
conda env create -f environment.yaml
conda activate causal_graph

# Graph PNG rendering
sudo apt install graphviz

# Pipeline configuration (paths, provider, API keys); config.yaml is git-ignored
cp config.yaml.example config.yaml

Evaluation runs each model in its own Docker container, so you need Docker with the NVIDIA Container Toolkit for GPU models. See evaluation/docs/docker_operations.md.


Quick start: evaluate a model

1. Try it on bundled sample data (no GPU, no download)

# From the repo root, in any Python β‰₯ 3.10 env with numpy, pillow, tqdm
export PYTHONPATH="$PYTHONPATH:$(pwd)"

# Simulate a full run (dataloader β†’ synthetic outputs β†’ 4-tier reports)
python evaluation/generate_sample_outputs.py

# Re-run post-processing on the simulated run
python evaluation/models/alpamayo_1_0/postprocess.py \
    --run-dir   evaluation/sample_outputs/<run_dir> \
    --bench-dir evaluation/sample_data/causal_nuscenes \
    --mode single --scene nuscenes-scene-0072

An example of the generated static HTML report is in evaluation/sample_reports/ (open index.html locally in a browser).

2. Evaluate a real model (Docker)

cd evaluation/models/<model>/            # e.g. alpamayo_1_5, recogdrive, orion, …

cp dev.env.example dev.env               # set data paths, HF token, GPU, …
docker compose build
docker compose --profile setup run --rm weight-downloader

# Smoke-test on one scene, then drop MODE/SCENE for the full benchmark
MODE=single SCENE=nuscenes-scene-0001 docker compose run --rm inference
MODE=single SCENE=nuscenes-scene-0001 docker compose --profile postprocess run --rm postprocess

Docker-based model folders have a commands.md cheat-sheet with their exact commands. Post-processing can also score reasoning quality with an LLM judge: four dimensions, 0–2 each. See evaluation/docs/llm_judge.md.

3. Evaluate several models at once

python evaluation/orchestrate.py \
    --models alpamayo_1_0,alpamayo_1_5 \
    --dataset nuscenes --mode subset --subset-size 50 \
    --output-dir evaluation/outputs --report-dir evaluation/reports

Adding your own model? Copy evaluation/models/_template/, implement the dataloader, inference and post-processor, then follow evaluation/docs/adding_a_model.md.


Supported models

Integrations live in evaluation/models/. Each one wraps the upstream model behind the same dataloader β†’ inference β†’ postprocess interface.

FolderUpstream modelType
alpamayo_1_0NVIDIA Alpamayo-R1-10B (reference implementation)Driving VLA
alpamayo_1_5NVIDIA Alpamayo-1.5-10BDriving VLA
doeDoe-1Driving world model
impromptu_vlaImpromptu-VLA 3BDriving VLA
omnidriveNVlabs OmniDriveDriving VLA
opendrivevlaOpenDriveVLA-0.5BDriving VLA
orionORIONDriving VLA
recogdriveReCogDrive-8B-RLDriving VLA
safeautoSafeAutoDriving VLA
simlingoSimLingoDriving VLA
gemma4Google Gemma 4 (E2B / E4B / 26B-A4B / 31B)General VLM
qwen25vlQwen2.5-VL-3B / 7B-InstructGeneral VLM
_templateStarting point for new integrations–

Results

The official results tables (per-rung and per-QA-type accuracy, BTE / CTE trajectory ADE) are in the paper. In short:

  • The best model reaches 70.6 % causal-QA accuracy. 4 of 13 models fall below random chance.
  • Driving-specific fine-tuning reduces causal-QA accuracy by 2–34 pp relative to the matching general-purpose backbone.
  • Causal-QA accuracy and trajectory accuracy are statistically uncorrelated: a model can plan well in the observed scene without understanding why.

To reproduce, run the evaluation framework above on the Hugging Face release. evaluation/sanity_check.py verifies run completeness, and evaluation/scripts/reorganize_and_report.py builds Markdown / LaTeX tables.


Regenerating the benchmark

The released dataset is all you need for evaluation. The sections below are for rebuilding or extending the benchmark from raw driving logs. Click a section to expand it.

Raw data β†’ Records β†’ Stage 1: causal graph β†’ Pruning β†’ Stage 3a/3b/3c: QA β†’ Stage 4cf / 5: counterfactual trajectories β†’ HTML / release
1. Data acquisition
  • nuScenes: download from https://www.nuscenes.org/: the full dataset (v1.0-trainval: metadata + camera images) and the map expansion pack.
  • OpenScene (NAVSIM): use the helper scripts:
    bash scripts/download/download_openscene_metadata.sh <LOGS_DIR>
    bash scripts/download/download_openscene_sensor.sh
    bash scripts/download/download_nuplan_maps.sh
    
  • Argoverse 2: download the sensor split (train and/or val) from https://www.argoverse.org/av2.html.
2. Record building

Record building converts each raw dataset into one unified record format that every downstream step consumes:

<RECORDS>/<scene_name>/SAMPLED_N/
β”œβ”€β”€ meta.json
β”œβ”€β”€ Tm1p5/  Tm1p0/  Tm0p5/        # T = -1.5 s, -1.0 s, -0.5 s: bev.png + cameras
└── Tp0p0/                        # T = 0 (present)
    β”œβ”€β”€ bev.png                   # 1536Γ—1536 BEV with heading arrows
    β”œβ”€β”€ cam_front.jpg …           # cameras annotated with 2D boxes + labels
    β”œβ”€β”€ state.json                # ego + agent states (ego-local coordinates)
    β”œβ”€β”€ calib.json                # camera intrinsics + extrinsics
    └── uuid_map.json             # short labels (car_1) β†’ dataset UUIDs

The record builders apply these rules:

  • Temporal BEVs: 4 frames, all in the T=0 ego frame.
  • Agent radius: 30 m for vehicles, 25 m for pedestrians.
  • Visibility filter (nuScenes): vehicles at least 40 % visible, pedestrians at least 60 %.
  • Occlusion filter: multi-ray 3D raycast.
  • Argoverse 2: uses 5 cameras.
  • Large images: anything over 2000 px is resized when batches are prepared.
conda activate causal_graph

# nuScenes
python scripts/build_records/build_nuscenes_records.py \
  --data /path/to/nuscenes --maps /path/to/maps/expansion \
  --records /path/to/records/nuscenes --num-scenes 120

# OpenScene (quartile sampling, 4 samples per scene)
python scripts/build_records/build_openscene_records.py \
  --logs /path/to/navsim_logs --blobs /path/to/openscene --maps /path/to/openscene/maps \
  --records /path/to/records/openscene --num-scenes 100 --max-samples 4

# Argoverse 2 (5 cameras); --split train | val | both
python scripts/build_records/build_argoverse2_records.py \
  --data /path/to/argoverse2/sensor --split val \
  --records /path/to/records/argoverse2 --num-scenes 133

The builders skip existing scenes unless you pass --force. Other useful flags:

  • --scenes …: build specific scenes only.
  • --samples-file: build specific scene/SAMPLED_N pairs.
  • --workers N: number of parallel workers (default 4).
3. Batch pipeline (graphs β†’ QA β†’ trajectories)

scripts/batch_processing/run_batch_pipeline.sh drives every generation stage through a provider's Batch API (Claude by default).

StageNameDescription
1GeneratorImages + state.json β†’ raw causal scene graph
prunePruningReverse-BFS reachability; nodes with no causal path to ego β†’ distractors
3aCausal Ladder QAActive edges β†’ active_qa.json
3bDormant QADormant edges β†’ dormant_qa.json
3cDistractor QADistractors β†’ distractor_qa.json
4cfCF trajectoriesQA items with trajectory_changes=true β†’ routed (below)
5LLM ego trajectoryAgent interventions (remove / reposition / speed change) β†’ LLM-predicted ego response (--nuplan uses the nuPlan simulator instead, stage 4np)

Stage 4cf routing:

RouteConditionPromptsOutput
nuplan_configentity_type=agentprompts/nuplan_config/Agent intervention config β†’ consumed by stage 5 / 4np
llm_t0infrastructure, anchor t0prompts/alternate_trajectories/Intervention_*8 future ego waypoints
llm_obs_windowinfrastructure, anchor observation_windowprompts/alternate_trajectories/CounterFactual_*4 alternate-history ego waypoints
# Full pipeline for one dataset (nuscenes | openscene | argoverse2)
bash scripts/batch_processing/run_batch_pipeline.sh nuscenes \
  --provider claude \
  --records-dir /path/to/records/nuscenes \
  --output-dir  /path/to/outputs/nuscenes \
  --batch-dir   /path/to/batch_jobs

# Stop early / resume
bash scripts/batch_processing/run_batch_pipeline.sh nuscenes ... --stop-after 1     # graphs only
bash scripts/batch_processing/run_batch_pipeline.sh nuscenes ... --stop-after 3c    # through QA
bash scripts/batch_processing/run_batch_pipeline.sh nuscenes ... --resume 3a        # graphs already exist
FlagDescription
--providerclaude (default), openai, gemini
--model, --reasoningOverride model; reasoning effort none (default, recommended) / low / medium / high
--records-dir, --output-dir, --batch-dirOverride paths from config.yaml (use a fresh --batch-dir per run)
--stop-after <stage>, --resume <stage>Run a sub-range of stages (1, prune, 3a–3c, 4cf, 5)
--graph-prompt-version, --qa-prompt-versionPrompt versions (default v5)
--nuplanUse the nuPlan simulator for agent interventions (stage 4np) instead of the LLM (stage 5)
--max-samples N, --filter, --dry-run, --skip-downloadLimit / filter samples, preview batches, reuse downloaded results

Prompt versions:

  • prompts/causal_scene_graph/v5 and prompts/causal_qas/v5 are the defaults. v6 is the newest graph schema and is opt-in.
  • v1–v4 are kept for reference.
  • All datasets share the same templates. The Argoverse 2 differences (camera count, names, image order) are injected at load time.
4. Graph pruning

After stage 1, prune_graphs.py reverses every edge (CONFOUNDED_BY becomes bidirectional) and runs a BFS from the ego. Any node it does not reach has no causal influence on the ego and moves to distractors. This takes O(V + E) per graph, parallelised across files. It runs automatically in the batch pipeline, or standalone:

python scripts/causal_graph_extraction/prune_graphs.py /path/to/outputs/nuscenes --dry-run   # preview
python scripts/causal_graph_extraction/prune_graphs.py /path/to/outputs/nuscenes --workers 8 # writes *_pruned.json
5. Graph post-processing (after human review)

The scripts in scripts/graph_postprocessing/ turn human-reviewed graphs into the canonical {scene_id}_verified.json, which downstream QA, trajectory and release steps consume.

# 1. Work on a copy; never modify the originals
cp -r outputs/nuscenes_full_edit/ outputs/nuscenes_full_edit_backup/

# 2. Rule-based edge / node clean-up (remove --dry-run to apply)
python scripts/graph_postprocessing/fix_causal_graphs.py \
  --input-dir outputs/nuscenes_full_edit_backup/ --edits-dir edits/ --dry-run

# 3. Align scene descriptions with the remaining active edges
#    test: real-time on a few scenes, writes side-by-side comparisons
python scripts/graph_postprocessing/align_scene_description.py test \
  --input-dir outputs/nuscenes_full_edit_backup/ --edits-dir edits/ \
  --records-dir records/nuscenes_full/ --out-dir /path/to/comparison_output/
#    run: submit batch, poll, and apply β†’ writes {scene_id}_verified.json
python scripts/graph_postprocessing/align_scene_description.py run \
  --input-dir outputs/nuscenes_full_edit_backup/ --edits-dir edits/ \
  --records-dir records/nuscenes_full/

Graph review itself happens in the Flask editor scripts/rendering/editor_server.py.

6. HTML visualisation

render_causal_graph.py renders an interactive page per sample: a D3 causal graph, the camera images, the BEV and QA cards. Each page has an Original / Pruned toggle and a JSON viewer.

# Paths are read from config.yaml for the given dataset
python scripts/rendering/render_causal_graph.py --dataset nuscenes \
  --html --index --root-index --serve 9888

# Non-canonical output folder
python scripts/rendering/render_causal_graph.py --dataset nuscenes \
  --output-dir /path/to/outputs/nuscenes_50 --records-dir /path/to/records/nuscenes_50 \
  --html --index --force

# Counterfactual BEV / camera overlays
python scripts/rendering/regenerate_cf_bevs.py \
  --outputs /path/to/outputs/nuscenes --records /path/to/records/nuscenes

The server serves from the parent of the outputs directory, so the relative image paths into records/ resolve.

7. Release packaging
python scripts/release/package_samples.py --dataset nuscenes      # nuscenes | openscene | argoverse2
#   --records / --outputs / --download   override paths from config.yaml

This assembles the release layout and writes a root manifest.json that flags any samples with missing graph or QA files. frames.json lists the original raw sensor image paths, relative to data_root, not the annotated copies in the records.


Data formats

state.json: ego + agent states
{
  "t_rel_s": 0.0,
  "nav_command": "GO STRAIGHT",
  "ego": {
    "speed": 4.058,
    "history": [{"t": -1.5, "x": -6.82, "y": -0.27, "speed": 4.53}],
    "future":  [{"t": 0.5,  "x": 2.07,  "y": -0.03, "speed": 4.14}]
  },
  "agents": {
    "car_1": {
      "category": "vehicle.car",
      "position": {"x": 12.5, "y": -11.3, "yaw": 1.65},
      "speed": 0.0,
      "history": [{"t": -1.5, "x": 12.66, "y": -11.33, "speed": 0.11}]
    }
  }
}

Coordinates are ego-local at T=0: +x is forward, +y is left, and the ego is at the origin. History has 3 steps (t = βˆ’1.5, βˆ’1.0, βˆ’0.5 s). Future has 6 steps (t = 0.5 … 3.0 s).

Causal scene graph (graph.json)
{
  "scene_id": "...",
  "scene_context": {"road_geometry": "...", "navigation_intent": "..."},
  "ego_state": {"speed_mps": "4.0", "inferred_acceleration": "...", "behavior_explanation": "..."},
  "nodes": [
    {"id": "ego", "type": "EGO"},
    {"id": "n1", "type": "TRAFFIC_CONTROL", "label": "Green signal"}
  ],
  "ego_edges": [
    {"source": "n1", "target": "ego", "effect_type": "GRANTS_PROCEED",
     "active": true, "causal_status": "active_sustaining", "justification": "..."}
  ],
  "inter_node_edges": [],
  "distractors": [{"id": "car_2", "rejection_reason": "..."}]
}

The full schema is in the stage-1 prompt, prompts/causal_scene_graph/v5/system_prompt.md. Evaluation-side formats (prompts.jsonl, outputs.jsonl, reports) are documented in evaluation/docs/data_formats.md.


Troubleshooting

Common issues
ProblemCauseSolution
Truncated JSON (max_tokens hit)Response too longmax_tokens is set in scripts/common/llm_provider.py
Image dimensions exceed 2000 pxAV2 cameras are 2048Γ—1550Images are auto-resized at batch preparation (scene_utils.py)
Old batch results reprocessedRe-used batch directoryUse a fresh / empty --batch-dir for every run
No Causal Ladder (active) questionsAll ego edges dormantCheck graph quality; active QA needs active edges
No dormant questionsAll ego edges activeExpected: dormant QA needs dormant edges
_pruned.json not found by QA stagesPruning not runpython scripts/causal_graph_extraction/prune_graphs.py <output_dir>
Empty BEV (no lanes / roads)--maps not providedRebuild records with the map path
Missing heading arrows in temporal BEVsStale recordsRebuild records
OpenScene IDs rejected by the batch APIDots in custom_idHandled automatically (dots β†’ -)
Docker / GPU / evaluation issues–See evaluation/docs/docker_operations.md

Citation

If you find CausalDriveBench useful, please cite:

@article{chembu2026causaldrivebench,
  title   = {CausalDriveBench: Evaluating Causal Reasoning in Vision-Language-Action Models for Autonomous Driving},
  author  = {Chembu, Narendiran and Rao, Navvrat and Kodate, Shreedhar Shreeshail and Banda, Gayatri Srujana and Sarkar, Arko and Khanna, Abhinav and Das, Rajarshee and Kanala, Umesh and Khandelwal, Siddarth and Aman, Kumar and Dubey, Aish and Beedkar, Kaustubh and Jain, Arjun},
  journal = {arXiv preprint arXiv:2609.32157},
  year    = {2026},
  doi     = {10.48550/arXiv.2609.32157},
  url     = {https://arxiv.org/abs/2609.32157}
}

License

  • Code: BSD 3-Clause, Β© 2026 Renesas Electronics.
  • Dataset (annotations, graphs, QA, trajectories on Hugging Face): CC BY-NC-SA 4.0.
  • Underlying sensor data (nuScenes, OpenScene / NAVSIM / nuPlan, Argoverse 2) remains under each dataset's own license and terms of use.

Acknowledgements

CausalDriveBench builds on nuScenes, OpenScene / NAVSIM, nuPlan and Argoverse 2. We thank the authors of all the evaluated models for releasing their code and weights.