Skip to content
nano-gpt-data-curation

claude-opus-5

nano-gpt-data-curation — graded by the task's verifier against a measured baseline.

backend
modal
variant
claude claude-opus-5
metric
held-out multi-domain perplexity
actions
53
duration
1h 5m
recorded
2026-08-03

run iddclm-nano-curation__Wz5kwvV

Everything claude-opus-5 did on this task, in order.

download JSON ↗
claude-codeclaude-opus-552 turns36 narration53 action53 observation16 reasoning1 final
#26
reasoning (redacted)

encrypted chain-of-thought — recorded, not exposed

toolBashLaunch round-3 evals plus per-register diagnostic
args
{
  "command": "nohup bash -c '\npython work/diag.py --train_npy /tmp/t_w1,1,1,2.npy --heldout_npy data/multi_dev.npy --out_json /tmp/diag_b.json > /tmp/diag_b.log 2>&1 &\nbash work/eval.sh /tmp/sel_prf.json prf 2>&1 | grep HELDOUT | sed \"s/^/[prf-1111] /\" &\nbash work/eval.sh /tmp/sel_prf1112.json prf1112 2>&1 | grep HELDOUT | sed \"s/^/[prf-1112] /\" &\nbash work/eval.sh /tmp/sel_w1113.json w1113 2>&1 | grep HELDOUT | sed \"s/^/[w-1113] /\" &\nwait' > work/round3.log 2>&1 &\nsleep 170; cat work/round3.log; echo \"=== diag\"; grep -aE \"OVERALL|REG \" /tmp/diag_b.log",
  "description": "Launch round-3 evals plus per-register diagnostic"
}
Bash result
Command did not complete within its 120s timeout and was moved to the background (ID: b9oy0bhpr). Output is being written to: /tmp/claude-0/-workspace/e5ac3a46-6b71-4760-9c46-a319e744a6bd/tasks/b9oy0bhpr.output. You will be notified when it completes. To check interim output, use Read on that file path.

[metadata] {"noOutputExpected": false, "backgroundTaskId": "b9oy0bhpr", "timedOutAfterMs": 120000}
#27
narration

While that batch runs, let me inspect what the S-register list actually retrieves at depth (to know whether more S weight has headroom).

toolBashInspect S-register list at increasing depth
args
{
  "command": "python - <<'EOF'\nimport numpy as np, json, sys\nsys.path.insert(0,'work')\nfrom curate_core import load, gates\nids,ntok,score,feat,sig,rep=load('/workspace/work/score_prf.npy')\ng=gates(ntok,feat,rep,False)\nc=np.where(g)[0]; c=c[np.argsort(-score[c,3])]\ncum=np.cumsum(ntok[c])\ntxt={}\nfor line in open('data/pool.jsonl'):\n    r=json.loads(line); txt[r['id']]=r['text']\nprint('eligible S docs',len(c),'tokens',int(ntok[c].sum()))\nfor target in [0, 1_000_000, 3_000_000, 5_000_000, 9_000_000]:\n    k=int(np.searchsorted(cum,target)); k=min(k,len(c)-1); idx=c[k]\n    print(f'--- at {target/1e6:.0f}M tok: s_S={score[idx,3]:.2f} id={ids[idx]} :: {txt[int(ids[idx])][:180]!r}')\nEOF",
  "description": "Inspect S-register list at increasing depth"
}
Bash result
eligible S docs 126186 tokens 104287198
--- at 0M tok: s_S=0.93 id=6138 :: 'XForms/Read and write with get and put\nSometimes all you need to do is to put a nice user friendly form that edits a single static XML file. In this case a static file is any file '
--- at 1M tok: s_S=0.23 id=157631 :: '<|endoftext|>Chit Chat [Archive] - Ambient Music Forum\nAmbient Music Forum > Non-Ambient Music section > Chit Chat\nPDA\nView Full Version : Chit Chat\nThe Marshmallow people\nNew to t'
--- at 3M tok: s_S=0.07 id=179243 :: ' Theme | Viral by Hash Themes<|endoftext|>Next Step | New England Fiber Arts\nSkip to main content area\nSearch form\nShopping cart\nYour shopping cart is empty.\nMain menu\nHome\nSlidesh'
--- at 5M tok: s_S=0.01 id=139532 :: ' New at FedEx? | FedEx Italy\nShipping\nShip All Features\nShip Quick & Simple\nGet Rates & Transit Times\nSchedule & Manage Pickups\nReturns\nPackaging & Shipping Supplies\nALL SHIPPING S'
--- at 9M tok: s_S=-0.04 id=95924 :: '.<|endoftext|>Browsing Recipes similiar to Sauteed Apples.\n"On a chilly morning, this fruity side dish warms you up. It complements just about anything you\'d choose to serve for br'

[stdout]
eligible S docs 126186 tokens 104287198
--- at 0M tok: s_S=0.93 id=6138 :: 'XForms/Read and write with get and put\nSometimes all you need to do is to put a nice user friendly form that edits a single static XML file. In this case a static file is any file '
--- at 1M tok: s_S=0.23 id=157631 :: '<|endoftext|>Chit Chat [Archive] - Ambient Music Forum\nAmbient Music Forum > Non-Ambient Music section > Chit Chat\nPDA\nView Full Version : Chit Chat\nThe Marshmallow people\nNew to t'
--- at 3M tok: s_S=0.07 id=179243 :: ' Theme | Viral by Hash Themes<|endoftext|>Next Step | New England Fiber Arts\nSkip to main content area\nSearch form\nShopping cart\nYour shopping cart is empty.\nMain menu\nHome\nSlidesh'
--- at 5M tok: s_S=0.01 id=139532 :: ' New at FedEx? | FedEx Italy\nShipping\nShip All Features\nShip Quick & Simple\nGet Rates & Transit Times\nSchedule & Manage Pickups\nReturns\nPackaging & Shipping Supplies\nALL SHIPPING S'
--- at 9M tok: s_S=-0.04 id=95924 :: '.<|endoftext|>Browsing Recipes similiar to Sauteed Apples.\n"On a chilly morning, this fruity side dish warms you up. It complements just about anything you\'d choose to serve for br'
[metadata] {"noOutputExpected": false}
#28
narration

The S list degrades into web nav boilerplate past ~1M tokens — it confuses "non-prose" with "code". Let me build a genuine code/technical-content feature so the S bucket gets real technical text.

toolBashCompute code/technical content features
args
{
  "command": "cat /workspace/.timer/remaining_secs; cat work/round3.log 2>/dev/null; grep -aE \"OVERALL|REG \" /tmp/diag_b.log 2>/dev/null\ncat > work/codefeat.py <<'EOF'\n\"\"\"Stage 2c: per-doc technical-content markers. The S target register is HTML-marked-up\nprogramming Q&A; unigram affinity alone confuses it with web nav boilerplate, so we measure\nexplicit code/markup evidence.\"\"\"\nimport json, re, numpy as np\nfrom multiprocessing import Pool\nCODE = re.compile(r'</?\\w+>|\\{|\\}|;\\s*$|\\(\\)|==|=>|\\bdef \\b|\\bfunction\\b|\\bimport \\b|\\breturn\\b'\n                  r'|&\\w+;|\\$\\w+|\\bclass \\b|#include|::|\\[\\]|</|/>|\\bvar \\b|\\bnull\\b|\\bvoid\\b', re.M)\nTECH = re.compile(r'\\b(code|function|variable|server|file|database|query|python|javascript|java|'\n                  r'linux|command|error|version|api|string|array|object|method|class|script|'\n                  r'install|config|windows|library|module|syntax|compile|debug|shell|sql|html|css)\\b', re.I)\ndef work(lines):\n    out = []\n    for line in lines:\n        r = json.loads(line); t = r['text']; n = max(1, len(t)); w = max(1, len(t.split()))\n        out.append((r['id'], len(CODE.findall(t)) / w * 100, len(TECH.findall(t)) / w * 100,\n                    t.count('\\n    ') / w * 100))\n    return out\nif __name__ == '__main__':\n    jobs, buf = [], []\n    for line in open('/workspace/data/pool.jsonl'):\n        buf.append(line)\n        if len(buf) == 2000: jobs.append(buf); buf = []\n    if buf: jobs.append(buf)\n    res = []\n    with Pool(16) as p:\n        for r in p.imap(work, jobs): res.extend(r)\n    res.sort(key=lambda x: x[0])\n    M = np.load('/workspace/work/pool_meta.npz')\n    d = {r[0]: r[1:] for r in res}\n    out = np.array([d[int(i)] for i in M['ids']], dtype=np.float32)\n    np.save('/workspace/work/codefeat.npy', out)\n    print('code/tech/indent pct:', np.percentile(out, [50, 90, 97, 99.5], axis=0).round(2))\nEOF\npython work/codefeat.py",
  "description": "Compute code/technical content features"
}
Bash result
4128
code/tech/indent pct: [[ 0.    0.    0.  ]
 [ 0.73  0.7   0.  ]
 [ 3.02  2.17  0.  ]
 [23.03  7.41  0.  ]]

[stdout]
4128
code/tech/indent pct: [[ 0.    0.    0.  ]
 [ 0.73  0.7   0.  ]
 [ 3.02  2.17  0.  ]
 [23.03  7.41  0.  ]]
[metadata] {"noOutputExpected": false}
#29
reasoning (redacted)

encrypted chain-of-thought — recorded, not exposed

toolBashRead round-3 results and diagnostic
args
{
  "command": "cat work/round3.log; echo \"=== diag\"; tail -6 /tmp/diag_b.log",
  "description": "Read round-3 results and diagnostic"
}
Bash result
=== diag
Traceback (most recent call last):
  File "/workspace/work/diag.py", line 4, in <module>
    from model import GPT, GPTConfig
ModuleNotFoundError: No module named 'model'

[stdout]
=== diag
Traceback (most recent call last):
  File "/workspace/work/diag.py", line 4, in <module>
    from model import GPT, GPTConfig
ModuleNotFoundError: No module named 'model'
[metadata] {"noOutputExpected": false}
#30
reasoning (redacted)

encrypted chain-of-thought — recorded, not exposed

toolBashRelaunch round-3 evals with correct PYTHONPATH
args
{
  "command": "ls -la /tmp/e_*.json /tmp/t_*.npy 2>/dev/null | tail -8; nvidia-smi --query-compute-apps=pid,used_memory --format=csv; echo \"--- relaunch\"\nPYTHONPATH=/workspace nohup bash -c '\npython work/diag.py --train_npy /tmp/t_w1,1,1,2.npy --heldout_npy data/multi_dev.npy --out_json /tmp/diag_b.json 2>&1 | grep -E \"OVERALL|REG \" | sed \"s/^/[diag] /\" &\nbash work/eval.sh /tmp/sel_prf.json prf 2>&1 | grep HELDOUT | sed \"s/^/[prf-1111] /\" &\nbash work/eval.sh /tmp/sel_prf1112.json prf1112 2>&1 | grep HELDOUT | sed \"s/^/[prf-1112] /\" &\nbash work/eval.sh /tmp/sel_w1113.json w1113 2>&1 | grep HELDOUT | sed \"s/^/[w-1113] /\" &\nwait' > work/round3.log 2>&1 &\nsleep 5; echo ok",
  "description": "Relaunch round-3 evals with correct PYTHONPATH"
}
Bash result
-rw-r--r-- 1 root root 24000128 Aug  3 23:34 /tmp/t_gates.npy
-rw-r--r-- 1 root root 24000128 Aug  3 23:44 /tmp/t_prf.npy
-rw-r--r-- 1 root root 24000128 Aug  3 23:44 /tmp/t_prf1112.npy
-rw-r--r-- 1 root root 24000128 Aug  3 23:33 /tmp/t_rand.npy
-rw-r--r-- 1 root root 24000128 Aug  3 23:40 /tmp/t_w1,1,1,2.npy
-rw-r--r-- 1 root root 24000128 Aug  3 23:40 /tmp/t_w1,2,2,1.npy
-rw-r--r-- 1 root root 24000128 Aug  3 23:44 /tmp/t_w1113.npy
-rw-r--r-- 1 root root 24000128 Aug  3 23:40 /tmp/t_w2,1,1,1.npy
pid, used_gpu_memory [MiB]
--- relaunch
ok

[stdout]
-rw-r--r-- 1 root root 24000128 Aug  3 23:34 /tmp/t_gates.npy
-rw-r--r-- 1 root root 24000128 Aug  3 23:44 /tmp/t_prf.npy
-rw-r--r-- 1 root root 24000128 Aug  3 23:44 /tmp/t_prf1112.npy
-rw-r--r-- 1 root root 24000128 Aug  3 23:33 /tmp/t_rand.npy
-rw-r--r-- 1 root root 24000128 Aug  3 23:40 /tmp/t_w1,1,1,2.npy
-rw-r--r-- 1 root root 24000128 Aug  3 23:40 /tmp/t_w1,2,2,1.npy
-rw-r--r-- 1 root root 24000128 Aug  3 23:44 /tmp/t_w1113.npy
-rw-r--r-- 1 root root 24000128 Aug  3 23:40 /tmp/t_w2,1,1,1.npy
pid, used_gpu_memory [MiB]
--- relaunch
ok
[metadata] {"noOutputExpected": false}
#31
narration

Let me size the genuinely technical portion of the pool and build a better S bucket.

toolBashSize technical pool and inspect quality at depth
args
{
  "command": "python - <<'EOF'\nimport numpy as np, json, sys\nsys.path.insert(0,'work')\nfrom curate_core import load, gates\nids,ntok,score,feat,sig,rep=load('/workspace/work/score_prf.npy')\nC=np.load('work/codefeat.npy')  # code_pct, tech_pct, indent_pct\ng=gates(ntok,feat,rep,False)\nfor cthr,tthr in [(3,3),(1.5,2),(0.5,1.5),(0.3,1.0)]:\n    m=g&((C[:,0]>=cthr)|(C[:,1]>=tthr))\n    print(f'code>={cthr} or tech>={tthr}: docs {m.sum()} tokens {ntok[m].sum()/1e6:.1f}M')\nm=g&((C[:,0]>=1.5)|(C[:,1]>=2.0))\nc=np.where(m)[0]; c=c[np.argsort(-score[c,3])]; cum=np.cumsum(ntok[c])\ntxt={}\nfor line in open('data/pool.jsonl'):\n    r=json.loads(line); txt[r['id']]=r['text']\nfor t in [0,1_000_000,3_000_000,6_000_000]:\n    k=min(int(np.searchsorted(cum,t)),len(c)-1); i=c[k]\n    print(f'--- {t/1e6:.0f}M: sS={score[i,3]:.2f} code={C[i,0]:.1f} tech={C[i,1]:.1f} :: {txt[int(ids[i])][:170]!r}')\nEOF",
  "description": "Size technical pool and inspect quality at depth"
}
Bash result
code>=3 or tech>=3: docs 2849 tokens 2.4M
code>=1.5 or tech>=2: docs 6550 tokens 5.0M
code>=0.5 or tech>=1.5: docs 16677 tokens 12.7M
code>=0.3 or tech>=1.0: docs 24347 tokens 19.2M
--- 0M: sS=0.93 code=7.5 tech=6.5 :: 'XForms/Read and write with get and put\nSometimes all you need to do is to put a nice user friendly form that edits a single static XML file. In this case a static file is'
--- 1M: sS=0.17 code=0.1 tech=2.0 :: '*<|endoftext|>Microsoft Word 2003 allows users to insert various objects, sounds, clip art and pictures into their documents, including PDF files. Embedding PDF files wit'
--- 3M: sS=-0.08 code=1.7 tech=0.1 :: 'os E-Alerts<|endoftext|>Housing Heroes\nhome\navailable properties\nFor Sale\nfor rent\nour products\nDeposit Layby Explained for Buyers & Sellers\nLive-In Layby Explained for B'
--- 6M: sS=-0.53 code=4.3 tech=0.0 :: 'Leon Washington’s record-tying eighth kickoff return for a touchdown in Sunday’s game against the Dolphins has earned the Seahawks’ return specialist NFC Special Teams Pl'

[stdout]
code>=3 or tech>=3: docs 2849 tokens 2.4M
code>=1.5 or tech>=2: docs 6550 tokens 5.0M
code>=0.5 or tech>=1.5: docs 16677 tokens 12.7M
code>=0.3 or tech>=1.0: docs 24347 tokens 19.2M
--- 0M: sS=0.93 code=7.5 tech=6.5 :: 'XForms/Read and write with get and put\nSometimes all you need to do is to put a nice user friendly form that edits a single static XML file. In this case a static file is'
--- 1M: sS=0.17 code=0.1 tech=2.0 :: '*<|endoftext|>Microsoft Word 2003 allows users to insert various objects, sounds, clip art and pictures into their documents, including PDF files. Embedding PDF files wit'
--- 3M: sS=-0.08 code=1.7 tech=0.1 :: 'os E-Alerts<|endoftext|>Housing Heroes\nhome\navailable properties\nFor Sale\nfor rent\nour products\nDeposit Layby Explained for Buyers & Sellers\nLive-In Layby Explained for B'
--- 6M: sS=-0.53 code=4.3 tech=0.0 :: 'Leon Washington’s record-tying eighth kickoff return for a touchdown in Sunday’s game against the Dolphins has earned the Seahawks’ return specialist NFC Special Teams Pl'
[metadata] {"noOutputExpected": false}
#32
reasoning (redacted)

encrypted chain-of-thought — recorded, not exposed

toolBashCheck round-3 results
args
{
  "command": "sleep 115; cat work/round3.log; cat /workspace/.timer/remaining_secs",
  "description": "Check round-3 results"
}
Bash result
[diag] OVERALL_PPL 301.417 loss 5.7085
[diag]   REG W loss 6.4412 ppl 627.2
[diag]   REG P loss 5.5615 ppl 260.2
[diag]   REG N loss 5.6767 ppl 292.0
[diag]   REG S loss 5.1521 ppl 172.8
3938

[stdout]
[diag] OVERALL_PPL 301.417 loss 5.7085
[diag]   REG W loss 6.4412 ppl 627.2
[diag]   REG P loss 5.5615 ppl 260.2
[diag]   REG N loss 5.6767 ppl 292.0
[diag]   REG S loss 5.1521 ppl 172.8
3938
[metadata] {"noOutputExpected": false}
#33
narration

Key diagnostic: W (wikitext) loss 6.44 / ppl 627 dominates, while S is the easiest (ppl 173). So leverage is in the encyclopedic quarter, not the code one. But my round-3 eval jobs produced no output — let me diagnose verbosely.

toolBashRun one eval verbosely to diagnose
args
{
  "command": "PYTHONPATH=/workspace timeout 200 bash work/eval.sh /tmp/sel_prf.json prf 2>&1 | tail -5; cat /workspace/.timer/remaining_secs",
  "description": "Run one eval verbosely to diagnose"
}
Bash result
packed 12000000 tokens from 17023 docs -> /tmp/t_prf.npy
HELDOUT_PPL 319.066  loss 5.7654  train_s 65  /tmp/t_prf.npy
3818

[stdout]
packed 12000000 tokens from 17023 docs -> /tmp/t_prf.npy
HELDOUT_PPL 319.066  loss 5.7654  train_s 65  /tmp/t_prf.npy
3818
[metadata] {"noOutputExpected": false}
#34
narration

PRF didn't help (319.1 vs 315.7) — dropping it. Concurrency was breaking the eval jobs, so I'll run at most two at a time. Let me inspect the W/P/N lists at depth, since W dominates the loss.

toolBashInspect W/P/N lists at depth
args
{
  "command": "python - <<'EOF'\nimport numpy as np, json, sys\nsys.path.insert(0,'work')\nfrom curate_core import load, gates\nids,ntok,score,feat,sig,rep=load()\ng=gates(ntok,feat,rep,True)\ntxt={}\nfor line in open('data/pool.jsonl'):\n    r=json.loads(line); txt[r['id']]=r['text']\nfor j,name in [(0,'W'),(1,'P'),(2,'N')]:\n    c=np.where(g)[0]; c=c[np.argsort(-score[c,j])]; cum=np.cumsum(ntok[c])\n    print('#'*10,name,'eligible tokens %.1fM'%(ntok[c].sum()/1e6))\n    for t in [0,1_500_000,3_000_000]:\n        k=min(int(np.searchsorted(cum,t)),len(c)-1); i=c[k]\n        print(f'  {t/1e6:.1f}M s={score[i,j]:.2f} :: {txt[int(ids[i])][:150]!r}')\nEOF",
  "description": "Inspect W/P/N lists at depth"
}
Bash result
########## W eligible tokens 93.4M
  0.0M s=0.71 :: ' work!<|endoftext|>It is understood that the processor is a Qualcomm Snapdragon 630 this year with the processor 660 to be accompanied by the flagship'
  1.5M s=0.09 :: ' weekend I booked my first trip of 2019 to the Western Front. I couldn’t wait any longer than January! It’s just an over night visit, but it’ll be eno'
  3.0M s=0.05 :: '<|endoftext|>Collioure is located in the Languedoc-Roussillon region. This region happens to be the single largest wine producing area in the world wi'
########## P eligible tokens 93.4M
  0.0M s=0.61 :: "How Will Obama's Israel Visit Play Out at Home?3/21/2013 4:49PM\nPresident Obama made a public appeal for sacrifice in the name of peace during his vis"
  1.5M s=0.38 :: 'ansas<|endoftext|>Billionaire casino magnate Sheldon Adelson has withdrawn his proposed investment in a $1.9-billion stadium plan to house the Raiders'
  3.0M s=0.36 :: 'Last of three parts\nMost people think that if you drink and drive, and you wear the blue, you’ll lose your job and your career if you’re caught.\nThe t'
########## N eligible tokens 93.4M
  0.0M s=0.83 :: 'Amarnath Yatra 2017\nAmarnath Yatra 2017 News\nJammu and Kashmir police said three people, alleged conspirators in the 10 July attack on Amarnath pilgri'
  1.5M s=0.34 :: ' Lawrence was onstage when a white tiger viciously attacked Roy Horn in 2003 during their Las Vegas show. Now, after a 15-year battle with PTSD, Lawre'
  3.0M s=0.30 :: '.<|endoftext|>Kragthorpe: New-look RSL playing to mixed reviews so far\nFour months after the events of that Monday in December radically altered the l'

[stdout]
########## W eligible tokens 93.4M
  0.0M s=0.71 :: ' work!<|endoftext|>It is understood that the processor is a Qualcomm Snapdragon 630 this year with the processor 660 to be accompanied by the flagship'
  1.5M s=0.09 :: ' weekend I booked my first trip of 2019 to the Western Front. I couldn’t wait any longer than January! It’s just an over night visit, but it’ll be eno'
  3.0M s=0.05 :: '<|endoftext|>Collioure is located in the Languedoc-Roussillon region. This region happens to be the single largest wine producing area in the world wi'
########## P eligible tokens 93.4M
  0.0M s=0.61 :: "How Will Obama's Israel Visit Play Out at Home?3/21/2013 4:49PM\nPresident Obama made a public appeal for sacrifice in the name of peace during his vis"
  1.5M s=0.38 :: 'ansas<|endoftext|>Billionaire casino magnate Sheldon Adelson has withdrawn his proposed investment in a $1.9-billion stadium plan to house the Raiders'
  3.0M s=0.36 :: 'Last of three parts\nMost people think that if you drink and drive, and you wear the blue, you’ll lose your job and your career if you’re caught.\nThe t'
########## N eligible tokens 93.4M
  0.0M s=0.83 :: 'Amarnath Yatra 2017\nAmarnath Yatra 2017 News\nJammu and Kashmir police said three people, alleged conspirators in the 10 July attack on Amarnath pilgri'
  1.5M s=0.34 :: ' Lawrence was onstage when a white tiger viciously attacked Roy Horn in 2003 during their Las Vegas show. Now, after a 15-year battle with PTSD, Lawre'
  3.0M s=0.30 :: '.<|endoftext|>Kragthorpe: New-look RSL playing to mixed reviews so far\nFour months after the events of that Monday in December radically altered the l'
[metadata] {"noOutputExpected": false}
#35
narration

The W list is the broken one — it degrades to travel blogs, which explains its loss of 6.44. Root cause: the W profile is scored against pool background, which mostly just says "not junk" — a criterion all news satisfies. Let me make the profiles discriminative between registers so W retrieves genuinely encyclopedic prose.

toolBashBuild discriminative profiles and encyclopedic features
args
{
  "command": "cat > work/disc.py <<'EOF'\n\"\"\"Stage 3b: discriminative register profiles + encyclopedic style features.\n\nScoring register r against the *pool background* mostly measures \"not junk\", which every\nnews article satisfies -- so the W (encyclopedic) list collapsed into generic web prose.\nInstead score each register against a mixture of the OTHER registers and the background:\n    lr_r(t) = log P_r(t) - log( 0.5 * P_other(t) + 0.5 * P_bg(t) )\nwhich isolates what makes a register distinct from its siblings.\n\"\"\"\nimport numpy as np, json, re, sys\nfrom multiprocessing import Pool\n\nV = 50257; REG = ['W','P','N','S']\ndev = np.load('/workspace/data/multi_dev.npy').astype(np.int64)\nlogpbg = np.load('/workspace/work/logpbg.npy').astype(np.float64); P_bg = np.exp(logpbg)\ncnt = np.stack([np.bincount(dev[j*250_000:(j+1)*250_000], minlength=V).astype(np.float64)\n                for j in range(4)])\nMIN = 6\nlr = np.zeros((4, V), dtype=np.float32)\nfor j in range(4):\n    other = cnt.sum(0) - cnt[j]\n    P_o = (other + 300.0 * P_bg) / (other.sum() + 300.0)\n    P_r = (cnt[j] + 300.0 * P_bg) / (cnt[j].sum() + 300.0)\n    ref = 0.5 * P_o + 0.5 * P_bg\n    v = np.clip(np.log(P_r) - np.log(ref), -6, 6)\n    v[cnt[j] < MIN] = 0.0\n    lr[j] = v\nnp.save('/workspace/work/logratio_disc.npy', lr)\n\n# rescore pool under discriminative profiles\nM = np.load('/workspace/work/pool_meta.npz'); ids, ntok = M['ids'], M['ntok']\nshard_of = ids // 1500\nout = np.zeros((len(ids), 4), dtype=np.float32)\nfor s in np.unique(shard_of):\n    m = np.where(shard_of == s)[0]\n    cat = np.load(f'/workspace/work/shards/tok_{s:03d}.npy'); o = 0\n    for k in m:\n        n = int(ntok[k]); a = cat[o:o+n].astype(np.int64); o += n\n        out[k] = lr[:, a].mean(axis=1)\nnp.save('/workspace/work/score_disc.npy', out)\n\n# encyclopedic surface style: third-person, entity/date dense, no reader address / promo\nPRON = re.compile(r\"\\b(i|you|your|my|we|our|me|us|i'm|you're|we're)\\b\", re.I)\nYEAR = re.compile(r'\\b(1[6-9]\\d\\d|20[0-2]\\d)\\b')\nPAST = re.compile(r'\\b(was|were|had|became|founded|established|during|however|although|which)\\b', re.I)\nPROMO = re.compile(r'(http|www\\.|click here|subscribe|\\$\\d|% off|sign up|contact us|©|cookies)', re.I)\nCAPMID = re.compile(r'(?<=[a-z,] )[A-Z][a-z]{2,}')\ndef work(lines):\n    r = []\n    for line in lines:\n        d = json.loads(line); t = d['text']; w = max(1, len(t.split()))\n        r.append((d['id'], len(PRON.findall(t))/w*100, len(YEAR.findall(t))/w*100,\n                  len(PAST.findall(t))/w*100, len(PROMO.findall(t))/w*100,\n                  len(CAPMID.findall(t))/w*100))\n    return r\nif __name__ == '__main__':\n    jobs, buf = [], []\n    for line in open('/workspace/data/pool.jsonl'):\n        buf.append(line)\n        if len(buf) == 2000: jobs.append(buf); buf = []\n    if buf: jobs.append(buf)\n    res = []\n    with Pool(16) as p:\n        for x in p.imap(work, jobs): res.extend(x)\n    d = {x[0]: x[1:] for x in res}\n    ES = np.array([d[int(i)] for i in ids], dtype=np.float32)\n    np.save('/workspace/work/encfeat.npy', ES)\n    print('pron/year/past/promo/capmid medians', np.median(ES, axis=0).round(2))\n    for j in range(4):\n        print(REG[j], 'top disc tokens ok, score mean %.3f' % out[:, j].mean())\nEOF\npython work/disc.py",
  "description": "Build discriminative profiles and encyclopedic features"
}
Bash result
pron/year/past/promo/capmid medians [ 2.27  0.23  0.35  0.   10.1 ]
W top disc tokens ok, score mean -0.308
P top disc tokens ok, score mean 0.079
N top disc tokens ok, score mean -0.056
S top disc tokens ok, score mean -0.216

[stdout]
pron/year/past/promo/capmid medians [ 2.27  0.23  0.35  0.   10.1 ]
W top disc tokens ok, score mean -0.308
P top disc tokens ok, score mean 0.079
N top disc tokens ok, score mean -0.056
S top disc tokens ok, score mean -0.216
[metadata] {"noOutputExpected": false}
#36
reasoning (redacted)

encrypted chain-of-thought — recorded, not exposed

toolBashCheck discriminative W retrieval quality
args
{
  "command": "python - <<'EOF'\nimport numpy as np, json, sys\nsys.path.insert(0,'work')\nfrom curate_core import load, gates\nids,ntok,score,feat,sig,rep=load('/workspace/work/score_disc.npy')\nE=np.load('work/encfeat.npy'); C=np.load('work/codefeat.npy')\ng=gates(ntok,feat,rep,True)\ntxt={}\nfor line in open('data/pool.jsonl'):\n    r=json.loads(line); txt[r['id']]=r['text']\n# W with discriminative score alone\nfor name,mask,j in [('W-disc',g,0),('W-disc+encstyle',g&(E[:,0]<1.2)&(E[:,3]<0.3)&(E[:,1]>0.15),0),('N-disc',g,2)]:\n    c=np.where(mask)[0]; c=c[np.argsort(-score[c,j])]; cum=np.cumsum(ntok[c])\n    print('#'*8,name,'avail %.1fM'%(ntok[c].sum()/1e6))\n    for t in [0,1_500_000,3_000_000]:\n        k=min(int(np.searchsorted(cum,t)),len(c)-1); i=c[k]\n        print(f'  {t/1e6:.1f}M s={score[i,j]:.2f} :: {txt[int(ids[i])][:150]!r}')\nEOF",
  "description": "Check discriminative W retrieval quality"
}
Bash result
######## W-disc avail 93.4M
  0.0M s=0.69 :: ' work!<|endoftext|>It is understood that the processor is a Qualcomm Snapdragon 630 this year with the processor 660 to be accompanied by the flagship'
  1.5M s=0.04 :: 'ieMeyer.com has just posted an official announcement about the Wolf Pack in New Moon-\nLos Angeles, CA — March 23, 2009 — Summit Entertainment announce'
  3.0M s=-0.01 :: ' Immediate ReleaseJune 27, 2017\nAbout 80 personnel called to wildfire; full containment expected by evening\n(JUNE 28 UPDATE BELOW)\nWoodacre, CA – The '
######## W-disc+encstyle avail 13.7M
  0.0M s=0.63 :: 'omaya Hendousa founded dumped in slums east of Khartoum , severely tortured and her hair shaved confirmed resources close to her family . Hendousa fam'
  1.5M s=0.01 :: "<|endoftext|>This retrospective at the Centre for Fine Arts\npresents a variety of aspects of the Danish artist's considerable oeuvre. The exhibition a"
  3.0M s=-0.04 :: 'SC upholds MERC’s nod for Tata Power deal\nThe Supreme Court upheld the Maharashtra Electricity Regulatory Commission’s (MERC’s) verdict over the sale '
######## N-disc avail 93.4M
  0.0M s=0.81 :: 'Amarnath Yatra 2017\nAmarnath Yatra 2017 News\nJammu and Kashmir police said three people, alleged conspirators in the 10 July attack on Amarnath pilgri'
  1.5M s=0.28 :: ' departure of Nicola Roxon and Chris Evans from the Government has been reported widely as though they are rats leaving the sinking ship. There is no '
  3.0M s=0.24 :: '<|endoftext|>Dated: 04 Apr 2009\nSearch below by year or month.\nTry our search to find a specific issue of Socialist Worker, or use the search at the t'

[stdout]
######## W-disc avail 93.4M
  0.0M s=0.69 :: ' work!<|endoftext|>It is understood that the processor is a Qualcomm Snapdragon 630 this year with the processor 660 to be accompanied by the flagship'
  1.5M s=0.04 :: 'ieMeyer.com has just posted an official announcement about the Wolf Pack in New Moon-\nLos Angeles, CA — March 23, 2009 — Summit Entertainment announce'
  3.0M s=-0.01 :: ' Immediate ReleaseJune 27, 2017\nAbout 80 personnel called to wildfire; full containment expected by evening\n(JUNE 28 UPDATE BELOW)\nWoodacre, CA – The '
######## W-disc+encstyle avail 13.7M
  0.0M s=0.63 :: 'omaya Hendousa founded dumped in slums east of Khartoum , severely tortured and her hair shaved confirmed resources close to her family . Hendousa fam'
  1.5M s=0.01 :: "<|endoftext|>This retrospective at the Centre for Fine Arts\npresents a variety of aspects of the Danish artist's considerable oeuvre. The exhibition a"
  3.0M s=-0.04 :: 'SC upholds MERC’s nod for Tata Power deal\nThe Supreme Court upheld the Maharashtra Electricity Regulatory Commission’s (MERC’s) verdict over the sale '
######## N-disc avail 93.4M
  0.0M s=0.81 :: 'Amarnath Yatra 2017\nAmarnath Yatra 2017 News\nJammu and Kashmir police said three people, alleged conspirators in the 10 July attack on Amarnath pilgri'
  1.5M s=0.28 :: ' departure of Nicola Roxon and Chris Evans from the Government has been reported widely as though they are rats leaving the sinking ship. There is no '
  3.0M s=0.24 :: '<|endoftext|>Dated: 04 Apr 2009\nSearch below by year or month.\nTry our search to find a specific issue of Socialist Worker, or use the search at the t'
[metadata] {"noOutputExpected": false}
#37
narration

The pool has no true encyclopedia, so W is largely irreducible — but formal expository prose is the best proxy. Let me build the v2 selector with register-specific gates and evaluate.

toolBashBuild v2 selections
args
{
  "command": "cat > work/select_v2.py <<'EOF'\n\"\"\"v2 selection: per-register candidate gates + discriminative ranking + token-balanced mix.\"\"\"\nimport numpy as np, json, argparse, sys\nsys.path.insert(0, '/workspace/work')\nfrom curate_core import gates, dedup_mask, FN\n\ndef build(weights, scorefile, use_reg_gates=True, budget=12_000_000, over=2.0):\n    M = np.load('/workspace/work/pool_meta.npz')\n    ids, ntok, feat, sig = M['ids'], M['ntok'], M['feat'], M['sig']\n    rep = np.load('/workspace/work/repfeat.npy')\n    score = np.load(scorefile)\n    E = np.load('/workspace/work/encfeat.npy')   # pron, year, past, promo, capmid (per 100 words)\n    C = np.load('/workspace/work/codefeat.npy')  # code, tech, indent (per 100 words)\n    gp = gates(ntok, feat, rep, True); gc = gates(ntok, feat, rep, False)\n\n    rank = score.copy()\n    if use_reg_gates:\n        # W: encyclopedic register -> third-person expository, entity/date dense, no promo\n        mW = gp & (E[:, 0] < 1.2) & (E[:, 3] < 0.3) & (E[:, 1] > 0.15)\n        # S: technical Q&A -> require explicit code/technical evidence, reward it in the ranking\n        mS = gc & ((C[:, 0] >= 0.5) | (C[:, 1] >= 1.5))\n        rank[:, 3] = score[:, 3] + 0.10 * np.minimum(C[:, 0], 10) + 0.05 * np.minimum(C[:, 1], 10)\n        rank[:, 0] = score[:, 0] + 0.05 * np.minimum(E[:, 1], 4)\n        elig = [mW, gp, gp, mS]\n    else:\n        elig = [gp, gp, gp, gc]\n\n    keep = dedup_mask(sig, np.argsort(-rank.max(axis=1)))\n    lists = [np.where(elig[j] & keep)[0][np.argsort(-rank[np.where(elig[j] & keep)[0], j])]\n             for j in range(4)]\n    for j, n in enumerate(['W','P','N','S']):\n        print(f'  {n}: {len(lists[j])} candidates, {ntok[lists[j]].sum()/1e6:.1f}M tokens')\n\n    w = np.array(weights, float); w /= w.sum()\n    ptr = np.zeros(4, int); tot = np.zeros(4); taken, out = set(), []\n    while tot.sum() < budget * over:\n        j = int(np.argmin(tot / np.maximum(w, 1e-9))); adv = False\n        while ptr[j] < len(lists[j]):\n            k = lists[j][ptr[j]]; ptr[j] += 1; i = int(ids[k])\n            if i in taken: continue\n            taken.add(i); out.append(i); tot[j] += int(ntok[k]) + 1; adv = True; break\n        if not adv:\n            w[j] = 0.0\n            if w.sum() == 0: break\n            w /= w.sum()\n    print('  shares', (tot / tot.sum()).round(3), 'total %.1fM' % (tot.sum()/1e6))\n    return out\n\nif __name__ == '__main__':\n    ap = argparse.ArgumentParser()\n    ap.add_argument('--weights', default='1,1,1,1')\n    ap.add_argument('--scores', default='/workspace/work/score_disc.npy')\n    ap.add_argument('--no_reg_gates', action='store_true')\n    ap.add_argument('--out', required=True)\n    a = ap.parse_args()\n    sel = build([float(x) for x in a.weights.split(',')], a.scores, not a.no_reg_gates)\n    assert len(sel) == len(set(sel))\n    json.dump(sel, open(a.out, 'w')); print('wrote', a.out, len(sel))\nEOF\npython work/select_v2.py --weights 1,1,1,1 --out /tmp/v2a.json\npython work/select_v2.py --weights 1.5,1,1,1 --out /tmp/v2b.json | tail -2\ncat /workspace/.timer/remaining_secs",
  "description": "Build v2 selections"
}
Bash result
W: 15095 candidates, 12.5M tokens
  P: 106492 candidates, 81.9M tokens
  N: 106492 candidates, 81.9M tokens
  S: 14411 candidates, 10.1M tokens
  shares [0.25 0.25 0.25 0.25] total 24.0M
wrote /tmp/v2a.json 32020
  shares [0.333 0.222 0.222 0.222] total 24.0M
wrote /tmp/v2b.json 31619
3668

[stdout]
  W: 15095 candidates, 12.5M tokens
  P: 106492 candidates, 81.9M tokens
  N: 106492 candidates, 81.9M tokens
  S: 14411 candidates, 10.1M tokens
  shares [0.25 0.25 0.25 0.25] total 24.0M
wrote /tmp/v2a.json 32020
  shares [0.333 0.222 0.222 0.222] total 24.0M
wrote /tmp/v2b.json 31619
3668
[metadata] {"noOutputExpected": false}
#38
reasoning (redacted)

encrypted chain-of-thought — recorded, not exposed

toolBashEvaluate v2 variants
args
{
  "command": "export PYTHONPATH=/workspace && for v in v2a v2b; do bash work/eval.sh /tmp/$v.json $v 2>&1 | tail -1 | sed \"s/^/[$v] /\"; done; cat /workspace/.timer/remaining_secs",
  "description": "Evaluate v2 variants"
}
Bash result · error
Exit code 143
Command timed out after 2m 0s
[v2a] HELDOUT_PPL 312.630  loss 5.7450  train_s 51  /tmp/t_v2a.npy

[error] tool reported failure
#39
narration

v2a: 312.6 — better than uniform baseline (315.7) but the best so far is still the S-weighted mix at 301.4. Let me test the improved buckets at that weighting.

toolBashTest v2 buckets at S-weighted mixture
args
{
  "command": "export PYTHONPATH=/workspace\npython work/select_v2.py --weights 1,1,1,2 --out /tmp/v2c.json | tail -1\npython work/select_v2.py --weights 1,1,1,2 --scores /workspace/work/pool_meta_score.npy --out /tmp/x.json 2>/dev/null || python - <<'EOF'\nimport numpy as np\nM=np.load('/workspace/work/pool_meta.npz'); np.save('/workspace/work/score_bg.npy', M['score'])\nEOF\npython work/select_v2.py --weights 1,1,1,2 --scores /workspace/work/score_bg.npy --out /tmp/v2d.json | tail -1\nfor v in v2c v2d; do bash work/eval.sh /tmp/$v.json $v 2>&1 | tail -1 | sed \"s/^/[$v] /\"; done\ncat /workspace/.timer/remaining_secs",
  "description": "Test v2 buckets at S-weighted mixture",
  "timeout": 420000
}
Bash result
wrote /tmp/v2c.json 32961
wrote /tmp/v2d.json 32593
[v2c] HELDOUT_PPL 305.200  loss 5.7210  train_s 51  /tmp/t_v2c.npy
[v2d] HELDOUT_PPL 301.900  loss 5.7101  train_s 51  /tmp/t_v2d.npy
3357

[stdout]
wrote /tmp/v2c.json 32961
wrote /tmp/v2d.json 32593
[v2c] HELDOUT_PPL 305.200  loss 5.7210  train_s 51  /tmp/t_v2c.npy
[v2d] HELDOUT_PPL 301.900  loss 5.7101  train_s 51  /tmp/t_v2d.npy
3357
[metadata] {"noOutputExpected": false}
#40
narration

Discriminative scoring slightly hurts; the register gates are neutral. The dominant levers are the balanced mixture and the S weighting. Let me sweep the S share further.

toolBashSweep S register weight
args
{
  "command": "export PYTHONPATH=/workspace\npython train_nano.py --train_npy /tmp/t_w1113.npy --heldout_npy data/multi_dev.npy --out_json /tmp/e1.json 2>&1 | grep HELDOUT | sed 's/^/[bg-1113-nogates] /'\npython work/select_v2.py --weights 1,1,1,3 --scores work/score_bg.npy --out /tmp/v3a.json | tail -1\npython work/select_v2.py --weights 1,1,1,5 --scores work/score_bg.npy --out /tmp/v3b.json | tail -1\nfor v in v3a v3b; do bash work/eval.sh /tmp/$v.json $v 2>&1 | tail -1 | sed \"s/^/[$v] /\"; done\ncat /workspace/.timer/remaining_secs",
  "description": "Sweep S register weight",
  "timeout": 450000
}
Bash result
[bg-1113-nogates] HELDOUT_PPL 296.538  loss 5.6922  train_s 50  /tmp/t_w1113.npy
wrote /tmp/v3a.json 32613
wrote /tmp/v3b.json 32626
[v3a] HELDOUT_PPL 305.691  loss 5.7226  train_s 51  /tmp/t_v3a.npy
[v3b] HELDOUT_PPL 319.816  loss 5.7677  train_s 51  /tmp/t_v3b.npy
3107

[stdout]
[bg-1113-nogates] HELDOUT_PPL 296.538  loss 5.6922  train_s 50  /tmp/t_w1113.npy
wrote /tmp/v3a.json 32613
wrote /tmp/v3b.json 32626
[v3a] HELDOUT_PPL 305.691  loss 5.7226  train_s 51  /tmp/t_v3a.npy
[v3b] HELDOUT_PPL 319.816  loss 5.7677  train_s 51  /tmp/t_v3b.npy
3107
[metadata] {"noOutputExpected": false}
#41
narration

S share of ~50% is the sweet spot so far (296.5, new best), and over-restricting the S bucket to code-only hurts. Let me bracket the peak and test a W boost on top.

toolBashBracket S weight peak and test W boost
args
{
  "command": "export PYTHONPATH=/workspace\npython work/curate_core.py --weights 1,1,1,4 --out /tmp/s4.json | tail -1\npython work/curate_core.py --weights 1.5,1,1,3 --out /tmp/w15s3.json | tail -1\nfor v in s4 w15s3; do bash work/eval.sh /tmp/$v.json $v 2>&1 | tail -1 | sed \"s/^/[$v] /\"; done\ncat /workspace/.timer/remaining_secs",
  "description": "Bracket S weight peak and test W boost",
  "timeout": 400000
}
Bash result
wrote /tmp/s4.json 34547 ids
wrote /tmp/w15s3.json 34695 ids
[s4] HELDOUT_PPL 309.256  loss 5.7342  train_s 51  /tmp/t_s4.npy
[w15s3] HELDOUT_PPL 304.552  loss 5.7188  train_s 51  /tmp/t_w15s3.npy
2907

[stdout]
wrote /tmp/s4.json 34547 ids
wrote /tmp/w15s3.json 34695 ids
[s4] HELDOUT_PPL 309.256  loss 5.7342  train_s 51  /tmp/t_s4.npy
[w15s3] HELDOUT_PPL 304.552  loss 5.7188  train_s 51  /tmp/t_w15s3.npy
2907
[metadata] {"noOutputExpected": false}
#42
narration

Peak is at S≈3× (296.5). Now let me test a structural hypothesis: the dev target has an EOS boundary every ~370 tokens, but my docs average ~700 — matching boundary density may help. Also measuring seed noise so I don't tune on it.

toolBashTest doc-length matching and measure seed noise
args
{
  "command": "export PYTHONPATH=/workspace\npython - <<'EOF'\nimport re\np='/workspace/work/curate_core.py'; s=open(p).read()\ns=s.replace(\"def gates(ntok, feat, rep, prose=True):\",\"def gates(ntok, feat, rep, prose=True, maxtok=40000):\")\ns=s.replace(\"(ntok >= 128) & (ntok <= 40000)\",\"(ntok >= 128) & (ntok <= maxtok)\")\ns=s.replace(\"def select(weights, budget=12_000_000, over=2.0, mode='balanced', scores=None):\",\n            \"def select(weights, budget=12_000_000, over=2.0, mode='balanced', scores=None, maxtok=40000):\")\ns=s.replace(\"    g_prose = gates(ntok, feat, rep, True)\\n    g_code = gates(ntok, feat, rep, False)\",\n            \"    g_prose = gates(ntok, feat, rep, True, maxtok)\\n    g_code = gates(ntok, feat, rep, False, maxtok)\")\ns=s.replace(\"    ap.add_argument('--scores', default=None)\",\"    ap.add_argument('--scores', default=None)\\n    ap.add_argument('--maxtok', type=int, default=40000)\")\ns=s.replace(\"sel = select(w, mode=a.mode, scores=a.scores)\",\"sel = select(w, mode=a.mode, scores=a.scores, maxtok=a.maxtok)\")\nopen(p,'w').write(s)\nEOF\npython work/curate_core.py --weights 1,1,1,3 --maxtok 500 --out /tmp/len500.json | tail -1\nbash work/eval.sh /tmp/len500.json len500 2>&1 | tail -1 | sed \"s/^/[maxtok500-s3] /\"\npython work/fastpack.py /tmp/sel_w1113.json /tmp/t_best.npy >/dev/null\npython train_nano.py --train_npy /tmp/t_best.npy --heldout_npy data/multi_dev.npy --out_json /tmp/e2.json --seed 4242 2>&1 | grep HELDOUT | sed 's/^/[best-seed4242] /'\ncat /workspace/.timer/remaining_secs",
  "description": "Test doc-length matching and measure seed noise",
  "timeout": 400000
}
Bash result
wrote /tmp/len500.json 56448 ids
[maxtok500-s3] HELDOUT_PPL 415.890  loss 6.0304  train_s 51  /tmp/t_len500.npy
[best-seed4242] HELDOUT_PPL 307.946  loss 5.7299  train_s 51  /tmp/t_best.npy
2666

[stdout]
wrote /tmp/len500.json 56448 ids
[maxtok500-s3] HELDOUT_PPL 415.890  loss 6.0304  train_s 51  /tmp/t_len500.npy
[best-seed4242] HELDOUT_PPL 307.946  loss 5.7299  train_s 51  /tmp/t_best.npy
2666
[metadata] {"noOutputExpected": false}
#43
narration

Two decisive findings: length-capping is catastrophic (415.9 — refuted), and seed noise is ±6 PPL (same data, seed 4242 → 307.9 vs 296.5). So configs in the 296–310 band are statistically tied. Let me pick the plateau center with 2-seed averages rather than tuning on noise.

toolBashTwo-seed comparison of finalist mixtures plus diagnostic
args
{
  "command": "export PYTHONPATH=/workspace\npython work/curate_core.py --weights 1,1,1,2.5 --out /tmp/s25.json | tail -1\npython work/fastpack.py /tmp/s25.json /tmp/t_s25.npy >/dev/null\nfor s in 1337 4242; do python train_nano.py --train_npy /tmp/t_s25.npy --heldout_npy data/multi_dev.npy --out_json /tmp/q.json --seed $s 2>&1 | grep HELDOUT | sed \"s/^/[S2.5 seed$s] /\"; done\npython train_nano.py --train_npy \"/tmp/t_w1,1,1,2.npy\" --heldout_npy data/multi_dev.npy --out_json /tmp/q.json --seed 4242 2>&1 | grep HELDOUT | sed \"s/^/[S2 seed4242] /\"\npython work/diag.py --train_npy /tmp/t_best.npy --heldout_npy data/multi_dev.npy --out_json /tmp/diag_s3.json 2>&1 | grep -E \"OVERALL|REG \" | sed 's/^/[diag S3] /'\ncat /workspace/.timer/remaining_secs",
  "description": "Two-seed comparison of finalist mixtures plus diagnostic",
  "timeout": 520000
}
Bash result
wrote /tmp/s25.json 34579 ids
[S2.5 seed1337] HELDOUT_PPL 297.207  loss 5.6944  train_s 50  /tmp/t_s25.npy
[S2.5 seed4242] HELDOUT_PPL 296.711  loss 5.6928  train_s 50  /tmp/t_s25.npy
[S2 seed4242] HELDOUT_PPL 298.089  loss 5.6974  train_s 50  /tmp/t_w1,1,1,2.npy
[diag S3] OVERALL_PPL 296.538 loss 5.6922
[diag S3]   REG W loss 6.4226 ppl 615.6
[diag S3]   REG P loss 5.5637 ppl 260.8
[diag S3]   REG N loss 5.6993 ppl 298.6
[diag S3]   REG S loss 5.0797 ppl 160.7
2376

[stdout]
wrote /tmp/s25.json 34579 ids
[S2.5 seed1337] HELDOUT_PPL 297.207  loss 5.6944  train_s 50  /tmp/t_s25.npy
[S2.5 seed4242] HELDOUT_PPL 296.711  loss 5.6928  train_s 50  /tmp/t_s25.npy
[S2 seed4242] HELDOUT_PPL 298.089  loss 5.6974  train_s 50  /tmp/t_w1,1,1,2.npy
[diag S3] OVERALL_PPL 296.538 loss 5.6922
[diag S3]   REG W loss 6.4226 ppl 615.6
[diag S3]   REG P loss 5.5637 ppl 260.8
[diag S3]   REG N loss 5.6993 ppl 298.6
[diag S3]   REG S loss 5.0797 ppl 160.7
2376
[metadata] {"noOutputExpected": false}
#44
narration

Final answer: S weight 2.5 — mean 297.0 across two seeds with 0.5 spread (vs 302.2 for S=3, 299.8 for S=2). Now let me write the reproducible deliverable. Note my exploratory dedup used Python's randomized hash(), so the shipped script uses a stable hash and I'll re-verify its exact output.

toolBashWrite and run the final curation script
args
{
  "command": "cat > /workspace/submission/curate.py <<'PYEOF'\n#!/usr/bin/env python3\n\"\"\"Curate a 12M-token pretraining set from a raw web pool for a broad, 4-register\nhigh-quality English target (encyclopedic / HQ web prose / news / technical Q&A).\n\nSTATED CRITERION\n----------------\nThe disclosed target is an equal-parts mixture of four registers. Inspecting the dev\ntarget confirms it is exactly four 250k-token blocks, one per register. So the selection\ncriterion is *mixture matching*, not a single global \"quality\" score:\n\n  1. JUNK GATE. Drop documents whose surface statistics mark them as non-prose web junk\n     (boilerplate, directory listings, link farms, degenerate repetition, non-English).\n     The gate is register-aware: the prose gate (stopword rate, alpha rate, word length)\n     is applied to the three prose registers, while the technical register keeps a\n     code-tolerant gate, because real code/markup legitimately fails prose surface tests.\n\n  2. REGISTER AFFINITY. For each target register r, estimate a GPT-2-token unigram\n     distribution P_r from that register's dev block, and a background P_bg from a random\n     pool sample. Score every pool document by its mean clipped log-likelihood ratio\n         s_r(d) = mean_{t in d} clip( log P_r(t) - log P_bg(t), -6, 6 )\n     i.e. a Naive-Bayes register classifier. Only tokens with >= 8 occurrences in the\n     register block contribute; rarer ones are sample noise and are zeroed out.\n\n  3. NEAR-DUPLICATE REMOVAL. 4 word-5-gram MinHashes per document; a document is dropped\n     if it shares >= 2 of the 4 hashes with an already-kept document (6 hash-pair bands).\n     Survivors are resolved in best-score-first order.\n\n  4. TOKEN-BALANCED ROUND-ROBIN. Rank each register's surviving candidates by s_r and emit\n     documents by always extending whichever register is furthest behind its target token\n     share. Because the training pipeline truncates the list at 12M tokens, this makes\n     *every prefix* of the selection match the intended mixture.\n\n     Target shares are (W, P, N, S) proportional to (1, 1, 1, 2.5). The technical register\n     is deliberately over-weighted relative to its 25% share of the target: measured on the\n     dev target, upweighting it 2-3x is worth ~15-20 perplexity points versus a uniform\n     25/25/25/25 mixture (and 5x is clearly worse). See claim.md.\n\nUsage:  python curate.py [--out selection.json]\nRuntime: ~3 min on 16 cores (one GPT-2 tokenization pass over the pool).\n\"\"\"\nimport argparse, json, os, re, zlib, sys\nimport numpy as np\nfrom multiprocessing import Pool\nfrom transformers import AutoTokenizer\n\nPOOL = '/workspace/data/pool.jsonl'\nDEV = '/workspace/data/multi_dev.npy'\nCACHE = '/workspace/work/final_cache'\nV, EOS = 50257, 50256\nREG = ['W', 'P', 'N', 'S']          # encyclopedic, hq web prose, news, technical Q&A\nWEIGHTS = [1.0, 1.0, 1.0, 2.5]\nBUDGET = 12_000_000\nOVERSHOOT = 2.0                     # emit ~2x the budget so truncation is never short\nNPROC = 16\nSTOP = set(\"the be to of and a in that have i it for not on with he as you do at this but his by \"\n           \"from they we say her she or an will my one all would there their\".split())\n\n# ----------------------------------------------------------------- stage 1: profiles\ndef build_profiles():\n    dev = np.load(DEV).astype(np.int64)\n    assert len(dev) % 4 == 0\n    Q = len(dev) // 4                                   # dev = 4 equal register blocks\n    tok = AutoTokenizer.from_pretrained('gpt2')\n    sample = []\n    with open(POOL) as f:                               # every 50th doc -> background\n        for i, line in enumerate(f):\n            if i % 50 == 0: sample.append(json.loads(line)['text'])\n    sample = sample[:3500]\n    bg = np.zeros(V)\n    for i in range(0, len(sample), 64):\n        for ids in tok(sample[i:i+64], add_special_tokens=False).input_ids:\n            np.add.at(bg, np.asarray(ids, dtype=np.int64), 1.0)\n    P_bg = (bg + 0.1) / (bg.sum() + 0.1 * V)\n    lr = np.zeros((4, V), dtype=np.float32)\n    for j in range(4):\n        c = np.bincount(dev[j*Q:(j+1)*Q], minlength=V).astype(np.float64)\n        P_r = (c + 300.0 * P_bg) / (c.sum() + 300.0)     # shrink toward background\n        v = np.clip(np.log(P_r) - np.log(P_bg), -6, 6)\n        v[c < 8] = 0.0                                  # rare-token noise carries no signal\n        lr[j] = v\n    np.save(f'{CACHE}/logratio.npy', lr)\n\n# ------------------------------------------- stage 2: tokenize + score + surface features\n_tok = None\n_LR = None\ndef _init():\n    global _tok, _LR\n    _tok = AutoTokenizer.from_pretrained('gpt2')\n    _LR = np.load(f'{CACHE}/logratio.npy')\n\ndef _surface(t):\n    n = len(t); words = t.split(); nw = len(words)\n    if n == 0 or nw == 0: return None\n    lw = [w.lower().strip('.,;:!?()\"\\'') for w in words]\n    lines = t.split('\\n'); nl = len(lines)\n    sig = [0, 0, 0, 0]\n    if nw >= 8:                                         # stable (hash-seed independent) MinHash\n        grams = [zlib.crc32(' '.join(lw[i:i+5]).encode()) for i in range(nw - 4)]\n        sig = [min((g ^ salt) & 0xFFFFFFFF for g in grams)\n               for salt in (0x9e3779b9, 0x85ebca6b, 0xc2b2ae35, 0x27d4eb2f)]\n    return (sum(c.isalpha() for c in t)/n, sum(c.isdigit() for c in t)/n,\n            sum(ord(c) > 127 for c in t)/n, sum(c.isupper() for c in t)/n,\n            sum(len(w) for w in words)/nw, sum(w in STOP for w in lw)/nw,\n            1.0 - len(set(lines))/nl, sum(len(l) < 40 for l in lines)/nl, sig)\n\ndef _work(job):\n    shard, lines = job\n    recs = [json.loads(l) for l in lines]\n    texts = [r['text'] for r in recs]\n    enc = []\n    for i in range(0, len(texts), 48):\n        enc.extend(_tok(texts[i:i+48], add_special_tokens=False).input_ids)\n    ids, ntok, sc, ft, sg, rp = [], [], [], [], [], []\n    for r, t, e in zip(recs, texts, enc):\n        s = _surface(t)\n        if s is None or len(e) == 0: continue\n        a = np.asarray(e, dtype=np.int64)\n        c = np.bincount(a)\n        b = a[:-1] * V + a[1:]\n        ids.append(r['id']); ntok.append(len(a))\n        sc.append(_LR[:, a].mean(axis=1)); ft.append(s[:8]); sg.append(s[8])\n        rp.append(((c > 0).sum()/len(a), c.max()/len(a),\n                   len(np.unique(b))/max(1, len(a)-1)))     # degeneracy / repetition\n    return (shard, np.array(ids, np.int32), np.array(ntok, np.int32), np.array(sc, np.float32),\n            np.array(ft, np.float32), np.array(sg, np.int64), np.array(rp, np.float32))\n\ndef score_pool():\n    jobs, buf, k = [], [], 0\n    with open(POOL) as f:\n        for line in f:\n            buf.append(line)\n            if len(buf) == 1500: jobs.append((k, buf)); buf = []; k += 1\n    if buf: jobs.append((k, buf))\n    res = []\n    with Pool(NPROC, initializer=_init) as p:\n        for r in p.imap_unordered(_work, jobs): res.append(r)\n    res.sort(key=lambda r: r[0])\n    np.savez(f'{CACHE}/meta.npz', ids=np.concatenate([r[1] for r in res]),\n             ntok=np.concatenate([r[2] for r in res]), score=np.concatenate([r[3] for r in res]),\n             feat=np.concatenate([r[4] for r in res]), sig=np.concatenate([r[5] for r in res]),\n             rep=np.concatenate([r[6] for r in res]))\n\n# --------------------------------------------------------------- stage 3: gate + select\ndef junk_gate(ntok, F, R, prose):\n    \"\"\"F cols: alpha,digit,nonascii,upper,meanwordlen,stopfrac,duplines,shortlines\n       R cols: uniq-token frac, top-token share, uniq-bigram frac\"\"\"\n    g = ((ntok >= 128) & (ntok <= 40000) & (F[:, 2] <= 0.10) & (F[:, 6] <= 0.25) &\n         (R[:, 2] >= 0.55) & (R[:, 1] <= 0.12) & (R[:, 0] >= 0.25))\n    if prose:\n        g &= ((F[:, 0] >= 0.60) & (F[:, 5] >= 0.16) & (F[:, 3] <= 0.20) & (F[:, 1] <= 0.12) &\n              (F[:, 4] >= 3.4) & (F[:, 4] <= 7.5) & (F[:, 7] <= 0.85))\n    else:                       # code/markup: prose surface gates would delete real code\n        g &= (F[:, 0] >= 0.35) & (F[:, 3] <= 0.35) & (F[:, 4] <= 12.0)\n    return g\n\ndef dedup(sig, order):\n    keep = np.ones(len(sig), bool)\n    bands = [(0,1), (0,2), (0,3), (1,2), (1,3), (2,3)]\n    seen = [set() for _ in bands]\n    for k in order:\n        s = sig[k]\n        if s[0] == 0 and s[1] == 0: continue\n        key = [(int(s[a]) << 21) ^ int(s[b]) for a, b in bands]\n        if any(key[b] in seen[b] for b in range(len(bands))):\n            keep[k] = False; continue\n        for b in range(len(bands)): seen[b].add(key[b])\n    return keep\n\ndef select():\n    M = np.load(f'{CACHE}/meta.npz')\n    ids, ntok, score, F, sig, R = M['ids'], M['ntok'], M['score'], M['feat'], M['sig'], M['rep']\n    gp = junk_gate(ntok, F, R, True); gc = junk_gate(ntok, F, R, False)\n    elig = [gp, gp, gp, gc]\n    keep = dedup(sig, np.argsort(-score.max(axis=1)))\n    lists = []\n    for j in range(4):\n        c = np.where(elig[j] & keep)[0]\n        lists.append(c[np.argsort(-score[c, j])])\n        print(f'  {REG[j]}: {len(c)} candidates, {ntok[c].sum()/1e6:.1f}M tokens')\n    w = np.array(WEIGHTS); w = w / w.sum()\n    ptr = np.zeros(4, int); tot = np.zeros(4); taken, out = set(), []\n    while tot.sum() < BUDGET * OVERSHOOT:\n        j = int(np.argmin(tot / np.maximum(w, 1e-9))); adv = False\n        while ptr[j] < len(lists[j]):\n            k = lists[j][ptr[j]]; ptr[j] += 1; i = int(ids[k])\n            if i in taken: continue\n            taken.add(i); out.append(i); tot[j] += int(ntok[k]) + 1; adv = True; break\n        if not adv:\n            w[j] = 0.0\n            if w.sum() == 0: break\n            w = w / w.sum()\n    print('  register token shares:', (tot / tot.sum()).round(3),\n          'total %.1fM tokens' % (tot.sum() / 1e6))\n    return out\n\nif __name__ == '__main__':\n    ap = argparse.ArgumentParser()\n    ap.add_argument('--out', default='/workspace/submission/selection.json')\n    ap.add_argument('--fresh', action='store_true', help='ignore cached stages')\n    a = ap.parse_args()\n    os.makedirs(CACHE, exist_ok=True)\n    if a.fresh or not os.path.exists(f'{CACHE}/logratio.npy'):\n        print('stage 1: register profiles'); build_profiles()\n    if a.fresh or not os.path.exists(f'{CACHE}/meta.npz'):\n        print('stage 2: tokenize + score pool'); score_pool()\n    print('stage 3: gate, dedup, balanced select')\n    sel = select()\n    assert len(sel) == len(set(sel)), 'duplicate ids'\n    json.dump(sel, open(a.out, 'w'))\n    print(f'wrote {a.out}: {len(sel)} ids')\nPYEOF\nTOKENIZERS_PARALLELISM=false python submission/curate.py --fresh 2>&1 | grep -vE \"warn|Warn|indices\"; cat /workspace/.timer/remaining_secs",
  "description": "Write and run the final curation script",
  "timeout": 500000
}
Bash result
stage 1: register profiles
stage 2: tokenize + score pool
stage 3: gate, dedup, balanced select
  W: 109181 candidates, 84.4M tokens
  P: 109181 candidates, 84.4M tokens
  N: 109181 candidates, 84.4M tokens
  S: 116142 candidates, 91.4M tokens
  register token shares: [0.182 0.182 0.182 0.455] total 24.0M tokens
wrote /workspace/submission/selection.json: 34584 ids
2246

[stdout]
stage 1: register profiles
stage 2: tokenize + score pool
stage 3: gate, dedup, balanced select
  W: 109181 candidates, 84.4M tokens
  P: 109181 candidates, 84.4M tokens
  N: 109181 candidates, 84.4M tokens
  S: 116142 candidates, 91.4M tokens
  register token shares: [0.182 0.182 0.182 0.455] total 24.0M tokens
wrote /workspace/submission/selection.json: 34584 ids
2246
[metadata] {"noOutputExpected": false}
#45
narration

Now let me validate the selection and run the official packer end-to-end while I write claim.md.

toolBashValidate selection and launch official end-to-end eval
args
{
  "command": "python - <<'EOF'\nimport json, numpy as np\nsel=json.load(open('/workspace/submission/selection.json'))\nprint('ids',len(sel),'unique',len(set(sel)),'min',min(sel),'max',max(sel))\nM=np.load('/workspace/work/final_cache/meta.npz'); nt=dict(zip(M['ids'].tolist(),M['ntok'].tolist()))\nprint('tokens covered (+EOS):', sum(nt[i]+1 for i in sel))\nassert len(sel)==len(set(sel)) and min(sel)>=0 and max(sel)<182016\nprint('VALID')\nEOF\nnohup bash dev_eval.sh /workspace/submission/selection.json > work/final_eval.log 2>&1 &\necho \"official eval launched\"",
  "description": "Validate selection and launch official end-to-end eval"
}
Bash result
ids 34584 unique 34584 min 1 max 181996
tokens covered (+EOS): 24000533
VALID
official eval launched

[stdout]
ids 34584 unique 34584 min 1 max 181996
tokens covered (+EOS): 24000533
VALID
official eval launched
[metadata] {"noOutputExpected": false}
#46
narration

Selection is valid (34,584 ids, 24M tokens — 2× the budget). Writing claim.md now.

toolWrite
args
{
  "file_path": "/workspace/claim.md",
  "content": "# Claim: the winning lever is *mixture matching*, not document quality\n\n## Hypothesis\n\nThe target is disclosed as \"equal parts encyclopedic / HQ web prose / news / technical Q&A\".\nDecoding `multi_dev.npy` shows this literally: it is **four contiguous 250k-token blocks**,\none per register (WikiText-103-style encyclopedic text with `@,@`/spaced-punctuation\ndetokenization artifacts; OpenWebText-style prose; a news wire; HTML-marked-up\nStackExchange Q&A with `<p>`, `<pre><code>`, `&gt;`).\n\n**Claim:** under a fixed 12M-token budget, held-out perplexity on such a target is governed\nfirst by *how the budget is divided across the target's registers*, and only second by\nper-document quality. A single global \"quality\" ranking — however good — spends the whole\nbudget on whichever register dominates the pool (here: generic web prose) and is therefore\nbadly mispriced against a 4-register target.\n\nConcretely: selecting documents by per-register affinity and emitting them so that **every\nprefix** of the list matches a target token mixture beats both a random selection and a\njunk-filtered global-quality ranking by a wide margin.\n\n## Mechanism — and an observable that is not the final perplexity\n\nMechanism: each register is a separate slice of the eval loss. Loss on a slice falls only if\nthe training set contains that register's surface form and vocabulary. Sorting the pool by\none global quality score leaves some slices essentially untrained, and their loss dominates\nthe mean. Balancing by token share trains every slice.\n\n**Predicted observable (measured with a diagnostic copy of the frozen trainer that reports\nper-quarter loss instead of the pooled number):** the per-register loss decomposition is\nstrongly *ordered and asymmetric*, and the ordering is predictable in advance from a\npool-side statistic — how much of the register's surface form exists in the pool at all:\n\n| register | pool documents matching its surface form | measured loss (nats) | ppl |\n|---|---|---|---|\n| W encyclopedic (WikiText) | **0** of 182,016 have `@,@`/`@-@`; only 129 have spaced punctuation | 6.42 | 616 |\n| N news | abundant | 5.70 | 299 |\n| P HQ web prose | abundant | 5.56 | 261 |\n| S technical Q&A (HTML) | **43** of 182,016 contain `<p>`/`<pre><code>` | **5.08** | **161** |\n\nTwo non-obvious predictions follow, both confirmed:\n\n1. **W is the loss floor-setter and is nearly irreducible.** The pool contains no\n   encyclopedic register to retrieve, so no selection rule can fix it. Prediction: attempts\n   to sharpen encyclopedic retrieval yield ~0 gain. Confirmed — a discriminative\n   register-vs-siblings profile plus a third-person/date-dense/no-promo style gate for W\n   changed dev ppl from 301.9 to 305.2 (i.e. nothing, at the noise level), and boosting W's\n   share 1.5x *hurt* (304.6 vs 296.5).\n2. **S is the cheapest slice despite being the rarest surface form**, because markup and code\n   are low-entropy once any structural text is seen. Prediction: its share should be pushed\n   *above* its 25% weight in the target. Confirmed: S-share 45% beats 25% by ~19 ppl.\n\n## Evidence\n\nAll numbers are dev perplexity from the frozen recipe, seed 1337 (train set = 12,000,000\ntokens in every row).\n\n| selection rule | dev ppl |\n|---|---|\n| random selection (do-nothing baseline) | 485.5 |\n| junk gate only, no register targeting | 430.9 |\n| single blended NB \"quality\" score, best-first | 429.7 |\n| register-balanced 25/25/25/25 | 315.7 |\n| register-balanced, S share 40% | 301.4 |\n| **shipped: register-balanced, weights 1:1:1:2.5 (S share 45%)** | **297.2** |\n| register-balanced, S share 50% | 296.5 |\n| register-balanced, S share 71% | 319.8 |\n| shipped rule but documents capped at 500 tokens | 415.9 |\n\nThe decisive comparison is row 3 vs row 4: **the same junk gate and the same NB machinery,\ndiffering only in whether the budget is divided by register (315.7) or spent best-first on a\nblended score (429.7)** — a 114-point swing with document-level quality held fixed.\n\nMeasured noise: the same 12M-token set retrained at seed 4242 gives 307.9 vs 296.5 at seed\n1337, so single-run differences below ~10 ppl are not meaningful. The shipped weighting was\nchosen for being the *stable* interior of the plateau, not the single-seed winner:\n2-seed means are 297.0 (S=2.5, spread 0.5), 299.8 (S=2), 302.2 (S=3, spread 11.4).\n\n## Falsification\n\nThe claim is wrong, or the mechanism is misattributed, if any of these hold:\n\n- **Mixture vs quality.** If a global-quality ranking (no register balancing) trained on the\n  same budget comes within ~10 ppl of the register-balanced mixture, the mechanism is not\n  mixture matching. *Tested: it loses by 114 ppl.*\n- **Register-share sensitivity.** If perplexity were flat in the register shares, \"matching\n  the mixture\" would be vacuous. *Tested: shares of 25%/45%/71% for S give 315.7/297.2/319.8\n  — a real, non-monotone optimum.*\n- **Prefix property.** If the pipeline's truncation point changed (say 6M instead of 12M) and\n  the mixture broke, the round-robin construction would be pointless. By construction every\n  prefix holds the target shares; a run at a different budget should show the same ranking.\n- **Sub-hypotheses that were refuted (reported as they came out):**\n  - *\"The S gain comes from genuine code/technical content.\"* Refuted. Requiring explicit\n    code/markup evidence for the S bucket (code-marker or tech-keyword rate above threshold,\n    2.4M–12.7M tokens available) gave 305.2/305.7, no better than the unrestricted S bucket\n    (301.9/296.5). The gain comes from broad structural/symbolic text, not from code per se.\n  - *\"Match the target's document-boundary density.\"* The dev target has an `<|endoftext|>`\n    every ~370 tokens; the selection averages ~700. Capping documents at 500 tokens to match\n    it gave **415.9** — catastrophically worse. Document coherence dominates boundary\n    statistics; short pool documents are fragments and boilerplate.\n  - *\"Refine the register profiles with pseudo-relevance feedback\"* (re-estimate each profile\n    from its own top-ranked pool documents, 2.5M tokens each, then re-score). Gave 319.1 vs\n    315.7 — no gain. The dev block vs pool background unigram is already sufficient.\n- **Falsifier for the shipped weights specifically:** evaluate on a *differently mixed*\n  target (e.g. all-encyclopedic). The S-upweighted selection must then lose to a W-heavy one.\n  If it still wins, the effect is not mixture matching but some generic property of the\n  S-bucket text, and the shipped weights are right for the wrong reason.\n\n## Transfer\n\n- **What transfers is the procedure, not the weights.** Segment a sample of the target into\n  registers; fit a cheap GPT-2-token unigram per register against a pool background; score\n  every pool document by mean clipped log-ratio; junk-gate *register-awarely* (prose gates\n  delete real code, so the technical bucket needs its own gate); dedup with word-5-gram\n  MinHash; then emit a **token-balanced round-robin** so the mixture is preserved at any\n  truncation point. No labels, no trained classifier, one tokenization pass (~1 min on 16\n  cores for 200M tokens), and it is budget-agnostic.\n- **The round-robin is the reusable trick.** When a downstream pipeline consumes a priority\n  list until a budget is met, ordering by \"whichever stratum is furthest behind its target\n  share\" makes the selection correct for every budget simultaneously — worth using anywhere a\n  cut point is out of the curator's control.\n- **Expect the optimal shares to differ from the target's shares.** They tilt toward registers\n  whose loss is most reducible per token (here: +20 points of share to the low-entropy\n  technical register) and away from registers with no matching surface form in the pool. That\n  is a small sweep, and it needs a noise estimate first: with a 30M model on 12M tokens,\n  seed-to-seed spread was ~10 ppl, which is larger than most of the weight-tuning effects.\n- **Limits.** Single pool, single target mixture, one model scale, and register profiles built\n  from a 1M-token target sample. The unigram profile is a weak retriever for registers that\n  are absent from the pool (the W quarter here); with a target register that the pool actually\n  contains, a stronger retriever should pay off more than it did here.\n"
}
Write result
File created successfully at: /workspace/claim.md (file state is current in your context — no need to Read it back)

[metadata] {"type": "create", "filePath": "/workspace/claim.md", "content": "# Claim: the winning lever is *mixture matching*, not document quality\n\n## Hypothesis\n\nThe target is disclosed as \"equal parts encyclopedic / HQ web prose / news / technical Q&A\".\nDecoding `multi_dev.npy` shows this literally: it is **four contiguous 250k-token blocks**,\none per register (WikiText-103-style encyclopedic text with `@,@`/spaced-punctuation\ndetokenization artifacts; OpenWebText-style prose; a news wire; HTML-marked-up\nStackExchange Q&A with `<p>`, `<pre><code>`, `&gt;`).\n\n**Claim:** under a fixed 12M-token budget, held-out perplexity on such a target is governed\nfirst by *how the budget is divided across the target's registers*, and only second by\nper-document quality. A single global \"quality\" ranking — however good — spends the whole\nbudget on whichever register dominates the pool (here: generic web prose) and is therefore\nbadly mispriced against a 4-register target.\n\nConcretely: selecting documents by per-register affinity and emitting them so that **every\nprefix** of the list matches a target token mixture beats both a random selection and a\njunk-filtered global-quality ranking by a wide margin.\n\n## Mechanism — and an observable that is not the final perplexity\n\nMechanism: each register is a separate slice of the eval loss. Loss on a slice falls only if\nthe training set contains that register's surface form and vocabulary. Sorting the pool by\none global quality score leaves some slices essentially untrained, and their loss dominates\nthe mean. Balancing by token share trains every slice.\n\n**Predicted observable (measured with a diagnostic copy of the frozen trainer that reports\nper-quarter loss instead of the pooled number):** the per-register loss decomposition is\nstrongly *ordered and asymmetric*, and the ordering is predictable in advance from a\npool-side statistic — how much of the register's surface form exists in the pool at all:\n\n| register | pool documents matching its surface form | measured loss (nats) | ppl |\n|---|---|---|---|\n| W encyclopedic (WikiText) | **0** of 182,016 have `@,@`/`@-@`; only 129 have spaced punctuation | 6.42 | 616 |\n| N news | abundant | 5.70 | 299 |\n| P HQ web prose | abundant | 5.56 | 261 |\n| S technical Q&A (HTML) | **43** of 182,016 contain `<p>`/`<pre><code>` | **5.08** | **161** |\n\nTwo non-obvious predictions follow, both confirmed:\n\n1. **W is the loss floor-setter and is nearly irreducible.** The pool contains no\n   encyclopedic register to retrieve, so no selection rule can fix it. Prediction: attempts\n   to sharpen encyclopedic retrieval yield ~0 gain. Confirmed — a discriminative\n   register-vs-siblings profile plus a third-person/date-dense/no-promo style gate for W\n   changed dev ppl from 301.9 to 305.2 (i.e. nothing, at the noise level), and boosting W's\n   share 1.5x *hurt* (304.6 vs 296.5).\n2. **S is the cheapest slice despite being the rarest surface form**, because markup and code\n   are low-entropy once any structural text is seen. Prediction: its share should be pushed\n   *above* its 25% weight in the target. Confirmed: S-share 45% beats 25% by ~19 ppl.\n\n## Evidence\n\nAll numbers are dev perplexity from the frozen recipe, seed 1337 (train set = 12,000,000\ntokens in every row).\n\n| selection rule | dev ppl |\n|---|---|\n| random selection (do-nothing baseline) | 485.5 |\n| junk gate only, no register targeting | 430.9 |\n| single blended NB \"quality\" score, best-first | 429.7 |\n| register-balanced 25/25/25/25 | 315.7 |\n| register-balanced, S share 40% | 301.4 |\n| **shipped: register-balanced, weights 1:1:1:2.5 (S share 45%)** | **297.2** |\n| register-balanced, S share 50% | 296.5 |\n| register-balanced, S share 71% | 319.8 |\n| shipped rule but documents capped at 500 tokens | 415.9 |\n\nThe decisive comparison is row 3 vs row 4: **the same junk gate and the same NB machinery,\ndiffering only in whether the budget is divided by register (315.7) or spent best-first on a\nblended score (429.7)** — a 114-point swing with document-level quality held fixed.\n\nMeasured noise: the same 12M-token set retrained at seed 4242 gives 307.9 vs 296.5 at seed\n1337, so single-run differences below ~10 ppl are not meaningful. The shipped weighting was\nchosen for being the *stable* interior of the plateau, not the single-seed winner:\n2-seed means are 297.0 (S=2.5, spread 0.5), 299.8 (S=2), 302.2 (S=3, spread 11.4).\n\n## Falsification\n\nThe claim is wrong, or the mechanism is misattributed, if any of these hold:\n\n- **Mixture vs quality.** If a global-quality ranking (no register balancing) trained on the\n  same budget comes within ~10 ppl of the register-balanced mixture, the mechanism is not\n  mixture matching. *Tested: it loses by 114 ppl.*\n- **Register-share sensitivity.** If perplexity were flat in the register shares, \"matching\n  the mixture\" would be vacuous. *Tested: shares of 25%/45%/71% for S give 315.7/297.2/319.8\n  — a real, non-monotone optimum.*\n- **Prefix property.** If the pipeline's truncation point changed (say 6M instead of 12M) and\n  the mixture broke, the round-robin construction would be pointless. By construction every\n  prefix holds the target shares; a run at a different budget should show the same ranking.\n- **Sub-hypotheses that were refuted (reported as they came out):**\n  - *\"The S gain comes from genuine code/technical content.\"* Refuted. Requiring explicit\n    code/markup evidence for the S bucket (code-marker or tech-keyword rate above threshold,\n    2.4M–12.7M tokens available) gave 305.2/305.7, no better than the unrestricted S bucket\n    (301.9/296.5). The gain comes from broad structural/symbolic text, not from code per se.\n  - *\"Match the target's document-boundary density.\"* The dev target has an `<|endoftext|>`\n    every ~370 tokens; the selection averages ~700. Capping documents at 500 tokens to match\n    it gave **415.9** — catastrophically worse. Document coherence dominates boundary\n    statistics; short pool documents are fragments and boilerplate.\n  - *\"Refine the register profiles with pseudo-relevance feedback\"* (re-estimate each profile\n    from its own top-ranked pool documents, 2.5M tokens each, then re-score). Gave 319.1 vs\n    315.7 — no gain. The dev block vs pool background unigram is already sufficient.\n- **Falsifier for the shipped weights specifically:** evaluate on a *differently mixed*\n  target (e.g. all-encyclopedic). The S-upweighted selection must then lose to a W-heavy one.\n  If it still wins, the effect is not mixture matching but some generic property of the\n  S-bucket text, and the shipped weights are right for the wrong reason.\n\n## Transfer\n\n- **What transfers is the procedure, not the weights.** Segment a sample of the target into\n  registers; fit a cheap GPT-2-token unigram per register against a pool background; score\n  every pool document by mean clipped log-ratio; junk-gate *register-awarely* (prose gates\n  delete real code, so the technical bucket needs its own gate); dedup with word-5-gram\n  MinHash; then emit a **token-balanced round-robin** so the mixture is preserved at any\n  truncation point. No labels, no trained classifier, one tokenization pass (~1 min on 16\n  cores for 200M tokens), and it is budget-agnostic.\n- **The round-robin is the reusable trick.** When a downstream pipeline consumes a priority\n  list until a budget is met, ordering by \"whichever stratum is furthest behind its target\n  share\" makes the selection correct for every budget simultaneously — worth using anywhere a\n  cut point is out of the curator's control.\n- **Expect the optimal shares to differ from the target's shares.** They tilt toward registers\n  whose loss is most reducible per token (here: +20 points of share to the low-entropy\n  technical register) and away from registers with no matching surface form in the pool. That\n  is a small sweep, and it needs a noise estimate first: with a 30M model on 12M tokens,\n  seed-to-seed spread was ~10 ppl, which is larger than most of the weight-tuning effects.\n- **Limits.** Single pool, single target mixture, one model scale, and register profiles built\n  from a 1M-token target sample. The unigram profile is a weak retriever for registers that\n  are absent from the pool (the W quarter here); with a target register that the pool actually\n  contains, a stronger retriever should pay off more than it did here.\n", "structuredPatch": [], "originalFile": null, "userModified": false}
#47
reasoning (redacted)

encrypted chain-of-thought — recorded, not exposed

toolBashCheck official end-to-end eval result
args
{
  "command": "cat work/final_eval.log | grep -aE \"packed|HELDOUT|Error\"; cat /workspace/.timer/remaining_secs",
  "description": "Check official end-to-end eval result"
}
Bash result
packed 12000000 tokens from 34584 ids -> /tmp/dev_train.npy
2155

[stdout]
packed 12000000 tokens from 34584 ids -> /tmp/dev_train.npy
2155
[metadata] {"noOutputExpected": false}
#48
narration

The official packer produced exactly 12,000,000 tokens from my selection — validity confirmed end-to-end. Let me get its perplexity and a second seed to confirm the shipped file matches the expected band.

toolBashConfirm shipped selection perplexity at two seeds
args
{
  "command": "sleep 45; grep -a HELDOUT work/final_eval.log | sed 's/^/[shipped seed1337] /'\npython train_nano.py --train_npy /tmp/dev_train.npy --heldout_npy data/multi_dev.npy --out_json /tmp/f2.json --seed 4242 2>&1 | grep HELDOUT | sed 's/^/[shipped seed4242] /'\ncat /workspace/.timer/remaining_secs",
  "description": "Confirm shipped selection perplexity at two seeds",
  "timeout": 300000
}
Bash result
[shipped seed1337] HELDOUT_PPL 300.683  loss 5.7061  train_s 50  /tmp/dev_train.npy
[shipped seed4242] HELDOUT_PPL 292.963  loss 5.6800  train_s 51  /tmp/dev_train.npy
2045

[stdout]
[shipped seed1337] HELDOUT_PPL 300.683  loss 5.7061  train_s 50  /tmp/dev_train.npy
[shipped seed4242] HELDOUT_PPL 292.963  loss 5.6800  train_s 51  /tmp/dev_train.npy
2045
[metadata] {"noOutputExpected": false}
#49
narration

Shipped file confirmed: 300.7 (seed 1337) and 293.0 (seed 4242), mean 296.8 — matching the expected band, vs the random baseline of 485.5. Let me spend remaining time on a robustness check that de-risks the hidden-sample evaluation: does the advantage hold on disjoint halves of each register?

toolBashCheck advantage holds on disjoint halves of each register
args
{
  "command": "export PYTHONPATH=/workspace\npython - <<'EOF'\ns=open('/workspace/work/diag.py').read()\ns=s.replace(\"\"\"Q=len(ho)//4\nper={r:ev(ho[j*Q:(j+1)*Q]) for j,r in enumerate(['W','P','N','S'])}\"\"\",\n\"\"\"Q=len(ho)//4\nper={}\nfor j,r in enumerate(['W','P','N','S']):\n    blk=ho[j*Q:(j+1)*Q]; H=len(blk)//2\n    per[r+'_h1']=ev(blk[:H]); per[r+'_h2']=ev(blk[H:])\nimport numpy as _np\nh1=_np.mean([per[r+'_h1'] for r in ['W','P','N','S']]); h2=_np.mean([per[r+'_h2'] for r in ['W','P','N','S']])\nprint(\"HALF1_PPL %.2f  HALF2_PPL %.2f\"%(math.exp(h1),math.exp(h2)))\"\"\")\nopen('/workspace/work/diag2.py','w').write(s)\nEOF\nfor nm in dev_train t_bal; do python work/diag2.py --train_npy /tmp/$nm.npy --heldout_npy data/multi_dev.npy --out_json /tmp/h_$nm.json 2>&1 | grep -E \"OVERALL|HALF\" | sed \"s/^/[$nm] /\"; done\ncat /workspace/.timer/remaining_secs",
  "description": "Check advantage holds on disjoint halves of each register",
  "timeout": 300000
}
Bash result
[dev_train] HALF1_PPL 299.70  HALF2_PPL 301.36
[dev_train] OVERALL_PPL 300.683 loss 5.7061
[t_bal] HALF1_PPL 314.63  HALF2_PPL 316.09
[t_bal] OVERALL_PPL 315.660 loss 5.7547
1905

[stdout]
[dev_train] HALF1_PPL 299.70  HALF2_PPL 301.36
[dev_train] OVERALL_PPL 300.683 loss 5.7061
[t_bal] HALF1_PPL 314.63  HALF2_PPL 316.09
[t_bal] OVERALL_PPL 315.660 loss 5.7547
1905
[metadata] {"noOutputExpected": false}
#50
narration

The advantage holds on both disjoint halves (299.7/301.4 vs 314.6/316.1) — consistent across independent samples of the same registers. Let me fold the shipped-file numbers and this robustness check into claim.md.

toolEdit
args
{
  "replace_all": false,
  "file_path": "/workspace/claim.md",
  "old_string": "| **shipped: register-balanced, weights 1:1:1:2.5 (S share 45%)** | **297.2** |",
  "new_string": "| **shipped: register-balanced, weights 1:1:1:2.5 (S share 45%)** | **300.7** (293.0 at seed 4242; 2-seed mean 296.8) |"
}
Edit result
The file /workspace/claim.md has been updated successfully. (file state is current in your context — no need to Read it back)

[metadata] {"filePath": "/workspace/claim.md", "oldString": "| **shipped: register-balanced, weights 1:1:1:2.5 (S share 45%)** | **297.2** |", "newString": "| **shipped: register-balanced, weights 1:1:1:2.5 (S share 45%)** | **300.7** (293.0 at seed 4242; 2-seed mean 296.8) |", "originalFile": "# Claim: the winning lever is *mixture matching*, not document quality\n\n## Hypothesis\n\nThe target is disclosed as \"equal parts encyclopedic / HQ web prose / news / technical Q&A\".\nDecoding `multi_dev.npy` shows this literally: it is **four contiguous 250k-token blocks**,\none per register (WikiText-103-style encyclopedic text with `@,@`/spaced-punctuation\ndetokenization artifacts; OpenWebText-style prose; a news wire; HTML-marked-up\nStackExchange Q&A with `<p>`, `<pre><code>`, `&gt;`).\n\n**Claim:** under a fixed 12M-token budget, held-out perplexity on such a target is governed\nfirst by *how the budget is divided across the target's registers*, and only second by\nper-document quality. A single global \"quality\" ranking — however good — spends the whole\nbudget on whichever register dominates the pool (here: generic web prose) and is therefore\nbadly mispriced against a 4-register target.\n\nConcretely: selecting documents by per-register affinity and emitting them so that **every\nprefix** of the list matches a target token mixture beats both a random selection and a\njunk-filtered global-quality ranking by a wide margin.\n\n## Mechanism — and an observable that is not the final perplexity\n\nMechanism: each register is a separate slice of the eval loss. Loss on a slice falls only if\nthe training set contains that register's surface form and vocabulary. Sorting the pool by\none global quality score leaves some slices essentially untrained, and their loss dominates\nthe mean. Balancing by token share trains every slice.\n\n**Predicted observable (measured with a diagnostic copy of the frozen trainer that reports\nper-quarter loss instead of the pooled number):** the per-register loss decomposition is\nstrongly *ordered and asymmetric*, and the ordering is predictable in advance from a\npool-side statistic — how much of the register's surface form exists in the pool at all:\n\n| register | pool documents matching its surface form | measured loss (nats) | ppl |\n|---|---|---|---|\n| W encyclopedic (WikiText) | **0** of 182,016 have `@,@`/`@-@`; only 129 have spaced punctuation | 6.42 | 616 |\n| N news | abundant | 5.70 | 299 |\n| P HQ web prose | abundant | 5.56 | 261 |\n| S technical Q&A (HTML) | **43** of 182,016 contain `<p>`/`<pre><code>` | **5.08** | **161** |\n\nTwo non-obvious predictions follow, both confirmed:\n\n1. **W is the loss floor-setter and is nearly irreducible.** The pool contains no\n   encyclopedic register to retrieve, so no selection rule can fix it. Prediction: attempts\n   to sharpen encyclopedic retrieval yield ~0 gain. Confirmed — a discriminative\n   register-vs-siblings profile plus a third-person/date-dense/no-promo style gate for W\n   changed dev ppl from 301.9 to 305.2 (i.e. nothing, at the noise level), and boosting W's\n   share 1.5x *hurt* (304.6 vs 296.5).\n2. **S is the cheapest slice despite being the rarest surface form**, because markup and code\n   are low-entropy once any structural text is seen. Prediction: its share should be pushed\n   *above* its 25% weight in the target. Confirmed: S-share 45% beats 25% by ~19 ppl.\n\n## Evidence\n\nAll numbers are dev perplexity from the frozen recipe, seed 1337 (train set = 12,000,000\ntokens in every row).\n\n| selection rule | dev ppl |\n|---|---|\n| random selection (do-nothing baseline) | 485.5 |\n| junk gate only, no register targeting | 430.9 |\n| single blended NB \"quality\" score, best-first | 429.7 |\n| register-balanced 25/25/25/25 | 315.7 |\n| register-balanced, S share 40% | 301.4 |\n| **shipped: register-balanced, weights 1:1:1:2.5 (S share 45%)** | **297.2** |\n| register-balanced, S share 50% | 296.5 |\n| register-balanced, S share 71% | 319.8 |\n| shipped rule but documents capped at 500 tokens | 415.9 |\n\nThe decisive comparison is row 3 vs row 4: **the same junk gate and the same NB machinery,\ndiffering only in whether the budget is divided by register (315.7) or spent best-first on a\nblended score (429.7)** — a 114-point swing with document-level quality held fixed.\n\nMeasured noise: the same 12M-token set retrained at seed 4242 gives 307.9 vs 296.5 at seed\n1337, so single-run differences below ~10 ppl are not meaningful. The shipped weighting was\nchosen for being the *stable* interior of the plateau, not the single-seed winner:\n2-seed means are 297.0 (S=2.5, spread 0.5), 299.8 (S=2), 302.2 (S=3, spread 11.4).\n\n## Falsification\n\nThe claim is wrong, or the mechanism is misattributed, if any of these hold:\n\n- **Mixture vs quality.** If a global-quality ranking (no register balancing) trained on the\n  same budget comes within ~10 ppl of the register-balanced mixture, the mechanism is not\n  mixture matching. *Tested: it loses by 114 ppl.*\n- **Register-share sensitivity.** If perplexity were flat in the register shares, \"matching\n  the mixture\" would be vacuous. *Tested: shares of 25%/45%/71% for S give 315.7/297.2/319.8\n  — a real, non-monotone optimum.*\n- **Prefix property.** If the pipeline's truncation point changed (say 6M instead of 12M) and\n  the mixture broke, the round-robin construction would be pointless. By construction every\n  prefix holds the target shares; a run at a different budget should show the same ranking.\n- **Sub-hypotheses that were refuted (reported as they came out):**\n  - *\"The S gain comes from genuine code/technical content.\"* Refuted. Requiring explicit\n    code/markup evidence for the S bucket (code-marker or tech-keyword rate above threshold,\n    2.4M–12.7M tokens available) gave 305.2/305.7, no better than the unrestricted S bucket\n    (301.9/296.5). The gain comes from broad structural/symbolic text, not from code per se.\n  - *\"Match the target's document-boundary density.\"* The dev target has an `<|endoftext|>`\n    every ~370 tokens; the selection averages ~700. Capping documents at 500 tokens to match\n    it gave **415.9** — catastrophically worse. Document coherence dominates boundary\n    statistics; short pool documents are fragments and boilerplate.\n  - *\"Refine the register profiles with pseudo-relevance feedback\"* (re-estimate each profile\n    from its own top-ranked pool documents, 2.5M tokens each, then re-score). Gave 319.1 vs\n    315.7 — no gain. The dev block vs pool background unigram is already sufficient.\n- **Falsifier for the shipped weights specifically:** evaluate on a *differently mixed*\n  target (e.g. all-encyclopedic). The S-upweighted selection must then lose to a W-heavy one.\n  If it still wins, the effect is not mixture matching but some generic property of the\n  S-bucket text, and the shipped weights are right for the wrong reason.\n\n## Transfer\n\n- **What transfers is the procedure, not the weights.** Segment a sample of the target into\n  registers; fit a cheap GPT-2-token unigram per register against a pool background; score\n  every pool document by mean clipped log-ratio; junk-gate *register-awarely* (prose gates\n  delete real code, so the technical bucket needs its own gate); dedup with word-5-gram\n  MinHash; then emit a **token-balanced round-robin** so the mixture is preserved at any\n  truncation point. No labels, no trained classifier, one tokenization pass (~1 min on 16\n  cores for 200M tokens), and it is budget-agnostic.\n- **The round-robin is the reusable trick.** When a downstream pipeline consumes a priority\n  list until a budget is met, ordering by \"whichever stratum is furthest behind its target\n  share\" makes the selection correct for every budget simultaneously — worth using anywhere a\n  cut point is out of the curator's control.\n- **Expect the optimal shares to differ from the target's shares.** They tilt toward registers\n  whose loss is most reducible per token (here: +20 points of share to the low-entropy\n  technical register) and away from registers with no matching surface form in the pool. That\n  is a small sweep, and it needs a noise estimate first: with a 30M model on 12M tokens,\n  seed-to-seed spread was ~10 ppl, which is larger than most of the weight-tuning effects.\n- **Limits.** Single pool, single target mixture, one model scale, and register profiles built\n  from a 1M-token target sample. The unigram profile is a weak retriever for registers that\n  are absent from the pool (the W quarter here); with a target register that the pool actually\n  contains, a stronger retriever should pay off more than it did here.\n", "structuredPatch": [{"oldStart": 61, "oldLines": 7, "newStart": 61, "newLines": 7, "lines": [" | single blended NB \"quality\" score, best-first | 429.7 |", " | register-balanced 25/25/25/25 | 315.7 |", " | register-balanced, S share 40% | 301.4 |", "-| **shipped: register-balanced, weights 1:1:1:2.5 (S share 45%)** | **297.2** |", "+| **shipped: register-balanced, weights 1:1:1:2.5 (S share 45%)** | **300.7** (293.0 at seed 4242; 2-seed mean 296.8) |", " | register-balanced, S share 50% | 296.5 |", " | register-balanced, S share 71% | 319.8 |", " | shipped rule but documents capped at 500 tokens | 415.9 |"]}], "userModified": false, "replaceAll": false}