Research log Small Model Experimentation
GitHub

Qwen3.5-4B Depth Scaling & Controls: saturation, data-vs-compute, depth-4

Variety keeps teaching, repetition barely helps

The one idea you need

A tireless robot bolts together the tools in its kit until it finds combinations that solve a puzzle, then writes each solution into a cookbook the model studies. What teaches the model is how many DIFFERENT recipes fill the cookbook, not how often it rereads them.

The question

When you teach a small model from a solver's worked solutions, does piling on more eventually stop helping, and is it the variety or just the extra training that matters?

What we found

Variety, decisively, and the gains never plateaued. Rereading the same 40 solved examples sixteen times over barely moved the solve rate (9% to 16%, within noise), but replacing them with more distinct examples at the exact same training cost jumped it (16% to 38%). And coverage kept climbing to 54% as distinct examples grew past a thousand, with no ceiling in sight.

Why it matters

When self-training a small model on a solver's verified solutions, spend your budget harvesting more DISTINCT solved problems, not more passes over the ones you have. Track distinct-solution count as the real lever, and keep collecting, because the curve never flattened.

More training, same 40 examples9% → 16%solve rate barely moved (within noise)
More variety, same training cost16% → 38%solve rate, a clean real jump
Kept climbing, no plateauup to 54%solve rate through 1,156 distinct examples
One rung deeper worked weakly7% → 18%harder-puzzle coverage, but first-try stayed flat at 3%
On this page
  1. Results at a glance
  2. Overview
  3. Report
    1. Summary
    2. Research Program Fit
    3. Method
    4. Pre-registered verdicts
    5. Honest limits
    6. Next Experiments
    7. Artifact Manifest
  4. Experiment log
  5. Figures
  6. Data files
  7. Reproduce
  8. Related

Results at a glance 3

Solve rate keeps rising as more distinct solved problems are banked

How to read

The horizontal axis is the number of distinct solved problems banked, from 39 up to 1,156. The upper line is the share solved within 16 tries; the lower line is the share solved on the very first try. Up and to the right is better.

0%20%40%60%5001000depth-3 think coverage@16depth-3 think cov…think single-shot greedy@1 (deployable)think single-shot…

Takeaway → Both lines climb steadily to the last point with no bend toward flat, so the model keeps gaining and there is still headroom past 1,156 distinct examples.

Data table
distinct depth-3 functions banked (N=40/160/640/1280 tool-pairs)depth-3 think coverage@16think single-shot greedy@1 (deployable)
398.7%1.3%
15321.2%3.7%
55537.5%13.8%
115653.7%18.8%

Numbers from

Technical framing

No saturation through 1280: depth-3 coverage keeps rising with distinct tool-found functions — C23 showed the depth-3 install is data-limited; this extends the dose curve. Coverage@16 climbs 0.087->0.212->0.375->0.537 at 39/153/555/1156 DISTINCT depth-3 functions (N=40/160/640/1280 tool-pairs), and deployable single-shot greedy@1 rises to 0.188 -- NO saturation through 1156 distinct functions. Distinct functions grow near-linearly with pairs, so this is real capacity, not running out of functions to harvest. (Adjacent-dose Wilson CIs marginally overlap at n=80; the overall trend is unmistakable. 2560 dose dropped: training ran 2x slower than budgeted.)

Variety beats extra training at the same cost

How to read

Three bars show the share of unseen puzzles solved within 16 tries: 40 examples trained briefly, the same 40 trained sixteen times harder, and a larger, more varied set at that same heavy training. Taller is better.

0%10%20%30%40%N=40 (40 funcs, 120 visits)N=40 (40 funcs, 120 visits)8.7%up40 (40 funcs, 1920 visits)up40 (40 funcs, 1920 visits)16.3%train_640 (640 funcs, 1920 visits)train_640 (640 funcs, 1920 visits)37.5%

Takeaway → The middle bar barely clears the left one (more training, no real gain), but the right bar more than doubles it at equal cost, so variety is the lever.

Data table
conditiondepth-3 coverage@16
N=40 (40 funcs, 120 visits)8.7%
up40 (40 funcs, 1920 visits)16.3%
train_640 (640 funcs, 1920 visits)37.5%

Numbers from

Technical framing

The gain is data-DIVERSITY, not compute (2x2 at matched steps/mixture) — Deconfounding C23's 'more data' gain. Holding compute/mixture fixed and adding DIVERSITY (up40->train_640, both 1920 depth-3 example-visits, 40 vs 640 distinct functions): 0.163->0.375 -- CLEANLY significant (non-overlapping Wilson CIs). Holding diversity fixed and adding COMPUTE (N=40->up40, same 40 functions, 120->1920 visits): 0.087->0.163 -- positive but WITHIN NOISE (overlapping CIs). So the gain is genuinely data-DIVERSITY-driven: banking more DISTINCT explorer-found functions, not just more gradient steps.

One rung deeper: extra examples lift coverage but not first-try success

How to read

For harder, deeper puzzles, three models each show two bars, solved-within-16-tries and solved-on-first-try. Left is the untrained model, middle is trained only on shallower puzzles, right adds 320 deeper examples. Taller is better.

0%5%10%15%20%raw baseraw base0%0%scaffold (640 d3, no d4 data)scaffold (640 d3, no d4 data)6.7%3.3%banked_d4 (+320 depth-4 pairs)banked_d4 (+320 depth-4 pairs)18.3%3.3%

Takeaway → Adding deeper examples nearly triples the 16-try coverage (7% to 18%), but the first-try bar stays flat at 3%, so the skill is present yet not reliable enough to deploy.

Data table
conditiondepth-4 coverage@16depth-4 single-shot greedy@1 (deployable)
raw base0%0%
scaffold (640 d3, no d4 data)6.7%3.3%
banked_d4 (+320 depth-4 pairs)18.3%3.3%

Numbers from

Technical framing

The recipe repeats one rung deeper (weakly): depth-4 installs over the depth-3 transfer baseline — Does the tool-search+banking recipe repeat one compositional rung deeper? Raw base can't do depth-4 (0.00). The depth-3 scaffold (banked_640, NO depth-4 data) already TRANSFERS to 0.067 -- so the correct attribution baseline is the scaffold, not base. Adding 320 depth-4 tool-pairs nearly TRIPLES coverage to 0.183. But deployable greedy@1 stays flat (0.033) = test-time-only, and n=60 CIs marginally overlap -- SUGGESTIVE not conclusive, the same weak stage depth-3 showed at low doses. No scaffold forgetting (depth-3 held at 0.425). A depth-4 dose ladder should strengthen it (per C23's logic).

In the author’s words from the Overview · “Results”

Arm 1: NO saturation through 1280. cov@16 0.00/0.087/0.212/0.375/0.537 at N=0/40/160/640/1280 (distinct funcs 39/153/555/1156); deployable greedy@1 -> 0.188. (Adjacent CIs marginally overlap at n=80.) Arm 2: data-DIVERSITY, not compute. N=40 0.087 -> up40 0.163 (+compute, within noise) -> train_640 0.375 (+diversity, cleanly significant). Arm 3: recipe repeats one rung deeper, weakly. base 0.00, scaffold-transfer 0.067, banked_d4 0.183 (~3x); greedy flat 0.033 (test-time-only), CIs marginally overlap at n=60. Depth-3 guardrail 0.425 (no forgetting). See reports/report.md, analysis/scaling_controls.png.

Overview

Research Program

  • Program: structured_execution_and_compilers
  • Three follow-ups to C23 (depth-3 install is data-limited): (1) does the dose curve saturate past 640? (2) is the gain data-diversity or compute? (3) does the recipe repeat one rung deeper (depth-4)?
  • Anchors: C23 (data-limited dose curve), C22 (weak crossing), C13-C21 (the recipe).

Setup

  • Model: Qwen3.5-4B only. Explorer: CPU interpreter brute-search over the 16-op DSL (no external model).
  • Arm 1: doses 640/1280 depth-3 tool-pairs (nested; 555/1156 distinct functions). Reuse C23 base/40/160/640.
  • Arm 2: banked_up40 (40 distinct x16=640 examples, matched size/mixture/steps to train_640) vs train_640 vs N=40 dose.
  • Arm 3: banked_d4 (d12+640d3+320d4) vs SCAFFOLD-only (banked_640) on a fresh depth-4 held-out set.
  • QLoRA r32/a64 epochs=3; frozen paired held-out, func-sig + op-composition dedup (0 leakage: d3 0/2305, d4 0/318).

Run

Smoke: python scripts/harvest2.py (CPU, builds all data). Full: harvest2 + train the 3 adapters + bash runs/launch_eval.sh + python scripts/analyze.py.

Results

  • Arm 1: NO saturation through 1280. cov@16 0.00/0.087/0.212/0.375/0.537 at N=0/40/160/640/1280 (distinct funcs 39/153/555/1156); deployable greedy@1 -> 0.188. (Adjacent CIs marginally overlap at n=80.)
  • Arm 2: data-DIVERSITY, not compute. N=40 0.087 -> up40 0.163 (+compute, within noise) -> train_640 0.375 (+diversity, cleanly significant).
  • Arm 3: recipe repeats one rung deeper, weakly. base 0.00, scaffold-transfer 0.067, banked_d4 0.183 (~3x); greedy flat 0.033 (test-time-only), CIs marginally overlap at n=60. Depth-3 guardrail 0.425 (no forgetting).

See reports/report.md, analysis/scaling_controls.png.

Interpretation

The C13->C24 ladder-climbing recipe is diversity-driven (banking DISTINCT explorer-found solutions) and rung-repeatable (depth-4 installs weakly over the depth-3 transfer baseline). No saturation through 1156 distinct depth-3 functions.

Knowledgebase Update

  • Program evidence: research_programs/structured_execution_and_compilers/evidence.md (C24)
  • Claim ledger: C24 added

Artifacts

  • scripts/harvest2.py, scripts/train_lora.py, scripts/eval_ladder.py, scripts/analyze.py
  • data/train_{1280,up40,d4}.jsonl, data/eval_frozen_d{3,4}.jsonl, data/tool_depth{3_2560,4}.jsonl
  • runs/eval_*.json, runs/verdict.json, analysis/scaling_controls.png, reports/{prereg,report,design_review}.md
  • Adapters (~180MB each) moved out of repo; regenerable.

Report

Rendered from reports/report.md

Summary

Three follow-ups to C23 (depth-3 install is data-limited), each hardened by an adversarial workflow review (reports/design_review.md). All on the list 16-op DSL, interpreter brute-search explorer (no external model), QLoRA r32/α64 epochs=3, frozen paired held-out deduped by function-signature AND op-composition (0 leakage verified: depth-3 0/2305, depth-4 0/318).

Arm 1 — No saturation through 1280 tool-pairs

N (depth-3 pairs)0401606401280
distinct functions0391535551156
think cov@16 (Wilson)0.000.0870.2120.375 [.28,.48]0.537 [.43,.64]
deployable greedy@10.000.0130.0370.1380.188

The depth-3 dose curve keeps climbing past 640 — cov@16 0.375 → 0.537 and deployable single-shot greedy@1 0.138 → 0.188. Distinct functions grow near-linearly (so a flat curve would be real saturation, not harvest-diversity exhaustion — it isn't flat). The data-limited regime extends at least to 1156 distinct depth-3 functions with no plateau. (Caveat: adjacent-dose Wilson CIs marginally overlap at n=80 — the overall trend is unmistakable and non-adjacent doses separate cleanly, but adjacent-point significance is not established. The 2560 dose was dropped: its training ran ~2× slower than budgeted and was blocking the eval phase.)

Arm 2 — The gain is data-DIVERSITY, not compute

A 2×2 at matched size/mixture/steps splits C23's "more data" gain:

40 distinct funcs640 distinct funcs
120 depth-3 visits0.087 (N=40 dose)
1920 visits0.163 (up40)0.375 (train_640)
  • Diversity at fixed compute (up40 → train_640, both 1920 visits): 0.163 → 0.375 — cleanly significant (non-overlapping Wilson CIs: up40 [.10,.26], train_640 [.28,.48]).
  • Compute at fixed diversity (N=40 → up40, same 40 functions): 0.087 → 0.163 — positive point estimate but within noise (overlapping CIs).

So C23's "data-limited" is genuinely data-diversity-limited: banking more distinct explorer-found functions is what drives the gain, not merely more gradient steps on the same functions.

Arm 3 — The recipe repeats one rung deeper, weakly

Depth-4 rung (cov@16, n=60), against the scaffold-only baseline (banked_640 = depth-1+2+640d3, no depth-4 data — the correct attribution reference, since depth-3 skill transfers):

raw basescaffold (640 d3)banked_d4 (+320 d4)
depth-4 cov@160.0000.0670.183
depth-4 greedy@10.0000.0330.033

Adding 320 depth-4 tool-pairs nearly triples depth-4 coverage over the transfer baseline (0.067 → 0.183, +0.116). But deployable greedy@1 stays flat (0.033) — a weak/test-time-only install, exactly the signature depth-3 showed at low doses (C22). At n=60 the Wilson CIs marginally overlap (scaffold [.03,.16] vs banked_d4 [.11,.30]), so this is suggestive, not conclusive. The depth-3 guardrail held (banked_d4 scores 0.425 on depth-3 vs the scaffold's 0.375 — no forgetting, slight improvement). By C23's logic, a depth-4 dose ladder should strengthen it.

Research Program Fit

Refines and stress-tests C23. Arm 1 shows the data-limited regime is deep (no saturation through 1156 distinct functions). Arm 2 attributes the gain to genuine data-diversity, tightening "self-training installs what the explorer finds" — it's the distinct verified solutions that matter. Arm 3 shows the whole recipe (tool-search explorer + banking installer) repeats one compositional rung deeper, at the same weak-then-scales efficiency per rung. Together: the ladder-climbing recipe is diversity-driven and rung-repeatable.

Method

scripts/harvest2.py (extend depth-3 to 2560 nesting C23's 640 excluding the held-out; upsampled-40; depth-4 harvest + held-out), scripts/train_lora.py, scripts/eval_ladder.py (func-sig + op-composition dedup + leakage report), scripts/analyze.py (Wilson CIs + CI-overlap verdicts). Reused C23's depth-3 frozen held-out

  • base/40/160/640 evals + banked_640 adapter (bit-identical → same numbers, no re-run).

Pre-registered verdicts

  • P1 (saturation): curve still rising at 1280 (0.375 → 0.537); no saturation through 1156 distinct functions (adjacent-dose significance marginal).
  • P2 (data vs compute): data-diversity dominates — diversity effect cleanly significant, compute effect within noise.
  • P3 (depth-4): recipe repeats, weakly — banked_d4 0.183 vs scaffold 0.067 (~3×), but test-time-only (greedy flat) and CIs marginally overlap at n=60; suggestive, needs a depth-4 dose ladder.

Honest limits

Single training seed at every point (Wilson CIs are eval-noise only; no seed error bars). n=60–80 underpowers adjacent-dose and depth-4 significance — point estimates are clear, adjacent CIs overlap. Fixed epochs (data confounded with gradient exposure except in the deconfounding up40 control). Depth-4 is a single dose (installs-vs-installs-a-little unresolved). 2560 dose dropped (training too slow). Harvested pairs are the search-easy tail.

Next Experiments

  • Depth-4 dose ladder (80/320/1280) to resolve installs-vs-installs-a-little and test whether depth-4 becomes deployable with more data (the C23 test one rung deeper).
  • ≥3 training seeds at the decision points (saturation top, up40, depth-4) for seed error bars.
  • Push depth-3 past 1280 with faster training to locate the eventual saturation.

Artifact Manifest

See reports/artifact_manifest.yaml. Adapters (~180MB each) moved out of repo.

Experiment log 1

Show the running log (1 entry)

Scaffold

Created as a new experiment scaffold.

Figures 1

scaling controls
scaling controls · analysis/

Data files 10

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

Reproduce

Smoke test

python scripts/harvest2.py

Full run

python scripts/harvest2.py && (train 3 adapters) && bash runs/launch_eval.sh && python scripts/analyze.py

Run steps are documented inside the experiment folder (README and scripts).

Browse the experiment folder on GitHub ↗