Repository navigation
Round 14: make the 1M synthetic corpus release reachable - #13
Merged
Merged
Conversation
The round-13 1M run (upnz22h5cdt6gdgrtshv) SUCCEEDED at 31,704 rows of a requested 1,000,000: 78 archetypes survived x 400 variants + 504 measured rows. Four mechanisms are fixed here, all of them post-mortem findings. 1. The wave loop could not stop itself. Wave 1 ran 19.5h against a 15h generation deadline, because the deadline was only tested AFTER asyncio.gather returned -- so the run generated once, blew the whole budget in an un-adapted first wave, and never reached wave 2. The deadline is now checked inside build_archetype, wave sizing is bounded by the time actually left (plan_wave, extracted and unit-tested), and wave 1 is deliberately small so there IS a keep-rate observation to size wave 2 with. 2. Work kept going to dead teachers. 277 archetypes died on HTTP 504 after exhausting all three retries -- retries 1/2/3 failed at essentially the same rate, because the endpoints were persistently unavailable rather than hiccuping. Each burned 5+10+20s of backoff first: ~2.8 hours of pure sleeping against the concurrency limit for zero recovered work. TeacherPool now round-robins over HEALTHY endpoints only and trips a breaker after N consecutive transport failures (never the last one standing), with a half-open probe each wave since these apps scale from zero and do come back. Per-call retries drop from 3/5s to 2/2s. 3. A broken archetype cost 7 pods to find out. The largest rejection bucket was `curated out: execution failed` (462 pods) -- code that imported fine and raised at runtime. A viability probe now runs the CHEAPEST calibration point first and stops there if the code cannot execute; it costs nothing when it passes, because that point is a measurement we needed anyway. It fires only on execution/pod failure, never on a point merely landing out of bounds -- that is a property of the parameter point, not the code, and rejecting there would throw away archetypes the probe was never meant to judge. 4. The new libraries had a one-line hint each. Round 13 admitted a dozen libraries with a sentence of guidance apiece, which names a library but pins none of the call signatures that decide whether a module runs. STACK_PITFALLS adds a narrow API contract per stack -- polars group_by, lightgbm's removed verbose_eval, networkx from_numpy_array, faiss float32 contiguity, langgraph recursion limits, lightning's writes-to-cwd defaults, transformers hidden_size % num_heads -- and the prompt now says outright that the module is executed at its range LOWS first and discarded if it raises there. Sizing follows from the measured unit cost: ~1,550 oracle pods in 19.5h at concurrency 24 is ~17 min of wall clock per pod, nearly all node scale-up and pulling the (much fatter) round-13 harness image. So oracle_concurrency 24 -> 160 (pods are one per t3a.xlarge on a 3-250 node pool), variants 400 -> 1200 (~834 archetypes for 1M: 10x what round 13 shipped, and well inside both gates that bound this axis -- near-duplication is measured over archetype code, not variants), peak-hold 150s dropped from the rotation, generation deadline 16h -> 20h and task runtime 24h -> 36h so a release that generates to its deadline still has time to ship. 23 tests over the wave planner, the breaker, the probe classifier and the stack contracts. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016huuSPKsdzj5YwzV846E8e
flyte's deploy-time literal conversion rejected an int default on a float
parameter ("Failed to convert default value for parameter
'gpu_max_vram_mib'"), aborting the deploy partway through the task list.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016huuSPKsdzj5YwzV846E8e
Covers the quality-gate work (and the two gate bugs that failed a good corpus, recovered via flyte fork), the round-13 stack axis and teacher tiers, and the round-14 post-mortem of the 1M release that shipped 31,704 rows and reported success. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016huuSPKsdzj5YwzV846E8e
Run uqjsqswf4fntdjrq9qzq started with only qwen38-27b: the three frontier teachers each needed GPU nodes and were still scaling when the 300s grace expired. All four were ACTIVE ~30 min later, by which point the release was locked to a single teacher for its whole 20-hour life -- throwing away the multi-family diversity that is the point of running them. 300s was tuned when the pool was two similar models. Waiting longer is also much safer than it was: a teacher that wakes and then goes bad now gets dropped mid-run by the circuit breaker rather than absorbing its share of archetypes forever. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016huuSPKsdzj5YwzV846E8e
Contributor
Author
|
Relaunched as us86v7zcfphfz76gjrdw after aborting the first attempt. The first run (uqjsqswf4fntdjrq9qzq) started with only qwen38-27b: the three frontier teachers each needed GPU nodes and were still scaling when the 300s grace expired. All four were ACTIVE ~30 min later — by which point the release was locked to a single teacher for its whole 20-hour life, throwing away the multi-family diversity that is the point of running them. Grace raised 300s → 1800s (commit 8027b49). That 300s was tuned when the pool was two similar models, and waiting longer is much safer now than it was: a teacher that wakes and then goes bad gets dropped mid-run by the new circuit breaker rather than absorbing its share of archetypes forever. |
Run us86v7zcfphfz76gjrdw generated with qwen38-27b alone. The logs name the cause: qwen35-397b and minimax-m3 timed out on BOTH their svc DNS and public URLs, every poll, for 30 minutes, while both apps reported ACTIVE. llama.cpp blocks its HTTP listener while loading weights, so a frontier-size model does not answer 503-while-loading -- it does not answer at all. The 20s probe gave up before the server could ever reply. Probing the same endpoints once they finished loading: HTTP 200 in ONE second. Separately, glm-5-2 is genuinely gone -- svc DNS NXDOMAIN and public HTTP 404, so nothing is behind the ACTIVE app record. Dropped from the teacher list for this round; that one needs an llm-service redeploy. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016huuSPKsdzj5YwzV846E8e
Run ukh2f7p6jhzbp8bm247x recruited qwen35-397b via the longer health probe,
then got HTTP 503 {"message":"Loading model"} on its completions:
/health returns 200 once llama.cpp's listener is up, but the weights are
not in yet. So a teacher can pass the wake check and still 503 every
request for minutes.
Two consequences, both wrong before this commit. The 2-retry/2s budget --
right for an endpoint that is simply down -- gave up after 6 seconds on a
model that was minutes from being the strongest teacher in the pool. And
those failures counted toward the circuit breaker, which would drop the
endpoint for the offence of becoming useful.
Loading now gets its own patient budget (20 retries, 30s apart) and is
excluded from the breaker. Every other failure keeps the short budget.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016huuSPKsdzj5YwzV846E8e
variants_per_archetype is an INPUT GUESS about how many archetypes will survive, not a quality requirement. The thing that actually protects the corpus from being N tasks photocopied is the concentration gate -- and it has enormous headroom: it admits 2% of the corpus per archetype, so 700 archetypes scaled to 1M rows sit at 0.14%. So a shortfall now raises the variant count to cover the target, as far as that gate still allows. 780 of 834 archetypes at 1283 variants each is the same corpus by every measure we gate on; failing there would discard a 20-hour release over the input guess. What it will NOT do is rescue a thin release. 40 archetypes stretched to 1M would be 2.5% each and the gate refuses -- as it does for the 78 archetypes round 13 actually shipped, where inflating to 1M would have been a lie. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016huuSPKsdzj5YwzV846E8e
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.
The round-13 1M run (upnz22h5cdt6gdgrtshv) succeeded at 31,704 rows of a requested 1,000,000 — 78 surviving archetypes × 400 variants, plus 504 measured calibration rows. It reported success because
require_target=Falseturns shipping short into a warning.Four mechanisms are fixed here, all of them post-mortem findings.
1. The wave loop could not stop itself
Wave 1 ran 19.5h against a 15h generation deadline, because the deadline was only tested after
asyncio.gatherreturned. The run generated once, spent its whole budget in a single un-adapted wave, and never reached wave 2 — the adaptive sizing that was supposed to respond to the observed keep rate never executed at all.The deadline is now checked inside
build_archetype, wave sizing is bounded by the time actually left (plan_wave, extracted as a pure function and unit tested), and wave 1 is deliberately small so there is a keep-rate observation to size wave 2 with.2. Work kept going to dead teachers
277 archetypes died on HTTP 504 after exhausting all three retries — and the histogram is the tell: 291 first retries, 290 second, 288 third. Essentially every retry failed too, because the endpoints were persistently unavailable rather than hiccuping. Each burned 5+10+20s of backoff first: ~2.8 hours of pure sleeping against the concurrency limit for zero recovered work.
TeacherPoolnow round-robins over healthy endpoints only and trips a breaker after N consecutive transport failures (content rejections don't count — that's a prompt problem, and dropping the endpoint wouldn't fix it), never the last one standing, with a half-open probe each wave since these apps scale from zero and do come back. Per-call retries drop from 3/5s to 2/2s.3. Broken code cost 7 pods to discover
The largest rejection bucket was
curated out: execution failed— 462 pods of code that passed the AST screen, imported fine, and raised at runtime.A viability probe now runs the cheapest calibration point first and stops there if the code cannot execute. It costs nothing when it passes, because that point is a measurement we needed anyway. It fires only on execution/pod failure, never on a point merely landing out of bounds — that's a property of the parameter point, not the code, and rejecting there would throw away archetypes the probe was never meant to judge.
4. A dozen new libraries had one line of guidance each
Round 13 admitted polars/duckdb/dask/jax/lightning/faiss/langgraph/llama-index with a sentence apiece, which names a library but pins none of the call signatures that decide whether a module runs.
STACK_PITFALLSadds a narrow API contract per stack — polarsgroup_by, lightgbm's removedverbose_eval, networkxfrom_numpy_array, faiss float32 contiguity, langgraph recursion limits, lightning's writes-to-cwd defaults, transformershidden_size % num_heads— and the prompt now says outright that the module is executed at its range lows first and discarded if it raises there.Sizing follows from the measured unit cost
upnz22h5ran ~1,550 oracle pods in 19.5h at concurrency 24: ~17 minutes of wall clock per pod, of which only ~1–2 min is the workload. The rest is node scale-up and pulling the (much fatter) round-13 harness image. That cost isn't going away, so the levers are width and pod count:oracle_concurrency24 → 160 (pods are one per t3a.xlarge on a 3–250 node pool — 24 was using a tenth of the available fan-out)variants_per_archetype400 → 1200 (~834 archetypes for 1M: 10× what round 13 shipped, and well inside both gates that bound this axis — near-duplication is measured over archetype code, so variants don't affect it, and concentration admits 2% per archetype = 20,000 rows at 1M)Also fixes an int default on a float task parameter that was aborting
flyte deploypartway through the task list.Tests
23 new tests over the wave planner, the circuit breaker, the probe classifier and the stack contracts (
tests/test_wave_throughput.py); 209 pass overall.Research log
Adds
research_log/2026-09-09-round-12-14-corpus-at-scale.mdcovering rounds 12–14 — the quality-gate work (including two gate bugs that failed a perfectly good corpus, recovered viaflyte fork), the stack axis and teacher tiers, and the post-mortem above.Run
uqjsqswf4fntdjrq9qzq is the first 1M attempt on this code, launched 2026-09-09 and running now. The ~14–16h projection is an estimate from one prior run's unit cost, not a measurement.
🤖 Generated with Claude Code
https://claude.ai/code/session_016huuSPKsdzj5YwzV846E8e