Usage
from peft import PeftModel
from transformers import AutoModelForCausalLM, AutoTokenizer
base = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3-4B", torch_dtype="bfloat16")
model = PeftModel.from_pretrained(base, "shubham4saurav/qwen3-4b-gita-lora")
tok = AutoTokenizer.from_pretrained("shubham4saurav/qwen3-4b-gita-lora")
msgs = [{"role": "user", "content": "Recite Bhagavad Gita 2.47."}]
prompt = tok.apply_chat_template(msgs, tokenize=False, add_generation_prompt=True,
enable_thinking=False)
out = model.generate(**tok(prompt, return_tensors="pt"), max_new_tokens=256)
print(tok.decode(out[0], skip_special_tokens=True))
Training
Table | |
|---|
| Base | unsloth/Qwen3-4B-unsloth-bnb-4bit |
| Method | LoRA (Unsloth + TRL SFTTrainer) |
| Rank / alpha / dropout | 16 / 16 / 0 |
| Target modules | q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj |
| Max sequence length | 2048 |
| Epochs | 3 (945 steps) |
| LR / batch / grad-accum | 2e-4 / 2 / 4 |
| Final train loss | 1.10 |
| Data | 2,520 instruction examples from 630 Gita verses |
Data source: JDhruv14/Bhagavad-Gita_Dataset
(701 verses). Each verse expands into 4 tasks — explanation, translation, quote,
transliteration — with randomised prompt templates.
Limitations
Every training target is short and templated (verse + a one-line translation),
even for "explain" prompts, so the adapter makes the model answer tersely and
stop early. On a 20-prompt held-out eval:
Table with columns: avg words / answer, chrF vs gold | avg words / answer | chrF vs gold |
|---|
| Base Qwen3-4B | 101 | 0.188 |
| + this adapter | 38 | 0.227 |
Higher chrF (closer to the terse gold answers) but far less elaboration. It is a
learning project, not a scholarly reference — do not rely on it for authoritative
interpretation of scripture.
License
MIT (adapter weights). The base model keeps its own license.