SUMANTH-CH commited on
Commit
593b032
Β·
verified Β·
1 Parent(s): ae3574c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +371 -303
app.py CHANGED
@@ -1,304 +1,372 @@
1
- # EDUTUTOR AI - Complete app.py for Hugging Face Spaces
2
- # An intelligent AI tutor powered by IBM Granite that provides personalized educational explanations across multiple subjects and difficulty levels.
3
-
4
- import gradio as gr
5
- import torch
6
- from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
7
- import warnings
8
- warnings.filterwarnings("ignore")
9
-
10
- class EduTutorAI:
11
- def __init__(self):
12
- self.model_name = "ibm-granite/granite-3.3-2b-instruct"
13
- self.tokenizer = None
14
- self.model = None
15
- self.pipe = None
16
- self.conversation_history = []
17
-
18
- def load_model(self):
19
- """Load the Granite model and tokenizer"""
20
- try:
21
- print("Loading EDUTUTOR AI model...")
22
-
23
- # Load tokenizer
24
- self.tokenizer = AutoTokenizer.from_pretrained(
25
- self.model_name,
26
- trust_remote_code=True
27
- )
28
-
29
- # Load model with optimization for deployment
30
- self.model = AutoModelForCausalLM.from_pretrained(
31
- self.model_name,
32
- torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
33
- device_map="auto" if torch.cuda.is_available() else None,
34
- trust_remote_code=True,
35
- low_cpu_mem_usage=True
36
- )
37
-
38
- # Create pipeline
39
- self.pipe = pipeline(
40
- "text-generation",
41
- model=self.model,
42
- tokenizer=self.tokenizer,
43
- torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
44
- device_map="auto" if torch.cuda.is_available() else None
45
- )
46
-
47
- print("βœ… Model loaded successfully!")
48
- return True
49
-
50
- except Exception as e:
51
- print(f"❌ Error loading model: {str(e)}")
52
- return False
53
-
54
- def create_educational_prompt(self, user_question, subject="General", difficulty="Intermediate"):
55
- """Create an educational prompt template"""
56
- system_prompt = f"""You are EDUTUTOR AI, an expert educational tutor specializing in {subject}.
57
- Your role is to:
58
- 1. Provide clear, accurate explanations at {difficulty} level
59
- 2. Break down complex concepts into digestible parts
60
- 3. Use examples and analogies when helpful
61
- 4. Encourage learning through questions
62
- 5. Be patient and supportive
63
-
64
- Student Question: {user_question}
65
-
66
- Please provide a comprehensive yet accessible explanation:"""
67
-
68
- return system_prompt
69
-
70
- def generate_response(self, question, subject, difficulty, max_length=512):
71
- """Generate educational response"""
72
- if not self.pipe:
73
- return "❌ Model not loaded. Please wait for initialization."
74
-
75
- try:
76
- # Create educational prompt
77
- prompt = self.create_educational_prompt(question, subject, difficulty)
78
-
79
- # Generate response
80
- response = self.pipe(
81
- prompt,
82
- max_length=max_length,
83
- num_return_sequences=1,
84
- temperature=0.7,
85
- do_sample=True,
86
- pad_token_id=self.tokenizer.eos_token_id,
87
- truncation=True
88
- )
89
-
90
- # Extract the generated text
91
- full_response = response[0]['generated_text']
92
-
93
- # Remove the prompt to get only the AI response
94
- ai_response = full_response.replace(prompt, "").strip()
95
-
96
- # Store in conversation history
97
- self.conversation_history.append({
98
- "question": question,
99
- "subject": subject,
100
- "difficulty": difficulty,
101
- "response": ai_response
102
- })
103
-
104
- return ai_response
105
-
106
- except Exception as e:
107
- return f"❌ Error generating response: {str(e)}"
108
-
109
- def get_conversation_history(self):
110
- """Get formatted conversation history"""
111
- if not self.conversation_history:
112
- return "No conversation history yet."
113
-
114
- history = "πŸ“š **EDUTUTOR AI - Learning Session History**\n\n"
115
- for i, conv in enumerate(self.conversation_history[-5:], 1): # Show last 5 conversations
116
- history += f"**Session {i}:**\n"
117
- history += f"🎯 Subject: {conv['subject']} | Level: {conv['difficulty']}\n"
118
- history += f"❓ Question: {conv['question']}\n"
119
- history += f"πŸ’‘ Response: {conv['response'][:200]}...\n\n"
120
-
121
- return history
122
-
123
- def clear_history(self):
124
- """Clear conversation history"""
125
- self.conversation_history = []
126
- return "πŸ—‘οΈ Conversation history cleared!"
127
-
128
- # Initialize the EduTutor AI
129
- edututor = EduTutorAI()
130
-
131
- # Load model function for Gradio
132
- def initialize_model():
133
- """Initialize the model and return status"""
134
- success = edututor.load_model()
135
- if success:
136
- return "βœ… EDUTUTOR AI is ready! You can now start asking questions."
137
- else:
138
- return "❌ Failed to load model. Please try again."
139
-
140
- # Main chat function
141
- def chat_with_edututor(question, subject, difficulty, max_length):
142
- """Main chat interface function"""
143
- if not question.strip():
144
- return "Please enter a question to get started!"
145
-
146
- response = edututor.generate_response(question, subject, difficulty, max_length)
147
- return response
148
-
149
- # Create Gradio interface
150
- def create_interface():
151
- """Create the EDUTUTOR AI Gradio interface"""
152
-
153
- with gr.Blocks(
154
- title="πŸŽ“ EDUTUTOR AI - Your Personal Learning Assistant",
155
- theme=gr.themes.Soft(),
156
- css="""
157
- .gradio-container {
158
- font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
159
- }
160
- .main-header {
161
- text-align: center;
162
- background: linear-gradient(45deg, #667eea 0%, #764ba2 100%);
163
- color: white;
164
- padding: 20px;
165
- border-radius: 10px;
166
- margin-bottom: 20px;
167
- }
168
- """
169
- ) as interface:
170
-
171
- # Header
172
- gr.HTML("""
173
- <div class="main-header">
174
- <h1>πŸŽ“ EDUTUTOR AI</h1>
175
- <p>Your Intelligent Educational Tutor powered by IBM Granite 3.3-2B</p>
176
- <p><em>Ask questions, learn concepts, and expand your knowledge!</em></p>
177
- </div>
178
- """)
179
-
180
- # Model initialization section
181
- with gr.Row():
182
- with gr.Column():
183
- init_button = gr.Button("πŸš€ Initialize EDUTUTOR AI", variant="primary", size="lg")
184
- init_status = gr.Textbox(
185
- label="Initialization Status",
186
- value="Click 'Initialize EDUTUTOR AI' to start",
187
- interactive=False
188
- )
189
-
190
- # Main interface
191
- with gr.Row():
192
- with gr.Column(scale=2):
193
- # Input section
194
- with gr.Group():
195
- gr.Markdown("### πŸ“ Ask Your Question")
196
- question_input = gr.Textbox(
197
- label="Your Question",
198
- placeholder="e.g., Explain quantum physics, How does photosynthesis work?, What is machine learning?",
199
- lines=3
200
- )
201
-
202
- with gr.Row():
203
- subject_dropdown = gr.Dropdown(
204
- choices=[
205
- "General", "Mathematics", "Physics", "Chemistry",
206
- "Biology", "Computer Science", "History", "Literature",
207
- "Geography", "Economics", "Philosophy"
208
- ],
209
- value="General",
210
- label="Subject Area"
211
- )
212
-
213
- difficulty_dropdown = gr.Dropdown(
214
- choices=["Beginner", "Intermediate", "Advanced"],
215
- value="Intermediate",
216
- label="Difficulty Level"
217
- )
218
-
219
- max_length_slider = gr.Slider(
220
- minimum=100,
221
- maximum=1000,
222
- value=512,
223
- step=50,
224
- label="Response Length (tokens)"
225
- )
226
-
227
- ask_button = gr.Button("πŸ€” Ask EDUTUTOR AI", variant="primary")
228
-
229
- with gr.Column(scale=1):
230
- # Quick actions
231
- with gr.Group():
232
- gr.Markdown("### ⚑ Quick Actions")
233
- history_button = gr.Button("πŸ“š View Learning History")
234
- clear_button = gr.Button("πŸ—‘οΈ Clear History")
235
-
236
- gr.Markdown("### πŸ’‘ Tips")
237
- gr.Markdown("""
238
- - Be specific with your questions
239
- - Select appropriate subject and difficulty
240
- - Use follow-up questions for deeper understanding
241
- - Experiment with different difficulty levels
242
- """)
243
-
244
- # Response section
245
- with gr.Row():
246
- response_output = gr.Textbox(
247
- label="πŸŽ“ EDUTUTOR AI Response",
248
- lines=15,
249
- max_lines=20,
250
- interactive=False
251
- )
252
-
253
- # History section
254
- with gr.Row():
255
- history_output = gr.Textbox(
256
- label="πŸ“š Learning Session History",
257
- lines=10,
258
- interactive=False,
259
- visible=False
260
- )
261
-
262
- # Event handlers
263
- init_button.click(
264
- fn=initialize_model,
265
- outputs=init_status
266
- )
267
-
268
- ask_button.click(
269
- fn=chat_with_edututor,
270
- inputs=[question_input, subject_dropdown, difficulty_dropdown, max_length_slider],
271
- outputs=response_output
272
- )
273
-
274
- question_input.submit(
275
- fn=chat_with_edututor,
276
- inputs=[question_input, subject_dropdown, difficulty_dropdown, max_length_slider],
277
- outputs=response_output
278
- )
279
-
280
- history_button.click(
281
- fn=edututor.get_conversation_history,
282
- outputs=history_output
283
- ).then(
284
- fn=lambda: gr.update(visible=True),
285
- outputs=history_output
286
- )
287
-
288
- clear_button.click(
289
- fn=edututor.clear_history,
290
- outputs=init_status
291
- )
292
-
293
- return interface
294
-
295
- # Launch the application
296
- if __name__ == "__main__":
297
- print("πŸŽ“ Starting EDUTUTOR AI...")
298
- print("=" * 50)
299
-
300
- # Create and launch interface
301
- demo = create_interface()
302
-
303
- # Launch for Hugging Face Spaces (simplified)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
304
  demo.launch()
 
1
+ # EDUTUTOR AI with Google Authentication
2
+ # Note: This collects user data - ensure you have proper privacy policy and user consent
3
+
4
+ import gradio as gr
5
+ import torch
6
+ from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
7
+ import warnings
8
+ import datetime
9
+ import json
10
+ warnings.filterwarnings("ignore")
11
+
12
+ # User session storage (in-memory for demo - use database in production)
13
+ user_sessions = {}
14
+ usage_analytics = []
15
+
16
+ class EduTutorAI:
17
+ def __init__(self):
18
+ self.model_name = "ibm-granite/granite-3.3-2b-instruct"
19
+ self.tokenizer = None
20
+ self.model = None
21
+ self.pipe = None
22
+ self.conversation_history = []
23
+
24
+ def load_model(self):
25
+ """Load the Granite model and tokenizer"""
26
+ try:
27
+ print("Loading EDUTUTOR AI model...")
28
+
29
+ self.tokenizer = AutoTokenizer.from_pretrained(
30
+ self.model_name,
31
+ trust_remote_code=True
32
+ )
33
+
34
+ self.model = AutoModelForCausalLM.from_pretrained(
35
+ self.model_name,
36
+ torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
37
+ device_map="auto" if torch.cuda.is_available() else None,
38
+ trust_remote_code=True,
39
+ low_cpu_mem_usage=True
40
+ )
41
+
42
+ self.pipe = pipeline(
43
+ "text-generation",
44
+ model=self.model,
45
+ tokenizer=self.tokenizer,
46
+ torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
47
+ device_map="auto" if torch.cuda.is_available() else None
48
+ )
49
+
50
+ print("βœ… Model loaded successfully!")
51
+ return True
52
+
53
+ except Exception as e:
54
+ print(f"❌ Error loading model: {str(e)}")
55
+ return False
56
+
57
+ def create_educational_prompt(self, user_question, subject="General", difficulty="Intermediate"):
58
+ """Create an educational prompt template"""
59
+ system_prompt = f"""You are EDUTUTOR AI, an expert educational tutor specializing in {subject}.
60
+ Your role is to:
61
+ 1. Provide clear, accurate explanations at {difficulty} level
62
+ 2. Break down complex concepts into digestible parts
63
+ 3. Use examples and analogies when helpful
64
+ 4. Encourage learning through questions
65
+ 5. Be patient and supportive
66
+
67
+ Student Question: {user_question}
68
+
69
+ Please provide a comprehensive yet accessible explanation:"""
70
+
71
+ return system_prompt
72
+
73
+ def generate_response(self, question, subject, difficulty, max_length, user_info=None):
74
+ """Generate educational response with user tracking"""
75
+ if not self.pipe:
76
+ return "❌ Model not loaded. Please wait for initialization."
77
+
78
+ try:
79
+ # Log user interaction
80
+ if user_info:
81
+ self.log_user_interaction(user_info, question, subject, difficulty)
82
+
83
+ # Create educational prompt
84
+ prompt = self.create_educational_prompt(question, subject, difficulty)
85
+
86
+ # Generate response
87
+ response = self.pipe(
88
+ prompt,
89
+ max_length=max_length,
90
+ num_return_sequences=1,
91
+ temperature=0.7,
92
+ do_sample=True,
93
+ pad_token_id=self.tokenizer.eos_token_id,
94
+ truncation=True
95
+ )
96
+
97
+ # Extract the generated text
98
+ full_response = response[0]['generated_text']
99
+ ai_response = full_response.replace(prompt, "").strip()
100
+
101
+ # Store in conversation history
102
+ self.conversation_history.append({
103
+ "user": user_info.get("name", "Anonymous") if user_info else "Anonymous",
104
+ "question": question,
105
+ "subject": subject,
106
+ "difficulty": difficulty,
107
+ "response": ai_response,
108
+ "timestamp": datetime.datetime.now().isoformat()
109
+ })
110
+
111
+ return ai_response
112
+
113
+ except Exception as e:
114
+ return f"❌ Error generating response: {str(e)}"
115
+
116
+ def log_user_interaction(self, user_info, question, subject, difficulty):
117
+ """Log user interaction for analytics"""
118
+ interaction = {
119
+ "timestamp": datetime.datetime.now().isoformat(),
120
+ "user_name": user_info.get("name", "Unknown"),
121
+ "user_email": user_info.get("email", "Unknown"),
122
+ "question": question,
123
+ "subject": subject,
124
+ "difficulty": difficulty
125
+ }
126
+ usage_analytics.append(interaction)
127
+ print(f"πŸ“Š Logged interaction: {user_info.get('name', 'Anonymous')} asked about {subject}")
128
+
129
+ # Initialize the EduTutor AI
130
+ edututor = EduTutorAI()
131
+
132
+ # Authentication functions
133
+ def authenticate_user(username, password):
134
+ """Simple authentication (replace with Google OAuth in production)"""
135
+ # This is a demo - in production, use proper Google OAuth
136
+ if username and password:
137
+ user_info = {
138
+ "name": username,
139
+ "email": f"{username}@example.com",
140
+ "login_time": datetime.datetime.now().isoformat()
141
+ }
142
+ user_sessions[username] = user_info
143
+ return True, f"βœ… Welcome {username}! You are now logged in.", user_info
144
+ return False, "❌ Please enter valid credentials.", None
145
+
146
+ def initialize_model():
147
+ """Initialize the model and return status"""
148
+ success = edututor.load_model()
149
+ if success:
150
+ return "βœ… EDUTUTOR AI is ready! You can now start asking questions."
151
+ else:
152
+ return "❌ Failed to load model. Please try again."
153
+
154
+ def chat_with_edututor(question, subject, difficulty, max_length, user_info):
155
+ """Main chat interface function with user tracking"""
156
+ if not question.strip():
157
+ return "Please enter a question to get started!"
158
+
159
+ # Parse user_info if it's a string
160
+ if isinstance(user_info, str) and user_info.startswith("{"):
161
+ try:
162
+ user_info = json.loads(user_info)
163
+ except:
164
+ user_info = None
165
+
166
+ response = edututor.generate_response(question, subject, difficulty, max_length, user_info)
167
+ return response
168
+
169
+ def get_user_analytics():
170
+ """Get analytics dashboard"""
171
+ if not usage_analytics:
172
+ return "No user interactions logged yet."
173
+
174
+ total_users = len(set([interaction["user_email"] for interaction in usage_analytics]))
175
+ total_questions = len(usage_analytics)
176
+
177
+ subjects = {}
178
+ for interaction in usage_analytics:
179
+ subject = interaction["subject"]
180
+ subjects[subject] = subjects.get(subject, 0) + 1
181
+
182
+ analytics = f"""
183
+ πŸ“Š **EDUTUTOR AI Analytics Dashboard**
184
+
185
+ πŸ‘₯ **Total Unique Users**: {total_users}
186
+ ❓ **Total Questions Asked**: {total_questions}
187
+
188
+ πŸ“š **Popular Subjects**:
189
+ """
190
+ for subject, count in sorted(subjects.items(), key=lambda x: x[1], reverse=True):
191
+ analytics += f"β€’ {subject}: {count} questions\n"
192
+
193
+ analytics += f"\nπŸ• **Recent Activity** (Last 5):\n"
194
+ for interaction in usage_analytics[-5:]:
195
+ analytics += f"β€’ {interaction['user_name']} asked about {interaction['subject']} ({interaction['timestamp'][:19]})\n"
196
+
197
+ return analytics
198
+
199
+ # Create Gradio interface with authentication
200
+ def create_interface():
201
+ """Create the EDUTUTOR AI Gradio interface with authentication"""
202
+
203
+ with gr.Blocks(
204
+ title="πŸŽ“ EDUTUTOR AI - Your Personal Learning Assistant",
205
+ theme=gr.themes.Soft(),
206
+ css="""
207
+ .gradio-container {
208
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
209
+ }
210
+ .main-header {
211
+ text-align: center;
212
+ background: linear-gradient(45deg, #667eea 0%, #764ba2 100%);
213
+ color: white;
214
+ padding: 20px;
215
+ border-radius: 10px;
216
+ margin-bottom: 20px;
217
+ }
218
+ .privacy-notice {
219
+ background: #f0f0f0;
220
+ padding: 15px;
221
+ border-radius: 5px;
222
+ margin: 10px 0;
223
+ border-left: 4px solid #ff6b6b;
224
+ }
225
+ """
226
+ ) as interface:
227
+
228
+ # Header
229
+ gr.HTML("""
230
+ <div class="main-header">
231
+ <h1>πŸŽ“ EDUTUTOR AI</h1>
232
+ <p>Your Intelligent Educational Tutor powered by IBM Granite 3.3-2B</p>
233
+ <p><em>Ask questions, learn concepts, and expand your knowledge!</em></p>
234
+ </div>
235
+ """)
236
+
237
+ # Privacy Notice
238
+ gr.HTML("""
239
+ <div class="privacy-notice">
240
+ <h3>πŸ”’ Privacy Notice</h3>
241
+ <p><strong>Data Collection:</strong> This app collects user names, questions, and usage analytics to improve the learning experience.</p>
242
+ <p><strong>By using this app, you consent to this data collection.</strong></p>
243
+ <p>πŸ“§ Contact: For privacy concerns, contact the administrator.</p>
244
+ </div>
245
+ """)
246
+
247
+ # Authentication Section
248
+ with gr.Row():
249
+ with gr.Column(scale=1):
250
+ gr.Markdown("### πŸ” Login to EDUTUTOR AI")
251
+ username_input = gr.Textbox(label="Username", placeholder="Enter your username")
252
+ password_input = gr.Textbox(label="Password", type="password", placeholder="Enter your password")
253
+ login_button = gr.Button("πŸ”‘ Login", variant="primary")
254
+ login_status = gr.Textbox(label="Login Status", value="Please login to continue", interactive=False)
255
+ user_info_state = gr.State(value=None)
256
+
257
+ # Model initialization section
258
+ with gr.Row():
259
+ with gr.Column():
260
+ init_button = gr.Button("πŸš€ Initialize EDUTUTOR AI", variant="primary", size="lg")
261
+ init_status = gr.Textbox(
262
+ label="Initialization Status",
263
+ value="Click 'Initialize EDUTUTOR AI' to start",
264
+ interactive=False
265
+ )
266
+
267
+ # Main interface
268
+ with gr.Row():
269
+ with gr.Column(scale=2):
270
+ # Input section
271
+ with gr.Group():
272
+ gr.Markdown("### πŸ“ Ask Your Question")
273
+ question_input = gr.Textbox(
274
+ label="Your Question",
275
+ placeholder="e.g., Explain quantum physics, How does photosynthesis work?, What is machine learning?",
276
+ lines=3
277
+ )
278
+
279
+ with gr.Row():
280
+ subject_dropdown = gr.Dropdown(
281
+ choices=[
282
+ "General", "Mathematics", "Physics", "Chemistry",
283
+ "Biology", "Computer Science", "History", "Literature",
284
+ "Geography", "Economics", "Philosophy"
285
+ ],
286
+ value="General",
287
+ label="Subject Area"
288
+ )
289
+
290
+ difficulty_dropdown = gr.Dropdown(
291
+ choices=["Beginner", "Intermediate", "Advanced"],
292
+ value="Intermediate",
293
+ label="Difficulty Level"
294
+ )
295
+
296
+ max_length_slider = gr.Slider(
297
+ minimum=100,
298
+ maximum=1000,
299
+ value=512,
300
+ step=50,
301
+ label="Response Length (tokens)"
302
+ )
303
+
304
+ ask_button = gr.Button("πŸ€” Ask EDUTUTOR AI", variant="primary")
305
+
306
+ with gr.Column(scale=1):
307
+ # Quick actions
308
+ with gr.Group():
309
+ gr.Markdown("### ⚑ Quick Actions")
310
+ analytics_button = gr.Button("πŸ“Š View Analytics")
311
+
312
+ gr.Markdown("### πŸ’‘ Tips")
313
+ gr.Markdown("""
314
+ - Login to track your learning progress
315
+ - Be specific with your questions
316
+ - Select appropriate subject and difficulty
317
+ - Use follow-up questions for deeper understanding
318
+ """)
319
+
320
+ # Response section
321
+ with gr.Row():
322
+ response_output = gr.Textbox(
323
+ label="πŸŽ“ EDUTUTOR AI Response",
324
+ lines=15,
325
+ max_lines=20,
326
+ interactive=False
327
+ )
328
+
329
+ # Analytics section
330
+ with gr.Row():
331
+ analytics_output = gr.Textbox(
332
+ label="πŸ“Š Usage Analytics",
333
+ lines=10,
334
+ interactive=False,
335
+ visible=False
336
+ )
337
+
338
+ # Event handlers
339
+ login_button.click(
340
+ fn=authenticate_user,
341
+ inputs=[username_input, password_input],
342
+ outputs=[gr.State(), login_status, user_info_state]
343
+ )
344
+
345
+ init_button.click(
346
+ fn=initialize_model,
347
+ outputs=init_status
348
+ )
349
+
350
+ ask_button.click(
351
+ fn=chat_with_edututor,
352
+ inputs=[question_input, subject_dropdown, difficulty_dropdown, max_length_slider, user_info_state],
353
+ outputs=response_output
354
+ )
355
+
356
+ analytics_button.click(
357
+ fn=get_user_analytics,
358
+ outputs=analytics_output
359
+ ).then(
360
+ fn=lambda: gr.update(visible=True),
361
+ outputs=analytics_output
362
+ )
363
+
364
+ return interface
365
+
366
+ # Launch the application
367
+ if __name__ == "__main__":
368
+ print("πŸŽ“ Starting EDUTUTOR AI with User Authentication...")
369
+ print("=" * 50)
370
+
371
+ demo = create_interface()
372
  demo.launch()