""" Hugging Face Space — Indic Language Identifier Supports 12 Indic languages + English. Uses best available model: Ensemble > CharNgram > Unicode Heuristic fallback. """ from __future__ import annotations import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).parent)) import gradio as gr from src.utils.languages import LANGUAGE_REGISTRY, ALL_LANGUAGE_CODES from src.data.preprocessor import IndicTextPreprocessor from src.models.ensemble_model import EnsembleLIDModel, UnicodeHeuristicModel # ── Model Loading ───────────────────────────────────────────────────────────── preprocessor = IndicTextPreprocessor() model = None for mpath in ["./artifacts/models/ensemble.pkl", "./artifacts/models/ngram_model.pkl"]: if Path(mpath).exists(): try: import pickle with open(mpath, "rb") as f: model = pickle.load(f) print(f"✓ Loaded: {mpath}") break except Exception as e: print(f"Could not load {mpath}: {e}") if model is None: model = EnsembleLIDModel() print("⚠ No trained model found — using Unicode heuristic fallback") # ── Inference ───────────────────────────────────────────────────────────────── def predict(text: str) -> str: """Clean inference function: text in → language name out.""" if not text or not text.strip(): return "Please enter some text." processed = preprocessor.preprocess(text) if hasattr(model, "predict_with_confidence"): result = model.predict_with_confidence([processed])[0] lang = result.get("predicted_lang", "?") conf = result.get("confidence", 0.0) elif hasattr(model, "predict"): lang = model.predict([processed])[0] conf = 0.9 else: lang, conf = "eng", 0.5 info = LANGUAGE_REGISTRY.get(lang) name = info.name if info else lang native = info.native_name if info else "" script = info.script if info else "?" direction = info.direction if info else "LTR" confidence_icon = "🟢" if conf > 0.8 else "🟡" if conf > 0.6 else "🔴" return ( f"**{name}** ({native})\n\n" f"Code: `{lang}` | Script: {script} | Direction: {direction}\n\n" f"Confidence: {conf:.2%} {confidence_icon}" ) def predict_detailed(text: str) -> tuple: """Returns (result_markdown, top5_table) for the full UI.""" if not text or not text.strip(): return "Please enter some text.", None processed = preprocessor.preprocess(text) if hasattr(model, "predict_with_confidence"): result = model.predict_with_confidence([processed])[0] lang = result.get("predicted_lang", "?") conf = result.get("confidence", 0.0) top5 = result.get("top_5", []) elif hasattr(model, "predict"): lang = model.predict([processed])[0] conf = 0.9 top5 = [{"lang": lang, "probability": conf}] else: lang, conf = "eng", 0.5 top5 = [] info = LANGUAGE_REGISTRY.get(lang) confidence_icon = "🟢" if conf > 0.8 else "🟡" if conf > 0.6 else "🔴" result_md = f"""### 🎯 {info.name if info else lang} ({info.native_name if info else ''}) | | | |---|---| | Code | `{lang}` | | Script | {info.script if info else '?'} | | Direction | {info.direction if info else 'LTR'} | | Family | {info.family if info else '?'} | | Confidence | {conf:.2%} {confidence_icon} | """ table = None if top5: import pandas as pd rows = [] for t in top5: i = LANGUAGE_REGISTRY.get(t["lang"]) rows.append({ "Language": i.name if i else t["lang"], "Code": t["lang"], "Probability": f"{t['probability']:.2%}", }) table = pd.DataFrame(rows) return result_md, table # ── Sample Texts ────────────────────────────────────────────────────────────── SAMPLES = [ ["भारत एक विशाल देश है जहाँ अनेक भाषाएँ बोली जाती हैं।"], ["বাংলাদেশ এবং পশ্চিমবঙ্গে বাংলা ভাষা প্রচলিত।"], ["தமிழ் மொழி உலகின் மிகவும் பழமையான மொழிகளில் ஒன்றாகும்."], ["India is a diverse country with hundreds of languages."], ["اردو پاکستان کی قومی زبان ہے۔"], ["ಕನ್ನಡ ಭಾಷೆ ಕರ್ನಾಟಕ ರಾಜ್ಯದ ಅಧಿಕೃತ ಭಾಷೆ."], ] # ── Gradio UI ───────────────────────────────────────────────────────────────── with gr.Blocks(title="Indic Language Identifier") as demo: gr.Markdown(""" # 🔤 Indic Language Identifier Detects language from text across **12 Indic languages + English**. Powered by Unicode heuristics + CharNgram ensemble. """) with gr.Row(): with gr.Column(scale=2): text_input = gr.Textbox( label="Input Text", placeholder="Type or paste text in any supported language...", lines=5, ) with gr.Row(): clear_btn = gr.Button("Clear", variant="secondary") detect_btn = gr.Button("🔍 Detect Language", variant="primary") gr.Examples(examples=SAMPLES, inputs=text_input, label="Try a sample") with gr.Column(scale=2): result_md = gr.Markdown(label="Result") top5_table = gr.Dataframe(label="Top Predictions", visible=True) detect_btn.click(fn=predict_detailed, inputs=text_input, outputs=[result_md, top5_table]) clear_btn.click(fn=lambda: ("", None), outputs=[result_md, top5_table]) text_input.submit(fn=predict_detailed, inputs=text_input, outputs=[result_md, top5_table]) gr.Markdown("""--- **Supported languages:** Bengali · English · Gujarati · Hindi · Kannada · Malayalam · Marathi · Odia · Punjabi · Tamil · Telugu · Urdu """) if __name__ == "__main__": demo.launch()