Downloads · 30 days
37
28% of all-time downloads
loopdesk-ai/lipika
lipika is a image classification model from loopdesk-ai. Use it when you need a label for an image. It is set up for pytorch. The card lists the license as apache-2.0.
लिपिका, "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.
Downloads · 30 days
37
28% of all-time downloads
All-time downloads
134
Public
Parameters
28.3M
362 MB on disk
Likes
2
Public
Click a slice to open those files.
.safetensors113 MB · 79%
From the Hugging Face model README
लिपिका, "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.
Developed & maintained by Loopdesk.
🎮 Try the live demo ·
📦 PyPI: pip install lipika ·
📊 Eval dataset ·
💻 Code on GitHub
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), ~98% consume content in Indian languages. The visual culture riding on these scripts is the largest in the world:
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, 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) 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.
Loopdesk 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 (595 families and counting) and open-sourced it, because the gap is much bigger than one product.
krutidev → Unicode
converter makes the text recoverable.Want to build an Indic font generator? We'd love to help. Start a thread on the Community tab or GitHub issues.
| Output | Detail |
|---|---|
family | Top-k over 595 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/ |
| open-set flag | Retrieval index (1,260 prototypes) with per-family calibrated thresholds flags fonts not in the catalog instead of guessing |
| Eval set | family top-1 | top-5 | script | weight MAE |
|---|---|---|---|---|
| Synthetic val (7,374 crops, all 595 families) | 0.861 | 0.980 | 0.990 | 57 |
| Real-world R1 (2,433 crops) | 0.894 | 0.966 | 0.973 | 52 |
| Display-styled val | 0.842 | 0.976 | 0.987 | 62 |
| Small-pixel val (12–24 px body text) | 0.854 | 0.976 | 0.989 | 56 |
| Retrieval top-1 (real R1) | 0.888 | 0.967 | n/a | n/a |
| IndicSTR12 scene-text script ID (1,650 crops) | n/a | n/a | 0.855 | n/a |
v2.6 adds real scene-text supervision: script ID on the IndicSTR12 benchmark (photos of storefronts, signboards and banners) jumped from 0.567 to 0.855 over v2.5.
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.
pip install lipika
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 595-family catalog
Inference runs fine on CPU (a few seconds per image, patch-voting); CUDA/MPS used automatically when available.
No model download needed. The demo Space doubles as a free API for prototypes:
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/.
fonts/ directory hosts WOFF2s only for freely redistributable
families (468 files); each font remains under its own upstream license (OFL, GPL+FE,
freeware). CDN-hosted families (Google Fonts) link to Fontsource/jsDelivr instead.model.safetensors # inference weights (28.3M params)
config.json # backbone, n_families, n_scripts, metrics
label_map.json # 595 families, 14 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)
@software{lipika2026,
title = {Lipika: Indic Font Recognition},
author = {Loopdesk},
year = {2026},
url = {https://huggingface.co/loopdesk-ai/lipika}
}