A newer version of this model is available: sourojitdotcom/AksharaLP-1M-v2

AksharaLP — Hindi transliteration in 4.53 MB

Live demo Core download size Complete download size Parameters On-device License

AksharaLP-1M

This is v1 (1.0.0). AksharaLP-1M-v2 is the recommended version (v2 live demo). Same 989K-parameter core architecture; v2 ships a 3M-word dictionary pack (v1: 1.5M) and a reranker refitted for chat-style spellings (h, nhi, bht).

v1 (this repo) v2
Complete download (gzipped) 4.53 MB 7.92 MB
Aksharantar top-1 / top-3 / top-8 % 70.37 / 87.66 / 92.79 70.04 / 88.31 / 93.63
Core-only top-1 % 53.36 56.01
Dakshina word acc / sentence EM % 87.55 / 21.66 89.02 / 25.70
Chat-spelling sentences, word acc % (480 held-out) 80.16 91.54
Browser latency / word (p50) 219.7 ms 206.0 ms

Numbers from the two model cards; the chat-spelling comparison is from the v2 card. Top-1 on Aksharantar differs by 0.33 points with overlapping 95% CIs ([69.50, 71.26] vs [69.16, 70.90]). Keep using v1 only if the smaller 4.53 MB download matters more than chat-spelling accuracy. v1 stays available for reproducibility.

The world’s 3rd most spoken language, typed on the world’s most used keyboard. In 4.5 MB.

Hindi typed in English letters → Devanagari, fully offline.

Why it matters

🌏 #3 🗣️ 611M 📦 4.5 MB
most spoken language in the world people speak Hindi (first or second language) is all it takes to type it — no server, no GPU

Source: Ethnologue 200 (Ethnologue: Languages of the World, 29th edition, SIL Global), 2026 — https://www.ethnologue.com/insights/ethnologue200/ (accessed 2026-10-31). Counts first- and second-language speakers.

On a Latin (QWERTY) keyboard, Hindi is often typed in English letters: “kal meeting hai, kaise ho?”. AksharaLP-1M turns that into proper Devanagari — accurately, in context, and entirely offline in the browser. It transliterates (changes the script); it does not translate.

AksharaLP-1M is the 989K-parameter member of the AksharaLP family of tiny transliteration models.

For “kal meeting hai, kaise ho?” AksharaLP writes कल मीटिंग है, कैसे हो?, the way a Hindi speaker would. It ships in two tiers: a 0.57 MB core (character Transformer with 989K parameters, reranker and runtime) that works on its own, and a 3.97 MB dictionary pack (1.5M-word lexicon and sentence language model) that the runtime fetches on first use and caches. The complete package is 4.53 MB to download. The complete package is 5× smaller than the model weights of IndicXlit, the most widely used open Indic transliteration model, and 47× smaller than IndicXlit with its rescoring dictionary — while scoring higher top-1 than both on Aksharantar (70.37% vs 59.16% for the model and 69.33% for the full package; the gap to the full package is within overlapping 95% CIs).

Live typing demo
Recorded from the live demo: inference runs in a Web Worker in the browser tab.

Highlights

🪶 Extremely small 0.57 MB core + 3.97 MB dictionary pack = 4.53 MB gzipped (8.69 MB on disk); 989K parameters, 4-bit weights. Fits in a keyboard app, a browser extension or a web page.
🎯 Accurate With the dictionary pack: 70.37% top-1 / 87.66% top-3 on the Aksharantar Hindi test set (9,991 words); 87.55% word accuracy on Dakshina sentences. Core-only numbers are in Variants.
🧠 Context-aware A compact bigram language model picks the right word from its neighbours: the same main becomes मैं or में.
📥 Starts fast, degrades gracefully The core is enough to start typing; the dictionary pack streams in after and is cached. If the pack cannot be fetched, the runtime keeps working with the core alone.
🔒 Private & offline Pure JavaScript, zero dependencies, no server. Nothing you type leaves the device; works offline after first load.
⚡ Fast 219.7 ms per word (p50) in the browser on an 8-vCPU Intel Xeon cloud VM (headless Chrome 156, Linux).

What it brings on-device

Everything below happens on the user’s own phone or laptop: the model is a set of static files plus a dependency-free JavaScript runtime. Each example output was produced by the released runtime when this card was built.

✈️ Fully offline

No network after the first load, so it keeps working in airplane mode, in a lift, or on a train.

flight mein hoon, land karke call karta hoon
→ फ्लाइट में हूं, लैंड करके कॉल करता हूं

🔒 Private by design

Text never leaves the device: no API call, no logging server. Suited to banking, health and personal chat.

mera account balance kitna hai
→ मेरा अकाउंट बैलेंस कितना है
doctor ne din mein do baar dawai lene ko kaha
→ डॉक्टर ने दिन में दो बार दवाई लेने को कहा

🌐 Runs wherever JavaScript runs

A browser tab, an Android or iOS WebView, an installable PWA, or Node.js. CPU only: no GPU, no server, no inference bill.

namaste, aapka swagat hai
→ नमस्ते, आपका स्वागत है

⚡ Real-time, as you type

The sentence is re-decoded on every keystroke in a Web Worker, and earlier words are corrected as context arrives:

main → मैं
main theek → मैं ठीक
main theek hoon → मैं ठीक हूं

Browser latency: 219.7 ms per word (p50) on an 8-vCPU Intel Xeon cloud VM (headless Chrome 156, Linux).

⌨️ Keyboard & input-box integration

Wire it to any <input> or <textarea>: chat, search, forms, CRM notes, customer-support replies. One call per keystroke: transliterate(text, {k}).

aapka refund teen din mein aa jayega
→ आपका रिफंड तीन दिन में आ जाएगा

🏷️ Brands your way

English words inside Hindi sentences are transliterated by the same model. Two writing styles for the same input:

Default → कल व्हाट्सएप पे मीटिंग है
Strict (brands stay in Latin) → कल whatsapp पे मीटिंग है

☰ Top-k suggestions

Ranked candidates for every word, ready for a suggestion bar or candidate picker. Picking one re-decodes the rest of the sentence.

main → मैं · मैन · मेन · माइन · में

📶 Built for Bharat

A 0.57 MB core to start, 4.53 MB in total, downloaded once and cached; after that, patchy or missing connectivity does not matter. Pure JavaScript on the CPU, with no GPU or native code, designed with entry-level Android phones in mind.

signal nahi aa raha, baad mein baat karte hain
→ सिग्नल नही आ रहा, बाद में बात करते हैं

₹0 per call at scale

Inference runs on your users’ devices, so there are no per-request API fees and no GPU servers to scale. Serving is static files from any CDN. Apache-2.0: free for commercial use.

mera order kab tak deliver hoga
→ मेरा ऑर्डर कब तक डिलीवर होगा

Best in class for its size

70.4%

top-1 — higher than IndicXlit (model only) (59.2%)
at 5× smaller · Aksharantar Hindi test

70.4%

top-1 — higher than IndicXlit (full package) (69.3%)
at 47× smaller · Aksharantar Hindi test

8.1 pts/MB

highest top-1 accuracy per MB among compared models
next: IndicXlit (model only) at 1.28 pts/MB

87.7%

right word in the first 3 suggestions — vs 59.2% top-1 for IndicXlit (model only)
Aksharantar Hindi test

87.7%

right word in the first 3 suggestions — vs 69.3% top-1 for IndicXlit (full package)
Aksharantar Hindi test

5×

smaller than IndicXlit (model only)
8.69 MB vs 46.0 MB on disk (fp32 weights)

47×

smaller than IndicXlit (full package)
8.69 MB vs 404 MB on disk (fp32 weights + 358 MB rescoring dictionary)

219.7 ms

per word (p50) in the browser
an 8-vCPU Intel Xeon cloud VM (headless Chrome 156, Linux)

4.53 MB

complete download
core + 1.5M-word dictionary pack · 989K parameters

0.57 MB

to start typing
the core works on its own (53.4% top-1 without the pack); the dictionary pack streams in after and is cached

Accuracy per MB (top-1 on Aksharantar Hindi test ÷ on-disk size; systems measured by us with the same harness):

# System On disk Top-1 % Top-1 pts per MB
1 AksharaLP-1M 8.69 MB 70.37 8.10
2 IndicXlit (model only) 46.0 MB 59.16 1.28
3 IndicXlit (full package) 404 MB 69.33 0.17

🏆 No compared model is both smaller and more accurate: AksharaLP-1M sits on the size–accuracy frontier.

Every tile above is generated by the release build from measured results and shown only if its rule holds (rules and outcomes are logged in the build report).

What it does — real outputs

Every output below was produced by the released runtime (aksharalp.mjs) and the files in this repository when this card was built.

Feature You type AksharaLP writes
Everyday Hindi kaise ho कैसे हो
Everyday Hindi mujhe bhookh lagi hai मुझे भूख लगी है
Context — main = “I” main theek hoon मैं ठीक हूं
Context — main = “in” ghar main kaun hai घर में कौन है
English words in Hindi kal office mein meeting hai कल ऑफिस में मीटिंग है
English words in Hindi whatsapp pe message karo व्हाट्सएप पे मेसेज करो
Acronyms sbi एसबीआई
Acronyms SBI ka ATM kahan hai एसबीआई का एटीएम कहां है
English words please mujhe call karna प्लीज मुझे कॉल करना
Kept as-is @rahul 5 baje milte hain, link: www.example.com @rahul 5 बजे मिलते हैं, लिंक: www.example.com

Two writing styles

The same sentence in each mode:

Mode kal whatsapp pe meeting ka link bhej dena
Default कल व्हाट्सएप पे मीटिंग का लिंक भेज देना
Strict कल whatsapp पे मीटिंग का लिंक भेज देना
  • Default — every word, English ones included, is written in Devanagari.
  • Strict — brand and product names stay in Latin script.

Top-k suggestions

Every word comes with ranked alternatives, ready for a keyboard suggestion bar:

Input 1 2 3 4 5
kaise कैसे केसे कइसे कैस किसे
main मैं मैन मेन माइन में
dhanyavaad धन्यवाद धन्यावाद धन्यवाद् धान्यवाद धन्यवादी

Core only vs. core + dictionary pack

The same inputs through the core alone (pack not loaded) and with the pack, from the released runtime:

You type Core only Core + dictionary pack
main theek hoon मैं थीक हूं मैं ठीक हूं
ghar main kaun hai घर मैं कौं है घर में कौन है
mujhe bhookh lagi hai मुझे भूख लगी है मुझे भूख लगी है
whatsapp pe message karo व्हाटसएप पीई मेसेज करो व्हाट्सएप पे मेसेज करो
doctor ne dawai lene ko kaha डॉक्टर ने दवाई लेने को कह डॉक्टर ने दवाई लेने को कहा

Small by design

Size comparison

What you download:

File What it is On disk gzipped
xlit.q4 core: transliteration Transformer, 4-bit weights 589 KB 544 KB
params.json core: reranker weights + decoding settings 12 KB 5 KB
aksharalp.mjs core: JavaScript runtime (zero dependencies) 52 KB 18 KB
Core total works on its own 0.65 MB 0.57 MB
dict/lex.bin dictionary pack: Hindi lexicon (trie + unigram scores) 5,647 KB 3,137 KB
dict/lm.bin dictionary pack: word-bigram language model, 4-bit 2,373 KB 826 KB
dict/params.json dictionary pack: reranker weights + decoding settings used with the pack 12 KB 5 KB
Dictionary pack total fetched on first use, then cached 8.03 MB 3.97 MB
Complete package core + pack 8.69 MB 4.53 MB

For comparison, IndicXlit’s fp32 model weights are 46.0 MB and its official rescoring dictionary adds another 358 MB. General-purpose LLMs that can transliterate are larger still, with hundreds of millions of parameters or more, and typically need a server or a GPU.

Benchmarks

Accuracy comparison

System Download Aksharantar top-1 % top-3 % top-8 % Dakshina word acc % Dakshina sentence EM % Latency / word (p50)
AksharaLP-1M (core + dictionary pack) 4.53 MB 70.37 [69.50, 71.26] 87.66 92.79 87.55 21.66 219.70 ms browser
IndicXlit (model only) 46.0 MB fp32 weights 59.16 [58.14, 60.13] 79.95 88.29 67.55 6.29 48.4 ms PyTorch CPU
IndicXlit (full package) 404 MB fp32 weights + 358 MB rescoring dictionary 69.33 [68.44, 70.23] 85.40 88.29 — — —

Accuracy versus size

Variants: core only vs. core + dictionary

The dictionary pack is optional. Each row below was scored once on the Aksharantar Hindi test set (9,991 words, beam 8); settings and the size of the smaller dictionary were chosen on the validation set only. The 200K-word pack is measured for comparison but not shipped in this release.

Variant Shipped Download (gz) On disk Test top-1 % [95% CI] top-3 % top-8 % Val top-1 % (2-fold CV) Test top-1 % with test words removed from the dictionary Dakshina sentences word acc %
Core only yes 0.57 MB 0.65 MB 53.36 [52.36, 54.32] 74.52 83.81 53.92 — 65.35
Core + 200K-word dictionary no (measured only) 1.13 MB 1.76 MB 68.38 [67.48, 69.30] 85.70 91.58 67.35 33.33 86.89
Core + 1.5M-word dictionary pack yes 4.53 MB 8.69 MB 70.37 [69.50, 71.26] 87.66 92.79 69.30 19.65 87.55

The “test words removed” column re-runs the same system with every Aksharantar test reference word deleted from the dictionary, so the dictionary cannot simply look up the answer; it shows how much of the gain comes from dictionary coverage (see the caveat below). Dakshina sentences: 4,976 romanized sentences.

How we measured. All systems were run by us on the same machine with the same scoring script (Unicode NFC, punctuation and danda normalised). Word-level: Aksharantar Hindi test set, 9,991 unique romanized words, beam 8 for every system; top-k = the reference appears among the first k candidates. Sentence-level: Dakshina romanized Hindi sentences (4,976 sentences); word accuracy, sentence exact match, CER and WER. IndicXlit “model only” is the released transformer checkpoint; “full package” adds rescoring with the official 4.2M-word dictionary (α = 0.9; our re-implementation of the released engine, which reproduces the published scores). Browser latency is per word with the dictionary pack loaded, single tab, measured in headless Chrome on an 8-vCPU Intel Xeon cloud VM (headless Chrome 156, Linux); IndicXlit latency is PyTorch fp32 on one CPU thread and is shown for reference only (different runtime).

Caveat. IndicXlit was trained on Aksharantar, so its Aksharantar test scores may benefit from train/test overlap. Our training pairs contain no Aksharantar test or validation native words (checked). The 1.5M-word dictionary pack is built from IndicCorp v2 text and naturally contains most test words: with every test reference word removed from the dictionary the same system scores 19.65% top-1 (47.27% top-3, 73.06% top-8), and the core alone scores 53.36% top-1. All tuning, the reranker fit and the choice of dictionary size used the validation set only; each test number comes from a single run.

Quickstart

Browser (ES module)

<script type="module">
  import { AksharaLP } from "https://huggingface.co/sourojitdotcom/AksharaLP-1M/resolve/main/aksharalp.mjs";

  const base = "https://huggingface.co/sourojitdotcom/AksharaLP-1M/resolve/main/";
  // core first (0.57 MB): usable immediately
  const aklp = await AksharaLP.load(base, { dict: false });
  // then the dictionary pack (3.97 MB): fetched once, kept in the Cache API; false = stays core-only
  const ok = await aklp.loadDict();
  const r = aklp.transliterate("kal meeting hai, kaise ho?");
  console.log(r.output);                       // कल मीटिंग है, कैसे हो? (with the pack)
  console.log(r.tokens[0].candidates);         // ranked alternatives for the first word
</script>

AksharaLP.load(base) without options loads the core and the pack together. For production, copy the files (including dict/) into your app and load them from your own origin (they are static and cache well); run the model in a Web Worker as the demo Space does.

Node.js (≥ 18)

hf download sourojitdotcom/AksharaLP-1M --local-dir aksharalp
import { loadFromDir } from "./aksharalp/aksharalp.mjs";

const aklp = await loadFromDir("./aksharalp/");            // core + dict/ pack; { dict: false } for core only
console.log(aklp.transliterate("main theek hoon", { mode: "conversational" }).output);   // मैं ठीक हूं
console.log(aklp.word("kaise", 5));                                                      // top-5 candidates with scores

Python (reference implementation)

from huggingface_hub import snapshot_download
import sys

path = snapshot_download("sourojitdotcom/AksharaLP-1M")
sys.path.insert(0, f"{path}/python")
from bhc.translit2 import BhcTranslit2          # needs numpy + torch (CPU)

xl = BhcTranslit2(path)                         # use_dict=False for core only
print(xl.convert("kal meeting hai, kaise ho?"))
print(xl.translit_words(["kaise", "namaste"], k=5))

The Python package is the reference used for training and evaluation; the JavaScript runtime reproduces it exactly (JS/Python parity test — core only: identical candidate sets and top-1 for 196/196 words, max feature difference 9.1e-06; with the dictionary pack: identical candidate sets and top-1 for 196/196 words, max feature difference 3.2e-05).

API at a glance

Call Returns
AksharaLP.load(baseUrl, {dict, cache}) engine (fetches manifest.json and the core; with dict: true, the default, also the dictionary pack)
loadDict({cache}) fetches the dictionary pack (Cache API name "aksharalp-dict" by default) and attaches it; returns false and keeps the core working if it fails
attachDict({lex, lm, params}) attaches a pack you fetched yourself (e.g. from IndexedDB or app assets)
transliterate(text, {mode, context, k, overrides}) {output, tokens[], ms}; each token has text, output, source, candidates[]; mode is "conversational" (default) or "strict"
word(romanWord, k) top-k {text, score} for one word
info() parameter count, lexicon size, bytes on disk / gzipped, hasDict, dictError

overrides pins a user-chosen suggestion ({tokenStartOffset: "मैं"}) and re-decodes the rest of the sentence around it.

How it works

Architecture

flowchart LR
    A["Romanized Hindi text"] --> T["① Tokenizer<br/>URLs, @mentions, numbers kept"]
    T -->|Strict mode: brand| P["kept in Latin"]
    T -->|word| X["② Char Transformer (core)<br/>d=128, 3+2 layers, 4 heads, FFN 384 · 4-bit · 989K"]
    X --> C["Candidates<br/>free beam + acronyms<br/>(+ lexicon-trie beam + skeleton lookups with the pack)"]
    C --> R["Learned reranker<br/>24-feature MLP"]
    R --> V["③ Sentence Viterbi (pack)<br/>bigram LM · 1.5M words"]
    P --> V
    V --> O["Devanagari + top-k"]
  1. Tokenizer. Splits words, numbers and punctuation; URLs, e-mail addresses and @mentions are kept as typed.
  2. Transliteration (core). A character-level encoder–decoder Transformer (d=128, 3+2 layers, 4 heads, FFN 384) proposes spellings with a free beam; letter-name acronyms are added and scored by the same model. With the dictionary pack, a second beam constrained to the 1.5M-word Hindi lexicon trie and consonant-skeleton lookups add in-vocabulary candidates. A small learned reranker (24 features → 16 hidden units → 1, fitted on the validation set) orders the candidates; the core and the pack each carry their own reranker weights.
  3. Sentence context (pack). A 4-bit quantized word-bigram language model (300K bigrams) runs Viterbi over the candidate lattice to choose the most fluent sentence. Core-only mode picks each word independently.

English words inside Hindi sentences go through the same model (Default) or, for brand names, stay in Latin script (Strict).

Files

File Contents
xlit.q4 core: transliteration Transformer, 4-bit weights
params.json core: reranker weights + decoding settings
dict/lex.bin dictionary pack: Hindi lexicon (trie + unigram scores)
dict/lm.bin dictionary pack: word-bigram language model, 4-bit
dict/params.json dictionary pack: reranker weights + decoding settings used with the pack
manifest.json file list, sizes, checksums (core + pack)
aksharalp.mjs core: JavaScript runtime (zero dependencies)
aksharalp.min.mjs same runtime, minified (attribution header preserved)
python/ reference Python implementation (numpy + PyTorch)
LICENSE, NOTICE Apache-2.0 and third-party attributions

Intended use

  • Hindi input methods: mobile and desktop keyboards, browser extensions, chat and messaging apps, search boxes.
  • Converting romanized Hindi text (chat logs, social posts, transcripts) to Devanagari for downstream NLP.
  • Privacy-sensitive or offline settings where text must not leave the device.

Limitations

  • Hindi only. Other Indic languages and scripts are not supported.
  • Names and rare words. Proper nouns, rare or very long words, and unusual spellings are the main source of errors. Check the top-k list.
  • Ambiguity. Some romanizations have several valid Devanagari spellings (e.g. हूं / हूँ). The model follows the most common written form, which may differ from a reference.
  • Short context. The language model sees one word on each side (bigram), so long-range agreement is not modelled.
  • Core only is less accurate. Without the dictionary pack, top-1 accuracy drops substantially (see Variants). Load the pack when you can.
  • Dictionary coverage. Much of the accuracy with the pack comes from the lexicon: with every test reference word removed from it, top-1 falls well below the core-only score. Words outside the lexicon (new names, slang, rare spellings) are harder.
  • English words and language tags. This release has no word-level language identifier and no loanword lexicon: English words are transliterated phonetically by the same model and can look unusual, and tokens are not tagged Hindi / English.
  • Short ambiguous words. Without a loanword lexicon, short words that are both English and Hindi can go the wrong way in context (for example, in our tests call sometimes came out as कल and do as डॉ). Check the top-k list.
  • Chat-speak. Heavy abbreviation (e.g. kr, rhe, btw) is handled only partly.
  • Speed depends on the device. Very old phones may see higher per-word latency than reported here.

License & attribution

Commercial use is allowed. Code and model weights are released under the Apache License 2.0 (see LICENSE), Copyright 2026 Sourojit Dhua. You may use, modify and ship AksharaLP-1M in commercial products, free of charge.

Attribution is required when you redistribute it. Apache-2.0 §4(d) requires every redistribution of the model or a derivative (shipping the files in an app, web page, browser extension or SDK; publishing a fine-tuned, quantized or converted version) to include the NOTICE file, and the JavaScript runtime keeps its /*! … */ attribution header, including the minified aksharalp.min.mjs. Please use this attribution text:

Transliteration by AksharaLP (Sourojit Dhua) — https://huggingface.co/sourojitdotcom/AksharaLP-1M

Recommended in-app credit (About, Settings or Licenses screen):

Hindi typing powered by <a href="https://huggingface.co/sourojitdotcom/AksharaLP-1M">AksharaLP by Sourojit Dhua</a>

Third-party data used to build the model is credited in NOTICE:

Source License Used for
Aksharantar (AI4Bharat) CC0 (mined data) / CC-BY (manually collected data) romanized ↔ Devanagari training pairs
IndicXlit (AI4Bharat) MIT teacher model for distillation
IndicCorp v2 (AI4Bharat) CC0 Hindi lexicon and bigram language model
CMUdict (Carnegie Mellon University) BSD-2-Clause-style English word cues

Fonts in the demo Space (Inter, Noto Sans Devanagari) are under the SIL Open Font License 1.1.

Citation

@software{dhua_aksharalp_2026,
  author    = {Dhua, Sourojit},
  title     = {{AksharaLP}: Tiny, Context-Aware Hindi Transliteration for the Browser},
  year      = {2026},
  version   = {1.0.0},
  url       = {https://huggingface.co/sourojitdotcom/AksharaLP-1M},
  license   = {Apache-2.0}
}

AksharaLP · v1.0.0 · built 2026-10-31 · Questions and feedback: open a discussion on this repository.

Downloads last month
18
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Datasets used to train sourojitdotcom/AksharaLP-1M

Space using sourojitdotcom/AksharaLP-1M 1

Evaluation results