--- 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. [![PyPI](https://img.shields.io/pypi/v/lipika?color=blue&label=pip%20install%20lipika)](https://pypi.org/project/lipika/) [![Python](https://img.shields.io/pypi/pyversions/lipika)](https://pypi.org/project/lipika/) [![License](https://img.shields.io/badge/license-Apache--2.0-green)](https://github.com/Loopdesk-AI/lipika/blob/main/LICENSE) [![Demo](https://img.shields.io/badge/%F0%9F%A4%97%20Space-lipika--demo-yellow)](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} } ```