Why this step
Checkpoints every 100 steps were each evaluated (pass@1, T 0.6, top-p 0.95, top-k 20, 32K response cap, robust answer
matching). Step 900 has the best mean score of this run.
Table with columns: benchmark, Qwen3.5-9B, this model| benchmark | Qwen3.5-9B | this model |
|---|
| mmstar | 0.775 | 0.721 |
| ocrbench | 0.859 | 0.855 |
| charxiv_reasoning | 0.604 | 0.514 |
| realworldqa | 0.771 | 0.733 |
| hallusionbench | 0.780 | 0.752 |
| ai2d | 0.880 | 0.858 |
| countbenchqa | 0.965 | 0.953 |
| cv_bench | 0.876 | 0.878 |
| mean | 0.819 | 0.788 |
Scores: accuracy with a robust answer matcher (official score where the matcher does not apply). On the image domains
SFT stays below the post-trained base; it shortens the answers (base 1.2K-15K tokens, SFT ~130-840) and fixes the format
(</think> closed and \boxed{} in > 99 % of answers). The next stage (GSPO RL from this checkpoint) is meant to
recover and exceed the base.
Use
from transformers import AutoProcessor, AutoModelForImageTextToTextmodel = AutoModelForImageTextToText.from_pretrained("ngqtrung/Qwen3.5-9B-MOPD-SFT-imgp", torch_dtype="bfloat16", device_map="auto")processor = AutoProcessor.from_pretrained("ngqtrung/Qwen3.5-9B-MOPD-SFT-imgp")# processor.apply_chat_template(messages, enable_thinking=True, add_generation_prompt=True, ...)
vLLM: vllm serve ngqtrung/Qwen3.5-9B-MOPD-SFT-imgp (stop token ids 248046, 248044 from generation_config.json).
Part of the collection MOPD: multi-teacher on-policy distillation (Qwen3.5-9B).