| --- |
| license: apache-2.0 |
| library_name: pytorch |
| pipeline_tag: image-classification |
| language: |
| - hi |
| - mr |
| - ne |
| - sa |
| - bn |
| - as |
| - pa |
| - gu |
| - or |
| - ta |
| - te |
| - kn |
| - ml |
| - ur |
| - sat |
| - mni |
| - en |
| tags: |
| - font-identification |
| - font-recognition |
| - indic |
| - typography |
| - devanagari |
| - tamil |
| - bengali |
| - telugu |
| - ocr |
| - convnext |
| --- |
| |
| # Lipika — Indic Font Recognizer |
|
|
| **लिपिका — "the scribe."** Upload an image of Indian-script text; Lipika tells you the font |
| family, weight, and style — and hands you a hosted WOFF2 URL so you can use the font |
| immediately. |
|
|
| [](https://pypi.org/project/lipika/) |
| [](https://pypi.org/project/lipika/) |
| [](https://github.com/Loopdesk-AI/lipika/blob/main/LICENSE) |
| [](https://huggingface.co/spaces/anilpai/lipika-demo) |
|
|
| Developed & maintained by **[Loopdesk](https://huggingface.co/loopdesk-ai)**. |
|
|
| 🎮 **[Try the live demo](https://huggingface.co/spaces/anilpai/lipika-demo)** · |
| 📦 **[PyPI: `pip install lipika`](https://pypi.org/project/lipika/)** · |
| 📊 **[Eval dataset](https://huggingface.co/datasets/loopdesk-ai/lipika-eval)** · |
| 💻 **[Code on GitHub](https://github.com/Loopdesk-AI/lipika)** |
|
|
| ## Why this exists |
|
|
| India writes in **22 scheduled languages across ~12 major scripts**, and its internet has |
| decisively gone Indic: of [**886M+ active internet users** (IAMAI–Kantar, 2024)](https://www.ibef.org/news/india-s-internet-users-to-exceed-900-million-in-2025-driven-by-indic-languages), |
| **~98% consume content in Indian languages**. The visual culture riding on these scripts is |
| the largest in the world: |
|
|
| - the **largest film industry on earth** — [1,700–2,400 releases a year in 20+ languages](https://en.wikipedia.org/wiki/Cinema_of_India), |
| every one with posters, title cards and lyric videos set in Indic display type; |
| - the **largest newspaper market on earth** — [240M+ copies in daily circulation](https://en.wikipedia.org/wiki/List_of_newspapers_in_India) |
| across 100,000+ registered publications, most of them not in English; |
| - packaging, street signage, election material, devotional publishing, meme culture — all set |
| in Devanagari, Bengali, Tamil, Telugu, and their siblings. |
|
|
| Yet point any mainstream font identifier at a Hindi movie title and it fails outright. |
| **WhatTheFont, Fontspring Matcherator, and Adobe Match Font** are trained on overwhelmingly |
| Latin catalogs; academic prior art is Latin-only ([DeepFont](https://arxiv.org/abs/1507.03196), |
| Adobe 2015) or ships zero Indic families (mixfont: 983 classes, 0 Indic). Indic type also |
| poses problems Latin tools never see: conjunct ligatures and matras reshape glyphs by context |
| (HarfBuzz shaping), sibling families are near-identical (the Baloo superfamily alone ships |
| 10 script variants), and headline styles routinely stack outlines, gradients and 3D extrusion. |
|
|
| India adds one more twist that makes *visual* font ID uniquely necessary here: the |
| **legacy-encoding ecosystem**. Government offices, courts and Hindi DTP shops still run on |
| non-Unicode fonts — [several states' official typing exams still test in Kruti Dev](https://en.wikipedia.org/wiki/Kruti_Dev) — |
| which map Devanagari glyphs onto ASCII codepoints. The underlying bytes of those documents |
| are meaningless unless you know the font, so recognizing **Kruti Dev, DevLys and friends from |
| pixels alone** (which Lipika does out of the box) is the entry point to reading them at all. |
|
|
| ## Why Loopdesk built this |
|
|
| [**Loopdesk**](https://huggingface.co/loopdesk-ai) is an **agentic video editor — built from |
| India, for the world** — and one of the first editors to support practically **every free |
| Indic font** on its platform. |
|
|
| Our pipeline analyses **millions of video frames every second**. When a creator's footage |
| contains Indic text — a title card, a lower third, a poster inside the shot — the editor |
| needs to know *which font that is* so it can load the matching free font and keep the |
| design consistent through edits. No existing tool could answer that for Indic scripts, so we |
| trained our own on every free Indic font we could source (563 families and counting) and |
| open-sourced it, because the gap is much bigger than one product. |
|
|
| ## What you could build with it |
|
|
| - **A "WhatTheFont for Indic" browser extension** — right-click any image on the web (movie |
| poster, meme, news graphic), get the family + a WOFF2 URL for an instant in-page preview. |
| Inference runs on CPU in seconds. |
| - **Movie-poster & title-card analysis** — catalogue the typography of 1,700+ Indian film |
| releases a year, or match a classic poster's lettering to a usable free font. |
| - **Font-aware OCR & archive digitization** — detect the family *before* OCR on newspapers |
| and magazines; on legacy pages (Kruti Dev/DevLys), where the text bytes are unreadable |
| without the font, Lipika identifies the encoding and the bundled `krutidev → Unicode` |
| converter makes the text recoverable. |
| - **Design & localization tooling** — recreate a look from a screenshot; find the |
| visually-nearest *free* alternative to a proprietary font via the retrieval embeddings. |
| - **Brand & typography audits** — flag off-brand or unlicensed fonts across thousands of |
| creatives in Indic markets. |
| - **Document forensics** — spot anachronistic or mismatched fonts in scanned |
| Hindi/Tamil/Bengali documents. |
| - **Font search & pairing engines** — the embedding space gives you "fonts that look like |
| this" for free. |
|
|
| **Want to build an Indic font *generator*?** We'd love to help — start a thread on the |
| [Community tab](https://huggingface.co/loopdesk-ai/lipika/discussions) or |
| [GitHub issues](https://github.com/Loopdesk-AI/lipika/issues). |
|
|
| ## What it does |
|
|
| | Output | Detail | |
| |---|---| |
| | `family` | Top-k over **563 font families** (Google Fonts Indic, SMC, Ekushey, ITF free fonts, CDAC Unicode, legacy Kruti Dev/DevLys series, …) | |
| | `script` | 13-way: Devanagari, Bengali, Gujarati, Gurmukhi, Kannada, Malayalam, Meetei Mayek, Odia, Ol Chiki, Perso-Arabic, Tamil, Telugu (+ Latin OOD class) | |
| | `weight` / `italic` | Continuous weight regression snapped to 100–900 buckets; italic flag | |
| | `woff2_url` | Hosted webfont for the match — jsDelivr/Fontsource CDN or this repo's [`fonts/`](./tree/main/fonts) | |
| | open-set flag | Retrieval index (1,194 prototypes) with per-family calibrated thresholds flags fonts **not in the catalog** instead of guessing | |
|
|
| ## Metrics (v2.4) |
|
|
| | Eval set | family top-1 | top-5 | script | weight MAE | |
| |---|---|---|---|---| |
| | Synthetic val (6,960 crops, all 563 families) | 0.849 | 0.977 | 0.991 | 60 | |
| | Real-world R1 (2,433 crops) | **0.895** | 0.965 | 0.970 | 52 | |
| | Display-styled val | 0.838 | 0.971 | 0.989 | 63 | |
| | Small-pixel val (12–24 px body text) | 0.841 | 0.977 | 0.988 | 60 | |
| | Retrieval top-1 (real R1) | 0.884 | 0.967 | — | — | |
|
|
| Architecture: `convnextv2_tiny` (28.3M params) backbone + multi-head (family softmax w/ |
| ArcFace training, script, weight regression, italic) + cosine-similarity retrieval index for |
| open-set detection. Trained on-the-fly-rendered synthetic text (HarfBuzz shaping, heavy |
| augmentation: display styles, fake-fat, condense, small-px, polarity mix) + 25% real crops. |
|
|
| ## Usage |
|
|
| ```bash |
| pip install lipika |
| ``` |
|
|
| ```python |
| from PIL import Image |
| from fontrecog.infer.predictor import Predictor |
| |
| predictor = Predictor.from_pretrained("loopdesk-ai/lipika") |
| result = predictor.predict(Image.open("hindi_poster.png")) |
| |
| print(result["script"]) # "devanagari" |
| print(result["predictions"][0]) # {"family": "Kruti Dev 010", "confidence": 0.71, |
| # "weight": 400, "italic": False, |
| # "woff2_url": "https://huggingface.co/loopdesk-ai/lipika/resolve/main/fonts/kruti-dev-010-400.woff2", ...} |
| print(result["retrieval"]["unknown_font"]) # True => not in the 563-family catalog |
| ``` |
|
|
| Inference runs fine on CPU (a few seconds per image, patch-voting); CUDA/MPS used |
| automatically when available. |
|
|
| ### Free hosted API |
|
|
| No model download needed — the [demo Space](https://huggingface.co/spaces/anilpai/lipika-demo) |
| doubles as a free API for prototypes: |
|
|
| ```python |
| from gradio_client import Client, handle_file # pip install gradio_client |
| |
| client = Client("anilpai/lipika-demo") |
| _, result = client.predict(handle_file("hindi_text.png"), api_name="/recognize") |
| print(result["predictions"][0]["family"]) |
| ``` |
|
|
| Runnable examples (local + hosted): |
| [`examples/`](https://github.com/Loopdesk-AI/lipika/tree/main/examples). |
|
|
| ## Fonts & licensing |
|
|
| - **Model weights: Apache-2.0.** |
| - The model is trained **only on freely available fonts** (OFL/GPL+FE/Apache Google Fonts, |
| SMC, Ekushey, CDAC Unicode releases, and freely distributed legacy families), plus a small |
| number of proprietary system fonts included **for recognition only** — those are never |
| redistributed and have no hosted files. |
| - The [`fonts/`](./tree/main/fonts) directory hosts WOFF2s **only for freely redistributable |
| families** (434 files); each font remains under its own upstream license (OFL, GPL+FE, |
| freeware). CDN-hosted families (Google Fonts) link to Fontsource/jsDelivr instead. |
|
|
| ## Repo layout |
|
|
| ``` |
| model.safetensors # inference weights (28.3M params) |
| config.json # backbone, n_families, n_scripts, metrics |
| label_map.json # 563 families, 13 scripts, weight/italic spec |
| index/ # retrieval prototypes + per-family calibrated thresholds |
| asset_urls.csv # family/weight/italic -> hosted WOFF2 URL table |
| fonts/ # 434 self-hosted WOFF2s (redistributable families only) |
| ``` |
|
|
| ## Citation |
|
|
| ```bibtex |
| @software{lipika2026, |
| title = {Lipika: Indic Font Recognition}, |
| author = {Loopdesk}, |
| year = {2026}, |
| url = {https://huggingface.co/loopdesk-ai/lipika} |
| } |
| ``` |
|
|