VLM · OPD Frank Yang2026

Independent research project · on-policy distillation · Qwen3-VL

Teach a small vision-language model on its own mistakes

On-policy distillation lets a 2B student learn from an 8B teacher on the states the student actually visits. On ChartQA, 300 questions of OPD match supervised distillation on 3,000 (three seeds), and a token-level analysis shows the teacher's feedback lands on answers and format long before it lands on what the model reads off the chart.

Code Measurement log Frank Yang Georgia Tech · Sept 2026 Colab A100 40 GB · PACE L40S

Relaxed accuracy · 500 held-out questions95% CI

0.668
Student
zero-shot
0.834
SFT
3,000 questions
0.827
OPD
300 questions · 3 seeds
0.844
Teacher
zero-shot
01Motivation

Supervised distillation is behavior cloning, and behavior cloning compounds its errors

DAgger (Ross et al., 2011) → GKD / OPD (Agarwal et al., 2024) → this project

Fine-tuning a student on teacher outputs only ever shows it the states the teacher visited. At inference the student drifts, enters states it never trained on, and its mistakes compound: regret grows quadratically in the sequence length, O(T²ε). Long chain-of-thought reasoning has a large T, so this is exactly where the problem bites.

DAgger's fix is to let the student act and then ask the expert what it should have done in the states the student actually reached, which brings regret down to O(Tε). A teacher language model can be queried this way for free: the student samples a solution, the teacher scores every generated token, and training minimizes the per-token KL between the two. That is on-policy distillation.

OPD only touches the distribution over text tokens. For a vision-language model the image is just part of the prefix, so the method should transfer. This project checks whether it does, whether the data-efficiency claim survives, and, since the prefix now contains a chart, where the teacher's feedback actually lands.

02Setup

One student, one teacher, one GPU, one fixed test set

Everything below is scored the same way: relaxed accuracy on the same 500 human-written ChartQA questions; seeds change only the training data order and rollout sampling.

Student

2B
Qwen3-VL-2B-Instruct · LoRA r=64 on the language model · 69.7M trainable (3.17%) · vision tower frozen

Teacher

8B
Qwen3-VL-8B-Instruct · same tokenizer, so the KL is exact over the full vocabulary

Data

3,000 / 500
ChartQA human-written questions · images capped at 768 px → 300 to 600 visual tokens

Scoring: numeric answers within 5% relative error, text answers exact after normalization, and a missing Answer: line counts as wrong. Every number carries a percentile bootstrap interval; comparisons between two systems use a paired bootstrap over the same questions, which is far tighter than comparing two independent intervals.

Why human-written questions only. On a random ChartQA mix, three quarters machine-generated, the 2B student already scores 0.84 zero-shot against 0.90 for a 4B teacher: too little headroom to separate any two methods. Human questions open a 17.6-point gap between student and teacher.

03Finding 1

OPD reaches full-data SFT accuracy with 10% of the questions

Both methods see the first N questions of the same train set. Update counts are fixed across budgets: SFT 302 steps, OPD 150 steps × 16 rollouts.

Accuracy vs. training questions

SFTOPDteacherzero-shot

Hover a point for its interval. Log-scaled x axis. Numbers regenerated from the result files on the Hub.

Training questionsSFTOPDOPD − SFT, paired 95% CI
100 (3%) · 4 seeds0.793 [0.775, 0.810]0.811 [0.794, 0.829]+0.018 [+0.004, +0.034]
300 (10%) · 3 seeds0.799 [0.782, 0.817]0.827 [0.807, 0.845]+0.029 [+0.013, +0.046]
900 (30%)0.808 [0.774, 0.842]0.820 [0.786, 0.854]+0.012 [−0.016, +0.040]
3,000 (100%)0.834 [0.802, 0.866]0.824 [0.790, 0.858]−0.010 [−0.036, +0.016]

The 100-question point is averaged over four seeds and the 300-question point over three (seed = data order and rollout sampling; the test set is fixed), with intervals pooled over questions and deltas paired by seed. OPD leads by 1.8 and 2.9 points and both intervals exclude zero. OPD on 100 questions (0.811) matches SFT on 900 (0.808). The first single-seed run had shown +5.8 at 300 questions; that seed turned out to be the weakest of four SFT draws, so the multi-seed estimate is the one to quote. OPD's across-seed spread (sd 0.008 to 0.009) is about half of SFT's (0.015 to 0.022).

04Finding 2

With enough data both methods saturate at the teacher

The expected shape, and the honest one.

At 900 and 3,000 questions the paired differences are +1.2 and −1.0 points, both inside their intervals. The full-data SFT student is already within one point of the 8B teacher, so there is nothing left for OPD to add on this task with this teacher. Separating the methods at full data would need a stronger teacher or a harder test set, not more steps.

Two caveats stated plainly. The 900- and 3,000-question points are single-seed. The 3,000-question OPD run covers each question less than once (2,400 rollouts), so it is undertrained relative to SFT's two epochs; the fixed-update design was deliberate, but it favours SFT at the largest budget.

05Finding 3

The teacher's feedback lands on the answer line first, not on the digits read off the chart

100 test questions, rollouts sampled at temperature 1.0, every generated token scored by both models. Concentration = share of KL ÷ share of tokens.

Where the teacher's KL mass lands, by token role

share of tokensshare of teacher feedback (KL mass)× = concentration
Token classZero-shot: tokens → KLConcentrationAfter OPD-300
answer line7.3% → 19.5%2.67×0.38×
text (connectives, format, words)74.8% → 73.9%0.99×1.24×
chart values (digits outside arithmetic)7.4% → 2.9%0.39×0.73×
arithmetic (digits and operators)10.5% → 3.7%0.36×0.42×
mean KL per token0.4890.235

Before training the teacher disagrees most where the student commits to an answer and where it chooses a format. The trained student switches to the teacher's Step 1: layout and the answer-line disagreement almost disappears. Digits get less feedback than their length would predict for two reasons visible in the heatmaps: both models condition on the same image, and numbers are tokenized digit by digit with the disagreement sitting on the first digit, which per-token averaging dilutes. What remains after OPD is mostly perception, not answer selection.

This is the premise of several 2026 papers that vanilla OPD under-weights visual grounding and propose re-weighting; the measurement here is an independent, cheaper way of seeing the same thing.

Token heatmap of a zero-shot student solution coloured by per-token reverse KL
Zero-shot student on test question 34. Background intensity is the per-token reverse KL; the underline colour is the token role.
Token heatmap of the OPD-300 student on the same question, same colour scale
The OPD-300 student on the same question and colour scale: shorter, in the teacher's format, with far less disagreement outside the numbers.
06Engineering

The method transfers; the engineering is where the work is

Measured on an A100 40 GB. Per OPD step at batch 16: rollout 15 to 47 s, teacher forward 1 s, student forward-backward 3.5 s, peak 27 GB.

Image tokens never enter the loss

A chart is 300 to 600 visual tokens in the prompt. The SFT collator and the OPD trainer mask every prompt and image position; only generated text up to the end-of-turn token is supervised or scored.

One image tensor, two models

The processor runs once per batch. Teacher and student receive identical pixel tensors and the identical token sequence.

Resolution is the memory knob

Capping the longer side at 768 px is what makes teacher, student, optimizer and activations fit in 27 GB.

Left-padded rollouts + logits_to_keep

Every generation starts at the same index, so both models compute logits only for the generated span: about 1.2 GB per model instead of logits over the image positions too.

Rollout, not scoring, is the cost

Decoding is latency-bound, so a larger rollout batch is nearly free. Batch 16 doubled throughput at the same memory as batch 8.

Disconnect-safe training

Adapter, optimizer, scheduler and data cursor go to the Hub every 25 steps with a pointer file. A real Colab disconnect at step 75 resumed and finished without repeating a batch.
RunCost
Evaluate 500 questions with vLLM12 s (2B) · 36 s (8B) · ~3 min engine start
Sample and verify teacher solutions, 3,000 questionsminutes · 80.1% kept
SFT, 302 steps, effective batch 1612 min · 2.3 s/step
OPD, 150 steps, batch 16~90 min · 35 s/step · peak 27 GB
07Limits

What this does not show

Kept short on purpose.
  • One task, one model family. The low-data result now rests on three to four seeds at two budgets; the saturation points are still single-seed, and a second task (Geometry3K) and out-of-distribution chart sets are in progress.
  • Token roles are heuristic (line-level cues and digit detection); the "text" class mixes structural tokens with reasoning words.
  • Only the vanilla OPD objective was run. The 2026 re-weighted variants (visual-advantage weighting, gradient steering, Fisher projection) are not compared.
  • Full-data results are ceiling-limited by an 8B teacher on ChartQA.
08Context

Where this sits in 2026

A small, fully reproducible replication with one measurement that corroborates the motivation of the re-weighting papers.
09Reproduce

Five Colab notebooks, zero local state

About 1,500 lines of Python, 53 CPU tests including a full OPD step on a tiny Qwen3-VL, CI on every push.

Each notebook is generated from a script in the repository, clones the repo, reads the HuggingFace token from Colab Secrets, and pushes every artifact (sampled data, verified teacher solutions, LoRA checkpoints, merged models, result JSON) to private Hub repos. Nothing lives on Drive or on the Colab disk.

uv venv && source .venv/bin/activate
uv pip install -e ".[dev]"
uv pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu
uv pip install transformers peft
pytest