File size: 5,292 Bytes
29467f3
 
 
 
 
 
 
 
 
 
 
6983962
29467f3
6983962
44992fb
 
29467f3
68dd873
 
cc6acca
29467f3
44992fb
29467f3
cc6acca
 
 
 
 
29467f3
44992fb
29467f3
cc6acca
29467f3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cc6acca
29467f3
cc6acca
29467f3
cc6acca
 
 
 
 
 
29467f3
 
cc6acca
29467f3
cc6acca
 
 
29467f3
 
 
 
 
 
 
 
ca2525b
29467f3
 
cc6acca
29467f3
 
 
cc6acca
29467f3
 
 
 
 
cc6acca
29467f3
 
 
cc6acca
29467f3
 
 
cc6acca
 
29467f3
 
 
cc6acca
 
29467f3
 
cc6acca
29467f3
 
 
44992fb
 
 
 
29467f3
ca2525b
29467f3
 
44992fb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
---
license: apache-2.0
pipeline_tag: image-classification
tags:
  - siglip2
  - document-classification
  - hierarchical
  - multi-task
library_name: transformers
---

# Med Doc Classifier (~96M)

The med-doc-classifier is a lightweight, encoder-only model (~96M parameters) built on the popular SigLIP2-base image backbone. In a single pass it sorts an image into one of 27 classes across two hierarchical levels, from broad group down to specific leaf, and answers two further questions: whether the subject matter is medical, and whether it was handwritten.

The model was built by training many specialised models, ensembling them, and distilling the ensemble into this one compact student.

[**Live demo**](https://medai.eka.care/classifier) Β· [**Launch blog**](https://info.eka.care/services/releasing-parrotlet-open-models-open-weights-for-medical-document-intelligence)

## Results

Full internal test = 16,204 images (see `benchmark_results.json`).

| Precision | Size | Accuracy (27-class) | Macro-F1 |
|-----------|------|---------------------|----------|
| bf16 | 193 MB | 96.45 | 0.965 |
| int8 | 103 MB | 96.43 | 0.965 |
| int4 | 60 MB | 95.22 | 0.955 |

int8 is effectively lossless; int4 trades about a point of accuracy for a model over 3Γ— smaller that runs comfortably on a plain CPU. It matches or beats models several times its size, including a 428M SigLIP2-SO400M variant (96.24%) and a 256M generative VLM baseline (90.42%).

## Taxonomy (5 L1 groups β†’ 27 L2 leaves)

```
Document  (10 leaves)
    β”œβ”€ Letter                 (key: letter)
    β”œβ”€ Other document         (key: other_document)
    β”œβ”€ Scan interpretation    (key: scan_interpretation)
    β”œβ”€ Lab / diagnostic report (key: lab_diagnostic_report)
    β”œβ”€ OPD Consultation Record (key: opd_consultation_record)
    β”œβ”€ Discharge summary      (key: discharge_summary)
    β”œβ”€ Insurance document     (key: insurance_document)
    β”œβ”€ Form                   (key: form)
    β”œβ”€ Invoice / bill         (key: invoice_bill)
    β”œβ”€ Certificate            (key: certificate)
Card / credential  (7 leaves)
    β”œβ”€ ABHA card              (key: abha_card)
    β”œβ”€ Aadhaar card           (key: aadhaar_card)
    β”œβ”€ PAN card               (key: pan_card)
    β”œβ”€ Voter ID               (key: voter_id)
    β”œβ”€ PMJAY / Ayushman       (key: pmjay_ayushman)
    β”œβ”€ Insurance e-card       (key: insurance_e_card)
    β”œβ”€ Other card             (key: other_card)
Diagnostic imaging  (5 leaves)
    β”œβ”€ X-ray                  (key: x_ray)
    β”œβ”€ CT                     (key: ct)
    β”œβ”€ MRI                    (key: mri)
    β”œβ”€ Ultrasound             (key: ultrasound)
    β”œβ”€ Other (Diagnostic imaging) (key: other_diagnostic_imaging)
Body images  (3 leaves)
    β”œβ”€ Skin / wound           (key: skin_wound)
    β”œβ”€ Headshot               (key: headshot)
    β”œβ”€ Other (Body images)    (key: other_body_images)
Miscellaneous  (2 leaves)
    β”œβ”€ Medication image       (key: medication_image)
    β”œβ”€ Other (Miscellaneous)  (key: other_miscellaneous)
```

## Usage

```python
from transformers import AutoModel
from PIL import Image

model = AutoModel.from_pretrained("ekacare/med-doc-classifier", trust_remote_code=True).eval()
img = Image.open("doc.jpg")

model.classify(img)
```

```jsonc
// example return value
{
  "l2":          { "source": "flat", "key": "lab_diagnostic_report",
                    "value": "Lab / diagnostic report", "confidence": 0.97 },
  "l1":          { "value": "Document", "source": "inferred_from_flat_l2" },
  "medical":     { "value": "medical", "confidence": 0.99, "p_positive": 0.99 },
  "handwritten": { "value": "printed", "confidence": 0.98, "p_positive": 0.02 }
}
```

By default L2 comes from a flat 27-way head and L1 is inferred from it. Other options:

```python
model.classify(img, scope="l1")           # L1 group only (no L2)
model.classify(img, scope="hierarchical") # L1 head β†’ that group's leaf L2 head
model.classify(img, l1="Document")        # fix L1 β†’ that group's leaf L2 head
model.classify(img, top_k=3)              # top-3 candidates for the multi-class heads
```

`medical` and `handwritten` are independent binary heads β€” disable them with `medical=False` / `handwritten=False`.

## Quantized loading (optimum-quanto β€” CPU & GPU)

Only the vision tower is quantized; the heads stay full precision.

```python
# pip install optimum-quanto
from transformers.dynamic_module_utils import get_class_from_dynamic_module

load_classifier = get_class_from_dynamic_module(
    "modeling_siglip2_hier.load_classifier", "ekacare/med-doc-classifier")

model = load_classifier("ekacare/med-doc-classifier", quantization="int4")  # None | "int8" | "int4"
model.classify(img)
```

Working from a clone instead? `from modeling_siglip2_hier import load_classifier`
inside the repo directory works too, and `load_classifier(".", quantization="int8")`
loads straight from the checkout.

## Citation

If you use this model, please cite:

```bibtex
@software{med_doc_classifier,
  author = {{Eka Care}},
  title  = {Med Doc Classifier: hierarchical classification of health-app document uploads},
  year   = {2026},
  url    = {https://huggingface.co/ekacare/med-doc-classifier}
}
```