Molmo2-O-7B, think symbolic image
Molmo2-O-7B, think symbolic image is a LoRA adapter of allenai/Molmo2-O-7B, Ai2's 7.8-billion-parameter vision model (the Molmo vision encoder and the OLMo 3 7B language model of 32 layers, trained on dense human picture captions), that looks at a picture and writes the row of thought-symbolic-image-captions: a short chain of plain-language thoughts, one named step per line, then the wordings (a caption, a prompt, tags, a critique, by depth), then the questions a careful looker would still ask, each with its answer and what settles it. It is one of five model families trained beside the Lucia line (Qwen3.5) and the Ulisse line (Gemma 4) under Lucia v1's recipe and read on the same held-out sets; it is not named yet. Every looker is taught the same rows under the same recipe; the base models differ in what they can hold, and the reads below say what this one holds. Its base model answered the row's form only a third of the time; the adapter writes it whole and backs its thoughts at Lucia's level, and the medium term reads at Ulisse's level.
see: A single figure, seated, holding a book, in three-quarter view.
place: The figure sits at the centre, the book held low against the lap.
form: The sitter fills the frame from the knees up, the background a plain dark wash.
colour: Brown ink over graphite, the paper a warm cream.
mood: The lowered eyes and the still hands suggest absorption, a reader lost in the page.
caption: A seated figure reads a book held in the lap, drawn in brown ink over graphite.
prompt: drawing, seated figure reading, three-quarter view, brown ink over graphite, cream paper, plain dark wash
question: thing name -> book [record]
question: medium -> ink and graphite [record]
question: mood tone -> absorbed [chain]
question: sitter identity -> unknown [unknown]
The steps a chain may use, in the order a careful looker takes them: see, name, place, count, relate, form, light, colour, mood,
mean, intend, story, compare, change, check, say. A quick look holds 1 to 2 thoughts, a closer look 3 to 5, a long look 6 to 10.
Questions end in [record] (the answer is a fact of the picture), [chain] (the chain worked it out) or [unknown]. The prompt
line's first term names the kind of picture (painting, print, drawing, photograph).
Loading
This repository holds the LoRA adapter (rank 32, 67.4 M trainable parameters, saved in fp32); there is no full fine-tune. Its model code is the base repository's own (trust_remote_code), pinned here to the revision it was trained on and written for transformers 4.57: install transformers==4.57.6 and peft 0.18 or newer (the training and the reads ran on exactly these).
Run it as it was trained: greedy decoding, no system prompt, no thinking (the base is not a reasoning model). Its rows end with <|endoftext|>, the id its generation config stops on. The processor comes from the base repository at the same revision; nothing of the base's code is copied here.
The base model, the adapter merged into it, the processor from the base repository at revision 78441065, the revision the adapter was trained on:
import torch
from huggingface_hub import snapshot_download
from peft import PeftModel
from transformers import AutoModelForImageTextToText, AutoProcessor
src = snapshot_download("allenai/Molmo2-O-7B", revision="784410650d12be9bc086118fdefa32d2c3bced86")
processor = AutoProcessor.from_pretrained(src, trust_remote_code=True)
processor.tokenizer.padding_side = "left" # its processor places its start token assuming left padding
model = AutoModelForImageTextToText.from_pretrained(src, trust_remote_code=True, dtype=torch.bfloat16, device_map="cuda")
model = PeftModel.from_pretrained(model, "AbstractPhil/molmo2-o-7b-think-symbolic-image").merge_and_unload().eval()
Then:
from PIL import Image
image = Image.open("picture.jpg").convert("RGB")
prompt = ("Look at this picture and think it through in writing, a closer look; then write a caption and a "
"prompt or tags, and the questions a careful looker would still ask, each as `question: what -> "
"answer [record, chain or unknown]`.")
messages = [{"role": "user", "content": [{"type": "image", "image": image}, {"type": "text", "text": prompt}]}]
text = processor.apply_chat_template(messages, add_generation_prompt=True, tokenize=False)
inputs = processor(text=[text], images=[image], return_tensors="pt").to(model.device)
out = model.generate(**inputs, max_new_tokens=800, do_sample=False)
print(processor.batch_decode(out[:, inputs["input_ids"].shape[1]:], skip_special_tokens=True)[0])
The prompts it was trained on
The adapter was trained on these exact asks (the trained forms of the package's prompts.full and prompts.short); a reworded
ask is a different input. The reads below use the whole row at each picture's depth.
| depth | the whole row (the form these reads use) | the short form |
|---|---|---|
| a quick look | Look at this picture and think it through in writing, a quick look; then write a caption, and the questions a careful looker would still ask, each as question: what -> answer [record, chain or unknown]. |
Look at this picture and think it through in writing, a quick look, ending with a caption. |
| a closer look | Look at this picture and think it through in writing, a closer look; then write a caption and a prompt or tags, and the questions a careful looker would still ask, each as question: what -> answer [record, chain or unknown]. |
Look at this picture and think it through in writing, a closer look, ending with a caption. |
| a long look | Look at this picture and think it through in writing, a long look; then write a caption, a prompt, tags and a critique, and the questions a careful looker would still ask, each as question: what -> answer [record, chain or unknown]. |
Look at this picture and think it through in writing, a long look, ending with a caption. |
The depth words: "a quick look" (1 to 2 thoughts), "a closer look" (3 to 5), "a long look" (6 to 10). The parser, the scorer and
the trainer are in qwen-symbolic-thinking
(qwen_symbolic_thinking.chain.parse, chain.score); the same package extracted every number below.
The reads
Read the same way as the Lucia and Ulisse lines, by the same reader, beside Lucia v1 (the model the recipe was made for) and Ulisse 12B. First a screen: 60 pictures and 40 specifications no training row came from, scored against the dataset's own rows. Row shape is the share of rows written in the row's form; at its depth, the share whose chain holds the number of thoughts its depth asks for; said is the share of a picture's own captions' content words that the thoughts and the caption say, and backed the share of the model's content words those captions back; a definition is a thought that defines a word instead of looking. Then the medium term on two sets no training row came from, from the picture list AbstractPhil/qwen-thinking-images: 500 National Gallery of Art pictures (100 drawings, prints, paintings, photographs and objects each), the prompt line's first term read against the catalogue's kind, and 200 pictures of the Art Institute of Chicago, the National Gallery, the Cleveland Museum of Art and the Met.
| read | Molmo2-O-7B | Lucia v1 (Qwen3.5-9B) | Ulisse 12B (Gemma 4 12B) |
|---|---|---|---|
| row shape, pictures / specifications | 1.00 / 1.00 | 1.00 / 1.00 | 1.00 / 1.00 |
| at its depth: pictures, whole row / short form; specifications | 1.00 / 1.00; 0.90 | 1.00 / 1.00; 0.95 | 1.00 / 1.00; 0.93 |
| said / backed, whole rows (short form) | 0.18 / 0.28 (0.23 / 0.27) | 0.19 / 0.30 (0.23 / 0.30) | 0.18 / 0.27 (0.21 / 0.27) |
| rows with a definition: pictures / specifications | 1 of 60 / 16 of 40 | 1 of 60 / 3 of 40 | 1 of 60 / 5 of 40 |
| 500 held-out pictures: painting / print / drawing / photograph / object named rightly of 100 (sum) | 83 / 73 / 82 / 82 / 88 (408) | 83 / 76 / 86 / 80 / 90 (415) | 83 / 74 / 80 / 81 / 91 (409) |
| 200 museum pictures: painting / print / drawing / photograph / object | 14 of 27 / 38 of 39 / 12 of 13 / 12 of 13 / 65 of 66 | 13 of 27 / 38 of 39 / 12 of 13 / 11 of 13 / 66 of 66 | 13 of 27 / 36 of 39 / 12 of 13 / 11 of 13 / 66 of 66 |
| time a picture on one RTX PRO 6000 (batch 64, 800 new tokens a row) | 0.63 s (batch 32) | 0.27 s | 0.36 s |
What this says: A broken base form became Lucia's: the adapter writes the row's shape every time and at its depth on every picture row (2.6 thoughts a closer look; the specification rows 0.90, the lowest of the five). The grounding comes up to her band: it backs 0.28 of what it says (its base 0.15; Lucia v1 0.30) and says 0.18 of a picture's own captions (hers 0.19). The medium term sits at Ulisse's level: 408 of the 500 held-out pictures (Ulisse 12B 409, Lucia v1 415), every kind within 4 of hers, prints the furthest (73 against 76); the museum pictures within 1 a kind of hers. Its specification rows define the most (16 of 40; Lucia 3), and its picture rows reach for the stock mood words most (81% of its mood lines; Lucia 46%). It reads in batches of 32 (it keeps about 512 KB of cache a token), at 0.63 seconds a picture, and took 338 minutes to train.
Before training the base model answered the row's form 0.35 of the time from the plain ask, wrote 11.8 thoughts a picture (0.17 of rows at their depth), and backed 0.15 of what it said. The training taught it the row's shape at each depth, the backing and the house vocabulary.
Limits, shared with the family: quick looks are the fragile depth, where one thought can name a wrong thing; the museum painting
row understates every model, because watercolours and gouaches on paper are named drawings, as the National Gallery's own catalogue
does; English only; the row's conventions (the steps, the depths, the question form) are the dataset's. The specification-row
definitions are counted on 40 rows, the noisiest line of the table. The reads are made with qwen_symbolic_thinking.tools
(probe_read, museum_read, museum_mismatch, screen_conflicts), so any adapter can be read the same way.
How it was trained
| base | allenai/Molmo2-O-7B at revision 784410650d12be9bc086118fdefa32d2c3bced86, bf16; pictures at the processor's default: up to 8 crops of 378 pixels and a global view, pooled 2 x 2, about 760 to 1,200 picture tokens; its vision encoder frozen, outside the adapter |
| adapter | LoRA rank 32, alpha 64, dropout 0.05 on the language model's fused attention projection (att_proj), attention output (attn_out), fused feed-forward projection (ff_proj) and feed-forward output (ff_out) of all 32 blocks; 67.4 M trainable parameters, saved in fp32 |
| data | Lucia v1's rows exactly: 951 picture rows taught twice, 500 long-look drawn rows, 2,000 synthetic closer looks and 17,385 museum rows whose catalogue gives the medium, the prompt line's first term set to it (6,606 drawings, 3,523 paintings, 3,000 prints, 2,016 photographs, 2,240 objects); 20,836 items, 21,787 examples (18,336 whole rows, 2,951 short forms, 500 specification rows); the 500 held-out probe pictures never trained |
| optimiser | plain Adam 2e-4, cosine schedule, 3% warmup, batch 8 x 2, two epochs (2,724 steps, 7.43 s a step, 338 minutes on one RTX PRO 6000), the loss on the answer only, seed 20261030; final training loss 0.446 (each family's own tokens, so not comparable across families) |
| length | max_len 2,560; no example of the 43,574 collated was cut (the longest 1,544 tokens) |
| thinking and turn end | not a reasoning model: no thinking, no system prompt; the rows end with `< |
| record | qwen-symbolic-thinking v0.1.37 on transformers 4.57.6, run_queue("remote_code_b") from notebooks/remote_code_b.ipynb; the run's full log is train_summary.json beside the weights |
Where it was trained
- The code: qwen-symbolic-thinking on GitHub: the trainer, the screens, the reads and what each model family
needs (
qwen_symbolic_thinking/family.py). This adapter was trained by v0.1.37 (tagv0.1.37); the batching and loading notes on this card hold for v0.1.38. - The run's record: the model repository AbstractPhil/qwen-symbolic-thinking-image-training (a model repository, not a
dataset): this adapter with its step checkpoints under
lora/Molmo2-O-7B/r32/20261102_123335_G_med4_2ep_molmo2o_v4/, the training sets it read (sft/pictures_v2.json,sft/drawn_deep_v2.json,synth/S_synth.json,sft/medium_v4.json) and the screens underscreens/. - The rows: the dataset thought-symbolic-image-captions (the row's form and the picture rows) and the picture list AbstractPhil/qwen-thinking-images (the museum pictures and the held-out probe).
Versions
| version | where | tag |
|---|---|---|
| Molmo2-O-7B, think symbolic image v1 | the root of this repository | v1 |
The lookers
The Lucia line is Qwen3.5 and starts at AbstractPhil/qwen3.5-9b-think-symbolic-image; the Ulisse line is Gemma 4. The five families below them (North-Micro-Vision, GLM-4.6V-Flash, Molmo2-O-7B, Ministral 3 14B and Phi-4-reasoning-vision-15B) are trained under Lucia v1's recipe at her learning rate (each has its own vision encoder, frozen under the adapter) and read on the same sets.
License
Apache-2.0, the base model's licence. The rows it was taught come from the datasets above under their own terms.