Fine-tuned
openbmb/MiniCPM-V-4.6 for
structured JSON extraction from Indian distributor (kirana) invoices.
1{
2 "invoice_number": "INV-2024-001",
3 "supplier": "Hindustan Unilever Ltd.",
4 "date": "2026-06-10",
5 "items": [
6 {
7 "product_raw": "SURF XL 1KG",
8 "quantity": 12,
9 "unit_price": 95.00,
10 "gst_rate": 18,
11 "line_total": 1140.00
12 },
13 {
14 "product_raw": "MAGGI MASALA 70G",
15 "quantity": 48,
16 "unit_price": 14.00,
17 "gst_rate": 5,
18 "line_total": 672.00
19 }
20 ],
21 "grand_total": 9650.00,
22 "extraction_warnings": []
23}
1import torch
2from transformers import AutoModel, AutoTokenizer
3from PIL import Image
4
5model = AutoModel.from_pretrained(
6 "naazimsnh02/minicpm-v-4-6-indian-invoice-extraction-merged",
7 trust_remote_code=True,
8 torch_dtype=torch.bfloat16,
9 device_map="auto",
10)
11model.eval()
12tokenizer = AutoTokenizer.from_pretrained(
13 "naazimsnh02/minicpm-v-4-6-indian-invoice-extraction-merged",
14 trust_remote_code=True,
15)
16
17image = Image.open("invoice.jpg").convert("RGB")
18
19prompt = (
20 "You are an OCR agent for Indian kirana store invoices. "
21 "Extract all information from this invoice image and return ONLY valid JSON "
22 "matching this schema exactly:\n"
23 '{"invoice_number": string|null, "supplier": string|null, "date": string|null, '
24 '"items": [{"product_raw": string, "quantity": number, "unit_price": number, '
25 '"gst_rate": number, "line_total": number}], '
26 '"grand_total": number, "extraction_warnings": [string]}\n'
27 "Return ONLY the JSON object, no markdown, no prose."
28)
29
30msgs = [{"role": "user", "content": [image, prompt]}]
31response = model.chat(image=None, msgs=msgs, tokenizer=tokenizer, sampling=False, max_new_tokens=2048)
32print(response)
1import fitz # PyMuPDF
2from PIL import Image
3import io, json
4
5doc = fitz.open("invoice.pdf")
6results = []
7for page in doc:
8 pix = page.get_pixmap(matrix=fitz.Matrix(2.0, 2.0))
9 img = Image.open(io.BytesIO(pix.tobytes("png"))).convert("RGB")
10 msgs = [{"role": "user", "content": [img, prompt]}]
11 raw = model.chat(image=None, msgs=msgs, tokenizer=tokenizer, sampling=False, max_new_tokens=2048)
12 results.append(json.loads(raw))
1@misc{kirana_detective_minicpmv_2026,
2 author = {Syed Naazim Hussain},
3 title = {MiniCPM-V 4.6 Fine-Tuned for Indian Invoice Extraction},
4 year = {2026},
5 publisher = {HuggingFace},
6 howpublished = {\url{https://huggingface.co/naazimsnh02/minicpm-v-4-6-indian-invoice-extraction-merged}},
7}
Apache 2.0 — same license as the base
openbmb/MiniCPM-V-4.6 model.