📌 Model Overview
- Model Type: PEFT LoRA Adapter (Not Merged)
- Base Model:
unsloth/Qwen3-4B-Thinking-2507
- Fine-Tuning Method: QLoRA (4-bit NF4 quantized base model + LoRA rank 128)
- Trainable Parameters: 264,241,152 (6.16% of total 4.28B parameters)
- Dataset Scope: Sample subset of Class 12 Physics topics (4,715 examples)
🎯 Intended Use & Limitations
Primary Use Cases
- Assisting with high school physics conceptual questions and standard numerical problems.
- Demonstrating step-by-step reasoning and physics derivations with explicit internal monologue (
<think> tags).
- Interactive physics tutoring on key topics represented in the sample dataset.
Limitations & Out-of-Scope
- Sample Dataset, Not Comprehensive: The training data is a sample collection (4,715 examples) and does not span all chapters, subtopics, or edge cases of the complete 12th-grade NCERT curriculum.
- Requires Base Model: As this repo hosts adapter weights only, it cannot be run without the base model
unsloth/Qwen3-4B-Thinking-2507.
- Numerical Verification: Complex multi-step calculations should always be cross-checked against standard reference textbooks.
📊 Dataset Details
- Source: [
KadamParth/NCERT_Physics_12th]
- Nature of Data: Sample dataset containing 4,715 Physics question-answer pairs with step-by-step explanations.
Conversation Schema
<|im_start|>system
Follow these steps to answer the user's question:
1. First, reason step-by-step inside <think> tags. This is your internal monologue.
2. After the </think> tag, provide a complete, helpful, and polished answer for the user that includes both a direct answer and an explanation.<|im_end|>
<|im_start|>user
{Question}<|im_end|>
<|im_start|>assistant
<think>
{Step-by-step reasoning and physics derivations}
</think>
Answer: {Direct Answer}
Explanation: {Detailed Explanation}<|im_end|>
📈 Training & Validation Loss
Table with columns: Step, Training Loss, Validation Loss| Step | Training Loss | Validation Loss |
|---|
| 10 | 0.8160 | 0.5512 |
| 20 | 0.5019 | 0.4574 |
| 30 | 0.4581 | 0.4241 |
| 40 | 0.4187 | 0.4070 |
| 50 | 0.4173 | 0.3952 |
| 60 | 0.4043 |
- Final Training Loss:
0.4640
- Final Validation Loss:
0.3805
🚀 How to Run Inference
1. Using Unsloth (Loading Base Model + Adapter)
from unsloth import FastLanguageModel
from transformers import TextStreamer
model, tokenizer = FastLanguageModel.from_pretrained(
model_name = "Rakesh7n/Qwen3_4B_NCRT_Physics_12th_Finetuned",
max_seq_length = 2048,
load_in_4bit = True,
)
FastLanguageModel.for_inference(model)
messages = [
{
"role": "user",
"content": "If 10^10 electrons move from one body to another every second, how long will it take to transfer 1 C of charge?"
}
]
text = tokenizer.apply_chat_template(
messages,
tokenize = False,
add_generation_prompt = True,
)
inputs = tokenizer(text, return_tensors = "pt").to("cuda")
streamer = TextStreamer(tokenizer, skip_prompt = False)
_ = model.generate(
**inputs,
max_new_tokens = 2048,
temperature = 0.7,
top_p = 0.8,
top_k = 20,
streamer = streamer,
)
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
from peft import PeftModel
base_model_id = "unsloth/Qwen3-4B-Thinking-2507"
adapter_model_id = "Rakesh7n/Qwen3_4B_NCRT_Physics_12th_Finetuned"
tokenizer = AutoTokenizer.from_pretrained(base_model_id)
base_model = AutoModelForCausalLM.from_pretrained(
base_model_id,
torch_dtype=torch.float16,
device_map="auto"
)
model = PeftModel.from_pretrained(base_model, adapter_model_id)
messages = [
{
"role": "system",
"content": "Follow these steps to answer the user's question:\n1. First, reason step-by-step inside <think> tags. This is your internal monologue.\n2. After the </think> tag, provide a complete, helpful, and polished answer for the user that includes both a direct answer and an explanation."
},
{
"role": "user",
"content": "What is the formula for electric flux according to Gauss's Law?"
}
]
prompt = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
inputs = tokenizer(prompt, return_tensors="pt").to("cuda")
outputs = model.generate(
**inputs,
max_new_tokens=1024,
temperature=0.7,
top_p=0.8,
do_sample=True
)
print(tokenizer.decode(outputs[0], skip_special_tokens=False))
📝 Example Output
User Prompt:
If 1010 electrons move from one body to another every second, how long will it take to transfer 1 C of charge?
Model Output:
<think>
1. Identify the given values:
- Rate of electron transfer = 10^10 electrons/second
- Total charge to transfer Q = 1 C
- Elementary charge e = 1.6 * 10^-19 C/electron
2. Calculate charge transferred per second:
- dq/dt = (10^10 electrons/s) * (1.6 * 10^-19 C/electron) = 1.6 * 10^-9 C/s (1.6 nC/s)
3. Calculate time t required:
- t = Q / (dq/dt) = 1 C / (1.6 * 10^-9 C/s) = 6.25 * 10^8 seconds
4. Convert seconds to years:
- 1 year ≈ 3.154 * 10^7 seconds
- t (years) = (6.25 * 10^8) / (3.154 * 10^7) ≈ 19.8 years
</think>
Answer: The charge transferred per second is 1.6 × 10⁻⁹ C/s. The total time required is 6.25 × 10⁸ seconds, which is approximately 19.8 years.
Explanation: Electrons carry a fundamental unit of charge equal to 1.6 × 10⁻¹⁹ C. With a transfer rate of 10¹⁰ electrons per second, the total charge moving per second is 1.6 × 10⁻⁹ C/s. To accumulate 1 Coulomb of charge, dividing the total required charge by the transfer rate yields 6.25 × 10⁸ seconds (~19.8 years).