Views
No views yet
scan → OCR → SLM route), trained/evaluated on
synthetic pages as an in-distribution capability check.Qwen/Qwen2.5-1.5B-Instruct1{"statement_type": "balance_sheet", "primary_entity": "...", "closing_date": "YYYY-MM-DD",
2 "duration": "as_at|year_ended|quarter|half_year", "output_fields": ["Total Assets", ...],
3 "continuing_page_flag": false}
4statement_type ∈ {balance_sheet, income_statement, cash_flow, changes_in_equity,
5other}. Useful for classifying statement pages and pulling key header/total fields.
6
7Out-of-Scope Use
8Trained on synthetic pages only — it is a capability check, not a
9production/real-world model. Use the real-data 3-class adapter for generalization to
10actual filings.
11
12Bias, Risks, and Limitations
13In-distribution: train and eval come from the same synthetic generator, so metrics reflect learned structure, not real-world generalization.
14English, single-page inputs; assumes reasonable OCR quality.
15Small (1.5B) model.
16Recommendations
17Do not rely on synthetic-only metrics for real documents; evaluate on real, source-disjoint
18pages (see the companion real-data adapter) before any production use.
19
20How to Get Started with the Model
21
22from transformers import AutoModelForCausalLM, AutoTokenizer
23from peft import PeftModel
24import json, re
25
26repo = "SudithH2O/ocr-slm-synthetic-qwen1.5b"
27tok = AutoTokenizer.from_pretrained(repo)
28model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5-1.5B-Instruct").eval()
29model = PeftModel.from_pretrained(model, repo)
30
31SYSTEM = ('You are a financial-document analyst. You are shown one page from a financial '
32 'report. Classify the page and extract its metadata.\n\n'
33 'Respond with a single JSON object and nothing else, using exactly these keys:\n'
34 ' "statement_type": one of "balance_sheet", "income_statement", "cash_flow", '
35 '"changes_in_equity", "other".\n'
36 ' "primary_entity": the company/entity name, or null.\n'
37 ' "closing_date": the reporting/closing date as YYYY-MM-DD, or null.\n'
38 ' "duration": one of "as_at", "year_ended", "quarter", "half_year", or null.\n'
39 ' "output_fields": a list of the key total/subtotal line labels on the page.\n'
40 ' "continuing_page_flag": true if this page continues a statement from a '
41 'previous page, else false.\n\n'
42 'If the page is not one of the four statements, use "other" and set the '
43 'financial fields to null / empty as appropriate.')
44
45def analyze(page_text):
46 msgs = [{"role": "system", "content": SYSTEM},
47 {"role": "user", "content": page_text}]
48 prompt = tok.apply_chat_template(msgs, tokenize=False, add_generation_prompt=True)
49 ids = tok(prompt, return_tensors="pt", add_special_tokens=False).to(model.device)
50 out = model.generate(**ids, max_new_tokens=200, do_sample=False)
51 text = tok.decode(out[0, ids["input_ids"].shape[1]:], skip_special_tokens=True)
52 return json.loads(re.search(r"\{.*\}", text, re.S).group())
53Training Details
54Training Data
55Synthetic financial-statement pages generated with internally-consistent numbers
56(ReportLab → PNG), then OCR'd with Tesseract back into text (deliberately including OCR
57noise). Labels: 5 statement types + metadata fields. Trained on 500 pages.
58
59Training Procedure
60Preprocessing
61Each example is a chat: system instruction + OCR page text → the label JSON.
62
63Training Hyperparameters
64LoRA: r=16, alpha=16, dropout=0, target=all-linear, task=CAUSAL_LM (~1.18% params trained)
65Objective: completion-only SFT (loss on the JSON target only)
66Optimizer: AdamW, lr 2e-4, cosine schedule, 2 epochs, batch 2 × grad-accum 4, max_len 2048
67Training regime: bf16, gradient checkpointing
68Hardware: Apple Silicon (MPS); ~30 min
69Evaluation
70Testing Data & Metrics
71Held-out synthetic val split (n=200), same generator as training (in-distribution).
72Metrics: statement-type accuracy, macro-F1, JSON-validity, and per-field accuracy.
73
74Results
75accuracy macro-F1 JSON-validity closing_date duration continuing_page_flag
761.000 1.000 1.000 1.000 1.000 1.000
77Per-class F1 = 1.00 for all four statement types; confusion matrix is perfectly diagonal.
78This matches (marginally exceeds) the Gemma-4 vision model's 0.993 on the same synthetic
79task — i.e., on synthetic data the text route is on par with vision.
80
81Summary
82In-distribution, the fine-tuned text SLM classifies statement type and extracts metadata
83essentially perfectly, and reliably emits valid JSON. This establishes capability; the
84real-data adapter measures generalization.
85
86Technical Specifications
87Model Architecture and Objective
88LoRA adapters over Qwen-2.5-1.5B-Instruct; trained to generate the label+metadata JSON.
89
90Framework versions
91PEFT 0.19.1
92Transformers 5.x
93