kshitij230's picture
Upload app.py with huggingface_hub
2b43ab8 verified
Raw
History Blame Contribute Delete
15.4 kB
"""
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()