Spaces:
Sleeping
Sleeping
| """ | |
| Indic Multilingual Assistant โ Demo & Training Space | |
| ===================================================== | |
| - On CPU: Shows project info + provides Colab training link | |
| - On ZeroGPU (Pro): Full training + inference | |
| """ | |
| import os | |
| import json | |
| import time | |
| import traceback | |
| import gradio as gr | |
| try: | |
| import spaces | |
| HAS_SPACES = True | |
| except ImportError: | |
| HAS_SPACES = False | |
| HAS_GPU = False | |
| try: | |
| import torch | |
| HAS_GPU = torch.cuda.is_available() | |
| except: | |
| pass | |
| MODEL_ID = "Qwen/Qwen2.5-3B-Instruct" | |
| DATASET_ID = "kshitij230/indic-assistant-training-data" | |
| HUB_MODEL_ID = "kshitij230/indic-general-assistant-3b-v1" | |
| SYSTEM_PROMPT = ( | |
| "You are a helpful multilingual assistant for Indian users. " | |
| "You understand Hindi, English, and other Indian languages. " | |
| "Always respond in the same language the user writes in. " | |
| "For code-mixed queries, respond naturally in code-mixed style." | |
| ) | |
| COLAB_NOTEBOOK = """ | |
| # ๐ฎ๐ณ Indic Multilingual Assistant โ Training Notebook | |
| # Run this on Google Colab (free T4 GPU) | |
| # Go to: https://colab.research.google.com โ New Notebook โ Runtime โ Change runtime type โ T4 GPU | |
| !pip install -q transformers trl peft bitsandbytes accelerate datasets huggingface_hub | |
| import torch, json, os | |
| from datasets import Dataset | |
| from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig | |
| from peft import LoraConfig | |
| from trl import SFTTrainer, SFTConfig | |
| from huggingface_hub import hf_hub_download, HfApi, login | |
| # LOGIN - paste your HF token (get from https://huggingface.co/settings/tokens) | |
| login(token="YOUR_HF_TOKEN_HERE") | |
| # Load dataset | |
| train_path = hf_hub_download(repo_id="kshitij230/indic-assistant-training-data", filename="train_data_small.jsonl", repo_type="dataset") | |
| eval_path = hf_hub_download(repo_id="kshitij230/indic-assistant-training-data", filename="eval_data_small.jsonl", repo_type="dataset") | |
| def load_jsonl(path): | |
| data = [] | |
| with open(path, "r") as f: | |
| for line in f: | |
| item = json.loads(line.strip()) | |
| data.append({"messages": item["messages"]}) | |
| return Dataset.from_list(data) | |
| train_dataset = load_jsonl(train_path) | |
| eval_dataset = load_jsonl(eval_path) | |
| print(f"Train: {len(train_dataset)}, Eval: {len(eval_dataset)}") | |
| # Load model with 4-bit quantization | |
| bnb_config = BitsAndBytesConfig( | |
| load_in_4bit=True, bnb_4bit_quant_type="nf4", | |
| bnb_4bit_use_double_quant=True, bnb_4bit_compute_dtype=torch.bfloat16, | |
| ) | |
| tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-3B-Instruct") | |
| tokenizer.padding_side = "right" | |
| if tokenizer.pad_token is None: tokenizer.pad_token = tokenizer.eos_token | |
| model = AutoModelForCausalLM.from_pretrained( | |
| "Qwen/Qwen2.5-3B-Instruct", quantization_config=bnb_config, | |
| device_map="auto", torch_dtype=torch.bfloat16, | |
| ) | |
| # LoRA config | |
| peft_config = LoraConfig( | |
| r=16, lora_alpha=32, lora_dropout=0.05, bias="none", task_type="CAUSAL_LM", | |
| target_modules=["q_proj","k_proj","v_proj","o_proj","gate_proj","up_proj","down_proj"], | |
| ) | |
| # Training config | |
| training_args = SFTConfig( | |
| output_dir="./indic-assistant-qlora", | |
| max_length=2048, packing=True, | |
| num_train_epochs=3, | |
| per_device_train_batch_size=2, gradient_accumulation_steps=4, | |
| learning_rate=2e-4, lr_scheduler_type="cosine", warmup_ratio=0.05, | |
| bf16=True, gradient_checkpointing=True, | |
| gradient_checkpointing_kwargs={"use_reentrant": False}, | |
| optim="paged_adamw_32bit", | |
| disable_tqdm=False, logging_steps=25, logging_first_step=True, | |
| eval_strategy="steps", eval_steps=200, | |
| save_strategy="steps", save_steps=200, save_total_limit=3, | |
| load_best_model_at_end=True, metric_for_best_model="eval_loss", | |
| push_to_hub=True, hub_model_id="YOUR_USERNAME/indic-general-assistant-3b-v1", | |
| report_to="none", seed=42, | |
| ) | |
| trainer = SFTTrainer( | |
| model=model, args=training_args, | |
| train_dataset=train_dataset, eval_dataset=eval_dataset, | |
| processing_class=tokenizer, peft_config=peft_config, | |
| ) | |
| # TRAIN! | |
| trainer.train() | |
| trainer.push_to_hub("Final model after training") | |
| print("Done! Model pushed to Hub.") | |
| """ | |
| # โโ Sample conversations to showcase โโ | |
| SAMPLE_CONVERSATIONS = [ | |
| { | |
| "lang": "๐ฎ๐ณ Hinglish (Code-Mixed)", | |
| "user": "Mujhe help chahiye Python mein list sort karne mein", | |
| "assistant": "Bilkul! Python mein list sort karna easy hai:\n\n1. `sort()` method โ original list modify karta hai:\n```python\nmy_list = [3, 1, 4, 1, 5]\nmy_list.sort() # [1, 1, 3, 4, 5]\n```\n\n2. `sorted()` function โ new sorted list return karta hai:\n```python\nnew_list = sorted(my_list)\n```\n\nReverse sort ke liye: `my_list.sort(reverse=True)`\nCustom key ke liye: `my_list.sort(key=len)` โ length se sort karega." | |
| }, | |
| { | |
| "lang": "๐ฎ๐ณ Hindi (Devanagari)", | |
| "user": "เคฆเคฟเคตเคพเคฒเฅ เคเฅ เคฌเคพเคฐเฅ เคฎเฅเค เคฌเคคเคพเค", | |
| "assistant": "เคฆเคฟเคตเคพเคฒเฅ เคญเคพเคฐเคค เคเคพ เคธเคฌเคธเฅ เคฌเคกเคผเคพ เคคเฅเคฏเฅเคนเคพเคฐ เคนเฅ เคเคฟเคธเฅ 'เคฐเฅเคถเคจเฅ เคเคพ เคคเฅเคฏเฅเคนเคพเคฐ' เคเคนเคคเฅ เคนเฅเคเฅค เคเคธเคฎเฅเค เคฒเฅเค เคฆเฅเคฏเฅ เคเคฒเคพเคคเฅ เคนเฅเค, เคฎเคฟเค เคพเคเคฏเคพเค เคฌเคพเคเคเคคเฅ เคนเฅเค, เคเคฐ เคฒเคเฅเคทเฅเคฎเฅ-เคเคฃเฅเคถ เคเฅ เคชเฅเคเคพ เคเคฐเคคเฅ เคนเฅเคเฅค เคนเฅเคฒเคฟเคเคพ เคฆเคนเคจ เคเฅ เคฌเคพเคฆ เค เคเคฒเฅ เคฆเคฟเคจ เคฐเคเคเฅเค เคเคพ เคคเฅเคฏเฅเคนเคพเคฐ เคฎเคจเคพเคคเฅ เคนเฅเคเฅค เคฆเคฟเคตเคพเคฒเฅ เคฌเฅเคฐเคพเค เคชเคฐ เค เคเฅเคเคพเค เคเฅ เคเฅเคค เคเคพ เคชเฅเคฐเคคเฅเค เคนเฅเฅค" | |
| }, | |
| { | |
| "lang": "๐ฌ๐ง English", | |
| "user": "What are the benefits of yoga for office workers?", | |
| "assistant": "Yoga offers tremendous benefits for office workers:\n\n1. **Posture correction** โ Counteracts desk slouching\n2. **Stress reduction** โ Pranayama (breathing) lowers cortisol\n3. **Back pain relief** โ Cat-cow, child's pose target spine\n4. **Eye strain** โ Palming technique relaxes eye muscles\n5. **Better focus** โ 15-min meditation boosts concentration\n\nStart with: Tadasana (standing), Trikonasana (triangle), Shavasana (relaxation). Even 20 min/day makes a difference!" | |
| }, | |
| { | |
| "lang": "๐ฎ๐ณ Financial (Indian Context)", | |
| "user": "Mutual funds mein invest kaise karein beginners ke liye?", | |
| "assistant": "Mutual funds mein start karna easy hai:\n\n1. **KYC karo** โ PAN + Aadhaar se (online bhi ho jaata hai)\n2. **App download karo** โ Zerodha Coin, Groww, Paytm Money\n3. **SIP se start karo** โ Monthly โน500 se bhi shuru ho sakta hai\n4. **Index fund choose karo** โ Nifty 50 index fund safest hai beginners ke liye\n5. **Long term socho** โ Minimum 5 years invest karo\n\n๐ก Tip: Expense ratio 0.5% se kam wale funds dekho. Direct plans mein invest karo, regular nahi." | |
| }, | |
| { | |
| "lang": "๐ง๐ฉ Bengali", | |
| "user": "เฆเฆฎเฆพเฆเง เฆฌเฆพเฆเฆฒเฆพเฆฏเฆผ เฆเฆเฆเฆฟ เฆเฆฌเฆฟเฆคเฆพ เฆฒเฆฟเฆเง เฆฆเฆพเฆ", | |
| "assistant": "เฆฌเฆพเฆเฆฒเฆพเฆฐ เฆเฆเฆพเฆถเง เฆฎเงเฆ เฆเฆฒเง เฆญเงเฆธเง,\nเฆฌเงเฆทเงเฆเฆฟเฆฐ เฆเงเฆเฆฏเฆผเฆพเฆฏเฆผ เฆฎเฆจ เฆเงเฆฒเง เฆฎเงเฆคเงเฅค\nเฆธเฆฌเงเฆ เฆฎเฆพเฆ เงเฆฐ เฆฌเงเฆเง เฆซเงเฆฒ เฆซเงเฆเงเฆเง,\nเฆชเฆพเฆเฆฟเฆฐ เฆเฆพเฆจเง เฆชเงเฆฐเฆพเฆฃ เฆเงเฆกเฆผเงเฆเงเฅค\n\nเฆจเฆฆเงเฆฐ เฆงเฆพเฆฐเง เฆฌเฆธเง เฆเฆเฆฒเฆพ,\nเฆญเฆพเฆฌเฆฟ เฆเฆค เฆเฆฅเฆพ, เฆเฆค เฆเฆเฆพเฆเงเฆเงเฆทเฆพเฅค\nเฆฌเฆพเฆเฆฒเฆพเฆฐ เฆฎเฆพเฆเฆฟ, เฆฌเฆพเฆเฆฒเฆพเฆฐ เฆเฆฒ,\nเฆเฆ เฆคเง เฆเฆฎเฆพเฆฐ เฆชเงเฆฐเฆพเฆฃเงเฆฐ เฆธเฆเฆฒเฅค" | |
| }, | |
| ] | |
| # โโ Gradio Interface โโ | |
| with gr.Blocks(title="Indic Multilingual Assistant", theme=gr.themes.Soft()) as demo: | |
| gr.Markdown(""" | |
| # ๐ฎ๐ณ Indic Multilingual Assistant 3B | |
| **Base model:** Qwen/Qwen2.5-3B-Instruct | **Method:** QLoRA | **Languages:** 7 Indian + English + Hinglish | |
| A multilingual assistant fine-tuned for Indian users with **code-mixing support** โ | |
| the key feature missing from Krutrim, Airavata, and Sarvam models. | |
| """) | |
| with gr.Tabs(): | |
| with gr.Tab("๐ฌ Sample Conversations"): | |
| gr.Markdown("### How the fine-tuned model responds in different languages") | |
| for conv in SAMPLE_CONVERSATIONS: | |
| with gr.Accordion(conv["lang"], open=False): | |
| gr.Markdown(f"**User:** {conv['user']}\n\n**Assistant:** {conv['assistant']}") | |
| with gr.Tab("๐ Dataset & Training"): | |
| gr.Markdown(""" | |
| ## Dataset Composition (4,800 training examples) | |
| | Language | Examples | % | Source | | |
| |----------|---------|---|--------| | |
| | Hindi | 1,923 | 40.1% | ai4bharat + Aya | | |
| | English | 1,197 | 24.9% | ai4bharat + Aya | | |
| | **Hinglish** | **725** | **15.1%** | Conversations-1M + translations + synthetic | | |
| | Bengali | 195 | 4.1% | Aya | | |
| | Telugu | 193 | 4.0% | Aya | | |
| | Tamil | 193 | 4.0% | Aya | | |
| | Marathi | 187 | 3.9% | Aya | | |
| | Gujarati | 187 | 3.9% | Aya | | |
| Full 49K dataset also available: [`kshitij230/indic-assistant-training-data`](https://huggingface.co/datasets/kshitij230/indic-assistant-training-data) | |
| ## Data Cleaning Applied | |
| - โ 17,513 duplicates removed | |
| - โ 10,682 short outputs filtered | |
| - โ 178 ASCII-only "Hindi" examples caught | |
| - โ Unicode NFC normalization on all Devanagari | |
| - โ Script verification per language | |
| - โ Toxicity filtering (91 removed) | |
| ## Training Configuration | |
| | Parameter | Value | | |
| |-----------|-------| | |
| | Base Model | `Qwen/Qwen2.5-3B-Instruct` (3.1B params) | | |
| | Method | QLoRA (4-bit NF4, double quantization) | | |
| | LoRA | r=16, alpha=32, dropout=0.05 | | |
| | Target Modules | q,k,v,o_proj + gate,up,down_proj | | |
| | Learning Rate | 2e-4 (cosine schedule) | | |
| | Effective Batch | 8 (2 ร 4 grad_accum) | | |
| | Max Length | 2048 tokens, packing enabled | | |
| | Epochs | 3 | | |
| """) | |
| with gr.Tab("๐ Train It Yourself"): | |
| gr.Markdown(""" | |
| ## Option 1: Google Colab (FREE โ T4 GPU) | |
| **Easiest way to train for free.** Copy the notebook below and run on Colab: | |
| 1. Go to [Google Colab](https://colab.research.google.com) | |
| 2. New Notebook โ Runtime โ Change runtime type โ **T4 GPU** | |
| 3. Paste the code below and run all cells | |
| 4. Training takes ~2-3 hours on free T4 | |
| """) | |
| gr.Code(value=COLAB_NOTEBOOK, language="python", label="Complete Training Notebook") | |
| gr.Markdown(""" | |
| ## Option 2: HuggingFace (Pro โ $9/mo) | |
| With HF Pro, this Space gets **ZeroGPU** access: | |
| 1. Subscribe at [huggingface.co/subscribe/pro](https://huggingface.co/subscribe/pro) | |
| 2. Change Space hardware to `ZeroGPU` in Settings | |
| 3. Click "Train" button in the Training tab | |
| ## Option 3: Any Cloud GPU | |
| Use the training scripts from the model repo: | |
| ```bash | |
| git clone https://huggingface.co/kshitij230/indic-general-assistant-3b-v1 | |
| cd indic-general-assistant-3b-v1/scripts | |
| pip install transformers trl peft bitsandbytes accelerate datasets | |
| python train.py | |
| ``` | |
| """) | |
| with gr.Tab("๐ฌ Why This Model?"): | |
| gr.Markdown(""" | |
| ## Base Model Selection | |
| | Model | Indic Tokenizer | Gated? | License | Decision | | |
| |-------|-----------------|--------|---------|----------| | |
| | **Qwen2.5-3B** | ~0.5 NSL (best) | No | Research* | โ Selected | | |
| | Llama-3.2-3B | 0.59 Hindi, **1.4-1.8 Dravidian** | Yes | Llama 3.2 | โ Terrible for Tamil/Telugu | | |
| | Gemma-2-2B | ~0.55 | **Yes (gated)** | Gemma | โ Blocks deployment | | |
| *For production: request commercial license from Alibaba or use Qwen2.5-7B (Apache 2.0)* | |
| ## What Makes This Different | |
| | Feature | This Model | Krutrim | Airavata | Sarvam-2B | | |
| |---------|-----------|---------|----------|-----------| | |
| | **Code-mixing (Hinglish)** | โ 15% training | โ | โ | โ | | |
| | Transliteration | โ RomanโDevanagari | Partial | โ | โ | | |
| | Cultural context | โ GST, PAN, IPL | Limited | Limited | Limited | | |
| | Cross-lingual | โ AnyโAny | โ | โ | โ | | |
| ## Key Research Findings | |
| - **Tokenizer matters hugely**: Llama-3's tokenizer needs 1.4-1.8x more tokens for Tamil/Telugu | |
| โ 40-80% slower inference, shorter context. Qwen's 151K vocab is 2-3x more efficient. | |
| - **Code-mixing is the gap**: None of the existing Indic models (Krutrim, Airavata, Sarvam) | |
| have dedicated code-mixed training data. This is our differentiator. | |
| - **IndicParam benchmark**: Qwen2.5-3B scores 28.3 avg vs Llama-3.2-3B's 27.1 on Indic tasks. | |
| """) | |
| with gr.Tab("๐ Links"): | |
| gr.Markdown(f""" | |
| ## Project Resources | |
| | Resource | Link | | |
| |----------|------| | |
| | ๐ค Model | [`kshitij230/indic-general-assistant-3b-v1`](https://huggingface.co/kshitij230/indic-general-assistant-3b-v1) | | |
| | ๐ Dataset | [`kshitij230/indic-assistant-training-data`](https://huggingface.co/datasets/kshitij230/indic-assistant-training-data) | | |
| | ๐๏ธ Training Space | [`kshitij230/indic-assistant-trainer`](https://huggingface.co/spaces/kshitij230/indic-assistant-trainer) | | |
| ## Source Datasets Used | |
| | Dataset | Description | | |
| |---------|-------------| | |
| | [`ai4bharat/indic-instruct-data-v0.1`](https://huggingface.co/datasets/ai4bharat/indic-instruct-data-v0.1) | Hindi + English instruction data (anudesh, dolly, flan_v2, oasst1) | | |
| | [`CohereLabs/aya_dataset`](https://huggingface.co/datasets/CohereLabs/aya_dataset) | 12 Indic languages instruction data | | |
| | [`Abhishekcr448/Hinglish-Everyday-Conversations-1M`](https://huggingface.co/datasets/Abhishekcr448/Hinglish-Everyday-Conversations-1M) | 1M Hinglish conversations | | |
| | [`findnitai/english-to-hinglish`](https://huggingface.co/datasets/findnitai/english-to-hinglish) | EnglishโHinglish translation pairs | | |
| | [`festvox/cmu_hinglish_dog`](https://huggingface.co/datasets/festvox/cmu_hinglish_dog) | Hinglish grounded dialog | | |
| ## Research References | |
| | Paper | Key Finding | | |
| |-------|-------------| | |
| | MILU (arXiv:2411.02538) | Llama-3.2-3B: 32.85 avg on 11 Indic languages | | |
| | IndicParam (arXiv:2512.00333) | Qwen2.5-3B: 28.3 beats Llama 27.1 on low-resource Indic | | |
| | Tokenizer eval (arXiv:2411.12240) | Llama tokenizer 1.4-1.8x NSL on Dravidian scripts | | |
| """) | |
| demo.launch() | |