verifydoc 0.2.0__tar.gz → 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. {verifydoc-0.2.0 → verifydoc-0.3.0}/CHANGELOG.md +23 -0
  2. {verifydoc-0.2.0 → verifydoc-0.3.0}/PKG-INFO +1 -1
  3. {verifydoc-0.2.0 → verifydoc-0.3.0}/benchmark/datasets/cord.py +57 -11
  4. {verifydoc-0.2.0 → verifydoc-0.3.0}/benchmark/datasets/funsd.py +1 -0
  5. verifydoc-0.3.0/configs/cord-paddleocr.yaml +15 -0
  6. verifydoc-0.3.0/configs/cord-rapidocr.yaml +11 -0
  7. verifydoc-0.3.0/configs/funsd-paddleocr.yaml +9 -0
  8. verifydoc-0.3.0/configs/funsd-rapidocr.yaml +9 -0
  9. verifydoc-0.3.0/docs/REAL_MODELS.md +77 -0
  10. verifydoc-0.3.0/paper/generated/REAL_MODELS_RESULTS.md +60 -0
  11. verifydoc-0.3.0/paper/generated/cord-paddleocr/calibration.md +34 -0
  12. verifydoc-0.3.0/paper/generated/cord-paddleocr/conformal.md +16 -0
  13. verifydoc-0.3.0/paper/generated/cord-paddleocr/extraction.md +5 -0
  14. verifydoc-0.3.0/paper/generated/cord-paddleocr/grounding.md +5 -0
  15. verifydoc-0.3.0/paper/generated/cord-paddleocr/selective.md +10 -0
  16. verifydoc-0.3.0/paper/generated/cord-rapidocr/calibration.md +34 -0
  17. verifydoc-0.3.0/paper/generated/cord-rapidocr/conformal.md +16 -0
  18. verifydoc-0.3.0/paper/generated/cord-rapidocr/extraction.md +5 -0
  19. verifydoc-0.3.0/paper/generated/cord-rapidocr/grounding.md +5 -0
  20. verifydoc-0.3.0/paper/generated/cord-rapidocr/selective.md +10 -0
  21. verifydoc-0.3.0/paper/generated/funsd-paddleocr/calibration.md +34 -0
  22. verifydoc-0.3.0/paper/generated/funsd-paddleocr/conformal.md +16 -0
  23. verifydoc-0.3.0/paper/generated/funsd-paddleocr/extraction.md +5 -0
  24. verifydoc-0.3.0/paper/generated/funsd-paddleocr/grounding.md +5 -0
  25. verifydoc-0.3.0/paper/generated/funsd-paddleocr/selective.md +10 -0
  26. verifydoc-0.3.0/paper/generated/funsd-rapidocr/calibration.md +34 -0
  27. verifydoc-0.3.0/paper/generated/funsd-rapidocr/conformal.md +16 -0
  28. verifydoc-0.3.0/paper/generated/funsd-rapidocr/extraction.md +5 -0
  29. verifydoc-0.3.0/paper/generated/funsd-rapidocr/grounding.md +5 -0
  30. verifydoc-0.3.0/paper/generated/funsd-rapidocr/selective.md +10 -0
  31. {verifydoc-0.2.0 → verifydoc-0.3.0}/pyproject.toml +1 -1
  32. {verifydoc-0.2.0 → verifydoc-0.3.0}/tests/test_pipeline.py +64 -1
  33. {verifydoc-0.2.0 → verifydoc-0.3.0}/tests/test_types.py +13 -0
  34. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/__init__.py +1 -1
  35. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/adapters/__init__.py +1 -0
  36. verifydoc-0.3.0/verifydoc/adapters/paddleocr_vl.py +99 -0
  37. verifydoc-0.3.0/verifydoc/adapters/rapidocr.py +94 -0
  38. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/adapters/text_search.py +6 -2
  39. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/eval/harness.py +5 -1
  40. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/types.py +2 -0
  41. verifydoc-0.2.0/configs/cord-paddleocr.yaml +0 -14
  42. verifydoc-0.2.0/docs/REAL_MODELS.md +0 -61
  43. verifydoc-0.2.0/verifydoc/adapters/paddleocr_vl.py +0 -50
  44. {verifydoc-0.2.0 → verifydoc-0.3.0}/.github/workflows/ci.yml +0 -0
  45. {verifydoc-0.2.0 → verifydoc-0.3.0}/.github/workflows/release.yml +0 -0
  46. {verifydoc-0.2.0 → verifydoc-0.3.0}/.gitignore +0 -0
  47. {verifydoc-0.2.0 → verifydoc-0.3.0}/.pre-commit-config.yaml +0 -0
  48. {verifydoc-0.2.0 → verifydoc-0.3.0}/CLAUDE.md +0 -0
  49. {verifydoc-0.2.0 → verifydoc-0.3.0}/LICENSE +0 -0
  50. {verifydoc-0.2.0 → verifydoc-0.3.0}/Makefile +0 -0
  51. {verifydoc-0.2.0 → verifydoc-0.3.0}/PROJECT.md +0 -0
  52. {verifydoc-0.2.0 → verifydoc-0.3.0}/README.md +0 -0
  53. {verifydoc-0.2.0 → verifydoc-0.3.0}/benchmark/__init__.py +0 -0
  54. {verifydoc-0.2.0 → verifydoc-0.3.0}/benchmark/card.md +0 -0
  55. {verifydoc-0.2.0 → verifydoc-0.3.0}/benchmark/datasets/__init__.py +0 -0
  56. {verifydoc-0.2.0 → verifydoc-0.3.0}/benchmark/datasets/synthetic.py +0 -0
  57. {verifydoc-0.2.0 → verifydoc-0.3.0}/benchmark/labeling/guide.md +0 -0
  58. {verifydoc-0.2.0 → verifydoc-0.3.0}/configs/cord.yaml +0 -0
  59. {verifydoc-0.2.0 → verifydoc-0.3.0}/configs/demo.yaml +0 -0
  60. {verifydoc-0.2.0 → verifydoc-0.3.0}/configs/funsd.yaml +0 -0
  61. {verifydoc-0.2.0 → verifydoc-0.3.0}/docs/USP.md +0 -0
  62. {verifydoc-0.2.0 → verifydoc-0.3.0}/docs/demo.gif +0 -0
  63. {verifydoc-0.2.0 → verifydoc-0.3.0}/paper/generated/calibration.md +0 -0
  64. {verifydoc-0.2.0 → verifydoc-0.3.0}/paper/generated/conformal.md +0 -0
  65. {verifydoc-0.2.0 → verifydoc-0.3.0}/paper/generated/cord/calibration.md +0 -0
  66. {verifydoc-0.2.0 → verifydoc-0.3.0}/paper/generated/cord/conformal.md +0 -0
  67. {verifydoc-0.2.0 → verifydoc-0.3.0}/paper/generated/cord/extraction.md +0 -0
  68. {verifydoc-0.2.0 → verifydoc-0.3.0}/paper/generated/cord/grounding.md +0 -0
  69. {verifydoc-0.2.0 → verifydoc-0.3.0}/paper/generated/cord/rc_curves.png +0 -0
  70. {verifydoc-0.2.0 → verifydoc-0.3.0}/paper/generated/cord/reliability.png +0 -0
  71. {verifydoc-0.2.0 → verifydoc-0.3.0}/paper/generated/cord/selective.md +0 -0
  72. {verifydoc-0.2.0 → verifydoc-0.3.0}/paper/generated/cord/summary.json +0 -0
  73. {verifydoc-0.2.0 → verifydoc-0.3.0}/paper/generated/extraction.md +0 -0
  74. {verifydoc-0.2.0 → verifydoc-0.3.0}/paper/generated/funsd/calibration.md +0 -0
  75. {verifydoc-0.2.0 → verifydoc-0.3.0}/paper/generated/funsd/conformal.md +0 -0
  76. {verifydoc-0.2.0 → verifydoc-0.3.0}/paper/generated/funsd/extraction.md +0 -0
  77. {verifydoc-0.2.0 → verifydoc-0.3.0}/paper/generated/funsd/grounding.md +0 -0
  78. {verifydoc-0.2.0 → verifydoc-0.3.0}/paper/generated/funsd/rc_curves.png +0 -0
  79. {verifydoc-0.2.0 → verifydoc-0.3.0}/paper/generated/funsd/reliability.png +0 -0
  80. {verifydoc-0.2.0 → verifydoc-0.3.0}/paper/generated/funsd/selective.md +0 -0
  81. {verifydoc-0.2.0 → verifydoc-0.3.0}/paper/generated/funsd/summary.json +0 -0
  82. {verifydoc-0.2.0 → verifydoc-0.3.0}/paper/generated/grounding.md +0 -0
  83. {verifydoc-0.2.0 → verifydoc-0.3.0}/paper/generated/rc_curves.png +0 -0
  84. {verifydoc-0.2.0 → verifydoc-0.3.0}/paper/generated/reliability.png +0 -0
  85. {verifydoc-0.2.0 → verifydoc-0.3.0}/paper/generated/selective.md +0 -0
  86. {verifydoc-0.2.0 → verifydoc-0.3.0}/paper/generated/summary.json +0 -0
  87. {verifydoc-0.2.0 → verifydoc-0.3.0}/paper/main.tex +0 -0
  88. {verifydoc-0.2.0 → verifydoc-0.3.0}/scripts/make_demo_gif.py +0 -0
  89. {verifydoc-0.2.0 → verifydoc-0.3.0}/scripts/run_benchmark.py +0 -0
  90. {verifydoc-0.2.0 → verifydoc-0.3.0}/tests/__init__.py +0 -0
  91. {verifydoc-0.2.0 → verifydoc-0.3.0}/tests/test_calibration.py +0 -0
  92. {verifydoc-0.2.0 → verifydoc-0.3.0}/tests/test_calibrators.py +0 -0
  93. {verifydoc-0.2.0 → verifydoc-0.3.0}/tests/test_confidence.py +0 -0
  94. {verifydoc-0.2.0 → verifydoc-0.3.0}/tests/test_cord_loader.py +0 -0
  95. {verifydoc-0.2.0 → verifydoc-0.3.0}/tests/test_extraction.py +0 -0
  96. {verifydoc-0.2.0 → verifydoc-0.3.0}/tests/test_funsd_loader.py +0 -0
  97. {verifydoc-0.2.0 → verifydoc-0.3.0}/tests/test_grounding.py +0 -0
  98. {verifydoc-0.2.0 → verifydoc-0.3.0}/tests/test_harness.py +0 -0
  99. {verifydoc-0.2.0 → verifydoc-0.3.0}/tests/test_harness_extractors.py +0 -0
  100. {verifydoc-0.2.0 → verifydoc-0.3.0}/tests/test_learned_combiner.py +0 -0
  101. {verifydoc-0.2.0 → verifydoc-0.3.0}/tests/test_selective.py +0 -0
  102. {verifydoc-0.2.0 → verifydoc-0.3.0}/tests/test_stats.py +0 -0
  103. {verifydoc-0.2.0 → verifydoc-0.3.0}/ui/streamlit_app.py +0 -0
  104. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/adapters/_ocr_common.py +0 -0
  105. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/adapters/api_vlm.py +0 -0
  106. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/adapters/base.py +0 -0
  107. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/adapters/docling.py +0 -0
  108. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/adapters/dots_ocr.py +0 -0
  109. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/adapters/mock.py +0 -0
  110. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/calibration/__init__.py +0 -0
  111. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/calibration/base.py +0 -0
  112. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/calibration/conformal.py +0 -0
  113. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/calibration/histogram.py +0 -0
  114. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/calibration/isotonic.py +0 -0
  115. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/calibration/platt.py +0 -0
  116. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/calibration/splits.py +0 -0
  117. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/calibration/temperature.py +0 -0
  118. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/cli.py +0 -0
  119. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/confidence/__init__.py +0 -0
  120. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/confidence/combined.py +0 -0
  121. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/confidence/consensus.py +0 -0
  122. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/confidence/grounding_based.py +0 -0
  123. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/confidence/learned.py +0 -0
  124. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/confidence/token_prob.py +0 -0
  125. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/confidence/verbalized.py +0 -0
  126. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/eval/__init__.py +0 -0
  127. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/eval/calibration.py +0 -0
  128. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/eval/extraction.py +0 -0
  129. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/eval/grounding.py +0 -0
  130. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/eval/selective.py +0 -0
  131. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/eval/stats.py +0 -0
  132. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/grounding/__init__.py +0 -0
  133. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/grounding/attach.py +0 -0
  134. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/ingest/__init__.py +0 -0
  135. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/ingest/loader.py +0 -0
  136. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/pipeline.py +0 -0
  137. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/policy/__init__.py +0 -0
  138. {verifydoc-0.2.0 → verifydoc-0.3.0}/verifydoc/policy/abstention.py +0 -0
@@ -1,5 +1,28 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.3.0 — 2026-07-21
4
+
5
+ First **real-model** results (issue #3).
6
+
7
+ - **RapidOCR adapter** (PP-OCRv6 via ONNX Runtime) — architecture-independent,
8
+ the robust real-OCR default; runs where paddle's GPU wheels don't.
9
+ - **PaddleOCR adapter** validated end-to-end (PP-OCRv5 pipeline) on a real GPU.
10
+ - **Real results on CORD + FUNSD** for both extractors, committed under
11
+ `paper/generated/` with an honest reading (`REAL_MODELS_RESULTS.md`):
12
+ grounding/learned signals rank errors (AUROC 0.74–0.89) while
13
+ verbalized/consensus don't; grounding-conditioned gap +0.83/+0.84. The
14
+ floor field-finder's low recall forces conformal abstention at 2–5% — the
15
+ documented motivation for the selective framing.
16
+ - **Harness**: `extractor:` dispatch via the adapter registry; CORD/FUNSD
17
+ image export (`with_images`); schema `x-aliases` for on-page label variants.
18
+ - **Learned combiner** (`verifydoc/confidence/learned.py`) as a harness row.
19
+ - **Grounder ~1000× faster** (exact-match fast path, token-anchored fuzzy
20
+ scan, token-overlap for paragraph values) — FUNSD grounding hours → seconds.
21
+ - **GPU runbook** (`docs/REAL_MODELS.md`) with the hard-won version pins
22
+ (`paddlex==3.1.0`, `langchain<0.2`, Blackwell caveat, dots.ocr→vllm).
23
+ - dots.ocr: adapter stub validated to load/generate with `transformers==4.51.3`;
24
+ full run deferred to its vllm serving path (issue #3).
25
+
3
26
  ## v0.2.0 — 2026-07-21
4
27
 
5
28
  Real data, faster grounding, learned fusion.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: verifydoc
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: A trust layer for document -> structured-JSON extraction: calibrated per-field confidence, source grounding, and abstention on top of any extractor.
5
5
  Project-URL: Homepage, https://github.com/bhaskargurram-ai/verifydoc
6
6
  Project-URL: Repository, https://github.com/bhaskargurram-ai/verifydoc
@@ -37,20 +37,52 @@ CORD_SCHEMA_RAW: dict = {
37
37
  "sub_total": {
38
38
  "type": "object",
39
39
  "properties": {
40
- "subtotal_price": {"type": "number", "x-numeric-tol": 0.01},
41
- "tax_price": {"type": "number", "x-numeric-tol": 0.01},
42
- "discount_price": {"type": "number", "x-numeric-tol": 0.01},
43
- "service_price": {"type": "number", "x-numeric-tol": 0.01},
40
+ "subtotal_price": {
41
+ "type": "number",
42
+ "x-numeric-tol": 0.01,
43
+ "x-aliases": ["subtotal", "sub total", "sub-total"],
44
+ },
45
+ "tax_price": {
46
+ "type": "number",
47
+ "x-numeric-tol": 0.01,
48
+ "x-aliases": ["tax", "ppn", "pb1"],
49
+ },
50
+ "discount_price": {
51
+ "type": "number",
52
+ "x-numeric-tol": 0.01,
53
+ "x-aliases": ["discount", "diskon"],
54
+ },
55
+ "service_price": {
56
+ "type": "number",
57
+ "x-numeric-tol": 0.01,
58
+ "x-aliases": ["service", "service charge"],
59
+ },
44
60
  },
45
61
  },
46
62
  "total": {
47
63
  "type": "object",
48
64
  "properties": {
49
- "total_price": {"type": "number", "x-numeric-tol": 0.01},
50
- "cashprice": {"type": "number", "x-numeric-tol": 0.01},
51
- "changeprice": {"type": "number", "x-numeric-tol": 0.01},
52
- "creditcardprice": {"type": "number", "x-numeric-tol": 0.01},
53
- "menuqty_cnt": {"type": "string"},
65
+ "total_price": {
66
+ "type": "number",
67
+ "x-numeric-tol": 0.01,
68
+ "x-aliases": ["total", "grand total", "amount due"],
69
+ },
70
+ "cashprice": {
71
+ "type": "number",
72
+ "x-numeric-tol": 0.01,
73
+ "x-aliases": ["cash", "tunai"],
74
+ },
75
+ "changeprice": {
76
+ "type": "number",
77
+ "x-numeric-tol": 0.01,
78
+ "x-aliases": ["change", "kembali", "kembalian"],
79
+ },
80
+ "creditcardprice": {
81
+ "type": "number",
82
+ "x-numeric-tol": 0.01,
83
+ "x-aliases": ["credit card", "debit", "card"],
84
+ },
85
+ "menuqty_cnt": {"type": "string", "x-aliases": ["qty", "items", "item qty"]},
54
86
  },
55
87
  },
56
88
  },
@@ -110,11 +142,18 @@ def load(
110
142
  split: str = "validation",
111
143
  limit: int | None = 100,
112
144
  cache_dir: str | Path = "data",
145
+ with_images: bool = False,
113
146
  ) -> list[BenchDocument]: # pragma: no cover - network on first call
114
- """Load CORD v2 (streamed; JSON-cached locally after the first download)."""
147
+ """Load CORD v2 (streamed; JSON-cached locally after the first download).
148
+
149
+ ``with_images=True`` additionally exports each receipt PNG (needed by
150
+ image-reading OCR adapters) and sets ``page.image_path``.
151
+ """
115
152
  schema = Schema.from_json_schema(CORD_SCHEMA_RAW, name="cord-receipt")
116
153
  cache = Path(cache_dir) / f"cord_{split}_{limit or 'all'}.json"
117
- if cache.exists():
154
+ image_dir = Path(cache_dir) / "cord_images" / split
155
+ need_images = with_images and not image_dir.exists()
156
+ if cache.exists() and not need_images:
118
157
  rows = json.loads(cache.read_text(encoding="utf-8"))
119
158
  else:
120
159
  try:
@@ -123,11 +162,15 @@ def load(
123
162
  raise ImportError("CORD loader requires: pip install 'verifydoc[data]'") from exc
124
163
  stream = load_dataset("naver-clova-ix/cord-v2", split=split, streaming=True)
125
164
  rows = []
165
+ if with_images:
166
+ image_dir.mkdir(parents=True, exist_ok=True)
126
167
  for i, row in enumerate(stream):
127
168
  if limit is not None and i >= limit:
128
169
  break
129
170
  gt = json.loads(row["ground_truth"])
130
171
  width, height = row["image"].size
172
+ if with_images:
173
+ row["image"].save(image_dir / f"{i:05d}.png")
131
174
  rows.append(
132
175
  {
133
176
  "gt_parse": gt["gt_parse"],
@@ -144,6 +187,9 @@ def load(
144
187
  doc = document_from_valid_lines(
145
188
  f"cord-{split}-{i:05d}", row["valid_line"], row["width"], row["height"]
146
189
  )
190
+ image_path = image_dir / f"{i:05d}.png"
191
+ if with_images and image_path.exists():
192
+ doc.pages[0].image_path = str(image_path)
147
193
  golds = golds_from_gt_parse(row["gt_parse"], schema, doc)
148
194
  if golds and doc.pages[0].words:
149
195
  out.append(BenchDocument(doc=doc, schema=schema, golds=golds))
@@ -160,5 +160,6 @@ def load(
160
160
  width, height = img.size
161
161
  item = bench_from_annotation(f"funsd-{split}-{ann_path.stem}", annotation, width, height)
162
162
  if item is not None:
163
+ item.doc.pages[0].image_path = str(img_path) # for image-reading OCR adapters
163
164
  out.append(item)
164
165
  return out
@@ -0,0 +1,15 @@
1
+ # Pinned real-model experiment (issue #3): PaddleOCR on CORD receipts.
2
+ # Needs a GPU + `pip install paddlepaddle-gpu paddleocr`; CORD images are
3
+ # exported automatically (with_images) — see docs/REAL_MODELS.md.
4
+ dataset: cord
5
+ split: validation
6
+ limit: 100
7
+ extractor: paddleocr-vl
8
+ seed: 7
9
+ k: 1 # the OCR pipeline is deterministic: consensus over k>1 is degenerate;
10
+ # the live signals here are token-prob (rec scores) and grounding.
11
+ calibration_fraction: 0.5
12
+ alphas: [0.02, 0.05]
13
+ n_boot: 300
14
+ # record at run time for the paper table header:
15
+ # paddleocr==<version>, GPU model, driver version
@@ -0,0 +1,11 @@
1
+ # Real-model experiment: RapidOCR (PP-OCR models via ONNX) on CORD receipts.
2
+ # Architecture-independent (CPU or GPU) — install: pip install rapidocr onnxruntime
3
+ dataset: cord
4
+ split: validation
5
+ limit: 100
6
+ extractor: rapidocr
7
+ seed: 7
8
+ k: 1 # deterministic OCR: token-prob (rec scores) + grounding are the live signals
9
+ calibration_fraction: 0.5
10
+ alphas: [0.02, 0.05]
11
+ n_boot: 300
@@ -0,0 +1,9 @@
1
+ # Real-model experiment: PaddleOCR on FUNSD scanned forms (noisy, low-res).
2
+ dataset: funsd
3
+ split: testing
4
+ extractor: paddleocr-vl
5
+ seed: 7
6
+ k: 1 # deterministic OCR: token-prob + grounding are the live signals
7
+ calibration_fraction: 0.5
8
+ alphas: [0.02, 0.05]
9
+ n_boot: 300
@@ -0,0 +1,9 @@
1
+ # Real-model experiment: RapidOCR (PP-OCR models via ONNX) on FUNSD forms.
2
+ dataset: funsd
3
+ split: testing
4
+ extractor: rapidocr
5
+ seed: 7
6
+ k: 1
7
+ calibration_fraction: 0.5
8
+ alphas: [0.02, 0.05]
9
+ n_boot: 300
@@ -0,0 +1,77 @@
1
+ # Running real extractors (GPU runbook)
2
+
3
+ The same harness, with a real extractor instead of the simulated one
4
+ (issue #3). Reproduces `paper/generated/{cord,funsd}-{rapidocr,paddleocr}/`.
5
+
6
+ ## Hard-won environment notes (read first)
7
+
8
+ These were discovered running on RunPod; they save hours:
9
+
10
+ - **PaddleOCR needs a GPU architecture paddle supports.** PaddlePaddle's
11
+ precompiled wheels have **no kernels for Blackwell (sm_120, e.g. RTX PRO
12
+ 6000 / 5090)** — you get `RuntimeError: Unsupported GPU architecture`. Use
13
+ Ampere (A100 sm_80, A5000/A6000 sm_86) or Ada (RTX 4090 / L4 / L40 sm_89).
14
+ - **Pin `paddlex==3.1.0`** to match `paddleocr==3.1.0`, or the constructor
15
+ dies with `PaddlePredictorOption.__init__() takes 1 positional argument`.
16
+ - **Pin `langchain<0.2`** (paddlex imports the removed `langchain.docstore`).
17
+ - **RapidOCR is architecture-independent** (ONNX Runtime) — it runs anywhere,
18
+ CPU or GPU, and is the most robust real-OCR option. Prefer it when the GPU
19
+ is exotic.
20
+ - **dots.ocr** loads with `transformers==4.51.3` + `qwen_vl_utils`, but raw
21
+ `transformers.generate` fights its custom model; its intended runtime is
22
+ **vllm serving** — wire the adapter to a vllm endpoint (issue #3).
23
+
24
+ ## Setup
25
+
26
+ ```bash
27
+ git clone https://github.com/bhaskargurram-ai/verifydoc && cd verifydoc
28
+ python3.11 -m venv .venv && source .venv/bin/activate
29
+ pip install -e ".[dev,data]"
30
+
31
+ # Option A — RapidOCR (recommended, architecture-independent)
32
+ pip install rapidocr onnxruntime # or onnxruntime-gpu for speed
33
+
34
+ # Option B — PaddleOCR (needs a paddle-supported GPU)
35
+ pip install "paddlepaddle-gpu==3.1.0" -i https://www.paddlepaddle.org.cn/packages/stable/cu126/
36
+ pip install "paddleocr==3.1.0" "paddlex==3.1.0" "langchain<0.2" "langchain-community<0.2"
37
+ ```
38
+
39
+ ## Smoke test one receipt
40
+
41
+ ```bash
42
+ python - <<'EOF'
43
+ from benchmark.datasets import cord
44
+ from verifydoc.adapters import get_adapter
45
+
46
+ item = cord.load(split="validation", limit=1, with_images=True)[0]
47
+ adapter = get_adapter("rapidocr") # or "paddleocr-vl"
48
+ for p in adapter.extract(item.doc, item.schema):
49
+ print(p.path, p.value, p.meta.get("token_logprobs"))
50
+ EOF
51
+ ```
52
+
53
+ ## Full run
54
+
55
+ ```bash
56
+ python scripts/run_benchmark.py --config configs/cord-rapidocr.yaml --out paper/generated/cord-rapidocr
57
+ python scripts/run_benchmark.py --config configs/funsd-rapidocr.yaml --out paper/generated/funsd-rapidocr
58
+ python scripts/run_benchmark.py --config configs/cord-paddleocr.yaml --out paper/generated/cord-paddleocr # paddle GPU
59
+ python scripts/run_benchmark.py --config configs/funsd-paddleocr.yaml --out paper/generated/funsd-paddleocr
60
+ ```
61
+
62
+ The harness dispatches `extractor:` through the adapter registry
63
+ (`mock` | `text-search` | `rapidocr` | `paddleocr-vl` | `dots-ocr` |
64
+ `docling` | `api-vlm`) and `dataset:` (`synthetic` | `cord` | `funsd`).
65
+ CORD/FUNSD images are exported automatically (`with_images`).
66
+
67
+ ## What to report
68
+
69
+ Pin model versions in the table header (`rapidocr==x`, `paddleocr==3.1.0`,
70
+ GPU + driver). Results feed the paper via `make results`; see
71
+ `paper/generated/REAL_MODELS_RESULTS.md` for the current numbers and reading.
72
+
73
+ ## Cloud
74
+
75
+ Any Ampere/Ada single-GPU pod (RTX 4090 ≈ $0.4–0.7/hr) runs everything except
76
+ Blackwell-only cards for paddle. The full sweep is an hours-not-days job.
77
+ ```
@@ -0,0 +1,60 @@
1
+ # Real-model results (issue #3)
2
+
3
+ Results from **real OCR extractors** on real documents, produced by the same
4
+ harness as the synthetic slice. Runs are pinned in `configs/*-<model>.yaml`
5
+ and reproduced with `scripts/run_benchmark.py`.
6
+
7
+ ## Summary — the thesis holds on real data
8
+
9
+ Across both real extractors and both datasets, the ranking of confidence
10
+ signals is consistent and matches the paper's claim:
11
+
12
+ | Signal | ranks errors? | CORD AUROC (RapidOCR / PaddleOCR) |
13
+ |---|---|---|
14
+ | **learned combiner** | best | **0.89 / 0.84** |
15
+ | **grounding** | strong | 0.82 / 0.74 |
16
+ | token-prob (rec. score) | moderate | 0.69 / 0.68 |
17
+ | verbalized / consensus | uninformative (k=1) | 0.50 / 0.50 |
18
+
19
+ **Grounding-conditioned correctness** (the core hypothesis) is large on real
20
+ data: grounded fields are 84–85% correct vs ~1% for ungrounded
21
+ (gap +0.83 RapidOCR, +0.84 PaddleOCR; box acc @IoU 0.5 = 0.75 / 0.78).
22
+
23
+ **Honest limitation:** with the `text-search` field-finder over raw OCR (the
24
+ floor baseline, no structured-output model), field recall is low (~0.19) and
25
+ the base error rate is high — so conformal abstention at a 2–5% budget forces
26
+ full review (Coverage@2% ≈ 0). This is the motivation for the whole selective
27
+ framing: you report *selective risk*, not headline accuracy, and you need a
28
+ stronger extractor to raise the STP rate. The synthetic slice (strong
29
+ simulated extractor) shows the other end (Coverage@2% ≈ 1.0).
30
+
31
+ ## RapidOCR (PP-OCRv6 via ONNX Runtime)
32
+
33
+ - Config: `configs/cord-rapidocr.yaml`, `configs/funsd-rapidocr.yaml`.
34
+ - CORD: F1 0.28, grounding AUROC 0.82, learned 0.89, grounding gap +0.83.
35
+ - Tables: `paper/generated/{cord,funsd}-rapidocr/`.
36
+
37
+ ## PaddleOCR (PP-OCRv5 pipeline, RTX 4090)
38
+
39
+ - Config: `configs/cord-paddleocr.yaml`, `configs/funsd-paddleocr.yaml`.
40
+ - The `paddleocr-vl` adapter runs the PP-OCR **detection+recognition
41
+ pipeline** (not the separate PaddleOCR-VL VLM); recognition scores feed the
42
+ token-prob signal.
43
+ - CORD: F1 0.28, grounding AUROC 0.74, learned 0.84, coverage@2% 0.026,
44
+ grounding gap +0.84, box acc@0.5 0.78.
45
+ - Tables: `paper/generated/{cord,funsd}-paddleocr/`.
46
+
47
+ ## dots.ocr (VLM) — deferred to vllm serving
48
+
49
+ Status: **partially validated, not run at scale.** The model loads and
50
+ generates via `transformers==4.51.3` + `qwen_vl_utils.process_vision_info`,
51
+ but raw `transformers.generate` fights the model's custom code across
52
+ versions (`mm_token_type_ids` handling), and the intended runtime per the
53
+ model authors is **vllm serving**. A `DotsOCRAdapter` stub exists
54
+ (`verifydoc/adapters/dots_ocr.py`); wiring it to a vllm endpoint is the clean
55
+ follow-up (tracked in issue #3). It is a *third data point* (VLM vs. the two
56
+ OCR pipelines), not load-bearing for the thesis, which the two OCR extractors
57
+ above already establish on real data.
58
+
59
+ *Every number here is regenerated by the pinned configs; re-verify model
60
+ versions before the paper.*
@@ -0,0 +1,34 @@
1
+ # Calibration: signal x calibrator (test split)
2
+
3
+ | signal | calibrator | ece | adaptive_ece | brier | nll |
4
+ |---|---|---|---|---|---|
5
+ | token_prob | raw | 0.2641 | 0.2508 | 0.2469 | 1.0664 |
6
+ | token_prob | temperature | 0.1199 | 0.1648 | 0.2002 | 0.5915 |
7
+ | token_prob | platt | 0.1629 | 0.1577 | 0.1959 | 0.5934 |
8
+ | token_prob | isotonic | 0.1344 | 0.1459 | 0.1943 | 0.9008 |
9
+ | token_prob | histogram | 0.0371 | 0.0933 | 0.1891 | 0.7167 |
10
+ | verbalized | raw | 0.1753 | 0.1948 | 0.2500 | 0.6931 |
11
+ | verbalized | temperature | 0.1753 | 0.1948 | 0.2500 | 0.6931 |
12
+ | verbalized | platt | 0.0225 | 0.1411 | 0.2198 | 0.6315 |
13
+ | verbalized | isotonic | 0.0225 | 0.1411 | 0.2198 | 0.6315 |
14
+ | verbalized | histogram | 0.0225 | 0.1411 | 0.2198 | 0.6315 |
15
+ | grounding | raw | 0.2607 | 0.2607 | 0.2447 | 4.7090 |
16
+ | grounding | temperature | 0.0801 | 0.1365 | 0.1690 | 0.5177 |
17
+ | grounding | platt | 0.0194 | 0.0752 | 0.1376 | 0.4406 |
18
+ | grounding | isotonic | 0.0238 | 0.0781 | 0.1374 | 0.4405 |
19
+ | grounding | histogram | 0.0299 | 0.0874 | 0.1429 | 0.6120 |
20
+ | consensus | raw | 0.3247 | 0.3247 | 0.3247 | 8.9711 |
21
+ | consensus | temperature | 0.0225 | 0.1411 | 0.2198 | 0.6315 |
22
+ | consensus | platt | 0.0225 | 0.1411 | 0.2198 | 0.6315 |
23
+ | consensus | isotonic | 0.0225 | 0.1411 | 0.2198 | 0.6315 |
24
+ | consensus | histogram | 0.0225 | 0.1411 | 0.2198 | 0.6315 |
25
+ | combined | raw | 0.2991 | 0.2994 | 0.2847 | 2.6709 |
26
+ | combined | temperature | 0.2396 | 0.2244 | 0.2113 | 0.6508 |
27
+ | combined | platt | 0.1842 | 0.1667 | 0.1810 | 0.8118 |
28
+ | combined | isotonic | 0.1101 | 0.1140 | 0.1544 | 0.4963 |
29
+ | combined | histogram | 0.0353 | 0.1508 | 0.1943 | 0.7352 |
30
+ | learned | raw | 0.1902 | 0.1884 | 0.1639 | 0.5090 |
31
+ | learned | temperature | 0.1429 | 0.1464 | 0.1558 | 0.4855 |
32
+ | learned | platt | 0.1069 | 0.0850 | 0.1306 | 0.4522 |
33
+ | learned | isotonic | 0.0567 | 0.0681 | 0.1148 | 0.3896 |
34
+ | learned | histogram | 0.0745 | 0.0985 | 0.1346 | 0.7547 |
@@ -0,0 +1,16 @@
1
+ # Conformal abstention: guarantee vs forced review
2
+
3
+ | signal | alpha | threshold | test_coverage | achieved_risk | guarantee_held |
4
+ |---|---|---|---|---|---|
5
+ | token_prob | 0.0200 | inf | 0.0000 | 0.0000 | True |
6
+ | token_prob | 0.0500 | inf | 0.0000 | 0.0000 | True |
7
+ | verbalized | 0.0200 | inf | 0.0000 | 0.0000 | True |
8
+ | verbalized | 0.0500 | inf | 0.0000 | 0.0000 | True |
9
+ | grounding | 0.0200 | inf | 0.0000 | 0.0000 | True |
10
+ | grounding | 0.0500 | inf | 0.0000 | 0.0000 | True |
11
+ | consensus | 0.0200 | inf | 0.0000 | 0.0000 | True |
12
+ | consensus | 0.0500 | inf | 0.0000 | 0.0000 | True |
13
+ | combined | 0.0200 | inf | 0.0000 | 0.0000 | True |
14
+ | combined | 0.0500 | inf | 0.0000 | 0.0000 | True |
15
+ | learned | 0.0200 | inf | 0.0000 | 0.0000 | True |
16
+ | learned | 0.0500 | inf | 0.0000 | 0.0000 | True |
@@ -0,0 +1,5 @@
1
+ # Extraction quality (single-run baseline)
2
+
3
+ | precision | recall | f1 | exact_match | omission_rate | hallucination_rate |
4
+ |---|---|---|---|---|---|
5
+ | 0.6379 | 0.1893 | 0.2787 | 0.1929 | 0.7216 | 0.0048 |
@@ -0,0 +1,5 @@
1
+ # Grounding quality (consensus predictions)
2
+
3
+ | box_acc@0.5 | box_acc@0.7 | mean_iou | acc_grounded | acc_ungrounded | grounding_gap |
4
+ |---|---|---|---|---|---|
5
+ | 0.7804 | 0.7804 | 0.8278 | 0.8528 | 0.0154 | 0.8374 |
@@ -0,0 +1,10 @@
1
+ # Selective prediction by signal (raw confidence, test split)
2
+
3
+ | signal | e_aurc | auroc | coverage@2% | coverage@5% | e_aurc_ci |
4
+ |---|---|---|---|---|---|
5
+ | token_prob | 0.2160 | 0.6835 | 0.0000 | 0.0000 | [0.1188, 0.2996] |
6
+ | verbalized | 0.3159 | 0.5000 | 0.0000 | 0.0000 | [0.1855, 0.3562] |
7
+ | grounding | 0.1931 | 0.7449 | 0.0000 | 0.0000 | [0.0805, 0.2193] |
8
+ | consensus | 0.3159 | 0.5000 | 0.0000 | 0.0000 | [0.1855, 0.3562] |
9
+ | combined | 0.2731 | 0.6693 | 0.0000 | 0.0000 | [0.1698, 0.3466] |
10
+ | learned | 0.0969 | 0.8405 | 0.0260 | 0.0260 | [0.0369, 0.1664] |
@@ -0,0 +1,34 @@
1
+ # Calibration: signal x calibrator (test split)
2
+
3
+ | signal | calibrator | ece | adaptive_ece | brier | nll |
4
+ |---|---|---|---|---|---|
5
+ | token_prob | raw | 0.3068 | 0.3043 | 0.2877 | 1.8498 |
6
+ | token_prob | temperature | 0.0963 | 0.1537 | 0.2082 | 0.6063 |
7
+ | token_prob | platt | 0.0980 | 0.1249 | 0.1963 | 0.5813 |
8
+ | token_prob | isotonic | 0.1067 | 0.1488 | 0.2006 | 1.2121 |
9
+ | token_prob | histogram | 0.0687 | 0.1328 | 0.2006 | 0.8964 |
10
+ | verbalized | raw | 0.1415 | 0.1981 | 0.2500 | 0.6931 |
11
+ | verbalized | temperature | 0.1415 | 0.1981 | 0.2500 | 0.6931 |
12
+ | verbalized | platt | 0.0311 | 0.1195 | 0.2309 | 0.6546 |
13
+ | verbalized | isotonic | 0.0311 | 0.1195 | 0.2309 | 0.6546 |
14
+ | verbalized | histogram | 0.0311 | 0.1195 | 0.2309 | 0.6546 |
15
+ | grounding | raw | 0.2638 | 0.2638 | 0.2423 | 3.7864 |
16
+ | grounding | temperature | 0.1265 | 0.1707 | 0.1596 | 0.4947 |
17
+ | grounding | platt | 0.0425 | 0.1013 | 0.1136 | 0.3811 |
18
+ | grounding | isotonic | 0.0267 | 0.0908 | 0.1118 | 0.3739 |
19
+ | grounding | histogram | 0.0414 | 0.1034 | 0.1175 | 0.5380 |
20
+ | consensus | raw | 0.3585 | 0.3585 | 0.3585 | 9.9055 |
21
+ | consensus | temperature | 0.0311 | 0.1195 | 0.2309 | 0.6546 |
22
+ | consensus | platt | 0.0311 | 0.1195 | 0.2309 | 0.6546 |
23
+ | consensus | isotonic | 0.0311 | 0.1195 | 0.2309 | 0.6546 |
24
+ | consensus | histogram | 0.0311 | 0.1195 | 0.2309 | 0.6546 |
25
+ | combined | raw | 0.3252 | 0.3252 | 0.3029 | 2.8066 |
26
+ | combined | temperature | 0.2896 | 0.2621 | 0.1982 | 0.5909 |
27
+ | combined | platt | 0.2292 | 0.2108 | 0.1630 | 0.5564 |
28
+ | combined | isotonic | 0.0306 | 0.0972 | 0.1127 | 0.3756 |
29
+ | combined | histogram | 0.0338 | 0.1407 | 0.1746 | 0.6830 |
30
+ | learned | raw | 0.2562 | 0.2204 | 0.1554 | 0.4886 |
31
+ | learned | temperature | 0.1776 | 0.1630 | 0.1419 | 0.4470 |
32
+ | learned | platt | 0.1659 | 0.1440 | 0.1164 | 0.4084 |
33
+ | learned | isotonic | 0.0761 | 0.0919 | 0.0822 | 0.6131 |
34
+ | learned | histogram | 0.0861 | 0.0889 | 0.0833 | 0.6082 |
@@ -0,0 +1,16 @@
1
+ # Conformal abstention: guarantee vs forced review
2
+
3
+ | signal | alpha | threshold | test_coverage | achieved_risk | guarantee_held |
4
+ |---|---|---|---|---|---|
5
+ | token_prob | 0.0200 | inf | 0.0000 | 0.0000 | True |
6
+ | token_prob | 0.0500 | inf | 0.0000 | 0.0000 | True |
7
+ | verbalized | 0.0200 | inf | 0.0000 | 0.0000 | True |
8
+ | verbalized | 0.0500 | inf | 0.0000 | 0.0000 | True |
9
+ | grounding | 0.0200 | inf | 0.0000 | 0.0000 | True |
10
+ | grounding | 0.0500 | inf | 0.0000 | 0.0000 | True |
11
+ | consensus | 0.0200 | inf | 0.0000 | 0.0000 | True |
12
+ | consensus | 0.0500 | inf | 0.0000 | 0.0000 | True |
13
+ | combined | 0.0200 | inf | 0.0000 | 0.0000 | True |
14
+ | combined | 0.0500 | inf | 0.0000 | 0.0000 | True |
15
+ | learned | 0.0200 | inf | 0.0000 | 0.0000 | True |
16
+ | learned | 0.0500 | inf | 0.0000 | 0.0000 | True |
@@ -0,0 +1,5 @@
1
+ # Extraction quality (single-run baseline)
2
+
3
+ | precision | recall | f1 | exact_match | omission_rate | hallucination_rate |
4
+ |---|---|---|---|---|---|
5
+ | 0.6175 | 0.1865 | 0.2756 | 0.1869 | 0.7041 | 0.0048 |
@@ -0,0 +1,5 @@
1
+ # Grounding quality (consensus predictions)
2
+
3
+ | box_acc@0.5 | box_acc@0.7 | mean_iou | acc_grounded | acc_ungrounded | grounding_gap |
4
+ |---|---|---|---|---|---|
5
+ | 0.7460 | 0.7460 | 0.8061 | 0.8405 | 0.0127 | 0.8279 |
@@ -0,0 +1,10 @@
1
+ # Selective prediction by signal (raw confidence, test split)
2
+
3
+ | signal | e_aurc | auroc | coverage@2% | coverage@5% | e_aurc_ci |
4
+ |---|---|---|---|---|---|
5
+ | token_prob | 0.1851 | 0.6872 | 0.0000 | 0.0000 | [0.1110, 0.2675] |
6
+ | verbalized | 0.2826 | 0.5000 | 0.0000 | 0.0000 | [0.2037, 0.3743] |
7
+ | grounding | 0.1228 | 0.8181 | 0.0000 | 0.0000 | [0.0579, 0.1817] |
8
+ | consensus | 0.2826 | 0.5000 | 0.0000 | 0.0000 | [0.2037, 0.3743] |
9
+ | combined | 0.2491 | 0.7367 | 0.0000 | 0.0000 | [0.1543, 0.3299] |
10
+ | learned | 0.0797 | 0.8870 | 0.0000 | 0.0000 | [0.0289, 0.1519] |
@@ -0,0 +1,34 @@
1
+ # Calibration: signal x calibrator (test split)
2
+
3
+ | signal | calibrator | ece | adaptive_ece | brier | nll |
4
+ |---|---|---|---|---|---|
5
+ | token_prob | raw | 0.3567 | 0.3884 | 0.4337 | 1.7918 |
6
+ | token_prob | temperature | 0.0507 | 0.1525 | 0.2526 | 0.6983 |
7
+ | token_prob | platt | 0.0936 | 0.1533 | 0.2468 | 0.6870 |
8
+ | token_prob | isotonic | 0.0542 | 0.1321 | 0.2511 | 0.6953 |
9
+ | token_prob | histogram | 0.0535 | 0.1139 | 0.2421 | 0.6779 |
10
+ | verbalized | raw | 0.0397 | 0.1349 | 0.2500 | 0.6931 |
11
+ | verbalized | temperature | 0.0397 | 0.1349 | 0.2500 | 0.6931 |
12
+ | verbalized | platt | 0.0553 | 0.1400 | 0.2515 | 0.6961 |
13
+ | verbalized | isotonic | 0.0553 | 0.1400 | 0.2515 | 0.6961 |
14
+ | verbalized | histogram | 0.0553 | 0.1400 | 0.2515 | 0.6961 |
15
+ | grounding | raw | 0.3242 | 0.3187 | 0.3254 | 4.8572 |
16
+ | grounding | temperature | 0.1053 | 0.2078 | 0.2415 | 0.6762 |
17
+ | grounding | platt | 0.1270 | 0.1991 | 0.2367 | 0.6660 |
18
+ | grounding | isotonic | 0.0890 | 0.1651 | 0.2258 | 0.6445 |
19
+ | grounding | histogram | 0.0973 | 0.1664 | 0.2321 | 0.6582 |
20
+ | consensus | raw | 0.5397 | 0.5397 | 0.5397 | 14.9120 |
21
+ | consensus | temperature | 0.1130 | 0.1634 | 0.2612 | 0.7157 |
22
+ | consensus | platt | 0.0553 | 0.1400 | 0.2515 | 0.6961 |
23
+ | consensus | isotonic | 0.0553 | 0.1400 | 0.2515 | 0.6961 |
24
+ | consensus | histogram | 0.0553 | 0.1400 | 0.2515 | 0.6961 |
25
+ | combined | raw | 0.4449 | 0.4449 | 0.4245 | 3.3265 |
26
+ | combined | temperature | 0.1461 | 0.2009 | 0.2500 | 0.6936 |
27
+ | combined | platt | 0.0742 | 0.1862 | 0.2378 | 0.6701 |
28
+ | combined | isotonic | 0.0773 | 0.1414 | 0.2302 | 0.6548 |
29
+ | combined | histogram | 0.0665 | 0.1188 | 0.2297 | 0.6521 |
30
+ | learned | raw | 0.0639 | 0.1586 | 0.2327 | 0.6574 |
31
+ | learned | temperature | 0.0941 | 0.1580 | 0.2338 | 0.6595 |
32
+ | learned | platt | 0.0969 | 0.1579 | 0.2338 | 0.6594 |
33
+ | learned | isotonic | 0.1163 | 0.1404 | 0.2397 | 0.6746 |
34
+ | learned | histogram | 0.1248 | 0.1409 | 0.2494 | 0.9558 |
@@ -0,0 +1,16 @@
1
+ # Conformal abstention: guarantee vs forced review
2
+
3
+ | signal | alpha | threshold | test_coverage | achieved_risk | guarantee_held |
4
+ |---|---|---|---|---|---|
5
+ | token_prob | 0.0200 | inf | 0.0000 | 0.0000 | True |
6
+ | token_prob | 0.0500 | inf | 0.0000 | 0.0000 | True |
7
+ | verbalized | 0.0200 | inf | 0.0000 | 0.0000 | True |
8
+ | verbalized | 0.0500 | inf | 0.0000 | 0.0000 | True |
9
+ | grounding | 0.0200 | inf | 0.0000 | 0.0000 | True |
10
+ | grounding | 0.0500 | inf | 0.0000 | 0.0000 | True |
11
+ | consensus | 0.0200 | inf | 0.0000 | 0.0000 | True |
12
+ | consensus | 0.0500 | inf | 0.0000 | 0.0000 | True |
13
+ | combined | 0.0200 | inf | 0.0000 | 0.0000 | True |
14
+ | combined | 0.0500 | inf | 0.0000 | 0.0000 | True |
15
+ | learned | 0.0200 | inf | 0.0000 | 0.0000 | True |
16
+ | learned | 0.0500 | inf | 0.0000 | 0.0000 | True |
@@ -0,0 +1,5 @@
1
+ # Extraction quality (single-run baseline)
2
+
3
+ | precision | recall | f1 | exact_match | omission_rate | hallucination_rate |
4
+ |---|---|---|---|---|---|
5
+ | 0.4692 | 0.2934 | 0.3480 | 0.1282 | 0.4293 | 0.0000 |
@@ -0,0 +1,5 @@
1
+ # Grounding quality (consensus predictions)
2
+
3
+ | box_acc@0.5 | box_acc@0.7 | mean_iou | acc_grounded | acc_ungrounded | grounding_gap |
4
+ |---|---|---|---|---|---|
5
+ | 0.4006 | 0.3691 | 0.4741 | 0.9843 | 0.1474 | 0.8369 |
@@ -0,0 +1,10 @@
1
+ # Selective prediction by signal (raw confidence, test split)
2
+
3
+ | signal | e_aurc | auroc | coverage@2% | coverage@5% | e_aurc_ci |
4
+ |---|---|---|---|---|---|
5
+ | token_prob | 0.3802 | 0.4278 | 0.0000 | 0.0000 | [0.3116, 0.4448] |
6
+ | verbalized | 0.3382 | 0.5000 | 0.0000 | 0.0000 | [0.2907, 0.4224] |
7
+ | grounding | 0.2169 | 0.6805 | 0.0000 | 0.0000 | [0.1879, 0.3290] |
8
+ | consensus | 0.3382 | 0.5000 | 0.0000 | 0.0000 | [0.2907, 0.4224] |
9
+ | combined | 0.2234 | 0.6900 | 0.0000 | 0.0000 | [0.1804, 0.3074] |
10
+ | learned | 0.2306 | 0.6640 | 0.0000 | 0.0000 | [0.1858, 0.3105] |
@@ -0,0 +1,34 @@
1
+ # Calibration: signal x calibrator (test split)
2
+
3
+ | signal | calibrator | ece | adaptive_ece | brier | nll |
4
+ |---|---|---|---|---|---|
5
+ | token_prob | raw | 0.3033 | 0.3343 | 0.3992 | 2.0715 |
6
+ | token_prob | temperature | 0.0273 | 0.1592 | 0.2516 | 0.6964 |
7
+ | token_prob | platt | 0.0533 | 0.1493 | 0.2517 | 0.6967 |
8
+ | token_prob | isotonic | 0.0324 | 0.1438 | 0.2463 | 0.6855 |
9
+ | token_prob | histogram | 0.0534 | 0.1583 | 0.2518 | 1.2098 |
10
+ | verbalized | raw | 0.0128 | 0.1410 | 0.2500 | 0.6931 |
11
+ | verbalized | temperature | 0.0128 | 0.1410 | 0.2500 | 0.6931 |
12
+ | verbalized | platt | 0.0273 | 0.1381 | 0.2506 | 0.6943 |
13
+ | verbalized | isotonic | 0.0273 | 0.1381 | 0.2506 | 0.6943 |
14
+ | verbalized | histogram | 0.0273 | 0.1381 | 0.2506 | 0.6943 |
15
+ | grounding | raw | 0.3358 | 0.3486 | 0.3474 | 5.1829 |
16
+ | grounding | temperature | 0.0678 | 0.1763 | 0.2413 | 0.6756 |
17
+ | grounding | platt | 0.0651 | 0.1634 | 0.2365 | 0.6657 |
18
+ | grounding | isotonic | 0.0880 | 0.1705 | 0.2410 | 0.6765 |
19
+ | grounding | histogram | 0.0811 | 0.1487 | 0.2337 | 0.6575 |
20
+ | consensus | raw | 0.5128 | 0.5128 | 0.5128 | 14.1698 |
21
+ | consensus | temperature | 0.0861 | 0.1449 | 0.2572 | 0.7078 |
22
+ | consensus | platt | 0.0273 | 0.1381 | 0.2506 | 0.6943 |
23
+ | consensus | isotonic | 0.0273 | 0.1381 | 0.2506 | 0.6943 |
24
+ | consensus | histogram | 0.0273 | 0.1381 | 0.2506 | 0.6943 |
25
+ | combined | raw | 0.4375 | 0.4375 | 0.4268 | 4.2464 |
26
+ | combined | temperature | 0.1284 | 0.1852 | 0.2471 | 0.6873 |
27
+ | combined | platt | 0.0452 | 0.1585 | 0.2393 | 0.6718 |
28
+ | combined | isotonic | 0.0956 | 0.1432 | 0.2468 | 0.6887 |
29
+ | combined | histogram | 0.0714 | 0.1240 | 0.2380 | 0.6700 |
30
+ | learned | raw | 0.0408 | 0.0998 | 0.2374 | 0.6676 |
31
+ | learned | temperature | 0.0766 | 0.1001 | 0.2384 | 0.6697 |
32
+ | learned | platt | 0.0755 | 0.0993 | 0.2383 | 0.6695 |
33
+ | learned | isotonic | 0.0768 | 0.1010 | 0.2393 | 0.6719 |
34
+ | learned | histogram | 0.0710 | 0.1285 | 0.2425 | 0.6802 |
@@ -0,0 +1,16 @@
1
+ # Conformal abstention: guarantee vs forced review
2
+
3
+ | signal | alpha | threshold | test_coverage | achieved_risk | guarantee_held |
4
+ |---|---|---|---|---|---|
5
+ | token_prob | 0.0200 | inf | 0.0000 | 0.0000 | True |
6
+ | token_prob | 0.0500 | inf | 0.0000 | 0.0000 | True |
7
+ | verbalized | 0.0200 | inf | 0.0000 | 0.0000 | True |
8
+ | verbalized | 0.0500 | inf | 0.0000 | 0.0000 | True |
9
+ | grounding | 0.0200 | inf | 0.0000 | 0.0000 | True |
10
+ | grounding | 0.0500 | inf | 0.0000 | 0.0000 | True |
11
+ | consensus | 0.0200 | inf | 0.0000 | 0.0000 | True |
12
+ | consensus | 0.0500 | inf | 0.0000 | 0.0000 | True |
13
+ | combined | 0.0200 | inf | 0.0000 | 0.0000 | True |
14
+ | combined | 0.0500 | inf | 0.0000 | 0.0000 | True |
15
+ | learned | 0.0200 | inf | 0.0000 | 0.0000 | True |
16
+ | learned | 0.0500 | inf | 0.0000 | 0.0000 | True |
@@ -0,0 +1,5 @@
1
+ # Extraction quality (single-run baseline)
2
+
3
+ | precision | recall | f1 | exact_match | omission_rate | hallucination_rate |
4
+ |---|---|---|---|---|---|
5
+ | 0.4683 | 0.3110 | 0.3627 | 0.1617 | 0.4054 | 0.0000 |
@@ -0,0 +1,5 @@
1
+ # Grounding quality (consensus predictions)
2
+
3
+ | box_acc@0.5 | box_acc@0.7 | mean_iou | acc_grounded | acc_ungrounded | grounding_gap |
4
+ |---|---|---|---|---|---|
5
+ | 0.4114 | 0.3604 | 0.4596 | 0.9927 | 0.1531 | 0.8396 |