""" Urdu Education & Reasoning — Gemma-3-4B adapted to Urdu via Adaption AutoScientist. A compelling results page + live demo, served on HF ZeroGPU. """ import os, spaces, gradio as gr, torch from threading import Thread from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer MODEL = os.environ.get("MODEL_REPO", "abdullah693/gemma-3-4b-it-urdu-edu-reasoning") print("loading model on cuda (module level for ZeroGPU)...", flush=True) tokenizer = AutoTokenizer.from_pretrained(MODEL) model = AutoModelForCausalLM.from_pretrained(MODEL, device_map="cuda", torch_dtype=torch.bfloat16) model.eval() print("ready", flush=True) @spaces.GPU(duration=120) def respond(message, history, max_tokens, temperature): msgs = [] for u, a in history: msgs.append({"role": "user", "content": u}) if a: msgs.append({"role": "assistant", "content": a}) msgs.append({"role": "user", "content": message}) enc = tokenizer.apply_chat_template(msgs, add_generation_prompt=True, return_tensors="pt", return_dict=True).to(model.device) streamer = TextIteratorStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True) Thread(target=model.generate, kwargs=dict(**enc, streamer=streamer, max_new_tokens=int(max_tokens), do_sample=temperature > 0, temperature=temperature if temperature > 0 else None, repetition_penalty=1.1, pad_token_id=tokenizer.pad_token_id or tokenizer.eos_token_id)).start() out = "" for t in streamer: out += t; yield out CSS = """ @import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@700&family=Inter:wght@400;500;600&display=swap'); .gradio-container{max-width:1000px!important;margin:0 auto!important} #hero{position:relative;border-radius:20px;overflow:hidden;margin-bottom:14px; background:linear-gradient(135deg,#01411C 0%,#0a7a43 55%,#01411C 100%);box-shadow:0 14px 40px rgba(1,40,20,.35)} #hero .in{padding:38px 26px;text-align:center;color:#fff} #hero h1{font-family:'Playfair Display',serif;font-size:2.4rem;margin:.1em 0;color:#fff;line-height:1.1} #hero h1 .a{color:#e9c75a} #hero p{font-family:'Inter',sans-serif;font-size:1.05rem;color:#fff;opacity:1;max-width:680px;margin:10px auto;text-shadow:0 1px 4px rgba(0,0,0,.4)} #hero .badges{display:flex;gap:8px;justify-content:center;flex-wrap:wrap;margin-top:14px} #hero .b{font-family:'Inter';font-size:.8rem;color:#06301c;background:#e9c75a;font-weight:600;padding:5px 13px;border-radius:999px} .sec{font-family:'Inter',sans-serif} .sec h2{font-family:'Playfair Display',serif;color:#01411C;font-size:1.5rem;margin:.2em 0 .1em} .kpi{display:flex;gap:10px;flex-wrap:wrap;justify-content:center;margin:6px 0 2px} .kpi .c{background:#f3f8f4;border:1px solid #d8e6dc;border-radius:14px;padding:12px 18px;text-align:center;min-width:120px} .kpi .v{font-size:1.7rem;font-weight:700;color:#0a7a43;font-family:'Inter'} .kpi .l{font-size:.78rem;color:#555} .note{background:#fbf6e9;border:1px solid #ecdfb8;border-radius:12px;padding:12px 16px;font-family:'Inter';font-size:.92rem;color:#4a4a4a} #foot{font-family:'Inter';font-size:.8rem;color:#888;text-align:center;margin-top:16px;line-height:1.7} #foot a{color:#0a7a43;text-decoration:none;font-weight:500} /* force visible (dark) text in light boxes regardless of light/dark theme */ .note,.note *{color:#3a3a3a!important} .note b,.note strong{color:#01411C!important;font-weight:700} .sec h2{color:#01411C!important} .sec p,.sec p *{color:#26332b!important} .sec p b,.sec p strong{color:#01411C!important} .kpi .v{color:#0a7a43!important}.kpi .l{color:#555!important} #foot,#foot *{color:#7a7a7a!important}#foot a{color:#0a7a43!important} #hero p,#hero p *,#hero h1{color:#fff!important}#hero h1 .a{color:#e9c75a!important} """ HERO = """

اردو Education & Reasoning

A Gemma-3-4B model adapted to Urdu by translating English knowledge corpora into Urdu with Adaption AutoScientist, then benchmarked on UrduMMLU.

Gemma-3-4BAdaption AutoScientist UrduMMLU 46.2%+1.3 vs base
""" KPI = """
+5.9
STEM (pts)
+3.6
Profession
+2.7
Social Sci.
46.2%
UrduMMLU overall
+1.3
vs base overall
""" VALIDATED = """

What this validates

We tested whether adapting English knowledge corpora into Urdu with Adaption AutoScientist improves a 4B model on a native Urdu benchmark. It does, for knowledge that is language-independent: every such domain improved and the model exceeded its base overall (44.96% to 46.21%). The effect does not extend to Urdu literature, which is intrinsic to the language and requires native data rather than translation.

""" APPROACH = """

Method

Most UrduMMLU subjects test knowledge that is largely language-independent: science, mathematics, reasoning, and social studies. We assembled about 40,000 examples from open English datasets covering these subjects, together with native-Urdu instruction and literature data, then used Adaption AutoScientist and the Adaptive Data pipeline to translate and localise each example into Pakistani Urdu, adding a reformulated prompt and an English reasoning trace. Gemma-3-4B was supervised-fine-tuned on the result and evaluated on UrduMMLU, zero-shot.

""" FINDING = """
Boundary of the method. Cross-lingual adaptation improved the science, mathematics, reasoning, and social-knowledge domains, but Urdu literature declined by 2.5 points. That content cannot be produced by translating English sources; improving it requires native Urdu literary data. This is a limitation of available data, not of the adaptation method.
""" FOOT = """""" EXAMPLES = [ "اگر ایک ٹرین 60 کلومیٹر فی گھنٹہ کی رفتار سے 2.5 گھنٹے چلے تو کتنا فاصلہ طے کرے گی؟", "ایک دکاندار نے 500 روپے کی چیز پر 20 فیصد رعایت دی۔ گاہک کو اب کتنے روپے ادا کرنے ہوں گے؟", "مشاعرہ کیا ہوتا ہے اور اردو ثقافت میں اس کی کیا اہمیت ہے؟", "تعلیم کسی معاشرے کی ترقی میں کیا کردار ادا کرتی ہے؟ مختصر وضاحت کریں۔", "نظامِ شمسی میں کتنے سیارے ہیں اور سب سے بڑا سیارہ کون سا ہے؟", ] with gr.Blocks(title="Urdu Education & Reasoning", theme=gr.themes.Soft(primary_hue="emerald"), css=CSS) as demo: gr.HTML(HERO) # ── chat front and centre ── gr.HTML('

Try it — اردو میں سوال پوچھیں

') with gr.Accordion("⚙️ settings", open=False): mt = gr.Slider(64, 512, value=256, step=32, label="Max new tokens") tp = gr.Slider(0.0, 1.0, value=0.0, step=0.1, label="Temperature") gr.ChatInterface(respond, additional_inputs=[mt, tp], examples=[[e] for e in EXAMPLES], cache_examples=False) # ── what we validated ── gr.HTML('
') gr.HTML(VALIDATED) gr.HTML(KPI) gr.Image("assets/fig_validated.png", show_label=False, container=False) # ── results ── gr.HTML('

Results on UrduMMLU

') with gr.Row(): gr.Image("assets/fig_overall.png", show_label=False, container=False) gr.Image("assets/fig_domains.png", show_label=False, container=False) # ── method ── gr.HTML(APPROACH) gr.Image("assets/fig_pipeline.png", show_label=False, container=False) gr.Image("assets/fig_data.png", show_label=False, container=False) gr.HTML(FINDING) gr.HTML(FOOT) if __name__ == "__main__": demo.queue().launch()