Bryceeee commited on
Commit
9a5aebe
Β·
verified Β·
1 Parent(s): 2185b3f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +158 -139
app.py CHANGED
@@ -1,12 +1,12 @@
1
  """
2
- Hugging Face Spaces Entry Point for CSRC Car Manual RAG System
3
- Optimized version with timeout protection and lazy loading
4
  """
5
  import os
6
  import sys
7
  from pathlib import Path
8
- import signal
9
- from contextlib import contextmanager
10
 
11
  # Add the current directory to Python path for Spaces environment
12
  sys.path.insert(0, str(Path(__file__).parent))
@@ -47,31 +47,28 @@ except ImportError as e:
47
  SCENARIO_CONTEXTUALIZATION_AVAILABLE = False
48
  print(f"⚠️ Scenario contextualization modules not available: {e}")
49
 
 
 
 
 
50
 
51
- class TimeoutError(Exception):
52
- pass
53
 
54
-
55
- @contextmanager
56
- def timeout(seconds):
57
- """Context manager for timeout operations"""
58
- def timeout_handler(signum, frame):
59
- raise TimeoutError(f"Operation timed out after {seconds} seconds")
60
-
61
- # Set the signal handler
62
- old_handler = signal.signal(signal.SIGALRM, timeout_handler)
63
- signal.alarm(seconds)
64
-
65
- try:
66
- yield
67
- finally:
68
- # Restore the old handler
69
- signal.alarm(0)
70
- signal.signal(signal.SIGALRM, old_handler)
71
 
72
 
73
  def initialize_system(config: Config) -> dict:
74
- """Initialize the RAG system components"""
 
 
 
 
 
 
 
 
75
  print("πŸ”§ Initializing core components...")
76
 
77
  # Initialize OpenAI client
@@ -122,62 +119,48 @@ def initialize_system(config: Config) -> dict:
122
  print("πŸ”§ Initializing knowledge graph...")
123
  knowledge_graph = KnowledgeGraphGenerator(client, vector_store_id, str(config.output_dir))
124
 
125
- # Initialize personalized learning (if available) - with timeout
126
  user_profiling = None
127
  learning_path_generator = None
128
  adaptive_engine = None
129
 
130
  if PERSONALIZED_LEARNING_AVAILABLE:
131
  try:
132
- print("πŸ”§ Initializing personalized learning...")
133
- with timeout(10):
134
- user_profiling = UserProfilingSystem()
135
- learning_path_generator = LearningPathGenerator(user_profiling, config.available_topics)
136
- adaptive_engine = AdaptiveLearningEngine(user_profiling, learning_path_generator)
137
  print("βœ… Personalized Learning System initialized!")
138
- except TimeoutError:
139
- print("⚠️ Personalized Learning System initialization timed out - skipping")
140
  except Exception as e:
141
  print(f"⚠️ Error initializing Personalized Learning System: {e}")
142
 
143
- # Initialize proactive learning (if available) - with timeout
144
  proactive_engine = None
145
  if PROACTIVE_LEARNING_AVAILABLE and user_profiling:
146
  try:
147
- print("πŸ”§ Initializing proactive learning...")
148
- with timeout(10):
149
- proactive_engine = ProactiveLearningEngine(
150
- client, rag_engine, user_profiling, adaptive_engine, config.available_topics
151
- )
152
  print("βœ… Proactive Learning Assistance initialized!")
153
- except TimeoutError:
154
- print("⚠️ Proactive Learning Assistance initialization timed out - skipping")
155
  except Exception as e:
156
  print(f"⚠️ Error initializing Proactive Learning Assistance: {e}")
157
 
158
- # Initialize scenario contextualization (if available) - with timeout
159
  enhanced_rag_engine = None
160
  if SCENARIO_CONTEXTUALIZATION_AVAILABLE:
161
  try:
162
- print("πŸ”§ Initializing scenario contextualization...")
163
- with timeout(15):
164
- scenario_database = ScenarioDatabase()
165
- feature_extractor = ADASFeatureExtractor(use_llm=False, client=client)
166
- scenario_retriever = ScenarioRetriever(
167
- scenario_database=scenario_database,
168
- scenario_vector_store_id=None,
169
- client=client
170
- )
171
- formatter = ConstructiveFormatter()
172
- enhanced_rag_engine = EnhancedRAGEngine(
173
- base_rag_engine=rag_engine,
174
- scenario_retriever=scenario_retriever,
175
- feature_extractor=feature_extractor,
176
- formatter=formatter
177
- )
178
  print("βœ… Scenario Contextualization initialized!")
179
- except TimeoutError:
180
- print("⚠️ Scenario Contextualization initialization timed out - skipping")
181
  except Exception as e:
182
  print(f"⚠️ Error initializing Scenario Contextualization: {e}")
183
 
@@ -197,41 +180,87 @@ def initialize_system(config: Config) -> dict:
197
  }
198
 
199
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
  def create_app():
201
- """Create and return the Gradio app for Hugging Face Spaces"""
 
 
 
 
 
202
  print("=" * 60)
203
- print("πŸš— CSRC Car Manual RAG System - Hugging Face Spaces")
204
  print("=" * 60)
205
 
206
  # Load configuration
207
  config = Config()
208
 
209
- # Initialize system with timeout
210
  try:
211
- print("⏱️ Starting initialization (max 90 seconds)...")
212
- with timeout(90):
213
- components = initialize_system(config)
214
- except TimeoutError:
215
- print("❌ System initialization timed out!")
216
- import gradio as gr
217
- error_msg = """
218
- # ❌ Initialization Timeout
219
-
220
- The system took too long to initialize. This usually happens when:
221
- 1. Vector store creation is slow
222
- 2. Too many modules are being loaded at startup
223
-
224
- **Suggested solutions:**
225
- 1. Reduce the number of modules loaded at startup
226
- 2. Use a smaller vector store
227
- 3. Implement lazy loading for optional features
228
- """
229
- return gr.Interface(
230
- fn=lambda: error_msg,
231
- inputs=None,
232
- outputs=gr.Markdown(),
233
- title="CSRC Car Manual RAG System",
234
- )
235
  except Exception as e:
236
  print(f"❌ Error initializing system: {e}")
237
  import traceback
@@ -243,15 +272,7 @@ def create_app():
243
 
244
  **Error:** {str(e)}
245
 
246
- **Possible solutions:**
247
- 1. Check if OPENAI_API_KEY is set in Spaces Secrets (Settings > Secrets)
248
- 2. Ensure PDF files are in the `car_manual/` directory
249
- 3. Check the logs for more details
250
-
251
- **Traceback:**
252
- ```
253
- {traceback.format_exc()}
254
- ```
255
  """
256
 
257
  return gr.Interface(
@@ -261,46 +282,39 @@ def create_app():
261
  title="CSRC Car Manual RAG System",
262
  )
263
 
264
- # Build Gradio interface with timeout
 
 
 
 
 
 
 
265
  print("\n🌐 Building Gradio interface...")
266
  try:
267
- print("⏱️ Creating interface (max 30 seconds)...")
268
- with timeout(30):
269
- interface_builder = GradioInterfaceBuilder(
270
- rag_engine=components["rag_engine"],
271
- question_generator=components["question_generator"],
272
- knowledge_graph=components["knowledge_graph"],
273
- config=components["config"],
274
- user_profiling=components["user_profiling"],
275
- adaptive_engine=components["adaptive_engine"],
276
- proactive_engine=components["proactive_engine"]
277
- )
278
-
279
- print("πŸ“¦ Creating interface components...")
280
- demo = interface_builder.create_interface()
281
- print("βœ… Gradio interface created successfully!")
282
- return demo
283
- except TimeoutError:
284
- print("❌ Gradio interface creation timed out!")
285
- import gradio as gr
286
- error_msg = """
287
- # ❌ Interface Creation Timeout
288
 
289
- The Gradio interface took too long to create. This usually happens when:
290
- 1. Too many components are being created
291
- 2. Complex initialization in component callbacks
292
 
293
- **Suggested solutions:**
294
- 1. Simplify the interface
295
- 2. Use lazy loading for complex components
296
- 3. Move initialization logic out of interface creation
297
- """
298
- return gr.Interface(
299
- fn=lambda: error_msg,
300
- inputs=None,
301
- outputs=gr.Markdown(),
302
- title="CSRC Car Manual RAG System",
303
  )
 
 
 
 
304
  except Exception as e:
305
  print(f"❌ Error building Gradio interface: {e}")
306
  import traceback
@@ -311,11 +325,6 @@ def create_app():
311
  # ❌ Interface Building Error
312
 
313
  **Error:** {str(e)}
314
-
315
- **Traceback:**
316
- ```
317
- {traceback.format_exc()}
318
- ```
319
  """
320
 
321
  return gr.Interface(
@@ -326,11 +335,16 @@ def create_app():
326
  )
327
 
328
 
329
- # Prevent multiple initializations
330
  _app_instance = None
331
 
332
  def get_app():
333
- """Get or create the app instance (singleton pattern)"""
 
 
 
 
 
334
  global _app_instance
335
  if _app_instance is None:
336
  print("πŸ”„ Creating new app instance...")
@@ -341,10 +355,15 @@ def get_app():
341
  return _app_instance
342
 
343
 
344
- # For Hugging Face Spaces
345
  if __name__ == "__main__":
346
  demo = get_app()
347
- demo.launch()
 
 
 
 
 
348
  else:
349
  # Module-level variable for Spaces auto-detection
350
  demo = get_app()
 
1
  """
2
+ Performance-Optimized Hugging Face Spaces Entry Point
3
+ Solves slow response and loading issues
4
  """
5
  import os
6
  import sys
7
  from pathlib import Path
8
+ import asyncio
9
+ from concurrent.futures import ThreadPoolExecutor
10
 
11
  # Add the current directory to Python path for Spaces environment
12
  sys.path.insert(0, str(Path(__file__).parent))
 
47
  SCENARIO_CONTEXTUALIZATION_AVAILABLE = False
48
  print(f"⚠️ Scenario contextualization modules not available: {e}")
49
 
50
+ # Performance configuration
51
+ ENABLE_CACHING = True # Enable query caching
52
+ MAX_WORKERS = 4 # Thread pool size
53
+ QUERY_TIMEOUT = 30 # Query timeout in seconds
54
 
55
+ # Global thread pool for async processing
56
+ executor = ThreadPoolExecutor(max_workers=MAX_WORKERS)
57
 
58
+ # Simple in-memory cache for queries
59
+ query_cache = {}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
 
61
 
62
  def initialize_system(config: Config) -> dict:
63
+ """
64
+ Initialize the RAG system components with performance optimization
65
+
66
+ Args:
67
+ config: Configuration object
68
+
69
+ Returns:
70
+ Dictionary containing all initialized components
71
+ """
72
  print("πŸ”§ Initializing core components...")
73
 
74
  # Initialize OpenAI client
 
119
  print("πŸ”§ Initializing knowledge graph...")
120
  knowledge_graph = KnowledgeGraphGenerator(client, vector_store_id, str(config.output_dir))
121
 
122
+ # Initialize optional modules (with reduced logging)
123
  user_profiling = None
124
  learning_path_generator = None
125
  adaptive_engine = None
126
 
127
  if PERSONALIZED_LEARNING_AVAILABLE:
128
  try:
129
+ user_profiling = UserProfilingSystem()
130
+ learning_path_generator = LearningPathGenerator(user_profiling, config.available_topics)
131
+ adaptive_engine = AdaptiveLearningEngine(user_profiling, learning_path_generator)
 
 
132
  print("βœ… Personalized Learning System initialized!")
 
 
133
  except Exception as e:
134
  print(f"⚠️ Error initializing Personalized Learning System: {e}")
135
 
 
136
  proactive_engine = None
137
  if PROACTIVE_LEARNING_AVAILABLE and user_profiling:
138
  try:
139
+ proactive_engine = ProactiveLearningEngine(
140
+ client, rag_engine, user_profiling, adaptive_engine, config.available_topics
141
+ )
 
 
142
  print("βœ… Proactive Learning Assistance initialized!")
 
 
143
  except Exception as e:
144
  print(f"⚠️ Error initializing Proactive Learning Assistance: {e}")
145
 
 
146
  enhanced_rag_engine = None
147
  if SCENARIO_CONTEXTUALIZATION_AVAILABLE:
148
  try:
149
+ scenario_database = ScenarioDatabase()
150
+ feature_extractor = ADASFeatureExtractor(use_llm=False, client=client)
151
+ scenario_retriever = ScenarioRetriever(
152
+ scenario_database=scenario_database,
153
+ scenario_vector_store_id=None,
154
+ client=client
155
+ )
156
+ formatter = ConstructiveFormatter()
157
+ enhanced_rag_engine = EnhancedRAGEngine(
158
+ base_rag_engine=rag_engine,
159
+ scenario_retriever=scenario_retriever,
160
+ feature_extractor=feature_extractor,
161
+ formatter=formatter
162
+ )
 
 
163
  print("βœ… Scenario Contextualization initialized!")
 
 
164
  except Exception as e:
165
  print(f"⚠️ Error initializing Scenario Contextualization: {e}")
166
 
 
180
  }
181
 
182
 
183
+ def create_optimized_query_wrapper(rag_engine):
184
+ """
185
+ Create an optimized query wrapper with caching, timeout, and async processing
186
+
187
+ Args:
188
+ rag_engine: The RAG query engine to wrap
189
+
190
+ Returns:
191
+ Optimized query function
192
+ """
193
+ def query_with_optimization(question: str, use_cache: bool = True) -> str:
194
+ """
195
+ Optimized query function with caching and timeout protection
196
+
197
+ Args:
198
+ question: User's question
199
+ use_cache: Whether to use cache (default: True)
200
+
201
+ Returns:
202
+ Answer string
203
+ """
204
+ if not question or not question.strip():
205
+ return "Please enter a question."
206
+
207
+ # Normalize question for cache key
208
+ cache_key = question.strip().lower()
209
+
210
+ # Check cache
211
+ if use_cache and ENABLE_CACHING and cache_key in query_cache:
212
+ print(f"πŸ“‹ Using cached result for: {question[:50]}...")
213
+ return query_cache[cache_key]
214
+
215
+ try:
216
+ print(f"πŸ” Processing query: {question[:50]}...")
217
+
218
+ # Execute query using thread pool (non-blocking)
219
+ future = executor.submit(rag_engine.query, question)
220
+
221
+ # Wait for result with timeout
222
+ result = future.result(timeout=QUERY_TIMEOUT)
223
+
224
+ # Cache the result
225
+ if ENABLE_CACHING:
226
+ query_cache[cache_key] = result
227
+ # Limit cache size
228
+ if len(query_cache) > 100:
229
+ # Remove oldest entry
230
+ query_cache.pop(next(iter(query_cache)))
231
+
232
+ print(f"βœ… Query completed successfully")
233
+ return result
234
+
235
+ except TimeoutError:
236
+ error_msg = "⏱️ Query timeout. Please try a simpler question or try again later."
237
+ print(error_msg)
238
+ return error_msg
239
+ except Exception as e:
240
+ error_msg = f"❌ Error processing query: {str(e)}"
241
+ print(error_msg)
242
+ return error_msg
243
+
244
+ return query_with_optimization
245
+
246
+
247
  def create_app():
248
+ """
249
+ Create and return the optimized Gradio app for Hugging Face Spaces
250
+
251
+ Returns:
252
+ Gradio Blocks app
253
+ """
254
  print("=" * 60)
255
+ print("πŸš— CSRC Car Manual RAG System - Performance Optimized")
256
  print("=" * 60)
257
 
258
  # Load configuration
259
  config = Config()
260
 
261
+ # Initialize system
262
  try:
263
+ components = initialize_system(config)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
264
  except Exception as e:
265
  print(f"❌ Error initializing system: {e}")
266
  import traceback
 
272
 
273
  **Error:** {str(e)}
274
 
275
+ Please check the logs for more details.
 
 
 
 
 
 
 
 
276
  """
277
 
278
  return gr.Interface(
 
282
  title="CSRC Car Manual RAG System",
283
  )
284
 
285
+ # Create optimized query wrapper
286
+ optimized_query = create_optimized_query_wrapper(components["rag_engine"])
287
+
288
+ # Replace original RAG engine query method with optimized version
289
+ original_query = components["rag_engine"].query
290
+ components["rag_engine"].query = optimized_query
291
+
292
+ # Build Gradio interface
293
  print("\n🌐 Building Gradio interface...")
294
  try:
295
+ interface_builder = GradioInterfaceBuilder(
296
+ rag_engine=components["rag_engine"],
297
+ question_generator=components["question_generator"],
298
+ knowledge_graph=components["knowledge_graph"],
299
+ config=components["config"],
300
+ user_profiling=components["user_profiling"],
301
+ adaptive_engine=components["adaptive_engine"],
302
+ proactive_engine=components["proactive_engine"]
303
+ )
 
 
 
 
 
 
 
 
 
 
 
 
304
 
305
+ print("πŸ“¦ Creating interface components...")
306
+ demo = interface_builder.create_interface()
 
307
 
308
+ # Enable queue for better performance
309
+ print("⚑ Enabling queue for better performance...")
310
+ demo.queue(
311
+ max_size=20, # Maximum queue size
312
+ default_concurrency_limit=5 # Concurrency limit
 
 
 
 
 
313
  )
314
+
315
+ print("βœ… Gradio interface created successfully!")
316
+ return demo
317
+
318
  except Exception as e:
319
  print(f"❌ Error building Gradio interface: {e}")
320
  import traceback
 
325
  # ❌ Interface Building Error
326
 
327
  **Error:** {str(e)}
 
 
 
 
 
328
  """
329
 
330
  return gr.Interface(
 
335
  )
336
 
337
 
338
+ # Prevent multiple initializations using singleton pattern
339
  _app_instance = None
340
 
341
  def get_app():
342
+ """
343
+ Get or create the app instance (singleton pattern)
344
+
345
+ Returns:
346
+ Gradio app instance
347
+ """
348
  global _app_instance
349
  if _app_instance is None:
350
  print("πŸ”„ Creating new app instance...")
 
355
  return _app_instance
356
 
357
 
358
+ # For Hugging Face Spaces auto-detection
359
  if __name__ == "__main__":
360
  demo = get_app()
361
+ demo.launch(
362
+ server_name="0.0.0.0",
363
+ server_port=7860,
364
+ show_error=True, # Show detailed errors
365
+ favicon_path=None, # Skip favicon loading for faster startup
366
+ )
367
  else:
368
  # Module-level variable for Spaces auto-detection
369
  demo = get_app()