ASTRALK/sentinel-lfm-mining-450m-full-v2
015
sentinel-lfm — LFM2.5-VL-450M FULL fine-tune v2 (improved recipe)
All-layers fine-tune of LiquidAI/LFM2.5-VL-450M with an improved training recipe over ASTRALK/sentinel-lfm-mining-450m-full: (1) all 1965 train patches (no downsampling) + class-weighted loss, (2) validation-based best-checkpoint selection (balanced accuracy), (3) weight decay, longer schedule. Replies {"mine_present": true|false}.
Results on the held-out test split (419 patches, 303 pos / 116 neg)
Training
- FULL fine-tune, 448718848 params, class-weighted loss
- 6 epochs, lr=2e-05 (warmup->cosine), wd=0.01
- best checkpoint by val balanced-acc: epoch 1 (bal_acc=0.7713)
- bf16 autocast + gradient checkpointing, ~25.8 min on H100
Usage
from transformers import AutoProcessor, AutoModelForImageTextToText
from transformers.image_utils import load_image
model = AutoModelForImageTextToText.from_pretrained("ASTRALK/sentinel-lfm-mining-450m-full-v2", dtype="bfloat16", device_map="auto")
proc = AutoProcessor.from_pretrained("ASTRALK/sentinel-lfm-mining-450m-full-v2")
img = load_image("patch.png")
conv = [{"role":"user","content":[
{"type":"image","image":img},
{"type":"text","text":'Does this satellite patch show illegal mining? Reply with only this JSON: {"mine_present": true} or {"mine_present": false}'}]}]
inp = proc.apply_chat_template(conv, add_generation_prompt=True, return_tensors="pt", return_dict=True, tokenize=True).to(model.device)
print(proc.decode(model.generate(**inp, max_new_tokens=16)[0][inp["input_ids"].shape[1]:], skip_special_tokens=True))