guilindev commited on
Commit
8d7b7e9
·
verified ·
1 Parent(s): 608ddf3

Publish recorded OCR verification experiment and interactive evidence

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +42 -0
  2. README.md +17 -4
  3. app.js +7 -0
  4. assets/00000001_invoice-000.png +0 -0
  5. assets/00000002_invoice-001.png +0 -0
  6. assets/00000003_invoice-002.png +0 -0
  7. assets/00000004_invoice-003.png +0 -0
  8. assets/00000005_invoice-004.png +0 -0
  9. assets/00000006_invoice-005.png +0 -0
  10. assets/00000007_invoice-006.png +0 -0
  11. assets/00000008_invoice-007.png +0 -0
  12. assets/00000009_invoice-008.png +0 -0
  13. assets/00000010_invoice-009.png +0 -0
  14. assets/00000011_invoice-010.png +0 -0
  15. assets/00000012_invoice-011.png +0 -0
  16. assets/00000013_invoice-012.png +0 -0
  17. assets/00000014_invoice-013.png +0 -0
  18. assets/00000015_invoice-014.png +0 -0
  19. assets/00000016_invoice-015.png +0 -0
  20. assets/00000017_invoice-016.png +0 -0
  21. assets/00000018_invoice-017.png +0 -0
  22. assets/00000019_invoice-018.png +0 -0
  23. assets/00000020_invoice-019.png +0 -0
  24. assets/00000021_invoice-020.png +0 -0
  25. assets/00000022_invoice-021.png +0 -0
  26. assets/00000023_invoice-022.png +0 -0
  27. assets/00000024_invoice-023.png +0 -0
  28. assets/00000025_invoice-024.png +0 -0
  29. assets/00000026_invoice-025.png +0 -0
  30. assets/00000027_invoice-026.png +0 -0
  31. assets/00000028_invoice-027.png +0 -0
  32. assets/00000029_invoice-028.png +0 -0
  33. assets/00000030_invoice-029.png +0 -0
  34. assets/00000031_invoice-030.png +0 -0
  35. assets/00000032_invoice-031.png +0 -0
  36. assets/00000033_invoice-032.png +0 -0
  37. assets/00000034_invoice-033.png +0 -0
  38. assets/00000035_invoice-034.png +0 -0
  39. assets/00000036_invoice-035.png +0 -0
  40. assets/00000037_invoice-036.png +0 -0
  41. assets/00000038_invoice-037.png +0 -0
  42. assets/00000039_invoice-038.png +0 -0
  43. assets/00000040_invoice-039.png +0 -0
  44. assets/00000041_invoice-040.png +0 -0
  45. assets/00000042_invoice-041.png +0 -0
  46. assets/00000043_invoice-042.png +0 -0
  47. assets/00000044_invoice-043.png +0 -0
  48. assets/00000045_invoice-044.png +0 -0
  49. assets/00000046_invoice-045.png +0 -0
  50. assets/00000047_invoice-046.png +0 -0
.gitattributes CHANGED
@@ -33,3 +33,45 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ assets/invoice-000-page.png filter=lfs diff=lfs merge=lfs -text
37
+ assets/invoice-001-page.png filter=lfs diff=lfs merge=lfs -text
38
+ assets/invoice-002-page.png filter=lfs diff=lfs merge=lfs -text
39
+ assets/invoice-003-page.png filter=lfs diff=lfs merge=lfs -text
40
+ assets/invoice-004-page.png filter=lfs diff=lfs merge=lfs -text
41
+ assets/invoice-005-page.png filter=lfs diff=lfs merge=lfs -text
42
+ assets/invoice-006-page.png filter=lfs diff=lfs merge=lfs -text
43
+ assets/invoice-006-region.png filter=lfs diff=lfs merge=lfs -text
44
+ assets/invoice-007-page.png filter=lfs diff=lfs merge=lfs -text
45
+ assets/invoice-008-page.png filter=lfs diff=lfs merge=lfs -text
46
+ assets/invoice-009-page.png filter=lfs diff=lfs merge=lfs -text
47
+ assets/invoice-011-page.png filter=lfs diff=lfs merge=lfs -text
48
+ assets/invoice-012-page.png filter=lfs diff=lfs merge=lfs -text
49
+ assets/invoice-013-page.png filter=lfs diff=lfs merge=lfs -text
50
+ assets/invoice-014-page.png filter=lfs diff=lfs merge=lfs -text
51
+ assets/invoice-015-page.png filter=lfs diff=lfs merge=lfs -text
52
+ assets/invoice-016-page.png filter=lfs diff=lfs merge=lfs -text
53
+ assets/invoice-016-region.png filter=lfs diff=lfs merge=lfs -text
54
+ assets/invoice-017-page.png filter=lfs diff=lfs merge=lfs -text
55
+ assets/invoice-018-page.png filter=lfs diff=lfs merge=lfs -text
56
+ assets/invoice-019-page.png filter=lfs diff=lfs merge=lfs -text
57
+ assets/invoice-020-page.png filter=lfs diff=lfs merge=lfs -text
58
+ assets/invoice-021-page.png filter=lfs diff=lfs merge=lfs -text
59
+ assets/invoice-022-page.png filter=lfs diff=lfs merge=lfs -text
60
+ assets/invoice-023-page.png filter=lfs diff=lfs merge=lfs -text
61
+ assets/invoice-024-page.png filter=lfs diff=lfs merge=lfs -text
62
+ assets/invoice-025-page.png filter=lfs diff=lfs merge=lfs -text
63
+ assets/invoice-026-page.png filter=lfs diff=lfs merge=lfs -text
64
+ assets/invoice-026-region.png filter=lfs diff=lfs merge=lfs -text
65
+ assets/invoice-027-page.png filter=lfs diff=lfs merge=lfs -text
66
+ assets/invoice-028-page.png filter=lfs diff=lfs merge=lfs -text
67
+ assets/invoice-029-page.png filter=lfs diff=lfs merge=lfs -text
68
+ assets/invoice-031-page.png filter=lfs diff=lfs merge=lfs -text
69
+ assets/invoice-032-page.png filter=lfs diff=lfs merge=lfs -text
70
+ assets/invoice-033-page.png filter=lfs diff=lfs merge=lfs -text
71
+ assets/invoice-034-page.png filter=lfs diff=lfs merge=lfs -text
72
+ assets/invoice-035-page.png filter=lfs diff=lfs merge=lfs -text
73
+ assets/invoice-036-page.png filter=lfs diff=lfs merge=lfs -text
74
+ assets/invoice-036-region.png filter=lfs diff=lfs merge=lfs -text
75
+ assets/invoice-037-page.png filter=lfs diff=lfs merge=lfs -text
76
+ assets/invoice-038-page.png filter=lfs diff=lfs merge=lfs -text
77
+ assets/invoice-039-page.png filter=lfs diff=lfs merge=lfs -text
README.md CHANGED
@@ -1,10 +1,23 @@
1
  ---
2
  title: Document Verification Lab
3
- emoji: 📊
4
- colorFrom: purple
5
- colorTo: indigo
6
  sdk: static
 
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
  title: Document Verification Lab
3
+ emoji: 🔎
4
+ colorFrom: green
5
+ colorTo: gray
6
  sdk: static
7
+ app_file: index.html
8
  pinned: false
9
+ license: mit
10
+ short_description: Explore OCR evidence and visual verification tradeoffs
11
  ---
12
 
13
+ # Document Verification Lab
14
+
15
+ An interactive replay of real MiniCPM-OCR and OCR Jev inference on 120 generated invoice regions, with 48 separate stress candidates. By Guilin Zhang.
16
+
17
+ Explore source pixels, extracted text, rendered candidates and raw scores. Adjust the review threshold and compare with simple rules. GPU calls were recorded locally; this static Space does not run live inference.
18
+
19
+ [Code, methodology, source data and model revisions](https://github.com/GuilinDev/document-verification-lab)
20
+
21
+ Main result: on 80 held-out regions, rules caught all three natural errors. Adding the verifier increased review from 3 to 16 cases, including 13 correct items. On 24 separately injected, internally consistent currency/amount errors, the verifier caught all 24 that rules missed. No fine-tuning was performed.
22
+
23
+ Models: [MiniCPM-OCR 1.0](https://huggingface.co/openbmb/MiniCPM-OCR-1.0) and [MiniCPM-OCR Jev](https://huggingface.co/openbmb/MiniCPM-OCR-Jev), OpenBMB, Apache-2.0. Project code and generated data: MIT. Video music licensed for synchronized use; standalone track excluded.
app.js ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ const $=s=>document.querySelector(s);let data,current,threshold;
2
+ const fmt=x=>x<.0001?x.toExponential(2):x.toFixed(4);
3
+ function mode(c){return c.set==='stress'?'stress':c.split}
4
+ function populate(id){const rows=data.cases.filter(c=>mode(c)===$('#dataset').value);$('#case').replaceChildren(...rows.map(c=>{const o=document.createElement('option');o.value=c.case_id;o.textContent=c.case_id+' · '+(c.mutation||c.condition).replaceAll('_',' ');return o}));if(id)$('#case').value=id;show($('#case').value)}
5
+ function show(id){current=data.cases.find(c=>c.case_id===id);const c=current;$('#source').src=c.region;$('#render').src=c.render_image;$('#fullPage').href=c.page;$('#ocr').textContent=c.text;$('#caseMeta').textContent=c.template_family+' · '+c.condition.replaceAll('_',' ');$('#candidateKind').textContent=c.set==='stress'?'Controlled candidate':'Actual model output';$('#ruleTitle').textContent=c.rule_issues.length?'Check failed':'Checks pass';$('#ruleTitle').className=c.rule_issues.length?'bad':'';$('#ruleDetail').textContent=c.rule_issues.length?c.rule_issues.join(', ').replaceAll('_',' '):'All four fields are present. Currency is consistent. Subtotal + shipping + tax equals total.';$('#score').textContent=c.score===null?'Unavailable':fmt(c.score);$('#scoreBar').style.width=100*(c.score||0)+'%';const review=c.rule_issues.length||c.score===null||c.score<data.summary.operating_point.threshold;$('#route').textContent=review?'Send to review':'Pass the OCR check';$('#route').className=review?'bad':'';$('#routeDetail').textContent='Review on a rule failure or a score below '+data.summary.operating_point.threshold.toFixed(6)+'.';$('#truth').textContent='Ground truth: '+(c.correct?'critical fields match':'critical fields differ');$('#truth').className='badge'+(c.correct?'':' bad');$('#audit').textContent=JSON.stringify({case:c.case_id,set:c.set,split:c.split,source_sha256:c.region_sha256||c.sha256_region,reference_fields:c.reference_fields,extracted_fields:c.extracted,score:c.score,rule_issues:c.rule_issues,ocr_including_preprocessing_ms:c.ocr_ms,verifier_forward_ms:c.verifier_ms,verifier_including_preprocessing_ms:c.verifier_total_ms,note:'Verifier timings exclude candidate rendering. Shared GPU; recorded inference.'},null,2);document.querySelectorAll('[data-case]').forEach(b=>b.classList.toggle('active',b.dataset.case===id))}
6
+ function updateThreshold(){const rows=data.cases.filter(c=>c.set==='natural'&&c.split==='test');const reviewed=rows.filter(c=>c.rule_issues.length||c.score===null||c.score<threshold);const caught=reviewed.filter(c=>!c.correct).length;$('#thresholdLabel').textContent=threshold.toFixed(6);$('#reviewCount').textContent=reviewed.length+' / 80';$('#caughtCount').textContent=caught+' / 3';$('#escapedCount').textContent=3-caught;const n=80-reviewed.length;$('#risk').textContent=n?`${3-caught} incorrect accepted out of ${n} accepted regions. This sample does not establish zero production risk.`:'Every region is routed to review.'}
7
+ fetch('evidence.json').then(r=>{if(!r.ok)throw Error('Evidence unavailable');return r.json()}).then(d=>{data=d;threshold=d.summary.operating_point.threshold;$('#threshold').value=threshold;populate('invoice-040-consistent_amounts');updateThreshold();const c=d.cases.find(c=>c.case_id==='invoice-040-reference');const amount=new Intl.NumberFormat('en-US',{style:'currency',currency:c.reference_fields.currency}).format(c.reference_fields.total/100);$('#businessExample').textContent=`The correctly transcribed total for DVL-0040 is ${amount}. If a separate purchase-order check expects ${new Intl.NumberFormat('en-US',{style:'currency',currency:c.reference_fields.currency}).format((c.reference_fields.total-10000)/100)}, route the difference to a business reviewer even when the visual score is high. This PO difference is a constructed workflow example.`;$('#dataset').addEventListener('change',()=>populate());$('#case').addEventListener('change',e=>show(e.target.value));document.querySelectorAll('[data-case]').forEach(b=>b.addEventListener('click',()=>{const c=d.cases.find(c=>c.case_id===b.dataset.case);$('#dataset').value=mode(c);populate(c.case_id)}));$('#threshold').addEventListener('input',e=>{threshold=Number(e.target.value);updateThreshold()});$('#reset').addEventListener('click',()=>{threshold=d.summary.operating_point.threshold;$('#threshold').value=threshold;updateThreshold()});fetch('walkthrough.mp4',{method:'HEAD'}).then(r=>{if(r.ok)$('#film').hidden=false}).catch(()=>{})}).catch(e=>{$('#workbench').textContent='Could not load recorded evidence. Please reload. '+e.message});
assets/00000001_invoice-000.png ADDED
assets/00000002_invoice-001.png ADDED
assets/00000003_invoice-002.png ADDED
assets/00000004_invoice-003.png ADDED
assets/00000005_invoice-004.png ADDED
assets/00000006_invoice-005.png ADDED
assets/00000007_invoice-006.png ADDED
assets/00000008_invoice-007.png ADDED
assets/00000009_invoice-008.png ADDED
assets/00000010_invoice-009.png ADDED
assets/00000011_invoice-010.png ADDED
assets/00000012_invoice-011.png ADDED
assets/00000013_invoice-012.png ADDED
assets/00000014_invoice-013.png ADDED
assets/00000015_invoice-014.png ADDED
assets/00000016_invoice-015.png ADDED
assets/00000017_invoice-016.png ADDED
assets/00000018_invoice-017.png ADDED
assets/00000019_invoice-018.png ADDED
assets/00000020_invoice-019.png ADDED
assets/00000021_invoice-020.png ADDED
assets/00000022_invoice-021.png ADDED
assets/00000023_invoice-022.png ADDED
assets/00000024_invoice-023.png ADDED
assets/00000025_invoice-024.png ADDED
assets/00000026_invoice-025.png ADDED
assets/00000027_invoice-026.png ADDED
assets/00000028_invoice-027.png ADDED
assets/00000029_invoice-028.png ADDED
assets/00000030_invoice-029.png ADDED
assets/00000031_invoice-030.png ADDED
assets/00000032_invoice-031.png ADDED
assets/00000033_invoice-032.png ADDED
assets/00000034_invoice-033.png ADDED
assets/00000035_invoice-034.png ADDED
assets/00000036_invoice-035.png ADDED
assets/00000037_invoice-036.png ADDED
assets/00000038_invoice-037.png ADDED
assets/00000039_invoice-038.png ADDED
assets/00000040_invoice-039.png ADDED
assets/00000041_invoice-040.png ADDED
assets/00000042_invoice-041.png ADDED
assets/00000043_invoice-042.png ADDED
assets/00000044_invoice-043.png ADDED
assets/00000045_invoice-044.png ADDED
assets/00000046_invoice-045.png ADDED
assets/00000047_invoice-046.png ADDED