Mull-Tokens are latent tokens that can be pre-trained to hold intermediate information in either image or text modalities so as to think towards the correct answer. Across four challenging spatial reasoning benchmarks, Mull-Tokens achieve a +3% average improvement and up to +16% on reasoning-heavy splits compared to the strongest baseline.
1from transformers import Qwen2_5_VLForConditionalGeneration, AutoProcessor
2from qwen_vl_utils import process_vision_info
3import torch
4
5# Choose model: "array/Qwen2.5-VL-Mull" or "array/Qwen2.5-VL-MullGRPO"
6MODEL_ID = "array/Qwen2.5-VL-Mull"
7NUM_LATENTS = 20
8
9# Load model and processor
10model = Qwen2_5_VLForConditionalGeneration.from_pretrained(
11 MODEL_ID,
12 torch_dtype=torch.bfloat16,
13 attn_implementation="flash_attention_2",
14 device_map="auto",
15)
16processor = AutoProcessor.from_pretrained(MODEL_ID)
17
18# Prepare your question
19image_path = "path/to/your/image.jpg"
20question = "If you stand at the X marked point and turn left, will the table be to your left or right? Please choose between the following answer choices: A. left. B. right. "
21question_type = "multiple choice"
22
23QUESTION_TEMPLATE_LATENT = (
24 "{Question}\n"
25 "Please think about this question deeply. "
26 "It's encouraged to include self-reflection or verification in the reasoning process. "
27 "Provide your final answer between the <answer> </answer> tags."
28)
29TYPE_TEMPLATE = {
30 "multiple choice": " Please provide only the single option letter (e.g., A, B, C, D, etc.) within the <answer> </answer> tags.",
31 "numerical": " Please provide the numerical value (e.g., 42 or 3.14) within the <answer> </answer> tags.",
32 "OCR": " Please transcribe text from the image/video clearly and provide your text answer within the <answer> </answer> tags.",
33 "free-form": " Please provide your text answer within the <answer> </answer> tags.",
34 "regression": " Please provide the numerical value (e.g., 42 or 3.14) within the <answer> </answer> tags.",
35}
36prompt = QUESTION_TEMPLATE_LATENT.format(Question=question) + TYPE_TEMPLATE[question_type]
37
38# Build messages with latent thinking tokens
39messages = [
40 {
41 "role": "user",
42 "content": [
43 {"type": "image", "image": image_path},
44 {"type": "text", "text": prompt},
45 ],
46 },
47 # IMPORTANT: Mull-Tokens requires latent thinking tokens before answer generation
48 {
49 "role": "assistant",
50 "content": [
51 {
52 "type": "text",
53 "text": "<think>" + "<|latent_pad|>" * NUM_LATENTS + "</think>\n",
54 }
55 ],
56 },
57]
58
59# Process inputs
60text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=False)
61text = text.replace("<|im_end|>\n", "") # Remove end token so model continues generating
62
63image_inputs, video_inputs = process_vision_info(messages)
64inputs = processor(
65 text=[text],
66 images=image_inputs,
67 videos=video_inputs,
68 padding=True,
69 return_tensors="pt",
70).to(model.device)
71
72# Generate response
73with torch.no_grad():
74 output_ids = model.generate(
75 **inputs,
76 max_new_tokens=512,
77 do_sample=False,
78 )
79
80# Decode output (skip input tokens)
81generated_ids = output_ids[:, inputs["input_ids"].shape[1]:]
82response = processor.batch_decode(generated_ids, skip_special_tokens=True)[0]
83print(response)
1from openai import OpenAI
2client = OpenAI(base_url="http://localhost:8000/v1", api_key="EMPTY")
3client.chat.completions.create(
4 model="array/Qwen2.5-VL-Mull",
5 messages=[{"role": "user", "content": [
6 {"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{b64}"}},
7 {"type": "text", "text": question},
8 ]}],
9 temperature=0, max_tokens=512,
10 # optional: vary the latent budget, or set 0 to disable it for an ablation
11 extra_body={"chat_template_kwargs": {"num_latents": 20}},
12)
1vllm serve array/Qwen2.5-VL-Mull --max-model-len 32768 \
2 --mm-processor-kwargs '{"min_pixels": 3136, "max_pixels": 12845056}'
A
recipe, serving scripts and an
HF-vs-vLLM parity harness live in
serving/.
1@misc{ray2025mulltokensmodalityagnosticlatentthinking,
2 title={Mull-Tokens: Modality-Agnostic Latent Thinking},
3 author={Arijit Ray and Ahmed Abdelkader and Chengzhi Mao and Bryan A. Plummer and Kate Saenko and Ranjay Krishna and Leonidas Guibas and Wen-Sheng Chu},
4 year={2025},
5 eprint={2512.10941},
6 archivePrefix={arXiv},
7 primaryClass={cs.CV},
8 url={https://arxiv.org/abs/2512.10941},
9}