Downloads · 30 days
200
29% of all-time downloads
gagan1985/tinybert-4l-312d-indian-address-parser
tinybert-4l-312d-indian-address-parser is a token classification model from gagan1985. Use it when you need labels on individual words, such as names. The card lists the license as apache-2.0.
A full fine-tune of huawei-noah/TinyBERTGeneral4L312D that parses raw, unstructured Indian address strings into 13 structured fields via token classification (BIO tagging) — the smallest and fastest of this project's…
Downloads · 30 days
200
29% of all-time downloads
All-time downloads
686
Public
Parameters
14.3M
57.1 MB on disk
Likes
1
Public
Click a slice to open those files.
.safetensors57.1 MB · 99%
From the Hugging Face model README
A full fine-tune of huawei-noah/TinyBERT_General_4L_312D that parses raw, unstructured Indian address strings into 13 structured fields via token classification (BIO tagging) — the smallest and fastest of this project's three models. ~14M params, vs. ~77M for flan-t5-small and ~596M for Qwen3-0.6B — yet scores within ~2-4 points of both on mean field accuracy (see below).
Input: "FLAT NO.32, UTTARA TOWERS, MG ROAD GUWAHATI , Kamrup Unclassified AS 781029"
Output: {"houseNumber": "FLAT NO.32", "houseName": "UTTARA TOWERS", "poi": null,
"street": "MG ROAD", "subsubLocality": null, "subLocality": null, "locality": null,
"village": null, "subDistrict": null, "district": "Kamrup", "city": "GUWAHATI",
"state": "AS", "pincode": "781029"}
Unlike the other two models (which generate a JSON string), this model predicts one BIO tag per token — it always produces a well-formed field dict; there's no "invalid JSON" failure mode to handle downstream.
import torch
from transformers import AutoModelForTokenClassification, AutoTokenizer
repo = "gagan1985/tinybert-4l-312d-indian-address-parser"
tokenizer = AutoTokenizer.from_pretrained(repo)
model = AutoModelForTokenClassification.from_pretrained(repo)
address = "FLAT NO.32, UTTARA TOWERS, MG ROAD GUWAHATI , Kamrup Unclassified AS 781029"
enc = tokenizer(address, return_tensors="pt", return_offsets_mapping=True, truncation=True, max_length=160)
offsets = enc.pop("offset_mapping")[0].tolist()
with torch.no_grad():
logits = model(**enc).logits
pred_ids = logits[0].argmax(-1).tolist()
# reconstruct fields from raw text spans (see inference_tinybert.py's extract_fields
# for the full implementation) — never tokenizer.decode, which would lose casing
# and introduce WordPiece "##"-continuation artifacts
Or use the included inference_tinybert.py / evaluate_tinybert.py (download
the repo, then python inference_tinybert.py --model . "<address>"). Both are
standalone — only transformers+torch required.
pip install indian-address-parser — all three models behind one interface (AddressParser(backend="tinybert")), source and benchmarks on GitHub: innerkorehq/indian-address-parserhouseNumber, houseName, poi, street, subsubLocality, subLocality,
locality, village, subDistrict, district, city, state, pincode
"PEDANANDIPALLE AGRAHARAMPEDANANDIPALLE AGRAHARAM") — not a training bug.
See bio_convert.py on GitHub for the exact algorithm.| Parameter | Value |
|---|---|
| Base model | huawei-noah/TinyBERT_General_4L_312D (~14M params, 4 layers, 312 hidden) |
| Fine-tuning | Full fine-tune, token classification head |
| Labels | 27 (O + B-/I- × 13 fields) |
| Epochs | 10 |
| Batch size | 32 |
| Learning rate | 5e-5 |
| Training time | ~2.2 minutes on Apple Silicon (MPS) — the tiny model size makes this by far the cheapest of the three to train |
| Field | Accuracy | Recall | Gold presence |
|---|---|---|---|
| pincode | 99.6% | 99.6% | 100.0% |
| district | 92.5% | 92.7% | 65.8% |
| subDistrict | 88.2% | 4.3% | 10.1% |
| houseNumber | 86.8% | 79.8% | 52.2% |
| state | 83.8% | 83.6% | 98.7% |
| houseName | 83.3% | 86.0% | 43.9% |
| city | 82.5% | 77.9% | 67.5% |
| poi | 78.1% | 18.6% | 18.9% |
| village | 70.6% | 0.0% | 22.4% |
| subsubLocality | 70.6% | 43.5% | 27.2% |
| subLocality | 76.8% | 0.0% | 21.9% |
| street | 56.1% | 49.6% | 53.9% |
| locality | 55.7% | 30.5% | 41.7% |
village and subLocality have 0% recall despite reasonably high raw
accuracy — the model defaults to null for these far more often than gold
does, so its "correct" score comes mostly from gold also being null, not
from successfully extracting the field when present. Same pattern as
poi on the flan-t5-small model card, and a plausible consequence of this
model's much smaller capacity (4 layers, 312 hidden) having less room for
the rarer, more context-dependent fields.locality/subLocality/subsubLocality/village conceptual overlap
noted on the other two model cards applies here too.Same non-invasive wrapper as the other two models — see
gazetteer_lookup.py (included). Adds districtAdministrative/
stateAdministrative/cityAdministrative as new, always-populated fields
without touching this model's own verbatim district/state/city output.
On the 228-sample test set: 99.6% administrative-field coverage, with zero
impact on the field accuracy numbers above.
from gazetteer_lookup import load_gazetteer, add_administrative_fields
gazetteer = load_gazetteer("pincodes.csv") # India Post format
result = add_administrative_fields(model_output, gazetteer)
model.safetensors, config.json — the fine-tuned modeltokenizer.json, tokenizer_config.json — tokenizerinference_tinybert.py / evaluate_tinybert.py — standalone CLI scripts, only need transformers+torchgazetteer_lookup.py — optional pincode → district/state/city lookup wrapper (needs a
pincodes CSV, not included here — see the GitHub repo for the source used)Apache 2.0, inherited from the base model (huawei-noah/TinyBERT_General_4L_312D).