{"slug": "yama-judges-chitragupta-keeps-the-records-open-source-ai-for-indian-languages", "title": "Yama Judges, Chitragupta Keeps the Records: Open-Source AI for Indian Languages", "summary": "An open-source PII detection model called Chitragupta, released on Hugging Face by developer arunp0, tags 18 types of personal data across 13 Indian languages in native scripts and Roman letters, including native digits and numbers spelled out as words. Chitragupta pairs a fine-tuned XLM-RoBERTa-large tagger (560M parameters) with a small rule layer that uses ID checksums to assign labels, runs at about 24 ms per short message on a multi-core server CPU in batches of 32, and raised a false alarm on 2.4% of the 293 texts without personal data in a 1,582-text test set. The model was trained entirely on synthetic text, and the developer's stated lesson is that when generating training data with an LLM, code should produce the labels because LLMs are unreliable at reporting exact character offsets.", "body_md": "**TL;DR**\n\nHere is a typical support message in India:\n\n“Hi, main Rohit Verma bol raha hoon. Mera Aadhaar XXXX XXXX 5246 hai aur UPI rohit.example@upi, refund isi pe bhej do. Call: 98765 43210”\n\nBefore this message goes anywhere useful, two things have to happen:\n\nIn Indian tradition, these are two different jobs. **Yama** is the judge who weighs what is placed before him and gives a verdict. **Chitragupta**, his record-keeper, writes down the details of every person’s life.\n\nI built one open model for each job. My previous article, [Before You Invent a New Architecture, Try a Bigger Encoder](https://medium.com/towards-artificial-intelligence/before-you-invent-a-new-architecture-try-a-bigger-encoder-8f2b39fc50a8), covered Yama. This one introduces Chitragupta and shows how the two work together.\n\nPersonal data in Indian text is hard to catch with English tools, for four reasons:\n\nMost open PII models are English-first. Of the Indian-focused ones I tested, few cover Indian IDs, 13 languages and a permissive licence in one model.\n\nChitragupta tags **18 types of personal data**:\n\nIt works in **Hindi, Hinglish, Bengali, Tamil, Telugu, Marathi, Gujarati, Kannada, Malayalam, Punjabi, Urdu, Odia and Indian English**, in native scripts and in Roman letters, including native digits and numbers spoken out as words.\n\n```\n# pip install torch transformers huggingface_hubimport sysfrom huggingface_hub import snapshot_downloadpath = snapshot_download(\"arunp0/chitragupta-pii-indic\")sys.path.insert(0, path)from chitragupta import Chitraguptam = Chitragupta(path)   # uses a GPU if available, otherwise CPUtext = (\"Hi, main Rohit Verma bol raha hoon. Mera Aadhaar XXXX XXXX 5246 hai aur \"        \"UPI rohit.example@upi, refund isi pe bhej do. Call: 98765 43210\")print(m.redact(text))# Hi, main [PERSON] bol raha hoon. Mera Aadhaar [AADHAAR] hai aur UPI [UPI_ID], refund isi pe bhej do. Call: [PHONE]print(m.detect(text)[1])# {'label': 'AADHAAR', 'start': 49, 'end': 63, 'text': 'XXXX XXXX 5246'}\n```\n\ndetect() returns character offsets, so you can mask, hash or tokenise the values however your system needs. Ordinary numbers are left alone: m.detect(\"Order #4410293 delivered on 12/03/2025 at 10:30. Thanks!\") returns nothing.\n\nOn a multi-core server CPU it takes about 24 ms per short message in batches of 32. You can also try it in the box on the model page.\n\nChitragupta has two parts.\n\n**1. A tagger.** XLM-RoBERTa-large (560M parameters) fine-tuned to label every token as the beginning, inside or outside of a personal-data span.\n\n**2. A small rule layer.** Most Indian IDs carry their own proof of validity:\n\nWhen the tagger sees an ID format it has never met, it often splits it into pieces with mixed labels. The rules glue the pieces back together and let the checksum decide the label. They never touch names or addresses, and they never relabel bank account or driving licence numbers, which have no checksum.\n\nThe effect is large where it matters:\n\n“Strict” means separator styles never seen in training. They turned out easier than unseen digit groupings, which is why that slice scores higher.\n\nSo the rules mostly fix *labels*, not coverage. The model already finds almost every value; the checksum decides whether it is an Aadhaar or a card number. A small model cannot memorise every way people type a GSTIN, but a few lines of arithmetic can verify one.\n\nNo real personal data, production data or public PII dataset went into training. Every training text is synthetic:\n\nThe lesson I would pass on: **when you generate training data with an LLM, let code produce the labels.** LLMs are good at writing realistic text and unreliable at reporting exact character offsets.\n\nA model trained on synthetic data can score well simply by memorising its own generator. I built the test set to make that impossible:\n\nThe test set has 1,582 texts: 1,289 with personal data (6,123 spans) and 293 without. On the texts with no personal data, Chitragupta raised a false alarm on 2.4% (7 of 293).\n\nAfter v1, I trained three v2 variants to fix two weaknesses the public benchmarks exposed: short one-line addresses and look-alike numbers such as timestamps and invoice IDs. On Ylemis, v2b jumped from 0.878 to 0.998. That gain is not independent: I designed v2’s data after reading the benchmark’s errors.\n\nBefore looking at the results, I had written down a release rule: **ship v2 only if it is not significantly worse than v1 on the fresh test set, overall or on driving licences.**\n\nBoth variants I tested with the bootstrap significantly hurt driving licences (v2b −3.5, v2c −1.6 points), which fails the rule. v2c also lost 3.6 points on voter IDs, and the first v2 had already broken slash-separated IDs. Teaching the model that invoice numbers are not personal data made it more cautious about ID formats it had never seen. A missed voter ID leaks real data; a masked timestamp is only over-redaction. So I shipped v1, and the model card lists short addresses and look-alike numbers as known limits.\n\nI ran nine public alternatives on the same texts. To compare models with different label sets, the score is **character-level redaction F1**: whatever label a model uses, did it mask the personal-data characters?\n\nTwo caveats belong next to this chart:\n\nOn two public benchmarks built by other people, Chitragupta is **not** the best model.\n\nIf your text has short addresses, test both models on a sample of your own data before choosing. Benchmarks tell you where to look, not what to deploy.\n\nThe pipeline from the diagram fits in a few lines. Chitragupta masks the personal data; Yama decides what the message is about. Far less personal data reaches your logs or a hosted LLM.\n\n``` python\nimport thx01   # pip install thx01  (the open-source library Yama uses)yama = thx01.load(\"arunp0/yama-indic\")safe = m.redact(text)   # Chitragupta, from the snippet aboveout = yama.system_one(safe, {    \"topic\":  {\"type\": \"choice\", \"instructions\": \"What is the customer writing about?\",               \"criteria\": {\"refund\": \"asking for a refund\", \"failed_payment\": \"payment failed\",                            \"account\": \"login or account access\", \"other\": None}},    \"urgent\": {\"type\": \"noul\", \"instructions\": \"Does the customer need help urgently?\"},})# log `safe` and `out`, never `text`\n```\n\nYama is a zero-shot classifier: you write the labels and questions at run time, with no fine-tuning. On 33 tasks it never trained on, across 19 languages, it scores 0.814 accuracy, against 0.770 for the next best zero-shot model I tested. I have not measured Yama’s accuracy on redacted text, so check it on your own data.\n\n**What is Chitragupta?** Chitragupta (arunp0/chitragupta-pii-indic) is an open-source PII detection and redaction model for Indian languages and Hinglish. It finds 18 types of personal data, including Aadhaar, PAN, UPI IDs, phone numbers and names, in 13 languages, and returns their character offsets.\n\n**How do I mask Aadhaar or PAN numbers in Python?** Download the model with snapshot_download(\"arunp0/chitragupta-pii-indic\"), then call Chitragupta(path).redact(text). It replaces each value with its label, such as [AADHAAR] or [PAN]. The full snippet is above.\n\n**Is it free for commercial use?** Yes. The weights and code are Apache-2.0, the base model (XLM-RoBERTa-large) is MIT, and the training data was generated only with open-weights models (Gemma 4 and Qwen3.6, both Apache-2.0).\n\n**Does it run offline?** Yes. It runs locally on CPU or GPU with PyTorch, and no text leaves your machine.\n\n**How is it different from Microsoft Presidio or regex rules?** Regex finds well-formed IDs but misses names, addresses, unusual formats, native digits and spoken numbers. On the fresh test set, Chitragupta masked 99.0% of personal-data characters, against 55.0% for Presidio with its Indian recognisers.\n\n**Does it make a system DPDP-compliant?** No model does that on its own. It helps you keep personal data out of logs, analytics and LLM prompts, as one part of a privacy process.\n\n**What is Yama?** Yama (arunp0/yama-indic) is a companion zero-shot text classifier for the same 13 languages. You describe the labels in plain English, and it returns a calibrated probability for each, without fine-tuning.\n\nIf you run Chitragupta on real text and it misses something, open a discussion on the model page. Real failure cases are the most useful thing anyone can send me.\n\n*Chitragupta and Yama are independent personal releases by Arun Prabhakaran, licensed Apache-2.0.*\n\n*Drafted with help from Claude (Anthropic); experiments, numbers and final edits by the author.*\n\n[Yama Judges, Chitragupta Keeps the Records: Open-Source AI for Indian Languages](https://pub.towardsai.net/yama-judges-chitragupta-keeps-the-records-open-source-ai-for-indian-languages-b7f8bf3b7576) was originally published in [Towards AI](https://pub.towardsai.net) on Medium, where people are continuing the conversation by highlighting and responding to this story.", "url": "https://wpnews.pro/news/yama-judges-chitragupta-keeps-the-records-open-source-ai-for-indian-languages", "canonical_source": "https://pub.towardsai.net/yama-judges-chitragupta-keeps-the-records-open-source-ai-for-indian-languages-b7f8bf3b7576?source=rss----98111c9905da---4", "published_at": "2026-10-24 21:01:01+00:00", "updated_at": "2026-10-24 21:43:50.864374+00:00", "lang": "en", "topics": ["natural-language-processing", "ai-tools", "machine-learning", "artificial-intelligence"], "entities": ["Chitragupta", "Hugging Face", "XLM-RoBERTa-large", "arunp0", "Aadhaar", "UPI"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/yama-judges-chitragupta-keeps-the-records-open-source-ai-for-indian-languages", "markdown": "https://wpnews.pro/news/yama-judges-chitragupta-keeps-the-records-open-source-ai-for-indian-languages.md", "text": "https://wpnews.pro/news/yama-judges-chitragupta-keeps-the-records-open-source-ai-for-indian-languages.txt", "jsonld": "https://wpnews.pro/news/yama-judges-chitragupta-keeps-the-records-open-source-ai-for-indian-languages.jsonld"}}