util_RandomizeOverlapOrder: interleave across worker files (ILE was seeing only 4 of 25 workers) - #169
Conversation
…within them The draw randomises which n_min points each worker file contributes and their order WITHIN that file, then appends each file's block in file order, so the merged output is [file0][file1]... That is invisible to a consumer that reads the whole file. The nested ILE does not: it reads a prefix. Measured on a live S240629by run, ILE evaluates rows 0-2999 of a 20,000-row merge, so with 25 workers x 800 it saw workers 0-3 and nothing from the other 21; at the more common 6 x 3334 the whole prefix sits inside worker 0. Which is exactly the failure the file header warns about -- "Important when merging files from many workers, to avoid accidentally using only the output from one of them." The hyperpipeline branch of write_joingrids_sub already gets this right, concatenating every shard and piping through shuf with the comment "shuffle so spokes are interleaved". This brings the XML path into line with its sibling rather than introducing a new policy. Verified on 25 real CIP worker files: row count unchanged at 20,000, no duplicates introduced, and contiguous same-worker runs go 25 -> 19,248 with all 25 workers represented in the first 3000 rows instead of 4. --preserve-block-order restores the previous behaviour exactly (25 runs, 4 workers) for reproducing earlier runs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Follow-up measurement: beyond correctness, interleaving gives a measured accuracy gain at zero extra cost. Arms differing only in this flag (no rescoring, DAG byte-identical), with training-set size matched (38,354 vs 38,355 rows) and scored on a third arm's evaluations so neither model sees points its own exploration chose. 5 RF seeds per cell:
RMSE improves by 2.0 and 3.6 nats against a seed scatter of ~0.1 (20–36σ); tail bias halves (+1.88 → +0.83 nats). Two independent held-out sets agree in direction and magnitude. Interpretation: evaluating a prefix drawn from 4 of 25 workers trains a measurably worse fit than the same number of points drawn from all 25. Same GPU cost, same row count — only the diversity of what got evaluated differs. Caveats: single event; a simplified coordinate set rather than CIP's implied coordinates, so absolute values are not CIP's (the between-arm comparison uses an identical feature map and is fair); and this does not move the transverse posterior width in the two sub-iterations measured so far — it improves the fit's ordering of tail candidates, which is what any targeted-followup stage would consume. |
util_RandomizeOverlapOrder.pyrandomises within each worker file but not across them, sothe merged grid is
[worker0][worker1]...[workerN]. Any consumer that reads the whole file isunaffected. The nested ILE reads a prefix, so it has been evaluating only the first few workers'
proposals.
Measured on a live S240629by run (25 CIP workers x 800 points, merged to 20,000 rows):
ILE evaluated rows 0-2999 and nothing beyond, so 21 of 25 workers contributed nothing to the
likelihood evaluations while costing full CIP time. At the more common 6 workers x 3334 the entire
3000-row prefix sits inside worker 0 — a single worker's proposal drives the iteration.
This is the failure the file header already warns about:
Why this is alignment, not new policy
The hyperpipeline branch of
write_joingrids_subalready does this, concatenating every shard andpiping through
shuf, with the comment "shuffle so spokes are interleaved". Only the XML pathwas missing it. This brings the two merge paths into agreement.
The change
One line — permute
P_listacross files before writing.--preserve-block-orderrestores the oldbehaviour exactly, for reproducing earlier runs.
Verified on 25 real worker files: row count unchanged, no duplicates introduced, and the legacy
flag reproduces the previous output structure exactly (25 runs, 4 workers in the prefix).
Impact on existing results
This changes which points get evaluated in every iteration of every run on the XML path, so results
will shift. That is the point — but it means in-flight runs should be pinned with
--preserve-block-orderif they need to stay self-consistent, and any A/B should be against amatched-ordering control.
🤖 Generated with Claude Code