Results
Fixed exam of 635 questions, same prompts and the same answer extractor for both models. None of these questions were used in training.
Table with columns: Part, Questions, Base (Qwen3-VL-2B), Vertex-Math-Vision v2, Difference| Part | Questions | Base (Qwen3-VL-2B) | Vertex-Math-Vision v2 | Difference |
|---|
| Synthetic visual problems (held out) | 300 | 72.3% | 80.3% | +8.0 |
| MathVision (subset) | 135 | 9.6% | 16.3% | +6.7 |
| MGSM, English | 100 | 65.0% | 60.0% | −5.0 |
| MGSM, Spanish | 100 | 53.0% | 52.0% | −1.0 |
| Total | 635 | 54.8% | 59.1% | +4.3 |
How to read the MGSM drop. Question by question, v2 fixes 12 English MGSM problems the base gets wrong and misses 17 the base gets right. A gap that size is within noise for 100 questions (McNemar p ≈ 0.46). In Spanish it is 14 against 15. So v2 keeps the base model's word-problem reasoning instead of damaging it.
Biggest gains by problem type: clocks 30% → 75%, rectangles 81% → 100%, bar charts 71% → 88%, Pythagoras 33% → 48%, equations 90% → 100%.
Why v2
v1 used the same data but a higher learning rate and short, answer-first solutions. It scored higher on visual problems, but it dropped 15 points on MGSM against the base: it had learned to answer too fast. v2 rewrote every solution to understand the problem first, then solve it, and halved the learning rate. That recovered MGSM (+10 in English, +14 in Spanish over v1).
Limitations
- Number lines are its weak spot (1/16 on the exam, base 4/16). It usually misreads by one tick mark.
- Counting objects in an image is still poor (22%).
- MathVision is hard for a 2B model. 16% is better than the base, but far from large models. Use it for school-level problems, not olympiad geometry.
- It was evaluated on one fixed exam. Treat the numbers as indicative.
How to use
With Unsloth:
from unsloth import FastVisionModelfrom PIL import Image model, tokenizer = FastVisionModel.from_pretrained("Denisijcu/vertex-math-vision", load_in_4bit=True)FastVisionModel.for_inference(model) image = Image.open("problem.png").convert("RGB")messages = [{"role": "user", "content": [ {"type": "image"}, {"type": "text", "text": "Resuelve el problema de la imagen paso a paso."},]}]prompt = tokenizer.apply_chat_template(messages, add_generation_prompt=True)inputs = tokenizer(image, prompt, add_special_tokens=False, return_tensors="pt").to("cuda")out = model.generate(**inputs, max_new_tokens=768, temperature=0.2, do_sample=True)print(tokenizer.decode(out[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True))
With PEFT, load Qwen/Qwen3-VL-2B-Instruct and apply this adapter with PeftModel.from_pretrained.
Training details
Table | |
|---|
| Method | QLoRA (4-bit base) with Unsloth + TRL SFTTrainer, language layers only (vision encoder frozen) |
| LoRA | r = 16, alpha = 16, dropout = 0, attention and MLP projections (0.81% of parameters trainable) |
| Optimizer | AdamW 8-bit, lr 5e-5, cosine schedule, 3% warmup, weight decay 0.01 |
| Batch | 1 × 8 gradient accumulation, max length 2048, fp16 |
| Steps | 750 (1 epoch over 6,000 examples) on a GTX 1660 Ti 6 GB |
Training data (6,000 examples)
Table with columns: Source, Share, Notes| Source | Share | Notes |
|---|
| Synthetic generator (Vertex Coders) | 80% | Bilingual visual problems drawn by code: charts, clocks, shapes, number lines, fractions, equations, prices, word problems on a card |
| GSM8K, rendered as images | 20% | Solutions rewritten to state what is asked and what is known before the steps |
MathVision and MGSM were used only for evaluation.
License
This adapter is a derivative of Qwen3-VL-2B-Instruct (Qwen Team, Alibaba Cloud), licensed under the Apache License 2.0, and is released under the same license. GSM8K is MIT-licensed.
About Vertex Coders
Vertex Coders LLC (Miami, FL; founded January 2026 by Denis Sanchez Leyva) builds AI-native software and custom private language models: local fine-tunes on open bases, with security guardrails and MCP-based agents.