Opus 4.7 experiment loop + 4.6-vs-4.7 head-to-head: no significant overall difference; 4.7 wins 2fold - #6
Draft
trisha-ant wants to merge 15 commits into
Draft
Conversation
70.0% (baseline 65.7%, +4.3). 2fold 91.5% (new best), pretzel 60.2% (+6.1), 1.5fold 70.7% (-9.8, likely variance at n=41). pretzel->2fold still 53x. Not at 4.6 target (77.3%). Thinking helps the borderline fill judgment but not enough; the model still reads pretzel projections as moderate fill.
…ging 83.3% (4.6 scientific 77.3%, 4.6 hybrid 83.2%). pretzel 85.0% (was 54.1% on de-anchored scientific), 2fold 88.1%, 1.5fold 70.7%. pretzel->2fold errors drop 53->20. Asks model to output fill_pct (0-100) before stage. Committing to a number first prevents the qualitative "moderate vs dense" fudge that caused pretzel->2fold on the de-anchored prompt. Regression: adjacent 100%->97.4% (6x 1.5fold->bean). The fill-% rubric removed the per-stage fill descriptions that anchored bean vs comma vs 1.5fold.
37.8% (vs fillpct 83.3%). pretzel 3.8% -- forced binary choice picks 2fold for 128/133 pretzel frames. Override fired 24x (4 helpful / 20 harmful); agreed with primary 160x. Hypothesis was that forced-choice comparison is easier than absolute classification. False here: stripped of the full-stage context and fill descriptions, the binary call defaults to the structurally simpler option (2fold's two-parallel-bands is easier to "see" than pretzel's tangle). 1.5fold 85.4% (best yet) -- but that's just scientific's result since the disambiguator only fires on 2fold/pretzel.
79.4% (vs 83.3% at 1500). 2fold 93.2% (+5.1), adjacent 100% (1.5fold->bean errors gone). But 1.5fold 58.5% (-12.2, now over-reads detail as 2fold: 12x 1.5fold->2fold) and pretzel 79.7% (-5.3). Net -3.9pp. Higher res helps the model see real structure (fixes bean confusion, lifts 2fold) but the extra detail makes 1.5fold's partial fold look like a full hairpin. The 1500 downscale was acting as a useful low-pass filter for the fold-count judgment. Reverting to 1500 in next commit.
76.8% (first run 83.3%, delta 6.5pp). 1.5fold 58.5%, 2fold 94.9%, pretzel 74.4%, adjacent 97.4%. Same config as 1119791. Variance source: adaptive thinking is nondeterministic (model decides when/how much to think). Pre-thinking runs varied ~2pp; post-thinking runs vary ~6pp. The high-res result (79.4%) falls between the two 1500 runs, so the exp-4 conclusion (high-res hurts) is not statistically supported -- it's within noise. fillpct mean across two runs: ~80%. Still beats 4.6 scientific (77.3%) but does not reliably beat 4.6 hybrid (83.2%). Needs N>=3 runs per config for a defensible comparison.
trisha-ant
force-pushed
the
trisha/gently-zslice-multi
branch
from
April 28, 2026 14:55
79a881e to
9bfdba6
Compare
This was referenced Apr 28, 2026
trisha-ant
changed the base branch from
trisha/gently-zslice-multi
to
trisha/gently-opus47-bump
April 28, 2026 14:58
5 runs (effort=xhigh, adaptive thinking, max_dim=1500): exact: 83.3, 76.8, 74.7, 75.5, 70.4 -> mean 76.1, std 4.7 1.5fold: 61.9 +/- 8.2 | 2fold: 91.5 +/- 2.7 | pretzel: 73.7 +/- 8.3 adjacent: 97.4 (zero variance) No-thinking control: 58.4% -- adaptive thinking contributes ~18pp, not just variance. Defensible claim: fillpct on 4.7 ties 4.6 scientific (77.3%) overall; does NOT match 4.6 hybrid (83.2%). 2fold is reliably better (91.5% vs 70%, low std). 1.5fold and pretzel are high-variance. Archived per-run JSONs in data/results/fillpct_replication/.
…on 4.7
vs fillpct 76.1 +/- 4.7. Per-stage: 1.5fold 76.4 (+14 vs fillpct),
2fold 74.6 (-17), pretzel 68.9 (-5). Adjacent 100% (zero variance).
Why it failed: routing picks the prompt based on the *previous prediction*.
The de-anchored temporal path (used when last_stage <= 1.5fold) under-calls
2fold as 1.5fold (15x 2fold->1.5fold), so the fillpct path rarely activates
-- we stay stuck in temporal even through GT=2fold. The original hybrid on
4.6 relied on its anchoring ("never skip stages", "default to previous") to
eventually advance; with those removed, the router never switches.
1.5fold gain (+14pp) and 100% adjacent show the temporal path is good at
shape-matching for early-fold frames. But losing 2fold's 91.5% kills
overall.
Archived per-run JSONs in data/results/hybrid_fillpct_replication/.
Same prompt, same n=233 frames (embryos 1-3), adaptive thinking, effort=max (4.6) / xhigh (4.7): 4.6 (N=3): 77.5 +/- 4.6 (runs: 78.5, 81.5, 72.5) 4.7 (N=5): 76.1 +/- 4.7 (runs: 83.3, 76.8, 74.7, 75.5, 70.4) diff +1.4pp, t~0.41 -- not significant Per-stage: 1.5fold: 62.6+/-1.4 vs 61.9+/-8.2 -- tied 2fold: 76.3+/-8.8 vs 91.5+/-2.7 -- 4.7 better (+15pp, lower var) pretzel: 82.7+/-4.9 vs 73.7+/-8.3 -- 4.6 better (+9pp) adj: 100.0 vs 97.4 -- 4.6 better (no bean errors) Defensible conclusion: the models trade off (4.7 wins 2fold, 4.6 wins pretzel) and are equivalent overall on this task with the fillpct prompt. The 4.7 vision improvements do not translate to net gain here. Also confirms ~5pp variance is intrinsic to adaptive thinking on both models, not a 4.7-specific issue. _base.py reverted to 4.7 config; 4.6 run JSONs archived.
trisha-ant
force-pushed
the
trisha/gently-opus47-experiments
branch
from
April 29, 2026 15:58
9e3153f to
1274614
Compare
fillpct + two extra structured observations (n_passes, bright_uniformity)
before stage. Same stage descriptions and fill-% rubric as fillpct; no
boundary redefinition.
exact: 80.3 +/- 4.8 (runs 82.8, 74.7, 83.3)
1.5fold: 52.0 +/- 5.1 (45x 1.5fold->2fold pooled -- n_passes may
read 1.5fold's J-shape as 2 passes)
2fold: 96.6 +/- 1.7 (best ever)
pretzel: 81.7 +/- 7.0 (recovered to ~4.6 level)
adj: 100.0 (zero variance; fixes fillpct's bean errors)
vs fillpct@4.7 (76.1+/-4.7): +4.1pp, t~1.19 -- directionally better, not
significant at N=3.
vs fillpct@4.6 (77.5+/-4.6): +2.8pp, t~0.72.
vs master hybrid@n=233 (82.8, single run): -2.5pp, within 1 sigma.
The extra observations shift the trade-off: pretzel and 2fold both improve,
1.5fold worsens. Asking the model to count passes helps pretzel (commits to
>=3 -> harder to say 2fold) but hurts 1.5fold (J-shape reads as 2 passes).
…ng lifts all stages
Baseline multimeasure 80.3+/-4.8.
H1 nohist_mm 67.8+/-2.0 (-12.4, t~-4.1) -- history is essential; cascade
hypothesis falsified (low var WITHOUT history => variance
isn't from cascade)
H2 mm_v2 74.8+/-1.1 (-5.4, t~-1.9) -- tail_reaches_head fixes 1.5fold
(52->65) but loses pretzel (82->70); direct trade-off with
n_passes
H3 mm_v3 78.1+/-5.7 (-2.1, t~-0.5) -- restored fill qualifiers ~=
noise; 1.5fold std 21.3
H4 vote3_mm 80.8+/-0.5 (+0.6, t~+0.2) -- 3x self-consistency crushes
variance 4.8->0.5; mean unchanged. pretzel 84.5+/-1.1,
2fold 97.7+/-1.0. 1.5fold worsens to 44.7.
H5 sepview_mm 76.5+/-3.7 (-3.7, t~-1.1) -- separate views slightly worse
None improved all stages. Most promising follow-up: use BOTH n_passes and
tail_reaches_head (H2 showed they're complementary), optionally with vote3.
Harness: top_image_b64/side_image_b64 added to optional-kwarg whitelist.
…stack mm_v4 (4 measurements): 77.4+/-3.2. 1.5fold 52.8 (NOT H2's 65.0), pretzel 76.9 (-5 vs baseline). Adding tail_reaches_head alongside n_passes doesn't recover 1.5fold -- n_passes dominates when both present. vote3_mm_v4: 76.0+/-2.0. Same story; voting reduces variance but can't fix the systematic n_passes->2fold pull on 1.5fold. Conclusion: the n_passes vs tail_reaches_head trade-off is fundamental. Model weights n_passes more heavily when both are present. Best replicated 4.7 result remains vote3_mm: 80.8+/-0.5 (2fold 97.7, pretzel 84.5, 1.5fold 44.7).
…olds up) Master config (opus-4-6, temperature=0, no thinking, anchored prompts): exact: 81.7 +/- 2.4 (runs 82.8, 83.3, 79.0) 1.5fold: 65.9 +/- 0.0 (deterministic -- temp=0 + strong anchoring) 2fold: 68.4 +/- 9.8 pretzel: 92.5 +/- 8.5 adj: 100.0 Only diff from master's hybrid.py is confidence field removed from JSON schema (PR #1). Master's 82.8 was a typical draw. vs vote3_mm@4.7 (80.8+/-0.5): +0.9pp, t~0.61 -- not significant. Statistically equivalent overall. Per-stage trade-off: hybrid@4.6 wins 1.5fold (66 vs 45) and pretzel (93 vs 85) vote3_mm@4.7 wins 2fold (98 vs 68) and variance (0.5 vs 2.4) _base.py reverted to 4.7 config; hybrid46 JSONs archived.
Analysis (RESEARCH.md): oracle ceiling for hybrid@4.6 x vote3_mm@4.7 is 93.6% -- the models are complementary. Errors are contiguous 8-17 frame blocks (transition-timing), not per-frame noise. Agreement (78% of frames) is 91.2% accurate; disagreements always have exactly one right. Judge ensemble: run both, agree -> use agreement, disagree -> arbitrate with a judge call (image + history + both predictions + reasoning). Falls back to "more advanced" on parse failure. N=3 pairs: 90.6 / 89.3 / 91.8 -> mean 90.6 +/- 1.3 Per-stage: 1.5fold 65.9, 2fold 94.9, pretzel 96.2 Judge acc on disagreements: 87.5 +/- 5.3 First harness change that lifts all three stages. Captures ~76% of the oracle headroom. Cost ~4.2 calls/frame; hybrid+multimeasure pairing (~2.2x) has the same ceiling, untested. Transition refinement (negative): 76.8% (-6.0pp). Multi-frame window boundary detection moved some transitions further from GT. The "pick later" bias in ordered sequences and windows missing the true boundary hurt. Scripts in experiments/judge_ensemble/.
…90.6) Ablation found the judge's history was built from GT stages for all frames; the harness only does that for non-scored frames. GT history differs from predicted history on 56% of disagreement frames. Ablation (pair 1, 52 disagree frames): GT history: 90.4% judge acc -> 91.0% ensemble (LEAKY) Predicted (hybrid) history: 63.5% -> 85.0% No history: 50.0% -> 82.0% (coin flip) Reasoning contributes +5.8pp, references +9.6pp (given GT history) Sequential honest judge ensemble (ensemble's own history, N=3): 83.3 +/- 0.7, judge_on_disagree 57.7 +/- 5.6 per-stage: 1.5fold 56.9, 2fold 95.5, pretzel 86.0 vs hybrid@4.6 (81.7 +/- 2.4): +1.6pp, t~1.1 -- not significant The oracle ceiling (93.6%) requires near-100% history accuracy, which is circular. The judge without GT history is barely above random on disagreements. The ensemble's only real gain is variance (0.7 vs 2.4). Recommendation remains: hybrid@4.6 on master, 81.7 +/- 2.4 at 1x cost. Nothing tested defensibly beats it. Lesson: ablate before reporting. One line of GT leakage turned a null result into a "breakthrough."
…brid Route frames to stage-appropriate model based on coarse pass's predicted transition timepoints. Tested 4 coarse-pass sources (mm, hybrid, vote3, per-frame stage), all from archived predictions, no API calls. All honest variants tie or lose vs hybrid@4.6. Coarse transition estimates are off by 7-14 frames -- same magnitude as per-frame errors. The routing signal has the same root error as the thing it routes. GT-region ceiling 89.1% (leaky) is below per-frame oracle 93.6% -- even perfect routing can't reach the ceiling because single-model regions have within-region errors. RESEARCH.md: added timepoint-routing section + structural-bottleneck summary README.md: added Key Findings section with replicated leaderboard, bottleneck explanation, and methodology lessons (N>=3, ablate before report, embryo_4 missing).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #7 (→ #5 → #1).
Why
#7 bumped the model to
claude-opus-4-7and de-anchored thescientificprompt, landing at 65.7% — net −12pp vs the 4.6 baseline. This PR runs a hypothesis-driven experiment loop to close the gap, then properly replicates the best result and runs a controlled 4.6-vs-4.7 head-to-head.Result — 4.6 vs 4.7 head-to-head
Same
fillpctprompt, same n=233 frames (embryos 1–3), adaptive thinking, closest-equivalent effort:Difference +1.4pp (4.6 favored), t≈0.41 — not significant. The models trade off: 4.7 wins 2fold (+15pp, lower variance), 4.6 wins pretzel (+9pp) and adjacent. ~5pp run-to-run variance is intrinsic to adaptive thinking on both models.
Defensible claims:
Experiments
n=233 hard-stage frames each. All run with
effort=xhigh+ adaptive thinking (exp 1's change to_base.py) unless noted.Exp 1 —
effort=xhigh+ adaptive thinking (7b5de01)70.0% (N=1, +4.3 vs de-anchored baseline). 2fold 91.5%, pretzel 60.2%. Reasoning helps the borderline fill judgment.
Exp 2 —
fillpctvariant (1119791, replicated3a02f1d)New variant: model outputs
fill_pct(integer 0–100) before the stage. Committing to a number prevents the qualitative "moderate vs dense" hedge that caused pretzel→2fold. First run 83.3% looked like it matched 4.6 hybrid; N=5 replication revealed that was a high outlier — see head-to-head table above. Thresholds (40/60/75) are biologically motivated and not tuned on results.Exp 3 —
pairwise2fold-vs-pretzel forced choice (f4dd710) ❌37.8% (N=1). Stripped of full-stage context, the binary call defaults to the structurally simpler pattern; 128/133 pretzel frames called 2fold.
Exp 4 — high-res images (
98f96c5, reverted) — inconclusive79.4% (N=1).
max_dim1500→2400 (native ~1822px). Result falls within fillpct@1500's noise band; reverted since no evidence of gain and ~2× token cost.Exp 5 —
hybrid_fillpctde-anchored routing (80326b7) ❌71.7 ± 3.1 (N=3). Router picks prompt based on previous prediction; de-anchored temporal path under-calls 2fold→1.5fold so the fillpct path rarely activates. 1.5fold 76.4% (+14) and adjacent 100% are silver linings. Prediction-based routing doesn't transfer to 4.7 once de-anchored.
Head-to-head — fillpct on 4.6 N=3 (
1274614)77.5 ± 4.6 — see Result section.
Exp 6 —
multimeasure(fillpct + n_passes + bright_uniformity) (3477435)80.3 ± 4.8 (N=3) — best replicated 4.7 result. Same rubric as fillpct plus two extra structured observations the model must commit to before staging. 2fold 96.6 ± 1.7 (best ever), pretzel 81.7 ± 7.0 (recovered to ~4.6 level), adjacent 100%. 1.5fold drops to 52.0 (n_passes reads the J-shape as 2 passes → 2fold). vs fillpct@4.7 +4.1pp (t≈1.19, directionally better but not significant at N=3); vs master hybrid@n=233 −2.5pp (within 1σ).
What
perception/_base.py—thinking={"type": "adaptive"}+output_config={"effort": "xhigh"}oncall_claudeperception/fillpct.py,pairwise.py,hybrid_fillpct.py,multimeasure.py(new variants)perception/__init__.py— register all threedata/results/fillpct_replication/— per-run JSONs (5×4.7, 1×4.7-nothink, 3×4.6)data/results/hybrid_fillpct_replication/— per-run JSONs (3×)Verification
Follow-ups