Instructions to use anandkaman/gemma3_12b_deedexp with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use anandkaman/gemma3_12b_deedexp with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="anandkaman/gemma3_12b_deedexp") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] pipe(text=messages)# pip install -U transformers accelerate # Load model directly from transformers import AutoProcessor, AutoModelForMultimodalLM processor = AutoProcessor.from_pretrained("anandkaman/gemma3_12b_deedexp") model = AutoModelForMultimodalLM.from_pretrained("anandkaman/gemma3_12b_deedexp", device_map="auto") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] inputs = processor.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=256) print(processor.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use anandkaman/gemma3_12b_deedexp with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "anandkaman/gemma3_12b_deedexp" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "anandkaman/gemma3_12b_deedexp", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/anandkaman/gemma3_12b_deedexp
- SGLang
How to use anandkaman/gemma3_12b_deedexp with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "anandkaman/gemma3_12b_deedexp" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "anandkaman/gemma3_12b_deedexp", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "anandkaman/gemma3_12b_deedexp" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "anandkaman/gemma3_12b_deedexp", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use anandkaman/gemma3_12b_deedexp with Docker Model Runner:
docker model run hf.co/anandkaman/gemma3_12b_deedexp
gemma3_12b_deedexp
Reads the OCR text of a Karnataka property registration document (Kannada + English) and returns one JSON record: buyers, sellers, property details and document details.
A fine-tune of Gemma 3 12B-it in three stages:
- domain-adaptive pre-training on registered-document text — 1,771 documents, ~16.0M tokens, every validation document excluded;
- an instruction bridge stage that teaches what the document wording means (roles, identifiers, dates);
- supervised extraction training across seven prompt styles, each also in a two-request split form (parties / transaction + property).
This repo carries the unquantised bf16 merged weights (~23 GB). Running them needs roughly 24 GB of VRAM; on smaller cards load in 4-bit. Quantised builds follow.
Status: for testing. No aggregate benchmark yet — see Evaluation. Contact: kamananand98@gmail.com
Prompts
One request per document: the user message is the prompt text + "\n\n" + the document's OCR text.
Greedy decoding, up to 2,500 new tokens, one <bos> (the chat template already adds it).
| file | use |
|---|---|
prompts/micro_full.txt |
single-request default — returns the whole record |
prompts/micro_parties.txt + prompts/micro_txn_property.txt |
split mode: two requests on the same OCR; merge the two JSON objects |
prompts/short_full.txt, prompts/medium_full.txt |
longer wordings of the same rules |
All 21 prompts are shipped: 7 styles (micro, brief, short, medium, long, fields, user) × 3 scopes
(full, parties, txn_property). The model was trained on all of them with the style drawn independently per
row, so any style works with any scope. A split request must use the split prompts, never the full prompt — each
returns only its own keys.
micro is carried over from the earlier 4B benchmark, where it won on the same validation set. It has not been
re-benchmarked at 12B, and neither has single vs split. Treat the choice as inherited, not established.
pip install "transformers>=4.50" torch accelerate
python inference.py document_ocr.txt # micro_full, one request
python inference.py document_ocr.txt --split # parties + txn_property, merged
python inference.py document_ocr.txt --prompt short # any of the 7 styles
Output schema
{
"buyer_details": [{"name", "gender": "Male|Female|null", "father_name", "aadhaar_number", "pan_card_number", "address"}],
"seller_details": [ ...same fields... ],
"property_details": {"schedule_c_property_address", "sale_consideration", "registration_fee"},
"document_details": {"transaction_date": "YYYY-MM-DD"}
}
Main rules it is trained on:
- Roles come from what the document says each party does, not print order. Confirming parties and consenting witnesses are not sellers. A promoter or developer is not a seller unless the document names it as vendor, seller or owner, or it is the only transferring party.
transaction_date= the registration date from the Sub-Registrar endorsement, not the execution date.father_nameof a married woman = her husband when her own description gives him.- Text is copied as printed — never translated, never normalised. An OCR character error in a name is still
copied; only genuinely missing or incomplete information becomes
null. - Identifiers are stricter: a malformed, masked or partial Aadhaar or PAN becomes
nulland is never repaired.
Evaluation
The 60-document held-out run has not been completed, so there are no aggregate F1 figures yet. What follows is everything that has been measured, including the failures.
Party extraction on documents the previous 4B model got wrong
Five held-out documents, chosen because the earlier 4B model mis-assigned parties on them — putting a seller in the buyer list or the reverse. Each run twice, single-request and split.
| document | earlier 4B behaviour | this model |
|---|---|---|
| 2 buyers / 1 seller | roles swapped | roles correct |
| 1 buyer / 10 sellers | collapsed to 9 buyers / 7 sellers | exact, both modes |
| 4 buyers / 1 seller | swapped to 2 / 2 | exact, both modes |
| 1 buyer / 5 sellers | swapped; a later attempt returned invalid JSON | exact, both modes |
| 1 buyer / 9 sellers | an earlier attempt inverted the document | follows the Party Type: (Executant) tag (note below) |
No role swap occurred on any of the five, in either mode, and single-request matched split everywhere — the split form was not needed to get these right. One name was copied with a mis-rendered initial.
Note on the last row: OCR flattens the registration table, so a party arrives as a bare Party Type: (Executant)
line with no table header or column context anywhere in the document. The model treats that as a statement that the
person executed the document, which is the only reading the text supports. A rule that depends on telling table from
body is not implementable from this input.
JSON schema: the prompt is required
Three documents, three prompt conditions:
| condition | valid JSON | schema correct |
|---|---|---|
| no schema given, "return JSON" | 3/3 | 0/3 |
| shipped prompt (schema described) | 3/3 | 3/3 |
| one worked JSON example, no description | 3/3 | 3/3 |
Without a schema the model invents its own keys — singular buyer/seller, an invented currency, a field this
schema does not contain, and in one case the whole record collapsed into a single key. Use the shipped prompts.
A single worked example works as well as the written schema, so the shape can be demonstrated rather than described.
Identifiers
Eight identifiers, valid and invalid: 8/8 judged correctly — a well-formed PAN and Aadhaar accepted; a
wrong-shape PAN, a PAN with the letter O in a digit position, a lowercase PAN, an 11-digit Aadhaar, a 16-digit
Aadhaar and a masked Aadhaar all rejected. Two of the eight explanations were wrong although the verdicts were
right, so the stated reasoning should not be relied on as an audit trail.
Long-range mapping. Where parties are named on one page and their identifiers appear many pages later as a bare
numbered list with no names, the model mapped them to the right people. Given five sellers and only four
identifiers it assigned four and left the fifth null. No identifier was fabricated or shifted in any test.
Dates
Asked about a document executed on one date, presented on another and registered on a third, it returned the registration date, with the correct reasoning.
Kannada domain knowledge — strong on documents, unreliable on law
Strong where it matters for extraction. Answers in Kannada distinguish sale, gift and partition deeds by consideration and name the parties to each correctly, explain ಚಕ್ಕುಬಂದಿ and ಅಳತೆ, translate registration and stamp-duty vocabulary in both directions, and give real reasons a consenting party appears in a deed (family settlement, a share in the property, an existing claim).
Unreliable on general legal procedure — do not use it as a legal reference. Asked open questions beyond document reading it produced confident but wrong answers: an invented registration deadline ("within 7 days"), a circular and incorrect account of whether a power-of-attorney holder is the seller — which also contradicts the rule it was trained on — an incoherent list of who may sell a minor's property, and one question answered with a preamble and no content. Occasional glosses are garbled.
Treat it as a document reader, not an adviser.
Weaknesses found
- Indian currency handling is weak. Given four separate part-payments and no stated total, it listed every payment correctly with its date and mode but summed them wrongly, by roughly a factor of ten. Copied amounts are reliable; derived or summed amounts are not, and should be recomputed downstream.
- Addresses are the weakest field — observed dropping a project-name prefix, reordering components, and omitting a PIN.
- Output shape drifts whenever the prompt does not carry the schema (above).
- Training loss was still falling when training ended, and the checkpoint was not selected on a validation curve.
Serving and throughput
serving/ has everything needed to reproduce this on a single 16 GiB GPU: exact hardware, driver and package
versions, both serving paths, the quantization and serve commands, and the pitfalls that cost us time.
| path | documents/hour | context | notes |
|---|---|---|---|
| plain transformers, 4-bit (NF4) | 114 sequential | full 20,480 | simplest; no quantized artifact needed |
| vLLM, W4A16, 4 concurrent | 480 (4.2x) | 12,288 | needs a quantized build; long documents must be routed elsewhere |
Measured on an RTX 5060 Ti (16 GiB), 20 held-out documents, warm-up discarded. Valid JSON on every request at
every concurrency, and no output lost to batching (abort/error/repetition counters all zero).
The binding constraint is KV cache, not weights: vLLM charges 6.57 GiB for a single 20,480-token sequence, so
even with 4-bit weights the pool holds ~28,500 tokens — about 3-4 documents of median length. W8A16 leaves too
little pool to batch at all on 16 GiB and is only useful on a larger card. See serving/REPRODUCE.md.
Limitations
- Trained with a 12,288-token context. About 4.8% of our own corpus is longer (up to 20,453 tokens); behaviour above the trained window is largely untested.
- Works on OCR text, so OCR errors in identifiers and names carry through. Always check extracted identifiers against the document.
- Trained on Karnataka property transfer documents. Other document types and other states are out of scope.
- The training documents contain personal data. Use only on documents you are authorised to process.
License
Derivative of Gemma 3, distributed under the Gemma Terms of Use; use is subject to the Gemma Prohibited Use Policy.
- Downloads last month
- 483