--- library_name: transformers pipeline_tag: image-segmentation base_model: - OpenGVLab/InternVL3_5-8B-HF - facebook/sam3 tags: - remote-sensing - reasoning-segmentation - earth-observation - custom_code license: other # TODO: SAM License on sam3_delta.safetensors, Apache-2.0 on the rest, some training datasets might be research use only --- # MLRS **More with Less: a Large Scale Remote Sensing VLM with a Simple Recipe** Accepted to **ACCV 2026**. 📄 Paper: https://arxiv.org/abs/2607.15942 MLRS is a remote-sensing vision-language model that answers questions and performs reasoning segmentation. MLRS supports wide range of inputs: ultra-high-res, SAR, thermal, false-color, multi-temporal, multi-view, visual prompting, multi-image. A LoRA-finetuned **InternVL3.5-8B** reasons about the image (or multiple images in rgb format) and either answers in text or calls a segmentation tool: ``` ...{"noun phrase": "...", "objects": [{"bbox": [x1, y1, x2, y2]}]} ``` Each noun phrase, its boxes (on a 0–999 grid), and the last rgb image are passed to **SAM3**, whose mask decoder was finetuned jointly via GRTO. SAM3 returns one mask per phrase, clipped to the predicted boxes. Text-only tasks answer with `...` and return no masks. This repository only holds the finetuned deltas (a LoRA adapter and SAM3 mask-decoder weights). The base models are downloaded from the Hub at the revisions pinned in `config.json`. > `facebook/sam3` is gated. Accept its license on the Hub and log in (`hf auth login` or set `HF_TOKEN` env.variable) before loading. ## Usage ```python import torch from PIL import Image from transformers import AutoModel, AutoProcessor repo = "INSAIT-Institute/MLRS" model = AutoModel.from_pretrained(repo, trust_remote_code=True, dtype=torch.bfloat16, device_map="cuda") processor = AutoProcessor.from_pretrained(repo, trust_remote_code=True) image = Image.open("scene.png") inputs = processor(images=image, text="Segment the buildings damaged by the flood.") out = model.generate(**inputs, max_new_tokens=1024) out.text[0] # full generation, including and the tool call / answer out.phrases[0] # noun phrases sent to SAM3 out.boxes[0] # per phrase: pixel boxes [x1, y1, x2, y2] masks = processor.post_process_masks(out, inputs)[0] # bool [K, H, W], one mask per phrase ``` **Multiple images** (for example, pre/post-event pairs): `processor(images=[pre, post], text=...)`. The segmentation tool runs on the last image; use `primary_image_index=` to pick a different one. **Batching:** `processor(images=[[img_a], [img_b1, img_b2]], text=[q_a, q_b])`. ## Inputs and outputs | Processor output | Description | |---|---| | `input_ids`, `attention_mask`, `pixel_values` | InternVL3.5 chat inputs. The instruction prompt is added automatically. | | `sam_inputs` | SAM3 image inputs for the primary image | | `sam_original_sizes` | `(H, W)` of the primary image after downsampling (longest side ≤ 4030, or ≤ 448 with 3 or more images) | | `image_original_sizes` | `(H, W)` of the primary image as given | `model.generate` returns `MLRSOutput(text, masks, phrases, boxes)`. `masks[i]` is a bool tensor of shape `[K, H, W]` at `sam_original_sizes` resolution. `processor.post_process_masks` resizes the masks back to the size of the input image. ## Notes - The defaults reproduce the evaluation setup: greedy decoding, `max_new_tokens=1024`, and the LoRA adapter kept unmerged. `AutoModel.from_pretrained(..., merge_lora=True)` generates faster, with small numerical differences. - Tested with `transformers==5.18.0`, `peft==0.18.0`, `torch==2.9.0`. ## Citation ```bibtex @misc{ailuro2026mlrs, title={{More with Less}: a Large Scale Remote Sensing {VLM} with a Simple Recipe}, author={Stefan Maria Ailuro and Mario Markov and Mohammad Mahdi and Luc Van Gool and Danda Pani Paudel}, year={2026}, eprint={2607.15942}, archivePrefix={arXiv}, primaryClass={cs.CV}, url={https://arxiv.org/abs/2607.15942}, } ```