CoolFace
Modelpublic

Aasdfip/longnav-objectnav-flow-nopose-cotrain-2p5hz-merged

sourceHugging Faceapache-2.0updated 1mo agoView on Hugging Face
0likes840downloads
Model Card

longnav-objectnav-flow-nopose-cotrain-2p5hz-merged

Weights-merged twin of [`Aasdfip/longnav-objectnav-flow-nopose-cotrain-2p5hz`](https://huggingface.co/Aasdfip/longnav-objectnav-flow-nopose-cotrain-2p5hz). Same policy, same step (trainer_state.json global_step 12000) — the LoRA is folded into the base weights instead of shipped alongside them. Numerically identical: verified as merged == base + (alpha/r)·B@A on a probe module, residual 1.5e-3 (bf16 rounding).

Why this exists

RL fine-tuning on top of this policy is run with the SFT LoRA already merged into the base, so the RL run's saved adapter contains the RL delta alone — about 1–2% of the SFT adapter's magnitude. Evaluating such an adapter against the plain adapter repo means composing two LoRAs (rank-stacking A/B into an r=256/alpha=512 adapter), and getting it wrong is quiet: apply the RL delta to the raw base and you evaluate the pretrained VLM plus a 1% perturbation, which scores near zero and raises nothing.

With this repo, an RL adapter loads directly on top:

python
model = AutoModelForImageTextToText.from_pretrained("Aasdfip/longnav-objectnav-flow-nopose-cotrain-2p5hz-merged")
model = PeftModel.from_pretrained(model, "<rl-run>/checkpoints/checkpoint_XXX")   # RL delta only

The adapter repo remains the canonical artifact: a merged model cannot be diffed against the base to recover the LoRA.

Files

filewhat
model.safetensors, config.jsonfull merged weights (no adapter/)
turn_vector_head.ptflow-matching action head + pose encoder
turn_vector_head_config.jsonhead config, including the <pose> modality spec
trainer_state.jsontraining curve, for provenance
tokenizer / preprocessor filesas trained

Optimizer and RNG state are not included — inference checkpoint, not a resume point.

Running it

Identical to the adapter repo, --ckpt pointed here. This policy is evaluated with no pose input: it declares a <pose> modality and was trained with pose on half its ObjectNav data, but scores better with the feed switched off entirely (0.663 vs 0.614 oracle success on sample101, n=101).

bash
python scripts/eval_objectnav_policy.py \
  --episodes   <hm3d objectnav val split> \
  --scene-root <scene_datasets> \
  --output-dir <out> \
  --episode-ids "$(cat sample101_ids.txt)" \
  --ckpt       <this checkpoint> \
  --policy-python   <env with transformers> \
  --policy-sys-path <longnav src> \
  --policy-backend flow_rollout --policy-seed 1000 \
  --max-steps 175 --dt 0.04 --gap 10 \
  --success-distance 1.0 --distance-to VIEW_POINTS \
  --seed 0 --navmesh dataset --fresh-sim-per-episode \
  --auto-stop --auto-stop-delay 15 \
  --no-pose-injection \
  --pid-preset baseline --keep-tracking-series

--no-pose-injection is required for the pose-free arm and is not in a public release of the harness at the time of upload; without it there is no way to remove the modality (feeding zeros is not equivalent — it is an in-distribution-looking input the model never trained on). The simulator and the model cannot share a Python environment, which is what --policy-python / --policy-sys-path are for.