Lucia v1: Qwen3.5-9B, think symbolic image
Lucia v1 is the largest of the Lucia family, the thinking lookers: a LoRA adapter of Qwen/Qwen3.5-9B 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. Every size is taught the same rows under the same recipe; the sizes differ in what they can hold, and the reads below say what this one holds. She is the reference the other sizes are read against: every number on their cards stands beside hers.
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; there is no full fine-tune at this size. Every Lucia loads the same way and is run the same way: thinking off, greedy decoding, no system prompt (the row's form is learned, and a system turn she was not trained with makes her over-write). Needs transformers 5; the adapter also needs peft 0.18 or newer.
The LoRA adapter (AbstractPhil/qwen3.5-9b-think-symbolic-image): the base model, the adapter merged into it, the processor from the adapter repository (the base processor's files are kept there).
import torch
from peft import PeftModel
from transformers import AutoModelForMultimodalLM, AutoProcessor
processor = AutoProcessor.from_pretrained("AbstractPhil/qwen3.5-9b-think-symbolic-image")
model = AutoModelForMultimodalLM.from_pretrained("Qwen/Qwen3.5-9B", dtype=torch.bfloat16, device_map="cuda")
model = PeftModel.from_pretrained(model, "AbstractPhil/qwen3.5-9b-think-symbolic-image").merge_and_unload().eval()
The full fine-tune: none at this size. The optimizer states of a full fine-tune of this model do not fit one card, so the adapter is the release here; the 4B, 2B and 0.8B have full fine-tunes (the family table below).
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, ending with a caption; then write a caption "
"and a prompt or tags, and the questions a careful looker would still ask.")
messages = [{"role": "user", "content": [{"type": "image", "image": image}, {"type": "text", "text": prompt}]}]
text = processor.apply_chat_template(messages, add_generation_prompt=True, tokenize=False, enable_thinking=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 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 against the original release (the adapter this one replaced at the root, kept under legacy/E_all_2ep/): 60 pictures and
40 specifications no adapter saw, against the dataset's own rows (row shape, said / backed, definitions); then the medium term on
two sets no training row came from: 500 National Gallery of Art pictures (100 drawings, prints, paintings, photographs and
objects each) and 200 pictures of AIC, NGA, Cleveland and the Met. Every other size of the family is read the same way and
printed beside these numbers on its own card.
| read | Lucia v1 | the original (legacy) |
|---|---|---|
| row shape, pictures / specifications | 1.00 / 1.00 | 1.00 / 1.00 |
| said / backed, whole rows | 0.19 / 0.30 | 0.21 / 0.31 |
| definitions, pictures / specifications | 0.02 / 0.08 | 0.02 / 0.10 |
| 500 held-out pictures: painting / print / drawing / photograph / object named rightly of 100 | 83 / 76 / 86 / 80 / 90 | 80 / 4 / 20 / 76 / 67 |
| 200 museum pictures: painting / print / drawing / photograph / object | 13 of 27 / 38 of 39 / 12 of 13 / 11 of 13 / 66 of 66 | 11 of 27 / 7 of 38 / 1 of 13 / 12 of 13 / 58 of 63 |
| the 200 museum pictures on one RTX PRO 6000, batch 64, 800 new tokens a row | 0.27 s a row | 0.27 s a row |
The museum painting row understates her: of the 14 catalogue paintings she did not name so, 7 are watercolours or gouaches on paper that she names drawings, as the National Gallery's own catalogue does, 2 are paintings on silk she names photographs, and 5 are objects or prints that the catalogue-line ruler mislabelled as paintings. Every oil on canvas or panel is named a painting.
A second seed of the same recipe (seed 20261031, the same rows and settings) reproduced the medium term: 83 / 80 / 84 / 80 / 90 on the 500 held-out pictures and 13 of 27 / 37 of 39 / 12 of 13 / 12 of 13 / 64 of 66 on the museum pictures, with said / backed 0.20 / 0.29. Its definitions on specification rows read 0.25 against this seed's 0.07: that 40-row read is the noisiest line of the table and does not judge the recipe at one seed. The rest of the row (the looking, the questions, the moods) reads at the original's level: the medium rows change the prompt line's first term and nothing else was asked of them.
Limits: quick looks are the fragile depth, where one thought can name a wrong thing. Specification rows (no picture) still carry
a defining thought in about one row in ten. The medium is named from the picture, so a watercolour or gouache on paper that a
museum catalogues as a painting is named a drawing, the National Gallery's convention, which the museum rows taught; those rows
are the adapter's own rows corrected on one line, not human rows. English only. The row's conventions (the steps, the depths,
the question form) are the dataset's. The reads are made with qwen_symbolic_thinking.tools (probe_read, museum_read,
museum_mismatch, screen_conflicts), so any arm can be read the same way.
How she was trained
| base | Qwen/Qwen3.5-9B, bf16, the vision tower frozen |
| adapter | LoRA rank 32, alpha 64, dropout 0.05 on the language model's q, k, v, o, gate, up, down, in_proj_qkv, in_proj_z and out_proj projections (80.2 M trainable parameters) |
| data | the original recipe (951 picture rows taught twice, 500 long-look drawn rows, 2,000 synthetic closer looks) plus 17,385 museum rows: the original adapter's own rows about pictures of the National Gallery of Art, the Metropolitan Museum, the Art Institute of Chicago and the Cleveland Museum 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; the 500 probe pictures held out |
| optimiser | plain Adam 2e-4, cosine schedule, 3% warmup, batch 8 x 2, two epochs (2,724 steps, 5.71 s a step, 259 minutes on one RTX PRO 6000), the loss on the answer only, seed 20261030 |
| thinking | off in training and at inference: the 9B thinks by default, and every Lucia is taught and run with enable_thinking=False |
| what the medium rows did | a one-sided set (paintings, prints, drawings only) made every museum picture a painting or a print; the two-sided set (photographs and objects kept as photographs) fixed the boundary; more drawings moved the drawing term most, from 20 to 86 of 100 |
| record | qwen-symbolic-thinking v0.1.14 at training time (the lane notebooks); the run's full log is train_summary.json beside the weights; the original release's card and record are under legacy/E_all_2ep/ |
Versions
| version | where | tag |
|---|---|---|
| Lucia v1 (2026-10-31) | the root of this repository | lucia-v1 (revision="lucia-v1") |
| the original (E_all_2ep, 2026-10-30) | legacy/E_all_2ep/ (subfolder="legacy/E_all_2ep"), with its card and training record |
legacy-e-all-2ep (the pre-swap revision) |
The root always holds the current version; each version keeps a tag, so PeftModel.from_pretrained(model, repo, revision="lucia-v1")
loads this one whatever the root holds later.
The family
| size | base | the LoRA adapter | the full fine-tune |
|---|---|---|---|
| 9B | Qwen/Qwen3.5-9B | qwen3.5-9b-think-symbolic-image | not trained (the states of a 9B full fine-tune do not fit one card) |
| 4B | Qwen/Qwen3.5-4B | qwen3.5-4b-think-symbolic-image | qwen3.5-4b-think-symbolic-image-full |
| 2B | Qwen/Qwen3.5-2B | qwen3.5-2b-think-symbolic-image | qwen3.5-2b-think-symbolic-image-full |
| 0.8B | Qwen/Qwen3.5-0.8B | qwen3.5-0.8b-think-symbolic-image | qwen3.5-0.8b-think-symbolic-image-full |
The 9B is Lucia v1; every other size is trained under her recipe and read on the same held-out sets.
License
Apache-2.0, the base model's licence. The rows she was taught come from the datasets above under their own terms.