Skip to content

Commit 5819a0c

Browse files
strukalexclaude
authored andcommitted
docs(experiments): add POST_BENCHMARK_FOLLOWUPS for cross-experiment work
Track the strict-equality re-evaluation, cost normalisation, latency percentile aggregation, and iteration-scorer rebaseline as items to do after E05 lands. None blocks the experiment chain; all benefit from having every run's benchmark-run.json committed first. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 1faa188 commit 5819a0c

1 file changed

Lines changed: 87 additions & 0 deletions

File tree

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Post-benchmark follow-ups (cross-experiment)
2+
3+
Tasks that cut across all five experiments — defer until E05 lands and the chained stack is complete. Pick up from this list once you have all five `benchmark-run.json` files committed.
4+
5+
## 1. Re-evaluate every run under strict equality
6+
7+
**Why.** All five experiments are evaluated with the same `schema-aware` evaluator using `defaultRule: { rule: "fuzzy", fuzzyThreshold: 0.85 }, passThreshold: 0.8` (wired in [`apps/shared/prisma/seed.ts:2044-2062`](../apps/shared/prisma/seed.ts#L2044-L2062)). This is correct for cross-experiment comparison — same rule, same dataset, same evaluator — but fuzzy@0.85 is forgiving on close-but-not-exact OCR misreads (e.g. predicted `2326.4` vs ground truth `2326.47`). For a stricter view of "the model got the value exactly right," re-evaluate every run with the rule changed to `"exact"` (or `fuzzyThreshold: 1.0`).
8+
9+
**What this affects** ([detailed in `experiments/results/04-vlm-direct/SUMMARY.md` "Gaps"](results/04-vlm-direct/SUMMARY.md)):
10+
11+
- All `metrics.*` aggregates: `pass_rate`, `f1.*`, `precision.*`, `recall.*`, `matchedFields.*`, `truePositives.*`, `falseNegatives.*`, `falsePositives.*`, `passing_samples`, `failing_samples`.
12+
- Per-sample: `metrics`, `pass`, `evaluationDetails[].matched`.
13+
- `perFieldResults[].{accuracy, correctCount, errorCount, errorRate, errors[]}`.
14+
- `errorDetectionAnalysis.fields[].{errorCount, errorRate, curve, suggestedBestBalance, suggestedCatch90, suggestedMinimizeReview}`.
15+
16+
The raw `similarity`, `predicted`, `expected`, `confidence` values are preserved per evaluation pair — re-evaluation only needs to recompute `matched` and the aggregates downstream of it. **No re-running the model.**
17+
18+
**Two ways to do it:**
19+
20+
### Option A — re-run the benchmarks under a tighter rule
21+
22+
Change the seed config:
23+
24+
```ts
25+
// apps/shared/prisma/seed.ts L2044-L2062
26+
evaluatorType: "schema-aware",
27+
evaluatorConfig: {
28+
defaultRule: { rule: "exact" }, // <- was { rule: "fuzzy", fuzzyThreshold: 0.85 }
29+
passThreshold: 0.8,
30+
},
31+
```
32+
33+
`npm run test:db:reset` to re-seed, then re-trigger every experiment via:
34+
35+
```bash
36+
cd apps/temporal
37+
for slug in 01 02 03 04 05; do
38+
npx tsx -r tsconfig-paths/register src/scripts/trigger-experiment-benchmark.ts $slug
39+
done
40+
```
41+
42+
Save the new exports to `experiments/results/<slug>/benchmark-run-strict.json` (parallel to `benchmark-run.json` so we keep both). Cost: full benchmark re-run for all five experiments (~$15-25, ~30 min wallclock).
43+
44+
### Option B — re-evaluate the existing exports without re-running
45+
46+
Write a script that reads each `benchmark-run.json` and recomputes metrics from the preserved `evaluationDetails[].similarity`. No paid calls, instant turnaround:
47+
48+
```ts
49+
// experiments/scripts/reevaluate-strict.ts (sketch)
50+
//
51+
// For each run:
52+
// - read perSampleResults[].evaluationDetails
53+
// - recompute matched = (similarity == 1.0) // or some other rule
54+
// - re-aggregate truePositives, falseNegatives, falsePositives per sample
55+
// - recompute precision, recall, f1 per sample
56+
// - re-aggregate to top-level metrics, perFieldResults, errorDetectionAnalysis
57+
// - write benchmark-run-strict.json
58+
```
59+
60+
Option B is the recommended path — it's lossless w.r.t. raw model output, runs in seconds, and produces a parallel comparison artifact you can diff against the fuzzy-evaluated original.
61+
62+
**Expected impact** (estimated from E04's distribution):
63+
64+
- E04 (VLM-direct): drops ~3-4 pp on f1.median because gpt-5.4 vision produces more close-but-not-exact OCR misreads (76 of 1646 matches in the canonical run are fuzzy-only).
65+
- E03 (CU): drops ~1-2 pp — CU's dedicated OCR layer transcribes digits exactly more often.
66+
- E02 (Mistral): somewhere in between.
67+
- Rank order stays the same; the *gap* between E03 and E04 widens slightly.
68+
69+
## 2. Cross-experiment cost normalisation
70+
71+
Each engine bills differently:
72+
73+
- E01 (Azure DI Neural): per-page custom-model invocation
74+
- E02 (Mistral DocAI): per-page OCR + per-token annotation
75+
- E03 (Azure CU): per-page content-extraction + per-token gpt-5.2 generative
76+
- E04 (gpt-5.4 VLM-direct): per-token (input + output) only
77+
- E05 (hybrid): E01-style DI Read per-page + E04-style VLM tokens
78+
79+
`benchmark-run.json` has `usage_info` / `prompt_tokens` / `completion_tokens` etc. but cross-engine cost normalisation requires hard-coded rate cards or a per-engine cost-aggregation activity. Defer until E05 lands; then add a `cost_per_page_usd` column to the comparison table.
80+
81+
## 3. P50 / P95 latency per engine
82+
83+
`benchmark-run.json` carries per-sample `startedAt` / `completedAt`. Compute P50 / P95 / P99 wallclock per engine and add to the comparison table. One small script reading all five exports.
84+
85+
## 4. Rebaseline `iterate-*-extraction.ts` scorer
86+
87+
The per-experiment iteration scripts use strict-with-normalisation matching, but the canonical benchmark uses fuzzy@0.85. This divergence cost time on E04 (iterating to 70.3% per-field accuracy that turned out not to predict the benchmark median). After re-evaluating runs under both rules (item 1), update the iteration scripts to optionally accept a `--scorer fuzzy|strict` flag so future experiments can iterate against whichever matches the configured benchmark rule.

0 commit comments

Comments
 (0)