moving
This commit is contained in:
137
benchmarks/harness/scripts/e1-aggregate.ts
Normal file
137
benchmarks/harness/scripts/e1-aggregate.ts
Normal file
@@ -0,0 +1,137 @@
|
||||
#!/usr/bin/env tsx
|
||||
/**
|
||||
* E1 aggregation — Eywa answers @ OUR gpt-5 judge vs Eywa self-judge.
|
||||
* Reads e1-eywa-ourjudge.jsonl + the original Eywa JSON, emits console + markdown.
|
||||
*/
|
||||
import fs from 'node:fs';
|
||||
|
||||
const EYWA_JSON =
|
||||
'D:/Projects/KorroResearch/benchmarks/eywa-artifacts/eywa-beam-sonnet46-answers.json';
|
||||
const OUT_JSONL =
|
||||
'D:/Projects/KorroResearch/benchmarks/eywa-artifacts/e1-eywa-ourjudge.jsonl';
|
||||
|
||||
interface EywaRecord { id: string; cat: string; eywaNugget: number[]; }
|
||||
interface OutRecord {
|
||||
id: string; cat: string; our_raw_score: number;
|
||||
our_nugget_scores: number[]; eywa_raw: number;
|
||||
}
|
||||
|
||||
const OUR_OWN_HEADLINE = 0.6482; // our own answers @ our gpt-5 judge
|
||||
|
||||
function mean(xs: number[]): number { return xs.length ? xs.reduce((s, x) => s + x, 0) / xs.length : 0; }
|
||||
function pct(x: number): string { return (x * 100).toFixed(2) + '%'; }
|
||||
|
||||
const eywaRecords = JSON.parse(fs.readFileSync(EYWA_JSON, 'utf-8')) as EywaRecord[];
|
||||
const eywaById = new Map(eywaRecords.map(r => [r.id, r]));
|
||||
|
||||
const out: OutRecord[] = [];
|
||||
for (const line of fs.readFileSync(OUT_JSONL, 'utf-8').split('\n')) {
|
||||
const t = line.trim(); if (!t) continue;
|
||||
out.push(JSON.parse(t) as OutRecord);
|
||||
}
|
||||
// dedup by id (last wins)
|
||||
const outById = new Map(out.map(r => [r.id, r]));
|
||||
const rows = [...outById.values()];
|
||||
|
||||
console.log(`[agg] scored records: ${rows.length}/700`);
|
||||
|
||||
// Overall
|
||||
const ourOverall = mean(rows.map(r => r.our_raw_score));
|
||||
const eywaOverall = mean(rows.map(r => r.eywa_raw));
|
||||
|
||||
// Per-category
|
||||
const cats = [...new Set(rows.map(r => r.cat))].sort();
|
||||
interface CatStat { cat: string; n: number; our: number; eywa: number; delta: number; }
|
||||
const catStats: CatStat[] = cats.map(cat => {
|
||||
const rs = rows.filter(r => r.cat === cat);
|
||||
const our = mean(rs.map(r => r.our_raw_score));
|
||||
const eywa = mean(rs.map(r => r.eywa_raw));
|
||||
return { cat, n: rs.length, our, eywa, delta: our - eywa };
|
||||
});
|
||||
|
||||
// Per-nugget agreement (align our_nugget_scores to eywaNugget by index)
|
||||
let nTotal = 0, nOurLess = 0, nOurMore = 0, nEqual = 0;
|
||||
let sumOur = 0, sumEywa = 0;
|
||||
for (const r of rows) {
|
||||
const e = eywaById.get(r.id);
|
||||
if (!e) continue;
|
||||
const our = r.our_nugget_scores;
|
||||
const eyw = e.eywaNugget;
|
||||
const k = Math.min(our.length, eyw.length);
|
||||
for (let i = 0; i < k; i++) {
|
||||
nTotal++;
|
||||
sumOur += our[i]; sumEywa += eyw[i];
|
||||
if (our[i] < eyw[i]) nOurLess++;
|
||||
else if (our[i] > eyw[i]) nOurMore++;
|
||||
else nEqual++;
|
||||
}
|
||||
}
|
||||
|
||||
// ── Console report ──
|
||||
console.log('\n=== OVERALL ===');
|
||||
console.log(`Eywa answers @ OUR gpt-5 judge : ${pct(ourOverall)}`);
|
||||
console.log(`Eywa self-judge (Sonnet 4.6) : ${pct(eywaOverall)} (published headline 81.45%)`);
|
||||
console.log(`Self-judge inflation delta : ${((eywaOverall - ourOverall) * 100).toFixed(2)} pp`);
|
||||
console.log(`\nHONEST SAME-JUDGE LEADERBOARD (gpt-5 nugget judge):`);
|
||||
console.log(` Eywa answers @ gpt-5 judge : ${pct(ourOverall)}`);
|
||||
console.log(` OUR answers @ gpt-5 judge : ${pct(OUR_OWN_HEADLINE)}`);
|
||||
console.log(` Eywa - ours = ${((ourOverall - OUR_OWN_HEADLINE) * 100).toFixed(2)} pp`);
|
||||
|
||||
console.log('\n=== PER CATEGORY ===');
|
||||
console.log('cat'.padEnd(28), 'n'.padStart(4), 'ourJ%'.padStart(8), 'eywaSelf%'.padStart(10), 'delta_pp'.padStart(9));
|
||||
for (const c of catStats.sort((a, b) => a.delta - b.delta)) {
|
||||
console.log(
|
||||
c.cat.padEnd(28), String(c.n).padStart(4),
|
||||
pct(c.our).padStart(8), pct(c.eywa).padStart(10),
|
||||
((c.delta) * 100).toFixed(2).padStart(9),
|
||||
);
|
||||
}
|
||||
|
||||
console.log('\n=== PER-NUGGET AGREEMENT ===');
|
||||
console.log(`total nuggets compared: ${nTotal}`);
|
||||
console.log(`our < eywa (we stricter): ${nOurLess} (${pct(nOurLess / nTotal)})`);
|
||||
console.log(`our > eywa (we lenient) : ${nOurMore} (${pct(nOurMore / nTotal)})`);
|
||||
console.log(`equal : ${nEqual} (${pct(nEqual / nTotal)})`);
|
||||
console.log(`mean(our) - mean(eywa) per nugget: ${((sumOur - sumEywa) / nTotal).toFixed(4)}`);
|
||||
|
||||
// ── Markdown ──
|
||||
const md: string[] = [];
|
||||
md.push('# E1 — Eywa BEAM answers re-judged with OUR canonical gpt-5 nugget judge\n');
|
||||
md.push(`_Judge: gpt-5 (model id \`gpt-5\`), verbatim mem0 graded nugget prompt from \`src/beam-nugget-judge.ts\` — the SAME judge behind our published 0.6482 headline. Per-question score = mean of 0/0.5/1 nugget scores._\n`);
|
||||
md.push(`_Scored ${rows.length}/700 Eywa Sonnet-4.6 answers over ${nTotal} rubric nuggets._\n`);
|
||||
md.push('## Headline\n');
|
||||
md.push('| Metric | Value |');
|
||||
md.push('|---|---|');
|
||||
md.push(`| Eywa answers @ **our gpt-5 judge** | **${pct(ourOverall)}** |`);
|
||||
md.push(`| Eywa self-judge (Sonnet 4.6), our recompute | ${pct(eywaOverall)} |`);
|
||||
md.push(`| Eywa published headline | 81.45% |`);
|
||||
md.push(`| **Self-judge inflation** (eywa-self − our-judge) | **${((eywaOverall - ourOverall) * 100).toFixed(2)} pp** |`);
|
||||
md.push('');
|
||||
md.push('## Honest same-judge leaderboard (both @ gpt-5 nugget judge)\n');
|
||||
md.push('| System | Answers @ gpt-5 judge |');
|
||||
md.push('|---|---|');
|
||||
md.push(`| Eywa (Sonnet 4.6 answers) | **${pct(ourOverall)}** |`);
|
||||
md.push(`| Ours (published) | ${pct(OUR_OWN_HEADLINE)} |`);
|
||||
md.push(`| Gap (Eywa − ours) | ${((ourOverall - OUR_OWN_HEADLINE) * 100).toFixed(2)} pp |`);
|
||||
md.push('');
|
||||
md.push('## Per-category (n=70 each)\n');
|
||||
md.push('| Category | n | Our gpt-5 judge % | Eywa self-judge % | Delta (pp) |');
|
||||
md.push('|---|---|---|---|---|');
|
||||
for (const c of catStats.sort((a, b) => a.delta - b.delta)) {
|
||||
md.push(`| ${c.cat} | ${c.n} | ${pct(c.our)} | ${pct(c.eywa)} | ${(c.delta * 100).toFixed(2)} |`);
|
||||
}
|
||||
md.push('');
|
||||
md.push('_Delta = our-judge − eywa-self-judge. Large negative delta = Eywa self-judge inflated that category. Small delta = self-judge was honest there._\n');
|
||||
md.push('## Per-nugget judge agreement\n');
|
||||
md.push(`- Total nuggets compared: ${nTotal}`);
|
||||
md.push(`- Our score **< **Eywa (we stricter / leniency in their favor): ${nOurLess} (${pct(nOurLess / nTotal)})`);
|
||||
md.push(`- Our score **>** Eywa (we more lenient): ${nOurMore} (${pct(nOurMore / nTotal)})`);
|
||||
md.push(`- Equal: ${nEqual} (${pct(nEqual / nTotal)})`);
|
||||
md.push(`- mean(our) − mean(eywa) per nugget: **${((sumOur - sumEywa) / nTotal).toFixed(4)}**`);
|
||||
md.push('');
|
||||
|
||||
fs.writeFileSync(
|
||||
'D:/Projects/KorroResearch/benchmarks/eywa-artifacts/E1-eywa-answers-ourjudge.md',
|
||||
md.join('\n'),
|
||||
);
|
||||
console.log('\n[agg] wrote E1-eywa-answers-ourjudge.md');
|
||||
Reference in New Issue
Block a user