Knowledge-Graph Extraction Benchmarks — April 2026

This page records the benchmark runs performed on 2026-04-23 while choosing the shipping configuration for the Phase 2 entity extractor and the save-time chunker. The goal was to pick a model/concurrency/chunk-size combination that could extract the full ~40k-chunk corpus in an operator-friendly wall-clock without swamping the review queue with noisy proposals.

The final choices in production:

Everything below shows why — and why each of the alternatives that looked promising on paper lost on actually-measured numbers.

Corpus baseline

Before rebuildAfter rebuild
kg_content_chunks39,26423,256
content_chunk_embeddings39,26423,256
chunk_entity_mentions3440 (FK-cascaded on chunk delete)
Mean tokens / chunk103174
p50 / p95 tokens / chunk77 / 261166 / 335
Max tokens / chunk1,9631,963 (atomic blocks unchanged)
Embedding rebuild wall-clock6m 18s

The chunker rebuild was driven by one configuration change: raising wikantik.chunker.merge_forward_tokens from 8 to 150. That change also exposed two previously-advertised-but-unwired knobs (target_tokens, min_tokens) which were removed from the ContentChunker.Config record.

Summary of extractor runs

All runs use the same system prompt, same chunker output (with differing chunk sizes between "old" and "new"), and the same post-processing (chunk_entity_mentions upsert, kg_proposals insert, kg_rejections suppression). Per-chunk RPC mean is the wall-clock latency of a single extraction call; effective s/chunk is per-chunk-RPC divided by concurrency.

RunModelPromptConcurrencyChunksPer-chunk RPCEffective s/chunkFull-corpus projection
1gemma4-assist:latestverbose139k8.5 s8.5 s≈ 93 h
2qwen2.5:7b-instruct-q5_K_Mverbose139k14.2 s14.2 s≈ 155 h
3qwen2.5:7b-instruct-q5_K_Mtightened239k18.8 s9.4 s≈ 104 h
4gemma4:e2btightened339k20.2 s6.7 s≈ 73 h
5gemma4-assist:latesttightened439k41.0 s10.3 s≈ 112 h
6gemma4-assist:latesttightened223k25.3 s12.7 s≈ 82 h
7gemma4-assist:latesttightened123k13.6 s13.6 s≈ 88 h

Run 6 is the shipping configuration. Runs 4 and 3 are faster on the clock but lose to run 6 on quality (detailed below). Run 5's c=4 shows scaling has negative returns past c=2 on a 4060 Ti serving a 7–8B-class model — the GPU is already bandwidth-bound.

Proposal volume comparison

On the same page (AbstractAlgebra, 42 chunks in the old corpus / 27 in the new):

Model / promptMentionsProposalsMentions:Proposals
gemma4-assist + verbose (run 1)81081 : 13
qwen2.5:7b + verbose (run 2)12131 : 213
qwen2.5:7b + tight (run 3)21581 : 79
gemma4:e2b + tight (run 4)41291 : 32
gemma4-assist + tight c=4 (run 5)15681 : 4.5
gemma4-assist + tight c=2 (run 6)12481 : 4

The tighter prompt reduced gemma4-assist's proposal-per-chunk rate from ~2.6 to ~1.3 while simultaneously doubling the mention rate. Roughly half the review queue to work through for equivalent coverage.

Quality observations — same page, different models

Sample of top entities emitted for AbstractAlgebra (first chunks):

gemma4-assist, verbose prompt (run 1)

rings, Ore rings, localization procedures, Ore condition, quantum groups,
C*-algebras, Ring theory, algebraic structures, integers, polynomials,
algebraic geometry, representation theory, non-commutative geometry,
categorical frameworks, geometric frameworks

All domain-appropriate named concepts. Reasoning grounded in specific chunk text.

qwen2.5:7b, verbose prompt (run 2)

Ring, Algebraic structures $(R, +, \x08oldsymbol{⋅})$,   ← LaTeX corruption
Integers ($\x08oldsymbol{ℤ}$),                            ← LaTeX corruption
AdvancedTechniques,                                        ← CamelCase phrase
SharedRigorousUnderstanding,                               ← phrase-as-entity
FoundationalObject,                                        ← meta-term
R, +, ⋅, R, abean,                                         ← operators, typo
ring, unital ring, non-unital ring

The \x08oldsymbol string is a JSON escape-character collision where the model's output of \b was decoded as the ASCII backspace control character. The abean entry is a hallucinated typo of "abelian". Both are pre-existing qwen JSON-mode issues on technical prose.

qwen2.5:7b, tightened prompt (run 3)

Ring theory, algebraic structures $(R, +, ⋅)$, arithmetic of integers ($ℤ$),
polynomials ($k[x]$), advanced techniques, foundational object,
R, +, ⋅, R, 0, Unity, FunctionalAnalysis (type=Article),
commutative rings, non-commutative rings

LaTeX corruption resolved. Still emits operators and single letters. FunctionalAnalysis correctly tagged as Article — the one win.

gemma4:e2b, tightened prompt (run 4)

Ring, R, +, ×, 0, a, b, c, FunctionalAnalysis, Rings, Commutativity,
Non-commutative, Ring, ideal, Prime Ideals, R, P, Spec(R), M

Single letters (a, b, c, R, M, P) appear frequently — the 2B model is the least discriminating about what qualifies as a named entity. Does correctly pick up Spec(R), Prime Ideals, FunctionalAnalysis.

gemma4-assist, tightened prompt (runs 5–7)

Quality is equivalent to run 1 but with the proposal-volume and mention-rate improvements from the tighter prompt.

Why concurrency doesn't help gemma4-assist

Adding concurrent requests to Ollama on a single 4060 Ti slows each in-flight request proportionally, because the GPU is bandwidth-bound on a 7–8B-class model. The net-net for gemma4-assist:

ConcurrencyEffective s/chunkRelative
c=113.6 sbaseline
c=212.7 s7% faster
c=410.3 s (old-chunks), degraded on new chunksmodest gain then regression

Concurrency does help the 2B gemma4:e2b — there's enough VRAM headroom for the GPU scheduler to actually run requests in parallel. But the quality regression on small models is severe enough that we didn't ship it.

Per-page timing detail (first 10 pages, run 6)

Reference for anyone tuning a sample: first 11 pages of run 6 (shipping config, 23k-chunk corpus, gemma4-assist c=2):

PageChunksTotal (ms)Per-chunk (ms)MentionsProposals
2026IranWar473,69118,423827
AbstractAlgebra27322,27411,9361248
AcceleratingAiLearning13140,73710,82686
AccountTypeStrategy12165,75713,8131224
AcidTransactionsAndIsolation29493,58717,020177
ActorModelProgramming26322,93912,421843
AdapterPattern28370,07313,2171845
AdjustmentOfStatusProcess13130,19410,015721
AdminSecurityUi230,97215,48628
AdvancedSkillPatterns24251,14510,464322
AdventureTravelPlanning23293,85212,776239

Chunker rebuild — search-ranking impact

Before the full extractor run we verified that the 39k → 23k chunker rebuild didn't regress search quality. The test compared top-10 results for the same queries before and after the rebuild, with graph rerank disabled (no mentions populated yet).

Methodology

For each query, capture top-10 page names from /api/search against the old corpus (39k chunks, stored baseline from 07:25 local), and again against the new corpus (23k chunks, captured immediately after the rebuild completed). Compare set overlap and ordering.

Results — "knowledge graph" top 10

RankOld chunksNew chunks
1WikantikKnowledgeGraphAdminInventionOfKnowledgeGraph
2InventionOfKnowledgeGraphWikantikKnowledgeGraphAdmin
3KnowledgeGraphCoreKnowledgeGraphCore
4KnowledgeGraphDogfoodingKnowledgeGraphVsRelationalDatabase
5KnowledgeGraphVsRelationalDatabaseGraphRAG
6GraphRAGKnowledgeGraphsAndManagement
7IndustrialKnowledgeGraphUseCasesIndustrialKnowledgeGraphUseCases
8KnowledgeGraphsAndManagementFederatedKnowledgeGraphs
9KnowledgeGraphCompletionKnowledgeGraphCompletion
10FederatedKnowledgeGraphsKnowledgeGraphConstructionPipeline

Set overlap: 8 of 10 preserved. Dropped: KnowledgeGraphDogfooding. Added: KnowledgeGraphConstructionPipeline. Positions 1–2 swapped; both are highly relevant.

Results — "GraphRAG" top 10

RankOld chunksNew chunks
1GraphRAGGraphRAG
2KnowledgeGraphsAndManagementKnowledgeGraphsAndManagement
3KnowledgeGraphsAndGenAIWorkflowsKnowledgeGraphsAndGenAIWorkflows
4InventionOfKnowledgeGraphInventionOfKnowledgeGraph
5RagImplementationPatternsRagImplementationPatterns
6AdvancedSearchTermEngineeringAdvancedSearchTermEngineering
7IndustrialKnowledgeGraphUseCasesIndustrialKnowledgeGraphUseCases
8AiFunctionCallingAndToolUseAiMemoryAndPersistence
9WikantikKnowledgeGraphAdminResourceDescriptionFramework
10ResourceDescriptionFrameworkWikantikKnowledgeGraphAdmin

Set overlap: 8 of 10 preserved. Top 7 identical. Dropped: AiFunctionCallingAndToolUse. Added: AiMemoryAndPersistence.

Interpretation

Takeaways

  1. Quality dominates throughput on this corpus. A "perfect throughput, low signal-to-noise" model is worse than "modest throughput, high signal-to-noise" because the admin review queue is the real bottleneck. Shipping gemma4-assist cost about 12 % more wall-clock than gemma4:e2b but produces about half the review noise.
  2. Prompt tightening beat model swapping. The same gemma4-assist model went from 2.6 proposals/chunk (verbose) to 1.3 (tight) while doubling its mention rate. No model change matched that on signal-to-noise.
  3. Concurrency is model-dependent. c=2 helps 7–8B models marginally (~7 %); c≥3 regresses. Small 2B models scale to c=3 with real gains. One knob doesn't fit all.
  4. Chunker floor is the biggest lever we pulled. 39k → 23k chunks is a 41 % reduction in extraction RPCs for ~0 search-quality cost, against a configuration change that took seconds.
  5. Claude Haiku 4.5 remains the "definitely finishes in a workday" fallback at ≈ $75 and ≈ 25 h for the full corpus, if the ~82 h local-only projection ever becomes operationally unacceptable.

Further reading