Tasks/AI Models & Agents

Vision-Language Compositional Generalization Post-Training

Design a GRPO recipe for visual counting across unseen attribute combinations and renderers

AI Models & Agentsvision-language RLpost-training
Background

Reinforcement learning against automatic answer checkers is now standard post-training for vision-language models, but which reward designs buy transferable skill rather than memorization remains unsettled. The starting point is a deliberately weak trainer for a two-billion-parameter model on rendered counting questions, paid only for output formatting. The work is to redesign what the policy is paid for and the optimization around it, within a fixed compute budget. Training accuracy saturates early, masking whether anything generalizes; grading happens on unseen attribute combinations and a different renderer.

instruction.mdthis is what the agent is given

You inherit a deliberately weak reinforcement-learning (GRPO) training project for the vision-language model Qwen2-VL-2B-Instruct: the starting point in /app/methods/main/ trains on the provided counting-VQA split with a trivial reward and conservative hyper-parameters, and barely beats the untrained model. You submit a trained model (full merged weights in /app/submission/), not code, and a sealed verifier scores it on two hidden test sets that are not in-distribution samples of your train split — so only real generalization moves the score.

Hard Constraints

  1. The submitted model must be Qwen2-VL-2B-Instruct (same architecture/tokenizer/processor), fine-tuned. Write the full merged model (config + weights + tokenizer + processor) to /app/submission/ with save_pretrained(...) so the verifier can load it with Qwen2VLForConditionalGeneration.from_pretrained("/app/submission"). The trainer does full fine-tuning by default, so the saved checkpoint already is the full model; train.sh copies it to /app/submission. If you switch to a LoRA adapter, merge it before saving.
  2. No internet at training time. The base model and the train data are already on disk / in the HF cache. You may not download anything, and in particular you may not fetch any test data.
  3. Train only on the provided train split. Do not hand-write or memorize answer tables, do not key behavior on the visible val ids.
  4. The verifier uses a fixed evaluation protocol (prompt template + greedy decoding, below). Train your model to that protocol — there is no separate prompt you get to submit.
  5. Keep per_device_train_batch_size 1 — batched training in this trainer is buggy.
  6. Everything must finish inside the wall-clock budget with the model saved. GRPO is slow (multiple generations per prompt); a run that never writes /app/submission/ scores nothing.
  7. There is no submit step and no per-attempt feedback. Iterate against your local self-check, then leave your best model in /app/submission/; it is graded once at the end on the hidden sets.

What You Have

Budget: 2 GPUs (48 GB each), 8h wall-clock (accelerate / torchrun / deepspeed are installed). That is meant for several rounds, not one long run — a LoRA GRPO round is ~40–60 min.

  • Base model (/app/models/Qwen2-VL-2B-Instruct/): the untrained instruct model to start from. This exact model, with no fine-tuning, is the floor — you must beat it.
  • Train data (/app/data/train/): ~68k counting-VQA examples (columns image (PIL), problem, solution), baked to disk, with the validation set removed. The baseline train.sh points --dataset_name /app/data/train at it (loaded offline). Train only on this.
  • In-distribution val (/app/data/val/): 2k examples held out from training, same distribution as train. A training-health check — is the model actually learning to count, is it under-/over-training. Do not train on it.
  • OOD val (/app/data/ood_val/): ~1k examples that are out-of-distribution relative to train, and visible to you. It is disjoint from the sealed test data and tracks the sealed out-of-distribution test. Do not train on it.
  • Editable baseline (/app/methods/main/): a GRPO trainer (open_r1/grpo.py + Qwen2VLGRPOTrainer) launched by train.sh, plus zero3.json. Two surfaces are yours: the reward functions and their registry in open_r1/grpo.py (new ones can be registered and referenced by name in --reward_funcs), and the training hyper-parameters in train.sh (optimization, GRPO group size, batching, step count, KL, vision-token budget, sequence lengths, and optionally LoRA via --use_peft --lora_r …). See methods/main/README.md. Running bash /app/methods/main/train.sh trains and writes the model to /app/submission/. Nothing here prescribes which changes work. Finding that out is the task.
  • Self-check (/app/selfcheck.py): runs the exact same eval as the verifier (same prompt, extraction, matching) on both val sets against whatever model is in /app/submission/. Free and unlimited.

What You Submit

A directory /app/submission/ that Qwen2VLForConditionalGeneration.from_pretrained can load (full merged Qwen2-VL-2B weights + tokenizer + processor). That directory is the graded artifact.

How It Is Judged

The verifier loads /app/submission/ in a clean, network-isolated box and runs the protocol below on two hidden test sets (5k examples each). One is a compositional-generalization split — the same visual domain, but attribute combinations that never co-occur in training; the other comes from a different distribution entirely (different renderer/scene statistics).

For every test example the model is prompted with the image and:

{question} First output the thinking process in <think> </think> and final answer (number) in <answer> </answer> tags.

Note: the trainer's training template says "Output …" while the eval template says "First output …". The grader uses the EVAL phrasing above. Train so your model is robust to it.

The model is generated greedily (do_sample=False, max_new_tokens=256). The grader extracts the first integer inside <answer>…</answer> (regex <answer>\s*(\d+)\s*</answer>) and counts the example correct only on exact integer equality with the gold count — no fuzzy matching and no fallback, so a model that stops emitting the <answer> tag is parsed wrong everywhere.

accuracy_pct = 100 * (correct / total)            # computed per test set
score = mean(accuracy_pct over the two hidden test sets)

Higher mean accuracy is better. A model that fails to load, is the wrong architecture, or produces unparseable output everywhere scores 0.

Rollouts

480 minWall clock
$59.18Spend
121.2MTokens
15Versions, 6 kept

On the visible set

10.5 12.0 13.5 15.0 16.5 18.0 0 200 400 600 800 Agent step OOD val accuracy ↓ v0 v5 v7 v5+v9-row v10 v11 v14 v16 v18 v19
keptrolled backsubmitted
  1. v0The agent measured the untouched Qwen2-VL model on the full visible OOD split.10.424 min · $1.93
  2. v5The agent aligned GRPO rewards and trained language q/v LoRA with concise outputs.15.994 min · $8.77
  3. v7The agent strengthened KL and shortened completions, but full OOD accuracy regressed.13.3161 min · $15.31
  4. v9-row-baseThe agent trained only the ‘items’ embedding row from the base model.7.0 (OOD n=200)194 min · $20.24
  5. v5+v9-rowThe agent added the ‘items’ row to v5, preserving OOD but losing one ID example.15.9223 min · $24.33
  6. v10The agent retrained the ‘items’ row directly on v5, substantially improving ID accuracy.15.9263 min · $32.49
  7. v11The agent trained only the shared ‘image’ row, sharply improving ID accuracy.15.6307 min · $37.44
  8. v12The agent tuned the evaluator’s ‘First’ row with accuracy rewards; OOD screening worsened.11.5 (OOD n=200)323 min · $40.19
  9. v13The agent tuned ‘First’ using format-only rewards; OOD screening fell further.11.0 (OOD n=200)327 min · $40.87
  10. v15The agent adapted visual qkv projections; prefix feedback improved but remained below v14.13.0 (OOD n=200)356 min · $47.76
  11. v16The agent merged v14 and v15; full evaluation rejected the visual addition.16.6380 min · $51.56
  12. v14The agent conservatively continued language q/v LoRA from v11, improving both splits.17.3397 min · $53.01
  13. v18The agent merged v17’s visual MLP branch into v14; full accuracy declined.16.8436 min · $56.20
  14. v14-image-s1.5The agent scaled v11’s ‘image’ row atop v14, narrowly improving full OOD accuracy.17.6453 min · $57.64
  15. v19The agent added the same row scaling to v18; full OOD accuracy regressed.16.7471 min · $58.73

On the hidden set

Original metricNormalised score
Starter14.210.0
Frontier-calibrated reference86.530.6
Upper100.01.0
This run (GPT-5.6-sol)21.380.0595
441 minWall clock
$35.83Spend
56.1MTokens
11Versions, 5 kept

On the visible set

30 45 60 75 90 0 2 5 8 10 Agent step MEAN(val ↓ v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 base
keptrolled backsubmitted
  1. v1The agent replaced the format-only reward with grader-exact counting and fixed truncation54.440 min · $6.16
  2. v2The agent pasted train scenes into panels to force question-conditioned counting57.583 min · $12.23
  3. v3The agent synthesized attribute-labelled scenes from verified train-object cut-outs86.5152 min · $16.37
  4. v4The agent replicated the v3 recipe with a new augmentation seed74.35$19.06
  5. v5The agent enriched the synthetic task with object-anchored relation questions78215 min · $21.74
  6. v6The agent continued training from the v5 checkpoint for 140 more steps82$24.01
  7. v7The agent refined the champion at a low learning rate88.75$26.29
  8. v8The agent resumed the champion on enriched synthetic data for 150 steps91.7329 min · $28.56
  9. v9The agent ran one more refinement pass with different seeds90.3$31.98
  10. v10The agent pushed the synthetic data share to sixty percent90.6441 min · $35.41
  11. baseThe agent started from the untrained Qwen2-VL-2B floor32.5$3.08

On the hidden set

Original metricNormalised score
Starter14.210.0
Frontier-calibrated reference86.530.6
Upper100.01.0
This run (Opus 5)86.10.5964
353 minWall clock
$12.17Spend
70.9MTokens
6Versions, 3 kept

On the visible set

10 15 20 25 30 35 0 2 3 4 Agent step OOD val accuracy (visible ood_va ↓ v0 v1 v2 v3 v4 v5
keptrolled backsubmitted
  1. v0The agent measured the untrained base model as its floor10.4
  2. v1The agent ran baseline GRPO with only a format reward19.4
  3. v2The agent added accuracy, proximity and reasoning rewards and aligned the prompt25.8
  4. v3The agent added a keyword reasoning bonus that triggered repetition loops15.5
  5. v4The agent added an anti-repetition trigram filter and raised beta23.6
  6. v5The agent widened the sampling group and enforced concise clean reasoning35.1

On the hidden set

Original metricNormalised score
Starter14.210.0
Frontier-calibrated reference86.530.6
Upper100.01.0
This run (Gemini 3.7 Flash)35.570.1772
463 minWall clock
$7.14Spend
10.6MTokens
11Versions, 7 kept

On the visible set

7.5 15.0 22.5 30.0 37.5 45.0 0 2 5 8 10 Agent step Ood_val accuracy (full 1000 wher ↓ v2-ck80->submission v2-sweep v3-sweep v4-sweep base
keptrolled backsubmitted
  1. v1The agent trained with a grader-aligned integer reward and killed the collapsing runkilled at step 55$1.46
  2. v2The agent mixed paraphrase and removal questions and checkpointed every forty stepsstill training$1.98
  3. v2-ck80->submissionThe agent promoted checkpoint eighty to the submission44.2$4.17
  4. v2-fixThe agent patched the saved generation config that crashed evaluationbug fix, not scored$2.71
  5. v2-sweepThe agent swept the v2 checkpoints and found step eighty best43$3.44
  6. v3The agent refined the data mix and annealed the learning ratestill training$4.89
  7. v3-sweepThe agent swept the annealed checkpoints and found them all worse39.3$5.34
  8. v4The agent re-ran the v2 mix with annealing to isolate the schedulestill training$5.79
  9. v4-sweepThe agent swept the v4 checkpoints and confirmed annealing lowered the peak39$6.46
  10. v5_final_recipeThe agent finalized the winning recipe in the main codesame as v2-ck80$6.46
  11. baseThe agent measured the untrained base model as its floor9.9$0.73

On the hidden set

Original metricNormalised score
Starter14.210.0
Frontier-calibrated reference86.530.6
Upper100.01.0
This run (Kimi K3)44.230.2491
405 minWall clock
$15.92Spend
28.2MTokens
8Versions, 4 kept

On the visible set

30 40 50 60 70 80 0 2 3 4 6 Agent step Mean of val and ood_val accuracy ↓ v1 v3 v4 v5 v5 soup v6 v7 floor
keptrolled backsubmitted
  1. v1The agent aligned prompt and rewards to the grader and fixed sampling collapse63.75
  2. v3The agent mixed paraphrases, negations and zero-count questions and shortened completions66.75
  3. v4The agent added SuperCLEVR-like tautology and zero-count question syntax70
  4. v5The agent dropped the conciseness reward and raised the token cap76
  5. v5 soupThe agent averaged the two best v5 checkpoints76.25
  6. v6The agent raised beta and blocked the useful drift63
  7. v7The agent re-ran the v5 recipe with a different seed72.25
  8. floorThe agent measured the untrained model as its floor32.75

On the hidden set

Original metricNormalised score
Starter14.210.0
Frontier-calibrated reference86.530.6
Upper100.01.0
This run (Grok 4.6)61.170.3896
85 minWall clock
$1.19Spend
11.8MTokens
1Versions, 1 kept

No comparable self-check score, so no curve — the versions below list what each one changed.

  1. v1The agent added a grader-exact accuracy reward and LoRA-tuned the language modelsmoke run, 19s/step13 min · $0.32

On the hidden set

Original metricNormalised score
Starter14.210.0
Frontier-calibrated reference86.530.6
Upper100.01.0
This run (DeepSeek V4 Pro)18.310.0340
91 minWall clock
$7.80Spend
26.7MTokens
4Versions, 3 kept

On the visible set

10 12 14 16 18 20 0 1 2 2 3 Agent step OOD val counting accuracy ↓ v0 v1-probe
keptrolled backsubmitted
  1. v0The agent measured the untrained base model as its floor10.69 min · $0.57
  2. v1The agent rewrote the reward as shaped counting and switched to LoRAprobe scored 19.429 min · $2.30
  3. v1-probeThe agent probed the new recipe with a forty-step run19.4$5.05
  4. v2The agent launched a four-hundred-step run at a higher learning ratestill training at end$5.05

On the hidden set

Original metricNormalised score
Starter14.210.0
Frontier-calibrated reference86.530.6
Upper100.01.0
This run (Qwen3.8 Max)21.270.0586
317 minWall clock
$8.29Spend
22.8MTokens
14Versions, 3 kept

On the visible set

30 45 60 75 90 0 4 8 12 Version Validation accuracy ↑ v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13
keptrolled backsubmitted
  1. v0The agent measured the untrained base model as its floor33$0.66
  2. v1The agent trained thirty-five steps with resolution augmentation on70.12$1.63
  3. v2The agent turned resolution augmentation off at step thirty-five65.25$1.93
  4. v3The agent enforced a strict single think-answer format through step forty68.38$2.24
  5. v4The agent added a KL tether and evaluated step sixteen64$2.54
  6. v5The agent required a substantive think block and evaluated step twenty-four68.12$5.57
  7. v6The agent trained the substantive-think variant to step thirty-two57.12$5.57
  8. v7The agent added appearance augmentation and evaluated step sixteen90$5.57
  9. v8The agent trained the appearance-augmented recipe to step twenty-four91.62$5.57
  10. v9The agent trained the same recipe to step thirty-two88.25$5.57
  11. v10The agent trained the same recipe to step forty89.38$5.57
  12. v11The agent added question paraphrasing and evaluated step sixteen85.03$5.57
  13. v12The agent added question paraphrasing and evaluated step twenty91.15$5.57
  14. v13The agent strengthened the augmentations and evaluated step twenty-four83.63$5.57

On the hidden set

Original metricNormalised score
Starter14.210.0
Frontier-calibrated reference86.530.6
Upper100.01.0
This run (GLM 5.3)86.530.6000
126 minWall clock
$12.83Spend
18.9MTokens
10Versions, 3 kept

On the visible set

0 20 40 60 80 0 30 60 90 120 Agent step Ood_val accuracy ↓ v0 v4 v5 v6 v7 v8 v9
keptrolled backsubmitted
  1. v0The agent measured the untrained base model as its floor6.253 min · $0.59
  2. v1The agent rewrote rewards and hyperparameters but the training port was takenport 12345 in use14 min · $1.57
  3. v2The agent fixed the port but DeepSpeed ZeRO-3 crashed with LoRAZeRO-3 + LoRA crash14 min · $1.81
  4. v3The agent dropped DeepSpeed but flash-attention still saw fp32 vision tensorsdtype ignored, crashed18 min · $2.35
  5. v4The agent forwarded bfloat16 into the trainer and finished the first run42.519 min · $2.69
  6. v5The agent shortened and weakened the reinforcement run28.539 min · $4.15
  7. v6The agent stopped the high-learning-rate run early at eighty steps6056 min · $5.42
  8. v7The agent cut the run to sixty steps8668 min · $6.75
  9. v8The agent cut the run further to fifty steps4992 min · $9.46
  10. v9The agent removed the proximity reward46115 min · $11.27

On the hidden set

Original metricNormalised score
Starter14.210.0
Frontier-calibrated reference86.530.6
Upper100.01.0
This run (GPT-5.5)86.480.5996

Leaderboard

Where each run landed on the sealed held-out set, on the same normalised-score scale as the anchors above.

0 0.3 0.6 1.0 1 GLM 5.3 claude code · max 0.600 2 GPT-5.5 codex · xhigh 0.600 3 Opus 5 claude code · max 0.596 4 Grok 4.6 grok · xhigh 0.390 5 Kimi K3 kimi cli · max 0.249 6 Gemini 3.7 Flash antigravity · high 0.177 7 GPT-5.6-sol codex · max 0.059 8 Qwen3.8 Max qwen coder · xhigh 0.059 9 DeepSeek V4 Pro claude code · max 0.034