malodept commited on
Commit
74e026e
·
0 Parent(s):

Clean push: app, requirements, README

Browse files
Files changed (4) hide show
  1. .gitattributes +1 -0
  2. README.md +93 -0
  3. app.py +46 -0
  4. requirements.txt +5 -0
.gitattributes ADDED
@@ -0,0 +1 @@
 
 
1
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🧠 ExplainMyAssignment
2
+
3
+ > Human-Interpretable Variable Assignment Explainer, powered by Mistral-7B
4
+
5
+ **ExplainMyAssignment** is an interactive web app that translates complex variable assignments into clear, human-readable explanations.
6
+ It is built on top of a fine-tuned [Mistral-7B-Instruct-v0.1](https://huggingface.co/mistralai/Mistral-7B-Instruct-v0.1) model, optimized to generate pedagogical interpretations of logical or algorithmic reasoning.
7
+
8
+ ---
9
+
10
+ ## ✨ Objectives
11
+
12
+ This project was designed to address three core tasks:
13
+
14
+ - ✅ **Run a local LLM** to generate natural-language explanations.
15
+ - ✅ **Use prompt engineering or fine-tuning** to transform variable assignments into readable language.
16
+ - ✅ **Deploy an app** that dynamically interprets user inputs with clarity and rigor.
17
+
18
+ ---
19
+
20
+ ## 💡 Example Use Cases
21
+
22
+ | ❓ User Input | 💬 Model Explanation |
23
+ |--------------|----------------------|
24
+ | *“I selected items 1, 2, and 4 in my knapsack solution because they give the highest value…”* | *“Having the highest total value doesn't guarantee a valid solution. You may have exceeded the weight capacity…”* |
25
+ | *“I get a negative tour cost even though all distances are positive.”* | *“A negative tour cost suggests some values in your matrix are incorrectly negative. Check your preprocessing or indexing…”* |
26
+ | *“My LP relaxation gives 0.5 values for variables that should be binary. Is this wrong?”* | *“This is expected in LP relaxations. You'll need a rounding scheme to recover a feasible integer solution…”* |
27
+
28
+ ---
29
+
30
+ ## 🛠️ Model & Tech Overview
31
+
32
+ - 🔍 **Base model**: [Mistral-7B-Instruct-v0.1](https://huggingface.co/mistralai/Mistral-7B-Instruct-v0.1)
33
+ - 🔧 **Fine-tuned** using [PEFT](https://huggingface.co/docs/peft/) + LoRA on 300+ handcrafted input/output pairs
34
+ - ⚙️ **Quantized** to 4-bit with `BitsAndBytesConfig` (nf4) for efficient runtime
35
+ - 🧪 **Training**: 3 epochs, 450 steps, trained on T4 GPU — final loss ≈ 1.05, perplexity ≈ 2.8
36
+
37
+ ---
38
+
39
+ ## 🧭 Input Guidelines
40
+
41
+ To get the best explanations from the model, follow these tips:
42
+
43
+ ### ✅ What works well
44
+ - Descriptions of **variable assignments** or **unexpected outputs**
45
+ - **Concrete questions** about the logic of a solution
46
+ - Inputs written in **semi-formal technical English**
47
+
48
+ ### 🚫 Avoid
49
+ - Vague prompts like *“Why doesn’t it work?”*
50
+ - Fully natural conversation or general questions
51
+ - Topics unrelated to logic or reasoning structure
52
+
53
+ ---
54
+
55
+ ## 🚀 Live Demo
56
+
57
+ 👉 Try it online at
58
+ 🔗 [https://huggingface.co/spaces/malomalom/ExplainMyAssignment](https://huggingface.co/spaces/malomalom/ExplainMyAssignment)
59
+
60
+ Features:
61
+ - Chat-style interface powered by [Gradio](https://www.gradio.app/)
62
+ - Hugging Face API compatible
63
+ - Powered by LoRA fine-tuning on Mistral-7B
64
+
65
+ ---
66
+
67
+ ## 🧪 Training Data
68
+
69
+ This fine-tuned model is trained on a handcrafted dataset like:
70
+ ```json
71
+ {"input":"I'm trying to solve a symmetric TSP and assumed that x[i][j] = x[j][i], but the tour ends up skipping some cities. Is symmetry not enough?",
72
+ "output":"While the distance matrix in a symmetric TSP is symmetric (i.e., d[i][j] = d[j][i]), the decision variables x[i][j] and x[j][i] represent different directions in the tour and are not automatically equal. You need to include both directions explicitly in your constraints and objective, and still enforce that each city is entered and exited exactly once to get a valid tour."}
73
+
74
+
75
+
76
+
77
+
78
+
79
+
80
+ ---
81
+ title: ExplainMyAssignment
82
+ emoji: 💬
83
+ colorFrom: yellow
84
+ colorTo: purple
85
+ sdk: gradio
86
+ sdk_version: 5.0.1
87
+ app_file: app.py
88
+ pinned: false
89
+ license: apache-2.0
90
+ short_description: 'Translate abstract symbolic mappings into natural language '
91
+ ---
92
+
93
+ An example chatbot using [Gradio](https://gradio.app), [`huggingface_hub`](https://huggingface.co/docs/huggingface_hub/v0.22.2/en/index), and the [Hugging Face Inference API](https://huggingface.co/docs/api-inference/index).
app.py ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig
3
+ from peft import PeftModel
4
+ import torch
5
+
6
+ MODEL_DIR = "malomalom/mistral-lora-assignments"
7
+
8
+ bnb_config = BitsAndBytesConfig(
9
+ load_in_4bit=True,
10
+ bnb_4bit_compute_dtype=torch.float16,
11
+ bnb_4bit_use_double_quant=True,
12
+ bnb_4bit_quant_type="nf4"
13
+ )
14
+
15
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_DIR)
16
+ base_model = AutoModelForCausalLM.from_pretrained(
17
+ "mistralai/Mistral-7B-Instruct-v0.1",
18
+ device_map="auto",
19
+ quantization_config=bnb_config
20
+ )
21
+ model = PeftModel.from_pretrained(base_model, MODEL_DIR)
22
+ model.eval()
23
+
24
+ def generate_explanation(user_input):
25
+ prompt = f"User: {user_input}\nAssistant:"
26
+ inputs = tokenizer(prompt, return_tensors="pt").to("cuda")
27
+ outputs = model.generate(**inputs, max_new_tokens=200, pad_token_id=tokenizer.eos_token_id)
28
+ response = tokenizer.decode(outputs[0], skip_special_tokens=True)
29
+ return response.split("Assistant:")[-1].strip()
30
+
31
+ # === Interface Gradio ===
32
+ gr.Interface(
33
+ fn=generate_explanation,
34
+ inputs=gr.Textbox(label="Ask your question"),
35
+ outputs=gr.Textbox(label="Generated explanation"),
36
+ title="ExplainMyAssignment",
37
+ description=(
38
+ "A local LLM-based assistant that transforms complex variable assignments (from optimization, logic, or symbolic reasoning) into clear human-readable explanations."
39
+
40
+ "Fine-tuned from Mistral-7B, this tool is built to translate abstract symbolic mappings into natural language feedback, understanding structural constraints, and improving interpretability."
41
+
42
+ "Designed to support AI engineers, teachers, and advanced students working with mathematical or logical models."
43
+
44
+ "Works locally and can be deployed in constrained environments (LoRA + 4-bit quantization)."
45
+ ),
46
+ ).launch()
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ transformers
2
+ peft
3
+ accelerate
4
+ bitsandbytes
5
+ gradio