Research log Small Model Experimentation
GitHub

Qwen 3.5 4B Typed Sketch Synthesis

Let the model sketch, let the solver fill

The one idea you need

Instead of writing a whole corrected mini-program, the model writes a fill-in-the-blank template — a number goes here, a word there, a yes/no test here — and an automated search tries every valid way to fill the blanks, keeping only completions that pass the visible examples.

The question

When a small model has to fix a broken little program, does it work better to write the whole fix, or to sketch the shape and let a solver finish it?

What we found

It depends on difficulty. On the hardest problems, sketching the shape and letting a verified search fill the blanks lifted correct fixes from 33% to 78%, and a safe blend of both methods reached 88%. But on easy problems, forcing sketches backfired — 100% dropped to 75% — because too many blank-fillings look equally right. So trust the model's direct fix whenever it already passes every visible test.

Why it matters

Use small models for what they do reliably — spotting the output shape and coarse control flow — and hand deep detail-composition to a typed search. Guard it: only override the direct fix when its whole-program attempt fails your visible tests.

Hardest problems fixed: writing the whole program vs sketch-plus-solver33% → 78%40 of 120 versus 94 of 120 hard repairs solved
Best result on the hardest problems88%safe blend that keeps the direct fix when it passes, else uses the solver
How often the correct program was somewhere in the solver's candidatesalways (100%)so remaining misses are picking the wrong candidate, not missing coverage
Easy problems fixed when forcing sketches instead of direct fixes100% → 75%sketching hurts when many fillings pass the visible tests equally
On this page
  1. Results at a glance
  2. Overview
  3. Report
    1. Objective
    2. Method
    3. Iterations
    4. Results
    5. Interpretation
    6. Failure Modes
    7. Next Experiment
    8. Artifacts
  4. Experiment log
  5. Figures
  6. Reproduce
  7. Related

Results at a glance 2

Passing hidden tests: writing the whole fix vs sketching for a solver

How to read

Bars group by difficulty tier (easy, medium, hardest); height is the share of hidden tests passed, taller is better. Each tier shows writing the whole fix directly, the solver filling a template, the safe blend of both, and the best-possible candidate pick.

0%25%50%75%100%100%75%100%100%IID97.5%58.3%98.3%100%Support33.3%78.3%88.3%100%Ceiling

Takeaway → On the hardest tier the sketch bar reaches 78% and the safe-blend bar 88%, both towering over the short 33% direct bar; the best-possible pick sits at 100% everywhere.

Data table
evaluation splitdirect programsketch selectedconservative hybridsketch oracle
IID100%75%100%100%
Support97.5%58.3%98.3%100%
Ceiling33.3%78.3%88.3%100%

Numbers from report table (reports/qwen35_4b_typed_sketch_synthesis_report.md); backing files reports/eval/program_*.json, reports/eval/sketch_*.json

Technical framing

Hidden-case success: direct generation vs typed sketch synthesis — On the hard ceiling split, typed sketches plus a verifier lift 33% to 88%, and the oracle 100% shows remaining misses are selection, not coverage.

Hardest problem types solved: writing the fix vs filling a template

How to read

One bar pair per problem type — ten types, twelve problems each; height is how many were solved, taller is better. The two bars compare writing the whole fix directly against the solver filling a template.

051015sorted_index_sum_branch_labelsorted_index_sum_branch_label012sorted_join_contains_codesorted_join_contains_code012sum_len_mod_labelsum_len_mod_label012sum_length_mod_gate_labelsum_length_mod_gate_label09text_absent_mod_codetext_absent_mod_code124text_value_gate_labeltext_value_gate_label1210token_absent_length_codetoken_absent_length_code41token_count_mod_length_codetoken_count_mod_length_code612tuple_sum_mod_gate_labeltuple_sum_mod_gate_label610tuple_value_mod_labeltuple_value_mod_label012

Takeaway → The template bar clears whole problem types the direct bar misses entirely, though direct still edges ahead on a couple of text-matching types.

Data table
ceiling task familydirect programsketch selected
sorted_index_sum_branch_label012
sorted_join_contains_code012
sum_len_mod_label012
sum_length_mod_gate_label09
text_absent_mod_code124
text_value_gate_label1210
token_absent_length_code41
token_count_mod_length_code612
tuple_sum_mod_gate_label610
tuple_value_mod_label012

Numbers from report table (reports/qwen35_4b_typed_sketch_synthesis_report.md); backing files reports/eval/program_ceiling.json, reports/eval/sketch_ceiling.json

Technical framing

Ceiling split by task family: direct vs sketch-selected (of 12 each) — Sketch synthesis solves whole families direct generation misses entirely, while direct still wins on a few text-gating families.

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

The ceiling split is the important result. Direct program generation solved 40/120 (33.3%). Sketch synthesis selected by visible cases solved 94/120 (78.3%). The conservative hybrid solved 106/120 (88.3%). Hidden-oracle coverage was 120/120 (100.0%), which means the verifier search space contained every target program on the ceiling split.

Overview

This standalone experiment tests whether Qwen/Qwen3.5-4B can improve executable DSL repair by emitting a typed partial program that a bounded symbolic synthesizer completes and verifies on visible execution cases.

The experiment trains two fresh adapters under the same data budget:

  • program_lora: emits one complete corrected DSL expression.
  • sketch_lora: emits one typed DSL sketch with holes such as ?NUM0, ?TEXT0, and ?PRED0.

The synthesizer fills sketch holes with type-valid expressions built from the input schema, executes each completed candidate on visible cases, and reports hidden-case success plus hidden-oracle coverage inside the candidate set.

Large adapters and checkpoints are intentionally outside this compact directory:

/workspace/large_artifacts/qwen35_4b_typed_sketch_synthesis/

Layout

  • configs/experiment.json: fixed design and hyperparameters.
  • src/: standalone DSL, data, prompt, model, and typed-sketch utilities.
  • scripts/: dataset generation, training, baseline evaluation, sketch-synthesis evaluation, and report entry points.
  • data/: generated JSONL datasets and manifest.
  • reports/: evaluation JSON files, final report, and generated charts under reports/figures/.
  • logs/ and run_logs/: experiment notebook and command output.
  • large_artifacts_manifest.md: pointers to adapter directories stored outside this compact directory.

Report

Final report path after evaluation:

reports/qwen35_4b_typed_sketch_synthesis_report.md

Report

Rendered from reports/qwen35_4b_typed_sketch_synthesis_report.md

Objective

Test whether Qwen 3.5 4B can produce typed executable sketches that a verifier completes into better DSL repairs than direct program generation.

Method

  • Base model: Qwen/Qwen3.5-4B, revision 851bf6e806efd8d0a36b00ddf55e13ccb7b8cd0a.
  • Training data: 240 records for each adapter.
  • Adapters:

    • program_lora: trained to emit complete DSL programs.
    • sketch_lora: trained to emit typed sketches with ?NUM, ?TEXT, ?SEQ, and ?PRED holes.
  • Verifier:

    • Completes typed holes from a schema-derived expression bank.
    • Runs candidates on visible cases.
    • Reports selected hidden success and hidden-oracle coverage.
  • Final selection rule:

    • Keep the direct-program result if it passes every visible case.
    • Otherwise use sketch synthesis when it passes every visible case.
    • Otherwise choose the candidate with more visible passes.

Iterations

  1. Deterministic target sketches recovered the target program on all train, IID, support, and ceiling records under the planned caps.
  2. Initial model-generated sketch synthesis failed on a five-record ceiling smoke test: target synthesis was 0/5 and oracle hidden success was 0/5.
  3. Added structural abstraction variants such as (if ?PRED0 high_label low_label) and (format "X{}" ?NUM0), plus deeper numeric and predicate expression-bank entries.
  4. Changed visible-pass tie-breaking to prefer input-dependent, structurally richer candidates instead of shorter programs.
  5. Fixed candidate tag merging so targeted predicates promote generic candidates already in the bank.

Results

SplitDirect programSketch selectedSketch oracleConservative hybrid
IID60/60 (100.0%)45/60 (75.0%)60/60 (100.0%)60/60 (100.0%)
Support117/120 (97.5%)70/120 (58.3%)120/120 (100.0%)118/120 (98.3%)
Ceiling40/120 (33.3%)94/120 (78.3%)120/120 (100.0%)106/120 (88.3%)

Overall hidden success

The ceiling split is the important result. Direct program generation solved 40/120 (33.3%). Sketch synthesis selected by visible cases solved 94/120 (78.3%). The conservative hybrid solved 106/120 (88.3%). Hidden-oracle coverage was 120/120 (100.0%), which means the verifier search space contained every target program on the ceiling split.

Ceiling family breakdown:

FamilyDirectSketchOracleHybridAvg candidates
sorted_index_sum_branch_label01212122123.3
sorted_join_contains_code012121238.0
sum_len_mod_label0121212833.0
sum_length_mod_gate_label091287486.5
text_absent_mod_code12412128000.0
text_value_gate_label121012128000.0
token_absent_length_code411258000.0
token_count_mod_length_code61212118000.0
tuple_sum_mod_gate_label61012108000.0
tuple_value_mod_label01212126987.0

Ceiling by family

Candidate counts

Interpretation

Typed sketch synthesis changed the ceiling result from 40/120 to 94/120 with sketch selection alone and to 106/120 with the conservative hybrid. The oracle result of 120/120 shows that the remaining failures are not expression coverage failures; they are visible-case selection failures.

The experiment did not produce a universal training tweak by itself. It did produce a strong concrete mechanism: use Qwen 3.5 4B to identify output format and coarse control structure, then let a typed verifier search deeper compositions than the model reliably emits token-by-token.

Failure Modes

  • Sketch-alone selection is unsafe on easy splits: IID direct generation is 60/60, while sketch-alone is 45/60 because many visible-equivalent candidates exist.
  • The conservative hybrid protects solved visible-all direct outputs, but ceiling still has 14 hidden failures versus a 120/120 oracle.
  • Several families hit the 8,000-candidate cap, so runtime is still dominated by broad symbolic enumeration.
  • The expression bank is manually engineered for this DSL. The result is evidence for the typed-sketch/verifier direction, not for a domain-independent recipe yet.

Next Experiment

The next experiment should make selection adaptive: after sketch synthesis finds many visible-equivalent programs, generate new discriminating visible cases on the fly, rerun the candidates, and train or evaluate the policy on that counterexample-acquisition loop. The MDP framing is direct: state is the candidate set plus visible traces, actions request additional cases or commit to a program, and reward is verified generalization under a fixed case budget.

Artifacts

  • Compact experiment directory: /workspace/experiments/qwen35_4b_typed_sketch_synthesis
  • Large adapter/checkpoint root: /workspace/large_artifacts/qwen35_4b_typed_sketch_synthesis
  • Direct evals: reports/eval/program_iid.json, reports/eval/program_support.json, reports/eval/program_ceiling.json
  • Sketch evals: reports/eval/sketch_iid.json, reports/eval/sketch_support.json, reports/eval/sketch_ceiling.json
  • Training logs: run_logs/training_program_lora_console.log, run_logs/training_sketch_lora_console.log

Experiment log 5

Show the running log (5 entries)

Objective

Test whether typed partial-program synthesis can improve held-out executable DSL repair over direct program generation for Qwen 3.5 4B.

Design Commitments

  • Use only Qwen/Qwen3.5-4B.
  • Train fresh adapters inside this standalone experiment.
  • Keep the training budget fixed at 240 records per adapter.
  • Keep adapter/checkpoint files outside the compact experiment directory.
  • Evaluate direct program generation and typed-sketch synthesis on IID, support, and held-out ceiling splits.
  • Report both visible-selected hidden success and hidden-oracle synthesis coverage.
  • Generate a final markdown report and charts.

Hypotheses

  1. Some held-out failures require compositional jumps that local edits cannot generate.
  2. A model-generated typed sketch can provide enough structure for bounded symbolic completion to find those jumps.
  3. If hidden-oracle synthesis coverage is much higher than visible-selected synthesis success, the bottleneck is visible-case discrimination.
  4. If hidden-oracle synthesis coverage remains low, the sketch space or expression bank is still not expressive enough.

Planned Runs

  1. Build deterministic datasets from seed 20260701.
  2. Add deterministic target sketches to every record.
  3. Train program_lora on complete DSL programs.
  4. Train sketch_lora on typed DSL sketches.
  5. Evaluate program_lora on IID, support, and ceiling splits.
  6. Evaluate typed-sketch synthesis on IID, support, and ceiling splits.
  7. Iterate the synthesizer or selector if early checks expose obvious failures.
  8. Generate charts and final report.
  9. Audit compact artifact size and large artifact separation.

Step Log

  • Initialized standalone experiment directory and large artifact directory.
  • Copied stable DSL, data generation, prompt, training, and direct-program evaluator utilities.
  • Implemented program-vs-sketch training targets, typed sketch prompts, deterministic target sketch generation, bounded typed synthesis, and sketch evaluation.
  • Built datasets with seed 20260701.
  • Target sketch recovery preflight:

    • data/static_bridge_60/dsl_train.jsonl: 240/240 target programs recovered.
    • data/eval/dsl_eval_iid.jsonl: 60/60 target programs recovered.
    • data/eval/dsl_eval_support.jsonl: 120/120 target programs recovered.
    • data/eval/dsl_eval_ceiling.jsonl: 120/120 target programs recovered.
  • Recovery preflight finding: initial ranking over-prioritized label-length numeric features and under-prioritized literal 0 for scalar gates. Fixed ranking before any model training.
  • Trained program_lora in /workspace/large_artifacts/qwen35_4b_typed_sketch_synthesis/models/program_lora.

    • Final eval loss: 0.0001638.
    • Train runtime: 857.4 seconds.
  • Trained sketch_lora in /workspace/large_artifacts/qwen35_4b_typed_sketch_synthesis/models/sketch_lora.

    • Final eval loss: 0.000158.
    • Train runtime: 916.7 seconds.
  • Direct program evaluation:

    • IID: 60/60 hidden all-cases success.
    • Support: 117/120 hidden all-cases success.
    • Ceiling: 40/120 hidden all-cases success.
  • Initial sketch smoke evaluation on five ceiling records failed: 0/5 target synthesized and 0/5 hidden-oracle success.
  • Iteration: added structural sketch abstraction variants and deeper typed expression-bank entries.

    • Five-record smoke improved to 5/5 target synthesized, 5/5 hidden-oracle success, and 2/5 selected hidden success.
  • Iteration: changed visible-pass ties to prefer input-dependent and structurally richer candidates.

    • Five-record smoke improved to 5/5 target synthesized, 5/5 hidden-oracle success, and 4/5 selected hidden success.
  • Iteration: reordered abstraction variants first and evaluated greedy-only sketch generation with an 8,000 total-candidate cap.

    • Five-record smoke retained 5/5 target synthesized, 5/5 hidden-oracle success, and 4/5 selected hidden success.
  • Iteration: fixed candidate tag merging so targeted predicate entries can promote generic candidates already present in the expression bank.

    • This fixed sorted_join_contains_code synthesis.
  • Final sketch evaluation with greedy sketch generation and 8,000 total-candidate cap:

    • IID: 45/60 sketch-selected, 60/60 sketch-oracle, 60/60 conservative hybrid.
    • Support: 70/120 sketch-selected, 120/120 sketch-oracle, 118/120 conservative hybrid.
    • Ceiling: 94/120 sketch-selected, 120/120 sketch-oracle, 106/120 conservative hybrid.
  • Generated final report and figures under reports/.

Figures 3

ceiling by family
ceiling by family · reports/figures/
ceiling candidate counts
ceiling candidate counts · reports/figures/
overall hidden success
overall hidden success · reports/figures/

Reproduce

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

Browse the experiment folder on GitHub ↗