SatNav NaVILA Baseline
This guide explains how to train NaVILA on SatNav-v0.1 trajectories and run single- or multi-GPU online evaluation in SatSim. NaVILA uses an isolated Python environment and external model source; it does not share an environment with SatNav Core, Classic baselines, or other VLM baselines.
Before starting, read Installation, Training Models with SatNav, and Evaluation.
1. Model and SatNav interface
NaVILA generates text actions from a navigation instruction, the current RGB observation, and visual history. The SatNav adapter maps model output to four primitive actions:
Model output |
SatNav action |
Environment behavior |
|---|---|---|
|
|
End the current Episode |
|
|
Move forward 10 m |
|
|
Turn left 15° |
|
|
Turn right 15° |
The default compact action format requires exactly one action word. The sentence format preserves NaVILA’s natural-language output. When a sentence specifies a longer distance or larger turn, the adapter expands it into a sequence of SatNav primitive actions.
Inference uses eight frames of observation history. The adapter pads an incomplete history with black frames; for a longer history, it samples uniformly while always retaining the current frame.
SatNav supports upstream revision AnjieCheng/NaVILA@76b98f233dd0fff05dfcd69435eec6740febff9d. Before using the source or weights, read UPSTREAM, NOTICE, and the upstream license.
2. Create an isolated environment
From the SatNav repository root:
conda env create -f baselines/vlm/navila/environment/conda.yml
conda activate satnav-navila
export PYTHONNOUSERSITE=1
python -m pip install --upgrade pip
python -m pip install torch==2.3.0 torchvision==0.18.0 \
--index-url https://download.pytorch.org/whl/cu121
Install the FlashAttention 2.5.8 wheel built for Python 3.10, PyTorch 2.3, CUDA 12.x, and the old CXX11 ABI:
export NAVILA_FLASH_ATTN_WHEEL="${NAVILA_FLASH_ATTN_WHEEL:-https://github.com/Dao-AILab/flash-attention/releases/download/v2.5.8/flash_attn-2.5.8+cu122torch2.3cxx11abiFALSE-cp310-cp310-linux_x86_64.whl}"
python -m pip install "$NAVILA_FLASH_ATTN_WHEEL"
If this wheel is incompatible with your platform, obtain a local wheel that exactly matches Python, PyTorch, CUDA, and the ABI, then point NAVILA_FLASH_ATTN_WHEEL to it.
Install the remaining dependencies and SatNav:
python -m pip install -r baselines/vlm/navila/requirements.txt
python -m pip install -e .
3. Prepare upstream source
Clone NaVILA outside the SatNav repository and check out the supported revision:
git clone https://github.com/AnjieCheng/NaVILA.git /path/to/NaVILA
git -C /path/to/NaVILA checkout --detach \
76b98f233dd0fff05dfcd69435eec6740febff9d
python -m pip install --no-deps -e /path/to/NaVILA
bash baselines/vlm/navila/scripts/patch_environment.sh
patch_environment.sh installs the Transformers and DeepSpeed compatibility files supplied by the pinned upstream revision into the current NaVILA environment. It does not modify the upstream checkout. Do not run it in another VLM environment.
Check the source revision, environment, and entry points:
git -C /path/to/NaVILA rev-parse HEAD
git -C /path/to/NaVILA status --short
python - <<'PY'
import accelerate
import deepspeed
import flash_attn
import torch
import transformers
print("torch", torch.__version__, "cuda", torch.cuda.is_available())
print("transformers", transformers.__version__)
print("accelerate", accelerate.__version__)
print("deepspeed", deepspeed.__version__)
print("flash_attn", flash_attn.__version__)
PY
python -m pip check
python -m baselines.vlm.navila.dataset --help
python -m baselines.vlm.navila.trainer --help
python -m baselines.vlm.navila.evaluate --help
python -m baselines.vlm.navila.checkpoint --help
command -v python
rev-parse must print the revision above, and status --short must print nothing. Record the result of command -v python; use it later as NAVILA_PYTHON.
4. Prepare SatNav data
4.1 Episodes, GeoTIFF scenes, and trajectories
Follow Download Episode Data, Download Satellite Scenes, and Generate Trajectory Data. NaVILA reads JPEG files directly from the trajectory export:
trajectory_data/
├── annotations.json
└── images/
└── <episode>/
└── rgb/
├── 001.jpg
└── ...
Set the data paths:
export SATNAV_DATA_ROOT=/path/to/SatNav-v0.1
export SATNAV_SCENES_DIR=/path/to/scenes
export SATNAV_TRAJECTORY_ROOT=/path/to/trajectory_data
First validate the Episode files and 59 GeoTIFF scenes:
bash scripts/validation/data_validation.sh
4.2 Validate trajectories
Check annotations, actions, frame counts, and image decoding:
python -m baselines.vlm.navila.dataset \
"$SATNAV_TRAJECTORY_ROOT" \
--expected-episodes 105164 \
--strict-frames \
--decode-samples 64
The launcher validates the complete train split again before full training. Missing images, out-of-root paths, invalid actions, and frame-count mismatches stop training instead of silently dropping samples.
5. Download model assets
Choose a model directory:
export NAVILA_MODEL_ROOT=/path/to/navila-models
mkdir -p "$NAVILA_MODEL_ROOT"
5.1 Released SatNav checkpoints
The SatNav Baseline Model Zoo provides two NaVILA checkpoints:
scratch, trained from the NaVILA pretraining checkpoint;
continue, trained from the NaVILA SFT checkpoint.
Download either checkpoint with the baseline downloader:
bash baselines/vlm/navila/scripts/download.sh \
--repo Eku127/navila-satnav-continue-1ep-8f-sample-hk7-fs7-stopx4 \
--model-root "$NAVILA_MODEL_ROOT"
Pass the downloaded directory to --model-path for evaluation. These releases
contain inference artifacts rather than optimizer and scheduler state.
The released checkpoints achieve the following reference results on the full splits with a 500-step cap.
Checkpoint |
Split |
Episodes |
NE ↓ |
OS ↑ |
SR ↑ |
SPL ↑ |
|---|---|---|---|---|---|---|
Scratch |
|
4,574 |
93.05 |
27.59 |
18.10 |
18.02 |
Scratch |
|
8,756 |
128.88 |
23.66 |
13.00 |
12.96 |
Continue |
|
4,574 |
93.88 |
35.00 |
24.99 |
24.88 |
Continue |
|
8,756 |
123.49 |
31.60 |
18.57 |
18.44 |
5.2 Training starting points
continue training uses the NaVILA SFT checkpoint:
bash baselines/vlm/navila/scripts/download.sh \
--repo a8cheng/navila-llama3-8b-8f \
--model-root "$NAVILA_MODEL_ROOT"
scratch training starts from the NaVILA pretraining checkpoint:
bash baselines/vlm/navila/scripts/download.sh \
--repo a8cheng/navila-siglip-llama3-8b-v1.5-pretrain \
--model-root "$NAVILA_MODEL_ROOT"
If a Hugging Face repository requires authorization, log in from the current environment first. Add --endpoint to the download command when using a mirror.
The resulting layout is:
navila-models/
├── navila-satnav-scratch-1ep-8f-sample-hk7-fs7-stopx4/
├── navila-satnav-continue-1ep-8f-sample-hk7-fs7-stopx4/
├── navila-llama3-8b-8f/
└── navila-siglip-llama3-8b-v1.5-pretrain/
Both directories must contain the complete model configuration, tokenizer, vision tower, multimodal projector, and all weights. A single weight shard or adapter is not sufficient.
6. Configure local paths
Copy the local template:
mkdir -p baselines/vlm/navila/.local
cp baselines/vlm/navila/local.env.example \
baselines/vlm/navila/.local/env.sh
Fill baselines/vlm/navila/.local/env.sh with the paths prepared above:
export NAVILA_REPO="${NAVILA_REPO:-/path/to/NaVILA}"
export NAVILA_PYTHON="${NAVILA_PYTHON:-/path/to/satnav-navila/bin/python}"
export NAVILA_MODEL_ROOT="${NAVILA_MODEL_ROOT:-/path/to/navila-models}"
export NAVILA_PRETRAIN_MODEL="${NAVILA_PRETRAIN_MODEL:-${NAVILA_MODEL_ROOT}/navila-siglip-llama3-8b-v1.5-pretrain}"
export NAVILA_SFT_MODEL="${NAVILA_SFT_MODEL:-${NAVILA_MODEL_ROOT}/navila-llama3-8b-8f}"
export SATNAV_NAVILA_TRAIN_DATA="${SATNAV_NAVILA_TRAIN_DATA:-/path/to/trajectory_data}"
export SATNAV_NAVILA_EVAL_EPISODES="${SATNAV_NAVILA_EVAL_EPISODES:-/path/to/SatNav-v0.1/episodes/eval/{split}/all_episodes.json}"
export SATNAV_NAVILA_SCENES_DIR="${SATNAV_NAVILA_SCENES_DIR:-/path/to/scenes}"
export SATNAV_NAVILA_OUTPUT="${SATNAV_NAVILA_OUTPUT:-output/baselines/vlm/navila}"
Variable sources:
Variable |
Source |
|---|---|
|
NaVILA checkout from Section 3 |
|
Output of |
|
Model directory selected in Section 5 |
|
Downloaded pretraining checkpoint |
|
Downloaded SFT checkpoint |
|
Validated |
|
SatNav-v0.1 evaluation Episode path template |
|
Validated GeoTIFF directory from Section 4 |
|
Training and evaluation output root |
Launchers load this file automatically. An environment variable set explicitly in the shell takes precedence over .local/env.sh. Do not commit local data, models, upstream source, output directories, or environment paths.
To use the variables directly in the current shell:
source baselines/vlm/navila/.local/env.sh
7. Training configuration and checkpoint validation
Before training, confirm that the SFT checkpoint loads completely:
python -m baselines.vlm.navila.checkpoint \
--model-path "$NAVILA_SFT_MODEL" \
--navila-repo "$NAVILA_REPO" \
--device cuda:0
For scratch, repeat the check with $NAVILA_PRETRAIN_MODEL. Missing, incompatible, or unloadable model components cause an explicit error.
Defaults are in baselines/vlm/navila/configs/train.yaml:
Parameter |
Default |
|---|---|
Video frames |
8 |
Epochs |
1 |
Per-device batch size |
1 |
Gradient accumulation |
1 |
Learning rate |
|
Warmup ratio |
|
Save interval |
1,000 steps |
DataLoader workers |
8 |
Training uses DeepSpeed ZeRO-2 from baselines/vlm/navila/configs/zero2.json. By default, it updates the vision tower, multimodal projector, and language model. A bounded smoke run can use --train-components projector to validate only the projector update path.
In training commands, --max-steps means optimizer steps. In evaluation commands, the same name means the maximum primitive actions per Episode.
8. Smoke training
Run two optimizer steps to validate data loading, parameter updates, and complete checkpoint saving:
CUDA_DEVICES=0,1,2,3,4,5,6,7 \
bash baselines/vlm/navila/scripts/train.sh continue \
--gpus 8 \
--trajectory-root "$SATNAV_NAVILA_TRAIN_DATA" \
--model-path "$NAVILA_SFT_MODEL" \
--output-dir output/baselines/vlm/navila/train/continue-smoke \
--max-steps 2 \
--save-steps 1 \
--batch-size 1 \
--gradient-accumulation 1 \
--warmup-ratio 0 \
--dataloader-workers 0 \
--train-components projector \
--max-samples 16
With eight GPUs, --max-samples 16 provides two complete global microbatches. If you change the GPU count or batch size, keep the sample limit at least GPU count × per-device batch size.
After training, confirm that the output reloads and the projector parameters changed from the starting model:
python -m baselines.vlm.navila.checkpoint \
--model-path output/baselines/vlm/navila/train/continue-smoke \
--compare-model "$NAVILA_SFT_MODEL" \
--navila-repo "$NAVILA_REPO" \
--device cuda:0
9. Full training
Continue from the NaVILA SFT checkpoint:
CUDA_DEVICES=0,1,2,3,4,5,6,7 \
bash baselines/vlm/navila/scripts/train.sh continue \
--gpus 8 \
--trajectory-root "$SATNAV_NAVILA_TRAIN_DATA" \
--model-path "$NAVILA_SFT_MODEL" \
--output-dir output/baselines/vlm/navila/train/continue-v0-1
Start from the NaVILA pretraining checkpoint:
CUDA_DEVICES=0,1,2,3,4,5,6,7 \
bash baselines/vlm/navila/scripts/train.sh scratch \
--gpus 8 \
--trajectory-root "$SATNAV_NAVILA_TRAIN_DATA" \
--model-path "$NAVILA_PRETRAIN_MODEL" \
--output-dir output/baselines/vlm/navila/train/scratch-v0-1
If GPU memory is insufficient, reduce --batch-size first and increase --gradient-accumulation to retain the desired effective batch size. The current launcher has no training-resume option; use an independent output directory for each full run.
10. Configure online evaluation
The training output directory is a complete checkpoint. Set the checkpoint to evaluate:
export NAVILA_CHECKPOINT=/path/to/trained-navila-checkpoint
Check Episode, scene, and output path resolution:
bash baselines/vlm/navila/scripts/eval.sh \
--model-path "$NAVILA_CHECKPOINT" \
--episodes "$SATNAV_NAVILA_EVAL_EPISODES" \
--scenes-dir "$SATNAV_NAVILA_SCENES_DIR" \
--split val_seen \
--limit 4 \
--max-steps 5 \
--gpus 1 \
--dry-run
Dry run validates configuration, data selection, and the output location without loading the model or interacting with the environment.
11. Single-GPU smoke evaluation
Select four Episodes with at most five steps each:
CUDA_DEVICES=0 \
bash baselines/vlm/navila/scripts/eval.sh \
--model-path "$NAVILA_CHECKPOINT" \
--episodes "$SATNAV_NAVILA_EVAL_EPISODES" \
--scenes-dir "$SATNAV_NAVILA_SCENES_DIR" \
--split val_seen \
--limit 4 \
--max-steps 5 \
--gpus 1 \
--output-dir output/baselines/vlm/navila/eval/v0-1/val_seen/5steps-1rank \
--fail-on-episode-error
Result layout:
<output-dir>/
├── rank_00000/
│ ├── episodes.jsonl
│ └── done.json
└── summary.json
Confirm that summary.json has status equal to complete, error_episode_count equal to 0, and includes distance_to_goal, success, oracle_success, spl, and path_length.
12. Multi-GPU evaluation
Each rank reads the complete Episode file. The shared evaluator handles deterministic sorting and stride sharding. A two-GPU smoke run is:
CUDA_DEVICES=0,1 \
bash baselines/vlm/navila/scripts/eval.sh \
--model-path "$NAVILA_CHECKPOINT" \
--episodes "$SATNAV_NAVILA_EVAL_EPISODES" \
--scenes-dir "$SATNAV_NAVILA_SCENES_DIR" \
--split val_seen \
--limit 4 \
--max-steps 5 \
--gpus 2 \
--output-dir output/baselines/vlm/navila/eval/v0-1/val_seen/5steps-2rank \
--fail-on-episode-error
After every rank exits successfully, the launcher writes the aggregated summary.json.
13. Full evaluation
Evaluate the complete val_seen split with a 500-step limit:
CUDA_DEVICES=0,1,2,3,4,5,6,7 \
bash baselines/vlm/navila/scripts/eval.sh \
--model-path "$NAVILA_CHECKPOINT" \
--episodes "$SATNAV_NAVILA_EVAL_EPISODES" \
--scenes-dir "$SATNAV_NAVILA_SCENES_DIR" \
--split val_seen \
--limit -1 \
--max-steps 500 \
--gpus 8 \
--output-dir output/baselines/vlm/navila/eval/v0-1/val_seen/500steps-8rank \
--fail-on-episode-error
After completion, change the split and output directory to val_unseen and run again. {split} in SATNAV_NAVILA_EVAL_EPISODES is replaced automatically.
To continue an interrupted evaluation, rerun with exactly the same parameters and output directory and add --resume. Resume skips Episodes already written by the current rank. Use a new output directory after changing the checkpoint, data, seed, GPU count, or evaluation parameters.
14. Troubleshooting
Why does the launcher report a NaVILA revision mismatch?
Make sure NAVILA_REPO points to the correct checkout, then restore the supported revision:
git -C "$NAVILA_REPO" checkout --detach \
76b98f233dd0fff05dfcd69435eec6740febff9d
git -C "$NAVILA_REPO" status --short
status --short must print nothing. Do not store models, logs, or other local files in this checkout.
Why can FlashAttention not be imported?
The wheel must match Python, PyTorch, CUDA, and the CXX11 ABI. In a clean environment, install PyTorch and FlashAttention before the remaining dependencies. Do not reuse another VLM environment.
Why did the environment patch fail?
Confirm that the environment uses the pinned Transformers and DeepSpeed versions and that NAVILA_REPO is at the supported revision. Run patch_environment.sh only after dependency installation.
Why does checkpoint loading fail?
Use a complete NaVILA checkpoint, not an isolated projector, adapter, or partial weight set. The model directory must include tokenizer, vision tower, multimodal projector, and language-model files.
Why does trajectory validation report a frame-count mismatch?
Check that each video path in annotations.json resolves under the current images/ directory and that trajectory generation completed. Do not combine annotations and images from different exports.
Why is model loading delayed after training starts?
The launcher validates the complete SatNav-v0.1 trajectory before loading the model. This can take time on network or slow storage; keep annotations and JPEG files on fast local storage when possible.
Why were some Episodes skipped after restarting evaluation?
With --resume, the evaluator skips Episodes already completed in the output directory. Reuse that directory only when continuing exactly the same evaluation; otherwise, choose a new --output-dir.