david167 commited on
Commit
dcf4289
·
1 Parent(s): be67b49

Add missing gradio_app.py file

Browse files
Files changed (1) hide show
  1. gradio_app.py +339 -0
gradio_app.py ADDED
@@ -0,0 +1,339 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import logging
3
+ import time
4
+ import asyncio
5
+ from typing import List, Optional, Dict, Any
6
+ import threading
7
+
8
+ import torch
9
+ from transformers import AutoTokenizer, AutoModelForSeq2SeqLM
10
+ import gradio as gr
11
+
12
+ # Configure logging
13
+ logging.basicConfig(level=logging.INFO)
14
+ logger = logging.getLogger(__name__)
15
+
16
+ # Global variables for model and tokenizer
17
+ model = None
18
+ tokenizer = None
19
+ device = None
20
+ model_loaded = False
21
+
22
+ class ModelManager:
23
+ def __init__(self):
24
+ self.model = None
25
+ self.tokenizer = None
26
+ self.device = None
27
+ self.model_loaded = False
28
+ self.load_model()
29
+
30
+ def load_model(self):
31
+ """Load the model and tokenizer"""
32
+ try:
33
+ logger.info("Starting model loading...")
34
+
35
+ # Check if CUDA is available
36
+ self.device = "cuda" if torch.cuda.is_available() else "cpu"
37
+ logger.info(f"Using device: {self.device}")
38
+
39
+ if self.device == "cuda":
40
+ logger.info(f"GPU: {torch.cuda.get_device_name(0)}")
41
+ logger.info(f"VRAM Available: {torch.cuda.get_device_properties(0).total_memory / 1024**3:.2f} GB")
42
+
43
+ # Get HF token from environment
44
+ hf_token = os.getenv("HF_TOKEN")
45
+
46
+ logger.info("Loading FLAN-T5-Large model...")
47
+ base_model_name = "google/flan-t5-large"
48
+
49
+ self.tokenizer = AutoTokenizer.from_pretrained(
50
+ base_model_name,
51
+ use_fast=True,
52
+ trust_remote_code=True,
53
+ token=hf_token
54
+ )
55
+
56
+ self.model = AutoModelForSeq2SeqLM.from_pretrained(
57
+ base_model_name,
58
+ torch_dtype=torch.float16 if self.device == "cuda" else torch.float32,
59
+ device_map="auto" if self.device == "cuda" else None,
60
+ trust_remote_code=True,
61
+ low_cpu_mem_usage=True,
62
+ token=hf_token
63
+ )
64
+
65
+ if self.device == "cuda":
66
+ self.model = self.model.to(self.device)
67
+
68
+ self.model_loaded = True
69
+ logger.info("Model loaded successfully!")
70
+
71
+ except Exception as e:
72
+ logger.error(f"Error loading model: {str(e)}")
73
+ raise
74
+
75
+ def generate_questions(self, statement: str, num_questions: int = 5, difficulty: str = "mixed", temperature: float = 0.8) -> List[str]:
76
+ """Generate questions from a statement"""
77
+ if not self.model_loaded:
78
+ return ["Model not loaded yet. Please wait..."]
79
+
80
+ try:
81
+ difficulty_instruction = {
82
+ "easy": "simple, straightforward questions that test basic understanding",
83
+ "medium": "questions that require some analysis and comprehension",
84
+ "hard": "complex questions that require deep thinking and reasoning",
85
+ "mixed": "a mix of easy, medium, and hard questions"
86
+ }
87
+
88
+ # Create prompt optimized for T5
89
+ prompt = f"""Generate {num_questions} {difficulty_instruction[difficulty]} about this statement:
90
+
91
+ "{statement}"
92
+
93
+ Requirements:
94
+ - Clear, well-formed questions
95
+ - Vary question types (what, how, why, when, where)
96
+ - Number each question (1., 2., 3., etc.)
97
+ - End each question with a question mark
98
+
99
+ Questions:"""
100
+
101
+ # Generate questions
102
+ inputs = self.tokenizer(prompt, return_tensors="pt", truncation=True, max_length=512)
103
+ if self.device == "cuda":
104
+ inputs = inputs.to(self.device)
105
+
106
+ with torch.no_grad():
107
+ outputs = self.model.generate(
108
+ **inputs,
109
+ max_new_tokens=512,
110
+ temperature=temperature,
111
+ top_p=0.95,
112
+ do_sample=True,
113
+ num_beams=1,
114
+ early_stopping=True
115
+ )
116
+
117
+ # Decode the generated text
118
+ generated_text = self.tokenizer.decode(outputs[0], skip_special_tokens=True)
119
+
120
+ # Extract questions
121
+ questions = self.extract_questions(generated_text)
122
+
123
+ # Ensure we have the requested number of questions
124
+ questions = questions[:num_questions]
125
+
126
+ # If we don't have enough questions, add fallbacks
127
+ while len(questions) < num_questions:
128
+ questions.append(f"What is the main point of this statement: '{statement[:100]}...'?")
129
+
130
+ return questions
131
+
132
+ except Exception as e:
133
+ logger.error(f"Error generating questions: {str(e)}")
134
+ return [f"Error generating questions: {str(e)}"]
135
+
136
+ def extract_questions(self, generated_text: str) -> List[str]:
137
+ """Extract questions from the generated text"""
138
+ questions = []
139
+ lines = generated_text.split('\n')
140
+
141
+ for line in lines:
142
+ line = line.strip()
143
+ # Look for numbered questions
144
+ if line and (line[0].isdigit() or line.startswith('Q')):
145
+ # Remove numbering and clean up
146
+ question = line
147
+ # Remove common prefixes
148
+ for prefix in ['1.', '2.', '3.', '4.', '5.', '6.', '7.', '8.', '9.', '10.',
149
+ 'Q1:', 'Q2:', 'Q3:', 'Q4:', 'Q5:', 'Question 1:', 'Question 2:',
150
+ 'Question 3:', 'Question 4:', 'Question 5:']:
151
+ if question.startswith(prefix):
152
+ question = question[len(prefix):].strip()
153
+ break
154
+
155
+ if question and question.endswith('?'):
156
+ questions.append(question)
157
+
158
+ # If no numbered questions found, try to extract any questions
159
+ if not questions:
160
+ for line in lines:
161
+ line = line.strip()
162
+ if line.endswith('?') and len(line) > 10:
163
+ questions.append(line)
164
+
165
+ return questions
166
+
167
+ # Initialize model manager
168
+ model_manager = ModelManager()
169
+
170
+ def chat_with_model(message, history, num_questions, difficulty, temperature):
171
+ """Main chat function for Gradio interface"""
172
+ if not message.strip():
173
+ return history, ""
174
+
175
+ # Add user message to history
176
+ history.append([message, None])
177
+
178
+ # Generate questions
179
+ questions = model_manager.generate_questions(
180
+ statement=message,
181
+ num_questions=num_questions,
182
+ difficulty=difficulty,
183
+ temperature=temperature
184
+ )
185
+
186
+ # Format response
187
+ if questions:
188
+ response = "Here are the questions I generated based on your statement:\n\n"
189
+ for i, question in enumerate(questions, 1):
190
+ response += f"{i}. {question}\n"
191
+ else:
192
+ response = "I couldn't generate questions from that statement. Please try rephrasing it."
193
+
194
+ # Add bot response to history
195
+ history[-1][1] = response
196
+
197
+ return history, ""
198
+
199
+ def clear_chat():
200
+ """Clear the chat history"""
201
+ return [], ""
202
+
203
+ # Custom CSS for ChatGPT-like styling
204
+ css = """
205
+ #chatbot {
206
+ height: 600px;
207
+ }
208
+
209
+ .gradio-container {
210
+ max-width: 1200px !important;
211
+ margin: auto;
212
+ }
213
+
214
+ #component-0 {
215
+ height: 100vh;
216
+ }
217
+
218
+ .chat-message {
219
+ padding: 10px;
220
+ margin: 5px 0;
221
+ border-radius: 10px;
222
+ }
223
+
224
+ .user-message {
225
+ background-color: #e3f2fd;
226
+ margin-left: 20%;
227
+ }
228
+
229
+ .bot-message {
230
+ background-color: #f5f5f5;
231
+ margin-right: 20%;
232
+ }
233
+ """
234
+
235
+ # Create Gradio interface
236
+ with gr.Blocks(css=css, title="Question Generation AI", theme=gr.themes.Soft()) as demo:
237
+ gr.Markdown(
238
+ """
239
+ # 🤖 Question Generation AI
240
+ ### Powered by FLAN-T5-Large
241
+
242
+ Enter any statement or text, and I'll generate thoughtful questions about it. Perfect for creating study materials, assessments, or exploring topics deeper!
243
+ """
244
+ )
245
+
246
+ with gr.Row():
247
+ with gr.Column(scale=4):
248
+ chatbot = gr.Chatbot(
249
+ elem_id="chatbot",
250
+ label="Chat",
251
+ show_label=False,
252
+ avatar_images=(None, "🤖"),
253
+ bubble_full_width=False,
254
+ show_share_button=False
255
+ )
256
+
257
+ with gr.Row():
258
+ msg = gr.Textbox(
259
+ placeholder="Enter a statement or topic to generate questions about...",
260
+ show_label=False,
261
+ scale=4,
262
+ container=False
263
+ )
264
+ submit_btn = gr.Button("Generate Questions", variant="primary", scale=1)
265
+
266
+ with gr.Row():
267
+ clear_btn = gr.Button("Clear Chat", variant="secondary")
268
+
269
+ with gr.Column(scale=1, min_width=300):
270
+ gr.Markdown("### ⚙️ Settings")
271
+
272
+ num_questions = gr.Slider(
273
+ minimum=1,
274
+ maximum=10,
275
+ value=5,
276
+ step=1,
277
+ label="Number of Questions",
278
+ info="How many questions to generate"
279
+ )
280
+
281
+ difficulty = gr.Radio(
282
+ choices=["easy", "medium", "hard", "mixed"],
283
+ value="mixed",
284
+ label="Difficulty Level",
285
+ info="Choose the complexity of questions"
286
+ )
287
+
288
+ temperature = gr.Slider(
289
+ minimum=0.1,
290
+ maximum=2.0,
291
+ value=0.8,
292
+ step=0.1,
293
+ label="Creativity",
294
+ info="Higher = more creative questions"
295
+ )
296
+
297
+ gr.Markdown("### 💡 Tips")
298
+ gr.Markdown(
299
+ """
300
+ - **Be specific**: Detailed statements produce better questions
301
+ - **Try different difficulties**: Easy for basic recall, hard for analysis
302
+ - **Adjust creativity**: Higher values for more diverse questions
303
+ - **Examples to try**:
304
+ - "Photosynthesis converts sunlight into chemical energy"
305
+ - "The American Civil War lasted from 1861 to 1865"
306
+ - "Machine learning algorithms learn from data patterns"
307
+ """
308
+ )
309
+
310
+ # Event handlers
311
+ def respond(message, history, num_q, diff, temp):
312
+ return chat_with_model(message, history, num_q, diff, temp)
313
+
314
+ msg.submit(respond, [msg, chatbot, num_questions, difficulty, temperature], [chatbot, msg])
315
+ submit_btn.click(respond, [msg, chatbot, num_questions, difficulty, temperature], [chatbot, msg])
316
+ clear_btn.click(clear_chat, outputs=[chatbot, msg])
317
+
318
+ # Add footer
319
+ gr.Markdown(
320
+ """
321
+ ---
322
+ <div style="text-align: center; color: #666; font-size: 0.9em;">
323
+ Built with ❤️ using Gradio and FLAN-T5-Large •
324
+ <a href="/docs" target="_blank">API Documentation</a>
325
+ </div>
326
+ """
327
+ )
328
+
329
+ if __name__ == "__main__":
330
+ # Launch Gradio interface
331
+ demo.launch(
332
+ server_name="0.0.0.0",
333
+ server_port=7860,
334
+ share=False,
335
+ show_error=True,
336
+ show_tips=False,
337
+ enable_queue=True,
338
+ max_threads=10
339
+ )