Upload docs/Claude Reports/ClaudeReport_session_2026-09-02_generative_eval_results.md with huggingface_hub
Browse files
docs/Claude Reports/ClaudeReport_session_2026-09-02_generative_eval_results.md
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Session report - 2026-09-02 - Generative RULER/VAL/NIAH results, and two root causes for the reach ceiling
|
| 2 |
+
|
| 3 |
+
Workspace: /root/Adhi/BluTrain/dist/Context_Parallelism (box loud-life-embraces-fin-03)
|
| 4 |
+
Hardware: 4x H100 80GB
|
| 5 |
+
Files: Scripts/Blutrain/bluscriptCP.cpp, run_longeval.sh, run_len_sweep.sh,
|
| 6 |
+
Tests/bluscriptcp/longeval_{gen,score}.py, compare_nll_vs_generative.py,
|
| 7 |
+
longcontext_results.ipynb, EVAL_COMPARISON.md
|
| 8 |
+
|
| 9 |
+
## 1. It built and ran
|
| 10 |
+
|
| 11 |
+
The CP_GENERATE patch written yesterday had never been compiled. It compiled CLEAN on
|
| 12 |
+
the first attempt (bluscriptCP.o, 0 errors) with
|
| 13 |
+
`make CP_FUSED_ROPE=1 CP_ATTN_SPLIT=1 SM_ARCH=90 bluscript-cp`. Verified sm_90a image
|
| 14 |
+
present in GQA_causal_cp_fwd_sm90.o and the flag stamp correct before running anything.
|
| 15 |
+
|
| 16 |
+
Four rounds of review before execution found 14 harness defects, ALL of which would
|
| 17 |
+
have failed silently as plausible-looking low scores. The ones that mattered most:
|
| 18 |
+
- PROMPT_LEN+MAX_NEW must equal 16384 exactly (pad_up(16368+24)=16640 > CP_T aborts
|
| 19 |
+
every job)
|
| 20 |
+
- DEPTHS was never forwarded to longeval_gen.py, so the depth grid would not have
|
| 21 |
+
matched the NLL probe's p_frac grid
|
| 22 |
+
- a signature mismatch wiped prompts but NOT $OUT/state/*, so stale .gen markers
|
| 23 |
+
would have scored old tokens against a new meta.json
|
| 24 |
+
- the summary parser split "arm_b_niah_single" on the first underscore -> name="arm"
|
| 25 |
+
- early stop on the first newline would convert HITs to MISSes (the answer prefix
|
| 26 |
+
ends "... is" with no newline, so a base model may emit "\n" first); needs a
|
| 27 |
+
per-task minimum, 14 for niah_multivalue which must emit three 7-digit values
|
| 28 |
+
- all N prompts shared byte-identical filler (hay loaded once, hay_pos reset to 0),
|
| 29 |
+
making them replicates rather than independent draws
|
| 30 |
+
|
| 31 |
+
## 2. Results
|
| 32 |
+
|
| 33 |
+
3,600 prompts across 52 jobs. niah_single (recall a random 7-digit number given its
|
| 34 |
+
key; answer space 10^7):
|
| 35 |
+
|
| 36 |
+
context base arm_a arm_b arm_c
|
| 37 |
+
1,024 84.0 78.0 64.0 76.0
|
| 38 |
+
2,048 82.0 66.0 56.0 70.0
|
| 39 |
+
4,096 74.0 62.0 48.0 60.0
|
| 40 |
+
8,192 40.0 36.0 36.0 40.0
|
| 41 |
+
16,360 0.0 0.0 0.0 0.0
|
| 42 |
+
|
| 43 |
+
At 16,360: 2 hits in 2000 across all models and 5 tasks. Verified NOT a harness bug --
|
| 44 |
+
the depth-1.0 prompts are well formed, needle present at 99.8% depth (~30 tokens before
|
| 45 |
+
the question), no <|endoftext|> between needle and question, and the same harness HITs
|
| 46 |
+
at 1024.
|
| 47 |
+
|
| 48 |
+
Reach in tokens (50% hit-rate crossing, reach = (1-depth_cross)*context):
|
| 49 |
+
|
| 50 |
+
context base arm_a arm_b arm_c
|
| 51 |
+
1,024 1,024 1,024 938 938
|
| 52 |
+
2,048 2,048 1,740 1,536 1,792
|
| 53 |
+
4,096 3,481 2,730 1,706 2,560
|
| 54 |
+
8,192 3,276 2,048 2,730 2,730
|
| 55 |
+
16,360 0 0 0 0
|
| 56 |
+
|
| 57 |
+
REACH SATURATES AT ~2,700-3,500 TOKENS and does not grow with more context -- 4,096 to
|
| 58 |
+
8,192 slightly DECREASES base's reach (3,481 -> 3,276).
|
| 59 |
+
|
| 60 |
+
Forward vs backward: val_backward (name the key given its number, 35-word answer space)
|
| 61 |
+
is 0-8% at EVERY length while forward retrieval of a 7-digit number hits 84%. The model
|
| 62 |
+
resolves key->value but not value->key. That is the one VAL Probing axis implemented and
|
| 63 |
+
it fails outright.
|
| 64 |
+
|
| 65 |
+
## 3. NLL proxy vs generation
|
| 66 |
+
|
| 67 |
+
Pooled niah_single over 1024/2048/4096 (n=150/model, +-95% Wilson):
|
| 68 |
+
|
| 69 |
+
base 80.0% +-6.4 NLL reach 6,047
|
| 70 |
+
arm_a 68.7% +-7.3 NLL reach 7,435
|
| 71 |
+
arm_c 68.7% +-7.3 NLL reach 12,976
|
| 72 |
+
arm_b 56.0% +-7.8 NLL reach 5,924
|
| 73 |
+
|
| 74 |
+
generative best->worst: base, arm_a = arm_c, arm_b
|
| 75 |
+
NLL reach best->worst: arm_c, arm_a, base, arm_b -> DISAGREE
|
| 76 |
+
|
| 77 |
+
VERDICT: the NLL proxy is a weak DIRECTIONAL signal, not a magnitude and not a ranking.
|
| 78 |
+
- overstates reach 2x (base) to 4.7x (arm_c)
|
| 79 |
+
- ranks arm_c first; generation ranks the untrained base first
|
| 80 |
+
- agrees only that arm_b is worst (true in every measurement we have)
|
| 81 |
+
- IN2 advantage shrinks from 2.19x / 9.5 sigma to +12.7pp / 2.3 sigma (arm_c vs arm_b)
|
| 82 |
+
- the 6.87-sigma "arm_c better at depth 0.25 than 0.5" anomaly comes out REVERSED
|
| 83 |
+
generatively: -40pp at -3.8 sigma
|
| 84 |
+
- BOTH metrics agree there is NO U-shape: depth curves rise monotonically toward the
|
| 85 |
+
question, no primacy bump at depth 0. Pure recency.
|
| 86 |
+
|
| 87 |
+
## 4. Two root causes for the ceiling
|
| 88 |
+
|
| 89 |
+
CAUSE 1 -- a YaRN config bug, fixable with one env var and no retraining.
|
| 90 |
+
YARNOps.cpp:57 defaults YARN_ORIG_MAXPOS to 1024, but the base model (run8) trained at
|
| 91 |
+
context_length 4096. So every run of this project emitted:
|
| 92 |
+
[YaRN][warn] seq_len(16384) != scale(4.000)*orig_maxpos(1024.0)=4096.0
|
| 93 |
+
The interpolation ramp targeted 4096 positions while the cache was SIZED 16384.
|
| 94 |
+
Setting YARN_ORIG_MAXPOS=4096 (ramp moves from low=7/high=25 to low=14/high=32):
|
| 95 |
+
|
| 96 |
+
niah_single @16,360, N=100/cell:
|
| 97 |
+
model before after
|
| 98 |
+
base 0.0% 17.0% +-7.3
|
| 99 |
+
arm_a 0.0% 17.0% +-7.3
|
| 100 |
+
arm_b 0.0% 4.0% +-4.1
|
| 101 |
+
arm_c 0.0% 18.0% +-7.5
|
| 102 |
+
|
| 103 |
+
depth breakdown (after): d0.50 ~0-5%, d0.75 20-30%, d1.00 55-65%
|
| 104 |
+
|
| 105 |
+
0/100 -> 17/100 is p<0.001. BUT the recovery sits only at depths 0.75-1.0, so reach at
|
| 106 |
+
the 50% bar is STILL 0 -- it un-suppresses the last ~15% of the window, not the whole
|
| 107 |
+
thing. And it is a train/eval mismatch (checkpoints trained under the 1024 default), so
|
| 108 |
+
a model actually TRAINED with the correct value should do better. vt barely moves
|
| 109 |
+
(0-5%), so the effect is specific to single-needle forward retrieval.
|
| 110 |
+
|
| 111 |
+
CAUSE 2 -- the training data has no long documents. This is the real ceiling.
|
| 112 |
+
flux document lengths (split on <|endoftext|>, 20M tokens):
|
| 113 |
+
median 826 p90 2,721 docs >=4k 4.50% >=8k 1.00% >=16k 0.27%
|
| 114 |
+
Measured reach saturates at 2,700-3,500. The p90 document length is 2,721. Those are the
|
| 115 |
+
same number. Each 16k training window was ~7 unrelated documents, so there was never a
|
| 116 |
+
gradient signal for attending past a document boundary. YaRN extends positional RANGE;
|
| 117 |
+
it cannot manufacture long-range dependencies that were never in the data. This is also
|
| 118 |
+
why the 750-step YaRN extension bought only +776 tokens on the NLL metric.
|
| 119 |
+
|
| 120 |
+
## 5. Errors of mine, recorded
|
| 121 |
+
|
| 122 |
+
- PRE-REGISTERED THRESHOLDS WERE ILL-POSED. "refuted iff |diff| <= 5pp" has no power
|
| 123 |
+
precondition, so at the 16k floor it is satisfied automatically and mechanically
|
| 124 |
+
returns "refuted" when the honest answer is "untestable". And no sign handling, so
|
| 125 |
+
prediction 3 coming out -40pp at -3.8 sigma (a significant REVERSAL) got mislabelled
|
| 126 |
+
"inconclusive". Should have required at least one arm above ~10% before evaluating.
|
| 127 |
+
- Reported the two sweep tasks BACKWARDS in one message (claimed val_backward was the
|
| 128 |
+
64-76% task and niah_single the 2-4% one; it is the reverse), which inverted the
|
| 129 |
+
answer-space caveat.
|
| 130 |
+
- Timing estimate was 12x off in one direction then 5x off in the other: first ~7 s
|
| 131 |
+
per forward from an fp32 H200 probe, then 0.23 s from a 2-equation/3-unknown fit
|
| 132 |
+
that over-attributed 35.6 s to model load. Measured truth: ~1.3 s/forward.
|
| 133 |
+
- Advocated against a mid-run restart for oversubscription, was pushed, recomputed
|
| 134 |
+
+21 min, executed -- real gain ~1 min. GPU time-slicing without MPS gave 1.42x not
|
| 135 |
+
1.8x, and 13 simultaneous 3.9 GB checkpoint loads cost ~6 min not 2.
|
| 136 |
+
- The degenerate-task exclusion rule emptied the primary table when ALL tasks were
|
| 137 |
+
degenerate; patched to fall back to pooling everything and label it a floor effect.
|
| 138 |
+
|
| 139 |
+
## 6. Deliverable
|
| 140 |
+
|
| 141 |
+
longcontext_results.ipynb -- executed, 6 figures embedded (695 KB). Reads the result
|
| 142 |
+
CSVs from disk; only the NLL reference values are hard-coded and they are labelled.
|
| 143 |
+
Followed the dataviz method: form first, categorical slots 1-4 in fixed order, no
|
| 144 |
+
dual-axis (NLL nats and generative % are separate panels), direct labels plus printed
|
| 145 |
+
tables (relief rule for the low-contrast slots). Could not run validate_palette.js --
|
| 146 |
+
no node runtime on the box -- so relied on palette.md's documented pass for the
|
| 147 |
+
unmodified reference palette on the adjacent pairlist.
|
| 148 |
+
Executing and LOOKING at it caught three defects I would otherwise have shipped: a log
|
| 149 |
+
y-axis rendering reach=0 as a spike off the plot, an x-tick labelling 16,360 as "15k",
|
| 150 |
+
and colliding end-labels in two figures (fixed with a collision-avoiding label placer
|
| 151 |
+
that must run AFTER set_ylim).
|
| 152 |
+
|
| 153 |
+
## 7. Not covered
|
| 154 |
+
|
| 155 |
+
RULER's CWE / FWE / QA / multiquery; VAL's code and structured-data contexts and
|
| 156 |
+
bi-directional retrieval; niah_multikey / niah_multivalue / vt in the length sweep.
|
| 157 |
+
And the bounding limitation: the two metrics never overlap at a context length where
|
| 158 |
+
both have signal -- NLL only at 16k (generation floored), generation only at 1-4k (NLL
|
| 159 |
+
never measured there, and measuring it would need a different YaRN cache).
|
| 160 |
+
|
| 161 |
+
## 8. Next
|
| 162 |
+
|
| 163 |
+
1. Set YARN_ORIG_MAXPOS=4096 everywhere AND retrain with it.
|
| 164 |
+
2. Source genuinely long documents, or pack related documents so cross-boundary
|
| 165 |
+
attention earns reward. This is the only thing that raises the ceiling.
|
| 166 |
+
3. IN2 properly resourced: far needles DID beat near needles (+12.7pp), but 400 steps
|
| 167 |
+
at 3e-4 on random-token needles cost more general ability than it bought -- longer,
|
| 168 |
+
lower LR, meaningful-text needles.
|
| 169 |
+
4. Batch the decode loop (CP_B>1). Util was ~40% at B=1; worth ~4-8x, vs the 1.42x
|
| 170 |
+
that GPU oversubscription bought.
|