BEIR NFCorpus
Applies to OML v0.6.x · Status: Measured · Last verified 2026-11-06
These are measurements by the OML maintainers on their own hardware, not independent results. Generated from the committed oml-bench/1 results.
Suite beir-nfcorpus, data beir/nfcorpus/test (ir_datasets 0.6.3): 3,633 memories, 323 queries; a method marked sampled asked a seeded subset, named in its row.
Run details
Measured 2026-11-05 on commits 2123e90, 66979b4, a1ad0c9, d3fdb72, f86c31c; build release, host 8 vCPU / 15 GB, postgres 17.9; build release, host 8 vCPU / 15 GB, postgres 18.6; build release, host 8 vCPU / 15 GB, load average 3.6 to 14 from other lanes, postgres 18.6; build release, host 8 vCPU / 15 GB, shared, load 8-12, postgres 18.
How to reproduce. Build oml and oml-server-lead in release mode, install eval/bench/requirements.txt in a scratch virtual environment, then run eval/bench/run.sh <out-dir> nfcorpus against a throwaway PostgreSQL superuser cluster. The harness loads the data over HTTP, promotes it with reviewer keys, asks every query through oml_read and writes the result files listed below.
Quality
| method | queries | nDCG@10 | R@10 | R@20 | R@100 | RR@10 | S@1 | S@5 | zero |
|---|---|---|---|---|---|---|---|---|---|
| keyword-all | 323 | 0.187 | 0.083 | – | 0.092 | 0.317 | 0.282 | 0.362 | 0.511 |
| keyword-any | 323 | 0.274 | 0.130 | – | 0.210 | 0.474 | 0.406 | 0.560 | 0.081 |
| bm25 | 323 | 0.321 | 0.155 | 0.184 | 0.247 | 0.526 | 0.440 | 0.656 | 0.046 |
| bm25-trigram | 100 (sampled) | 0.267 | 0.147 | – | 0.245 | 0.482 | 0.380 | 0.600 | 0.000 |
| bm25-postings | 323 | 0.321 | 0.155 | 0.184 | 0.247 | 0.526 | 0.440 | 0.656 | 0.046 |
| sparse | 323 | 0.343 | 0.164 | 0.191 | 0.276 | 0.544 | 0.464 | 0.656 | 0.009 |
| bm25-sparse | 323 | 0.349 | 0.166 | 0.196 | 0.277 | 0.565 | 0.483 | 0.662 | 0.009 |
| bm25-sparse-rrf | 323 | 0.344 | 0.166 | 0.194 | 0.272 | 0.557 | 0.461 | 0.678 | 0.009 |
| bm25-rerank-d20 | 100 (sampled) | 0.330 | 0.162 | – | 0.243 | 0.543 | 0.470 | 0.630 | 0.040 |
| bm25-sampled | 100 (sampled) | 0.320 | 0.152 | – | 0.243 | 0.550 | 0.480 | 0.630 | 0.040 |
| reference-bm25s-k1-0.9-b-0.4 | 323 | 0.318 | 0.145 | – | 0.246 | 0.522 | 0.440 | 0.647 | 0.046 |
| reference-bm25s-k1-1.2-b-0.75 | 323 | 0.318 | 0.145 | – | 0.247 | 0.523 | 0.436 | 0.644 | 0.046 |
Reference: BEIR BM25 (Anserini, k1 0.9, b 0.4, title and text fields), ndcg@10 0.325 (source).
Chart: nDCG@10 by pipeline
Latency
Client wall time per recall, in milliseconds, nearest-rank percentiles.
| method | p50 | p95 | p99 |
|---|---|---|---|
| keyword-all | 477 | 513 | 537 |
| keyword-any | 586 | 1,016 | 1,072 |
| bm25 | 51.8 | 83.8 | 106 |
| bm25-trigram | 2,172 | 3,047 | 3,391 |
| bm25-postings | 38.0 | 54.8 | 77.2 |
| sparse | 35.7 | 49.4 | 63.6 |
| bm25-sparse | 48.5 | 65.9 | 78.8 |
| bm25-sparse-rrf | 34.4 | 58.7 | 182 |
| bm25-rerank-d20 | 5,247 | 15,467 | 16,744 |
| bm25-sampled | 69.5 | 140 | 197 |
| reference-bm25s-k1-0.9-b-0.4 | offline | offline | offline |
| reference-bm25s-k1-1.2-b-0.75 | offline | offline | offline |
Chart: p95 latency by pipeline
What this result does not show
NFCorpus is nutrition and medical text. It does not predict recall over short chat notes.
Limits of this run
One abstract per memory as '
- Offline bm25s over the same memories (Lucene BM25, English stop words, Snowball stems), not a served path;
- Served bm25 over the same seeded sample, on the same host in the same hour, for comparison with bm25-rerank-d20; the full-set bm25 row is the reference run.
- Known gap: served bm25 measures below BEIR's published 0.325 and Pyserini's single-field 0.322; the offline textbook BM25 over the same memories measures 0.318, so most of the gap is the one-body mapping and the analyser (Snowball against Lucene's Porter, hyphenated words kept whole), not the ranking. bm25's list reranked by ms-marco-MiniLM-L6-v2 through candle on the CPU at depth 20 (the default became 10 after this run), with a cap of 8 and a 60 s deadline so no rerank was skipped; the host carried a load average of 9 to 29 from other work, and the LoCoMo run shared it with the NFCorpus run, so its latency is an upper bound (.
- Known gap: served bm25 measures below BEIR's published 0.325 and Pyserini's single-field 0.322; the offline textbook BM25 over the same memories measures 0.318, so most of the gap is the one-body mapping and the analyser (Snowball against Lucene's Porter, hyphenated words kept whole), not the ranking. bm25-postings takes its candidates from the postings of the query forms it reads; when a query's readable postings pass POSTING_BUDGET (10,000) it leaves out the forms held by more than 10% of the readable rows, so a row holding only those is no candidate, and below the budget it reads every form and ranks as bm25.
Sources: eval/bench/results/beir-nfcorpus/keyword-all.json, eval/bench/results/beir-nfcorpus/keyword-any.json, eval/bench/results/beir-nfcorpus/bm25.json, eval/bench/results/beir-nfcorpus/bm25-trigram.json, eval/bench/results/beir-nfcorpus/bm25-postings.json, eval/bench/results/beir-nfcorpus/sparse.json, eval/bench/results/beir-nfcorpus/bm25-sparse.json, eval/bench/results/beir-nfcorpus/bm25-sparse-rrf.json, eval/bench/results/beir-nfcorpus/bm25-rerank-d20.json, eval/bench/results/beir-nfcorpus/bm25-sampled.json, eval/bench/results/beir-nfcorpus/reference-bm25s-k1-0.9-b-0.4.json, eval/bench/results/beir-nfcorpus/reference-bm25s-k1-1.2-b-0.75.json.