Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
bda4f7f
feat: add benchmark result store
janpower Jul 10, 2026
73f11d2
feat: preserve retrieval benchmark runs
janpower Jul 10, 2026
27c686b
feat: preserve extraction benchmark diagnostics
janpower Jul 10, 2026
a509fc7
feat: discover nested benchmark runs
janpower Jul 10, 2026
8b46432
feat: allow named retrieval benchmark runs
janpower Jul 10, 2026
cd0c284
feat: checksum benchmark dataset directories
janpower Jul 10, 2026
5e0533b
fix: compare benchmark runs from result root
janpower Jul 10, 2026
02b1551
docs: document benchmark run artifacts
janpower Jul 10, 2026
040ceb1
fix: distinguish extraction filtering stages
janpower Jul 10, 2026
568d247
fix: label RAG-HPO benchmark datasets correctly
janpower Jul 10, 2026
468783d
feat(benchmark): add llm to BenchmarkType
janpower Jul 10, 2026
29aaf71
feat(benchmark): let write_manifest register caller-supplied artifact…
janpower Jul 10, 2026
4454157
style: ruff-format new result_store tests
janpower Jul 10, 2026
73feb45
feat(benchmark): add term/case record derivation for the llm benchmark
janpower Jul 10, 2026
e2afda3
feat(benchmark): return term_records/case_records from run_llm_benchmark
janpower Jul 10, 2026
bc84cba
feat(benchmark): move llm benchmark CLI onto create_run_layout
janpower Jul 10, 2026
7c86ab2
fix(tests): update llm benchmark integration tests for create_run_lay…
janpower Jul 10, 2026
20f5392
feat(cli): replace llm benchmark --output-path/--checkpoint-path/--ar…
janpower Jul 10, 2026
cf41057
refactor(scripts): pass --output-dir only to phentrieve benchmark llm
janpower Jul 10, 2026
7bf7f6e
test(benchmark): cover discover_artifacts across retrieval/extraction…
janpower Jul 10, 2026
b672249
fix(benchmark): omit misleading term/case counts from partial llm man…
janpower Jul 10, 2026
b232911
docs: document llm benchmark result-store layout and CSC/GSC support
janpower Jul 10, 2026
dd95680
fix(benchmark): persist capture_phase1_debug so llm checkpoint resume…
janpower Jul 11, 2026
2b114c6
fix(benchmark): match llm checkpoints against resolved provider/model…
janpower Jul 11, 2026
28fec91
fix(benchmark): default capture_phase1_debug for pre-fix llm checkpoints
janpower Jul 11, 2026
64b10b3
docs: keep manuscript planning out of product branch
janpower Jul 12, 2026
ec70549
fix benchmark checkpoint reproducibility
janpower Jul 12, 2026
e94a832
chore(deps)(deps-dev): bump vite from 8.1.3 to 8.1.4 in /frontend
dependabot[bot] Jul 13, 2026
397ee89
chore(deps)(deps): bump the frontend-minor-patch group across 1 direc…
dependabot[bot] Jul 13, 2026
ab776f7
fix(benchmark): stop runs inheriting artifacts and rows they did not …
berntpopp Jul 13, 2026
4676b52
fix(benchmark): key every retrieval case row on a stable case_id
berntpopp Jul 13, 2026
5a280d5
fix(benchmark): bind llm checkpoints to prompts and report true run s…
berntpopp Jul 13, 2026
e00a053
fix(benchmark): clamp the distance-to-similarity fallback
berntpopp Jul 13, 2026
28cba5c
docs(benchmark): correct the compare default and LLM trace gating
berntpopp Jul 13, 2026
0812fb6
Merge remote-tracking branch 'origin/dependabot/npm_and_yarn/frontend…
berntpopp Jul 13, 2026
879b2ac
chore(deps): fold in frontend dependency bumps from #307 and #308
berntpopp Jul 13, 2026
a263840
chore(release): 0.26.0 (CLI 0.26.0 / API 0.17.0 / Frontend 0.17.1)
berntpopp Jul 13, 2026
fb733c3
fix(deps): upgrade click and pillow to clear new advisories
berntpopp Jul 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,54 @@ together:

## [Unreleased]

## [0.26.0] — 2026-07-13 (CLI 0.26.0 / API 0.17.0 / Frontend 0.17.1)

Reproducible benchmark result storage. Retrieval, extraction, and LLM benchmarks
now write to one collision-free run directory per run, described by a manifest
that records the run's identity, dataset checksum, configuration, and the
machine-readable location of every artifact it produced. The API is unchanged.

### Added

- **Shared benchmark result store** (`phentrieve/benchmark/result_store.py`).
Runs land in `results/<type>/<dataset>/<model>/<run-id>/` with a `manifest.json`,
a `summary.json`, and analysis-first `terms.jsonl` / `cases.jsonl` artifacts;
extraction additionally emits `diagnostics/chunks.jsonl` with every retrieved
candidate and the stage at which it was filtered. Previous flat output formats
are preserved under `legacy/` for the migration period.
- **`--run-id` / `--overwrite` / `--output-dir`** on the retrieval, extraction, and
LLM benchmark commands, for stable run names and explicit reuse. The LLM
benchmark's `--output-path`, `--checkpoint-path`, and `--artifacts-dir` are
deprecated but still honoured.
- **CSC/GSC LLM benchmark support** and recursive discovery of nested runs by
comparison and visualization commands.

### Changed

- **Checkpoint reuse is bound to the inputs that determine its contents** —
dataset checksum, accounting configuration, resolved provider/model/base URL,
and the contents of the prompt templates the run loads. An edited prompt
template can no longer be resumed into an existing run, which would have merged
old-prompt and new-prompt document outputs into one set of metrics.
- **Retrieval benchmarks record non-evaluable cases explicitly** rather than
dropping them, and every row of `cases.jsonl` is keyed on the same 0-based
`case_id` that `terms.jsonl` joins on.
- **Frontend dependencies** bumped (vite, eslint, prettier, postcss, terser,
libphonenumber-js, @vitest/coverage-v8).

### Fixed

- **Overwritten runs no longer inherit artifacts they did not produce.** Reusing a
run directory left the previous run's files in place, and the manifest — which
decides what to advertise from what exists on disk — published them as the new
run's own output.
- **`benchmark compare` no longer lists extraction and LLM runs as retrieval
models.** All three benchmark types write a `summary` artifact into the shared
results root, so the dense-retrieval comparison table had been picking them up
and scoring them `MRR (Dense) = 0`.
- **LLM run status is derived from per-case outcomes.** A run in which every
document failed had still been recorded in its manifest as `complete`.

## [0.25.0] — 2026-07-04 (CLI 0.25.0 / API 0.17.0 / Frontend 0.17.0)

LLM extraction contract v2 (Phase 2, blocks B0–B3): the model's assertion and
Expand Down
126 changes: 113 additions & 13 deletions docs/user-guide/benchmarking-guide.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,115 @@
# Benchmarking Guide

This page shows the concrete benchmark commands for retrieval and LLM full-text
validation.
This page shows the concrete benchmark commands for retrieval, document
extraction, and LLM full-text validation.

## Retrieval Benchmark

Use the canonical German single-term datasets for official retrieval
comparisons:

```bash
phentrieve benchmark run \
--test-file tests/data/benchmarks/german/570terms_german.json \
--model-name "FremyCompany/BioLORD-2023-M" \
--results-dir results
```

```bash
phentrieve benchmark run \
--test-file tests/data/benchmarks/german/200cases_o3_v1.json \
--model-name "FremyCompany/BioLORD-2023-M" \
--results-dir results
```

The default benchmark remains the small smoke dataset for fast local checks:

```bash
phentrieve benchmark run \
--test-file tests/data/benchmarks/german/tiny_v1.json \
--model-name "sentence-transformers/LaBSE"
--model-name "sentence-transformers/LaBSE" \
--results-dir results
```

Each model run receives its own directory. Use `--run-id baseline` for a stable
name. Reusing that name requires the explicit `--overwrite` option.

## GSC And CSC Extraction Benchmarks

The canonical text-fragment corpora are the converted RAG-HPO `GSC` and `CSC`
sets under `tests/data/en/raghpo_paper/`. They are legacy polarity-blind
corpora, so use `present-only` scoring while leaving assertion detection
enabled:

```bash
phentrieve benchmark extraction run tests/data/en/raghpo_paper \
--dataset GSC \
--model "FremyCompany/BioLORD-2023-M" \
--language en \
--scoring-mode present-only \
--output-dir results
```

```bash
phentrieve benchmark extraction run tests/data/en/raghpo_paper \
--dataset CSC \
--model "FremyCompany/BioLORD-2023-M" \
--language en \
--scoring-mode present-only \
--output-dir results
```

Use `GSC_plus`, `ID_68`, and `GeneReviews` under
`tests/data/en/phenobert/` for regression and diagnostic runs.

## Run Artifacts

Retrieval, extraction, and LLM full-text runs use this hierarchy:

```text
results/
retrieval/<dataset>/<model>/<run-id>/
extraction/<dataset>/<model>/<run-id>/
llm/<dataset>/<model>/<run-id>/
```

The important files are:

- `manifest.json`: run identity, dataset checksum, model, configuration, status,
and machine-readable artifact locations.
- `summary.json`: aggregate metrics and per-case arrays used by comparisons and
the standard benchmark graphics.
- `terms.jsonl`: ranked or extracted HPO terms, scores, gold membership, and
TP/FP/FN outcomes. Extraction records distinguish pipeline predictions from
evaluated predictions and identify whether a term was removed by the chunk
threshold, chunk selection, aggregation confidence, or scoring mode. Use
this for term-level analysis.
- `cases.jsonl`: query/document inputs, predictions, per-case metrics, timings,
and errors. Use this for statistical analysis.
- `diagnostics/chunks.jsonl`: extraction chunks and every returned top-N
candidate before thresholding. This is diagnostic material rather than the
primary result. Extraction only; absent for retrieval and LLM runs.
- `legacy/`: the previous summary JSON, CSV, and extraction result formats.
Retrieval and extraction only.
- `predictions/<llm-mode>/`, `traces/<llm-mode>/`, and `metrics/`: per-document
LLM predictions, per-document pipeline traces, and an aggregate metrics JSON.
LLM runs only. Traces are always written; `--capture-phase1-debug` adds the
phase-1 retrieval detail to them rather than enabling them.

Comparison and visualization commands discover structured runs recursively and
still accept old flat summary directories. Both compare dense retrieval metrics,
so they only ever load `retrieval` runs; pointing them at a results root that
also holds extraction and LLM runs is safe:

```bash
phentrieve benchmark compare --summaries-dir results
phentrieve benchmark visualize --summaries-dir results
```

When `--results-dir` is omitted for retrieval, `PHENTRIEVE_RESULTS_DIR` or the
configured user results directory is used. Extraction defaults to the local
`results/` root.

## LLM Full-Text Benchmark

The primary LLM benchmark workflow uses the converted PhenoBERT full-text
Expand All @@ -31,16 +130,17 @@ The converted corpus contains these dataset subsets:
- `GeneReviews`
- `all`

The output JSON includes:

- `cases`
- `dataset`
- `llm_model`
- `llm_mode`
- `dataset_metadata`
- `metrics`
- `results`
- `output_path`
The RAG-HPO `GSC` and `CSC` sets under `tests/data/en/raghpo_paper/` are also
supported (see [GSC And CSC Extraction Benchmarks](#gsc-and-csc-extraction-benchmarks)
for background on the corpora).

Like retrieval and extraction runs, each invocation writes to its own
`results/llm/<dataset>/<model>/<run-id>/` directory (see
[Run Artifacts](#run-artifacts)): `manifest.json`, `summary.json`,
`terms.jsonl`, `cases.jsonl`, plus the LLM-specific `predictions/`, `traces/`,
and `metrics/` artifacts. Use `--run-id` for a stable name; reusing that name
requires the explicit `--overwrite` option, matching the retrieval and
extraction commands. `--output-dir` (default `results`) sets the result root.

## Corpus Acquisition And Conversion

Expand Down
Loading
Loading