Research log Small Model Experimentation
GitHub

Qwen Action-Conditioned VM-ECHO Policy Iteration

Learning to judge its own code barely helped

The one idea you need

The model writes a tiny program to solve each puzzle, then runs every draft in a sandbox to watch what it computes. A second model grades those drafts by their consequences, trying to pick the one whose output actually answers the puzzle.

The question

If a model can run each of its draft programs and watch what they compute, can it learn to pick the correct one and get better at writing them?

What we found

Barely. Learning to grade drafts by their run results nudged picking accuracy only from about 10% to 11%, far short of the 37% reachable by always choosing the best available draft. It reliably picked programs that ran, just not ones that were correct. Yet feeding even those imperfect picks back still lifted directly-written program accuracy from 18% to 23%.

Why it matters

When a small model self-improves by running its own candidate answers, the bottleneck isn't generating candidates or reusing good ones — it's the judge. Invest in teaching it to compare rival candidates, not to polish its own writing.

Picking the right program10% → 11%accuracy after learning to grade its own drafts
Best it could pick if flawlessabout 37%how often a correct draft was among the options
Writing correct programs directly18% → 23%gain from reusing its imperfect picks
Ceiling when shown the answers82%same task with full correct-answer supervision
On this page
  1. Results at a glance
  2. Overview
  3. Report
    1. Abstract
    2. Setup
    3. Main Results
    4. Learned Candidate Selection
    5. Policy-Distillation Targets
    6. Training Dynamics
    7. Threshold Pilot
    8. Interpretation
    9. Artifacts
  4. Experiment log
  5. Figures
  6. Data files
  7. Reproduce
  8. Related

Results at a glance 5

Writing correct programs directly, across training methods

How to read

Each cluster is a family of puzzles; taller bars mean more solved by writing one program with no retries. The four bars are the frozen starting model, two ways of reusing its own drafts, and a model simply shown the correct answers.

0%25%50%75%100%fresh pairedfresh pairedfresh paraphrasefresh paraphrasefresh standardfresh standardhard compositionhard composition

Takeaway → The reuse bars hover right around the starting model — sometimes a touch above, often a touch below — while the shown-answers bar towers far above, so self-teaching helps only slightly.

Data table
Held-out splitseed (frozen compiler)learned-selector distillanswer-verified distillfull supervision (ceiling)
fresh paired18%22.7%16.4%82%
fresh paraphrase15.6%14.8%14.8%72.7%
fresh standard14.8%19.5%18%69.5%
hard composition14.8%15.6%12.5%51.6%

Numbers from analysis/main_metrics.csv

Technical framing

Direct bytecode-emission accuracy by training phase — Distilling on learned-selected candidates gives modest direct gains (18.0->22.7% on fresh paired), far below the full-supervision ceiling.

Solving puzzles when allowed to try several drafts

How to read

Each cluster is a family of puzzles; taller bars mean more solved when the model may generate and test several drafts and keep a working one. Bars compare the starting model against two ways of reusing its own drafts.

0%20%40%60%80%fresh pairedfresh paired51.6%64.1%57%fresh paraphrasefresh paraphrase35.2%43%48.4%fresh standardfresh standard44.5%52.3%57%hard compositionhard composition35.2%52.3%48.4%

Takeaway → Reusing drafts helps most here — the hardest puzzle family rises from 35% to 52% solved — even though the drafts were picked imperfectly.

Data table
Held-out splitseed (frozen compiler)learned-selector distillanswer-verified distill
fresh paired51.6%64.1%57%
fresh paraphrase35.2%43%48.4%
fresh standard44.5%52.3%57%
hard composition35.2%52.3%48.4%

Numbers from analysis/main_metrics.csv

Technical framing

Answer-search accuracy: distillation gains are largest under search — Even imperfect learned targets help most under candidate search: hard-composition search rises from 35.2% to 52.3%.

How often the chosen program is actually correct

How to read

Bars group practice puzzles and fresh ones; taller means the chosen draft is correct more often. Three bars per group: the model's raw hunch, its learned grader, and the score if it always grabbed its best available draft.

0%20%40%60%training candidatestraining candidates15.2%14.6%40.7%validation candidatesvalidation candidates10.2%10.9%36.7%

Takeaway → The learned grader barely differs from the raw hunch while the best-possible bar sits far higher, showing weak judgment is the real bottleneck.

Data table
Candidate setbase (compiler logprob)learned selectororacle (best candidate)
training candidates15.2%14.6%40.7%
validation candidates10.2%10.9%36.7%

Numbers from analysis/main_consequence_selection_eval.csv

Technical framing

Learned consequence selector roughly matches compiler logprob, far from oracle — The selector recovers almost none of the oracle gap (10.2% -> 10.9% vs 36.7% oracle), so selector precision is the bottleneck.

Being pickier about which drafts to reuse

How to read

Two puzzle families; taller bars mean more solved by direct writing afterward. Bars compare reusing every draft against keeping only the higher-scoring drafts.

0%5%10%15%fresh pairedfresh paired6.2%9.4%hard compositionhard composition12.5%12.5%

Takeaway → Keeping only higher-scoring drafts raises fresh-puzzle accuracy, showing the quality of the reused drafts matters more than their quantity.

Data table
Pilot splitthreshold 0.0 (all targets, 12.5% precision)threshold 0.7 (filtered, 24.6% precision)
fresh paired6.2%9.4%
hard composition12.5%12.5%

Numbers from analysis/pilot_threshold_comparison.csv

Technical framing

Pilot: higher target threshold trades volume for precision — Filtering learned targets at score 0.7 halves target count but doubles precision and improves pilot fresh-paired direct accuracy.

Direct solving per puzzle family, self-teaching vs shown answers

How to read

Each cluster is a puzzle family; taller bars mean more solved by writing directly. Four bars: the starting model, two self-teaching methods, and a model shown correct answers.

0%25%50%75%100%fresh_pairedfresh_pairedfresh_standardfresh_standardfresh_paraphrasefresh_paraphrasehard_compositionhard_compositionval_mixedval_mixed

Takeaway → Self-teaching bars edge only a few points above the start, dwarfed by the shown-answers bars reaching 52 to 82%.

Data table
Evaluation splitSeed supervisedLearned-policy distillAnswer-verified distillFull supervised (ceiling)
fresh_paired18%22.7%16.4%82%
fresh_standard14.8%19.5%18%69.5%
fresh_paraphrase15.6%14.8%14.8%72.7%
hard_composition14.8%15.6%12.5%51.6%
val_mixed10.2%11.7%12.5%74.2%

Numbers from experiments/qwen_action_conditioned_vm_echo_policy_iteration/analysis/main_metrics.csv

Technical framing

Per-split direct emission: self-distillation gains are tiny next to the full-supervision ceiling — Distilling self-generated candidates lifts direct emission by a few points at most; full supervision reaches 52-82% on the same splits.

In the author’s words from the Report · “Abstract”

The learned consequence selector did not close the oracle gap in the main run: on validation candidates it moved from 10.2% base top-1 accuracy to 10.9%, with an oracle of 36.7%. However, filtered learned-policy distillation still improved the compiler on several generalization splits. Fresh-paired direct accuracy increased from 18.0% to 22.7%, and hard-composition answer-search accuracy increased from 35.2% to 52.3%. The fully supervised ceiling remained much higher: fresh-paired direct accuracy reached 82.0%.

Overview

This standalone experiment tests whether a frozen-Qwen bytecode compiler can improve by learning the consequences of its own generated candidate programs.

Hypothesis

If the model proposes a candidate bytecode program, executing that candidate in the VM gives dense action-conditioned feedback: validity, final value, stack trace, and whether the candidate solves the prompt. A consequence model trained on those observations should rank candidates better than raw compiler logprob, and distilling the best learned candidates back into the compiler should improve direct bytecode emission.

Layout

  • src/typed_bytecode_core.py: standalone task generator, bytecode VM, typed decoding, and candidate search.
  • src/qwen_action_conditioned_vm_echo_policy_iteration_experiment.py: Qwen feature extraction, compiler training, candidate generation, consequence model training, learned reranking, and policy distillation.
  • src/analyze_qwen_action_conditioned_vm_echo_policy_iteration.py: aggregate metrics, charts, Markdown report, and HTML report.
  • runs/: per-run manifests, logs, and metrics.
  • analysis/: aggregate CSVs and figures.
  • reports/: final writeups.
  • large_artifacts/qwen_action_conditioned_vm_echo_policy_iteration/checkpoints/: checkpoints kept outside the experiment directory.

Primary Metrics

  • Greedy direct executable accuracy.
  • Learned candidate-selection accuracy.
  • Answer-verified oracle/search accuracy.
  • Oracle gap recovered by learned consequence ranking.
  • Distilled compiler direct accuracy after training on learned-selected candidates.

Report

Rendered from reports/qwen_action_conditioned_vm_echo_policy_iteration_report.md

Abstract

This experiment tests a candidate-conditioned route from program search to better direct program emission. A frozen-Qwen compiler first proposes typed bytecode candidates. A consequence model then receives the prompt representation and a candidate program, and learns from VM execution labels: validity, final value, stack trace, and whether that candidate solves the prompt. The learned selector is then used to choose policy-distillation targets for the compiler.

The main result is mixed. The learned consequence selector did not close the oracle gap in the main run: on validation candidates it moved from 10.2% base top-1 accuracy to 10.9%, with an oracle of 36.7%. However, filtered learned-policy distillation still improved the compiler on several generalization splits. Fresh-paired direct accuracy increased from 18.0% to 22.7%, and hard-composition answer-search accuracy increased from 35.2% to 52.3%. The fully supervised ceiling remained much higher: fresh-paired direct accuracy reached 82.0%.

Setup

  • Base model: Qwen/Qwen3-4B, used only as a frozen hidden-state feature extractor.
  • Seed examples: 192.
  • Candidate-training prompts: 1024.
  • Full-supervised examples: 1024.
  • Fresh split size: 128.
  • Candidate search: top-k 3, second-order argument pairs 8, max candidates 256.
  • Learned-target threshold: 0.7.
  • Checkpoints: large_artifacts/qwen_action_conditioned_vm_echo_policy_iteration/checkpoints/main_action_vm_echo_s192_thr070/.

Main Results

PhaseSplitDirectAnswer searchOracleLearned selectorProgram exact
Seedfresh_paired18.0%51.6%51.6%0.8%
Seedfresh_paraphrase15.6%35.2%35.2%3.1%
Seedfresh_standard14.8%44.5%44.5%2.3%
Seedhard_composition14.8%35.2%35.2%1.6%
Learned distillfresh_paired22.7%64.1%64.1%17.2%3.1%
Learned distillfresh_paraphrase14.8%43.0%43.0%7.0%0.8%
Learned distillfresh_standard19.5%52.3%52.3%17.2%3.1%
Learned distillhard_composition15.6%52.3%52.3%13.3%1.6%
Answer distillfresh_paired16.4%57.0%57.0%18.8%0.8%
Answer distillfresh_paraphrase14.8%48.4%48.4%13.3%2.3%
Answer distillfresh_standard18.0%57.0%57.0%18.8%4.7%
Answer distillhard_composition12.5%48.4%48.4%14.1%0.0%
Full sup.fresh_paired82.0%94.5%94.5%32.0%70.3%
Full sup.fresh_paraphrase72.7%90.6%90.6%30.5%57.0%
Full sup.fresh_standard69.5%85.9%85.9%28.1%46.9%
Full sup.hard_composition51.6%79.7%79.7%28.9%28.9%

Main accuracy

Learned Candidate Selection

The action-conditioned selector learned a real but weak signal. It selected mostly valid programs, but it did not reliably select answer-correct programs at main scale.

Training candidate set:

  • Groups: 1024 prompts.
  • Candidates: 246910 programs.
  • Positive candidate rate: 9.3%.
  • Prompts with at least one positive candidate: 40.7%.

Learned rerank gap

Policy-Distillation Targets

phasetargetsoracle_found_rateselected_correct_rateselected_valid_ratechanged_ratemean_selected_score
learned_policy47040.7%28.9%99.6%100.0%0.884
answer_verified41740.7%100.0%100.0%62.6%

The learned selector chose more targets than answer verification, but with much lower known precision. The useful signal is that even imperfect learned targets improved some direct and search metrics, suggesting that consequence-conditioned filtering is not useless. The limiting factor is selector precision.

Target selection

Training Dynamics

Consequence training

Threshold Pilot

A small threshold sweep was used to avoid using every learned-selected target. The higher threshold traded volume for precision and produced better pilot direct accuracy.

Pilot threshold comparison

Interpretation

The candidate-conditioned objective is closer to the desired mechanism than target-trace-only supervision: it asks what a proposed program will do, not only what the correct program should look like. But this implementation still underfits the hardest part: comparing candidate consequences to the prompt-implied answer. The next improvement should strengthen the selector, not the compiler head. Good next changes are pairwise preference training over candidates from the same prompt, harder negative mining, and using the compiler's answer representation directly inside the consequence model.

Artifacts

Experiment log 5

Show the running log (5 entries, 2026-06-24)

2026-06-24

  • Created a fresh standalone experiment directory.
  • Selected intervention: action-conditioned VM-ECHO policy iteration.
  • Core idea: generate candidate bytecode programs from a frozen-Qwen compiler, execute those candidates in the VM, train a consequence model on candidate observations, then distill consequence-selected candidates back into the compiler.
  • Large artifacts will be stored in large_artifacts/qwen_action_conditioned_vm_echo_policy_iteration/checkpoints/.

Implementation Notes

  • Built src/qwen_action_conditioned_vm_echo_policy_iteration_experiment.py.
  • Built src/analyze_qwen_action_conditioned_vm_echo_policy_iteration.py.
  • Reused the typed bytecode VM core as local experiment source in src/typed_bytecode_core.py, with checkpoint paths redirected to the experiment-specific large-artifact directory.
  • Added checkpoint tracking in checkpoint_manifest.csv.
  • Generated both Markdown and HTML reports under reports/.

Iteration Record

  • smoke_action_vm_echo: verified that Qwen feature extraction, candidate generation, consequence training, target selection, distillation, metrics, and checkpoint writing all run end to end.
  • pilot_action_vm_echo_s96: exposed two bookkeeping issues: inconsistent target-selection CSV schemas and quick validation using the wrong prompt feature set.
  • Patched the target-selection schema, fixed quick-validation prompt features, and restored the best quick-validation consequence checkpoint before target selection.
  • pilot_action_vm_echo_s96_v2: unfiltered learned target selection chose all available candidates and had low target precision.
  • pilot_action_vm_echo_s96_thr070: tested a 0.7 learned-score threshold. It selected fewer targets with higher known correctness and improved pilot direct accuracy, so the threshold was used for the main run.
  • main_action_vm_echo_s192_thr070: completed the scaled run with 192 seed examples, 1024 candidate-training prompts, 1024 full-supervised examples, and 128-example validation/fresh/hard splits.

Main Result

  • Validation selector gap: base top-1 10.2%, learned selector 10.9%, candidate oracle 36.7%.
  • Learned-policy distillation improved several downstream splits despite weak learned selection: fresh-paired direct 18.0% -> 22.7%, fresh-paired answer search 51.6% -> 64.1%, hard-composition answer search 35.2% -> 52.3%.
  • Fully supervised training remained the practical ceiling: fresh-paired direct 82.0%, fresh-paired answer search 94.5%, hard-composition direct 51.6%.
  • Main conclusion: the candidate-conditioned learning signal is real but still too weak. The next experiment should target selector precision with pairwise preference training, harder negatives, or direct answer-representation access.

Final Artifacts

  • Markdown report: reports/qwen_action_conditioned_vm_echo_policy_iteration_report.md.
  • HTML report: reports/qwen_action_conditioned_vm_echo_policy_iteration_report.html.
  • Analysis summary: analysis/summary.md.
  • Figures: analysis/figures/.
  • Checkpoints: large_artifacts/qwen_action_conditioned_vm_echo_policy_iteration/checkpoints/.

Figures 5

consequence training
consequence training · analysis/figures/
learned rerank gap
learned rerank gap · analysis/figures/
main accuracy by phase
main accuracy by phase · analysis/figures/
pilot threshold comparison
pilot threshold comparison · analysis/figures/
target selection
target selection · analysis/figures/

Data files 19

Result tables and metrics copied from the experiment folder — preview inline or open the raw file.

Reproduce

This entry is source code or analysis only — there is no separate run to reproduce.

Browse the experiment folder on GitHub ↗