Views
No views yet
mudasir13cs/qwen25-vl-3b-floorplan-sft; trained with GRPO and geometric rewards. Base checkpoint: Qwen2.5-VL-3B-Instruct (LICENSE).
| Resource | Link |
|---|---|
| CubiCasa5K paper | A Dataset and an Approach to Floorplan Reconstruction |
| Zenodo download | doi:10.5281/zenodo.2613548 |
| License | CC BY-NC 4.0 |
| HF mirrors | Claudio9701/cubicasa5k · Forceless/Zenodo10K |
| Method | FloorplanVLM (arXiv:2602.06507) |
| Stage 1 adapter | mudasir13cs/qwen25-vl-3b-floorplan-sft |
train_floorplan_grpo.py — reward R = 0.1·R_val + 0.5·R_ext + α·0.4·R_int; SFT_MODEL_ID, HUB_MODEL_ID, and OUTPUT_DIR are edited at the top of that script.train_floorplan_vlm.py.pip install torch torchvision transformers trl peft accelerate pillow1from transformers import Qwen2_5_VLForConditionalGeneration, AutoProcessor
2from peft import PeftModel
3
4BASE = "Qwen/Qwen2.5-VL-3B-Instruct"
5ADAPTER = "mudasir13cs/qwen25-vl-3b-floorplan-grpo"
6
7processor = AutoProcessor.from_pretrained(BASE)
8model = Qwen2_5_VLForConditionalGeneration.from_pretrained(
9 BASE, torch_dtype="auto", device_map="auto"
10)
11model = PeftModel.from_pretrained(model, ADAPTER)
12model.eval()ADAPTER = "./floorplan-vlm-grpo" (or an absolute path) instead of the Hub repo id.SYSTEM_PROMPT in train_floorplan_vlm.py). GRPO training uses a shorter system string in train_floorplan_grpo.py; either works, but the schema-explicit SFT prompt below usually yields more stable JSON.train_floorplan_vlm.py):1import json, re, torch
2from PIL import Image
3
4# Same strings as train_floorplan_vlm.py (schema-in-the-prompt; recommended for decoding).
5SYSTEM_PROMPT = (
6 "You are a floor plan vectorization expert. Extract wall, door, window geometry "
7 "from floor plan images into structured JSON.\n\n"
8 "Output ONLY valid JSON with this schema:\n"
9 '{"walls":[{"id":"wall_N","start":[x,y],"end":[x,y],"thickness":T,"curvature":0,'
10 '"openings":[{"type":"door"|"window","center":D,"width":W}]}],'
11 '"rooms":[{"label":"room_type","walls":["wall_N",...]}]}\n\n'
12 "Coordinates normalized so longer image edge = 1024."
13)
14USER_PROMPT = "Vectorize this floor plan into structured JSON with all walls, doors, windows, and rooms."
15
16image = Image.open("plan.png").convert("RGB")
17
18messages = [
19 {"role": "system", "content": [{"type": "text", "text": SYSTEM_PROMPT}]},
20 {"role": "user", "content": [{"type": "image"}, {"type": "text", "text": USER_PROMPT}]},
21]
22text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
23inputs = processor(text=[text], images=[image], return_tensors="pt", padding=True)
24inputs = {k: v.to(model.device) if hasattr(v, "to") else v for k, v in inputs.items()}
25
26with torch.no_grad():
27 out = model.generate(**inputs, max_new_tokens=4096, do_sample=False)
28
29raw = processor.batch_decode(out[:, inputs.input_ids.shape[1] :], skip_special_tokens=True)[0]
30m = re.search(r"\{[\s\S]*\}", raw)
31plan = json.loads(m.group()) if m else Nonewalls (with optional openings) and rooms. Example JSON shape is spelled out under Output JSON Schema in the manitocross training README.mudasir13cs/qwen25-vl-3b-floorplan-sft.train_floorplan_grpo.py from a checkout with the environment described there (CubiCasa5K under ./cubicasa_data, huggingface-cli login if PUSH_TO_HUB = True; config block at top of file).1@article{floorplanvlm2026,
2 title={FloorplanVLM: A Vision-Language Model for Floorplan Vectorization},
3 journal={arXiv preprint arXiv:2602.06507},
4 year={2026}
5}