andersoncliffb commited on
Commit
33178bf
Β·
verified Β·
1 Parent(s): 15d8e0e

Initial commit

Browse files
Files changed (4) hide show
  1. .gitignore +106 -0
  2. gradio_app.py +433 -0
  3. readme.md +96 -0
  4. requirements.txt +16 -0
.gitignore ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ downloads/
11
+ eggs/
12
+ .eggs/
13
+ lib/
14
+ lib64/
15
+ parts/
16
+ sdist/
17
+ var/
18
+ wheels/
19
+ pip-wheel-metadata/
20
+ share/python-wheels/
21
+ *.egg-info/
22
+ .installed.cfg
23
+ *.egg
24
+ MANIFEST
25
+
26
+ # PyInstaller
27
+ *.manifest
28
+ *.spec
29
+
30
+ # Installer logs
31
+ pip-log.txt
32
+ pip-delete-this-directory.txt
33
+
34
+ # Unit test / coverage reports
35
+ htmlcov/
36
+ .tox/
37
+ .nox/
38
+ .coverage
39
+ .coverage.*
40
+ .cache
41
+ nosetests.xml
42
+ coverage.xml
43
+ *.cover
44
+ *.py,cover
45
+ .hypothesis/
46
+ .pytest_cache/
47
+
48
+ # Virtual environments
49
+ .env
50
+ .venv
51
+ env/
52
+ venv/
53
+ ENV/
54
+ env.bak/
55
+ venv.bak/
56
+
57
+ # IDEs
58
+ .vscode/
59
+ .idea/
60
+ *.swp
61
+ *.swo
62
+ *~
63
+
64
+ # OS
65
+ .DS_Store
66
+ .DS_Store?
67
+ ._*
68
+ .Spotlight-V100
69
+ .Trashes
70
+ ehthumbs.db
71
+ Thumbs.db
72
+
73
+ # Gradio
74
+ gradio_cached_examples/
75
+ flagged/
76
+
77
+ # LlamaIndex
78
+ storage/
79
+ *.index
80
+
81
+ # Temporary files
82
+ tmp/
83
+ temp/
84
+ *.tmp
85
+ *.temp
86
+
87
+ # API keys and secrets
88
+ .env
89
+ .env.local
90
+ .env.*.local
91
+ config.json
92
+ secrets.json
93
+
94
+ # Large files
95
+ *.pdf
96
+ *.docx
97
+ *.doc
98
+ *.ppt
99
+ *.pptx
100
+ *.zip
101
+ *.tar.gz
102
+ *.rar
103
+
104
+ # Logs
105
+ *.log
106
+ logs/
gradio_app.py ADDED
@@ -0,0 +1,433 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+ import time
4
+ import tempfile
5
+ import shutil
6
+ from pathlib import Path
7
+ from collections import defaultdict
8
+ import json
9
+
10
+ # LlamaIndex imports
11
+ from llama_index.core import (
12
+ VectorStoreIndex,
13
+ SimpleDirectoryReader,
14
+ Settings,
15
+ StorageContext,
16
+ load_index_from_storage
17
+ )
18
+ from llama_index.core.node_parser import SentenceSplitter
19
+ from llama_index.llms.openrouter import OpenRouter
20
+ from llama_index.embeddings.huggingface import HuggingFaceEmbedding
21
+
22
+ # Global variables
23
+ current_index = None
24
+ current_query_engine = None
25
+ query_stats = defaultdict(list)
26
+ temp_doc_dir = None
27
+
28
+ # Available models
29
+ AVAILABLE_MODELS = {
30
+ "GPT-4o": "openai/gpt-4o",
31
+ "GPT-4o Mini": "openai/gpt-4o-mini",
32
+ "Claude 3.5 Sonnet": "anthropic/claude-3.5-sonnet",
33
+ "Claude 3 Haiku": "anthropic/claude-3-haiku",
34
+ "Llama 3.1 70B": "meta-llama/llama-3.1-70b-instruct",
35
+ "Llama 3.1 8B": "meta-llama/llama-3.1-8b-instruct",
36
+ "Mistral Large": "mistralai/mistral-large",
37
+ "Gemini Pro": "google/gemini-pro"
38
+ }
39
+
40
+ def initialize_embeddings():
41
+ """Initialize the embedding model"""
42
+ try:
43
+ Settings.embed_model = HuggingFaceEmbedding(
44
+ model_name="BAAI/bge-small-en-v1.5"
45
+ )
46
+ return "βœ“ Embedding model initialized successfully"
47
+ except Exception as e:
48
+ return f"❌ Error initializing embeddings: {str(e)}"
49
+
50
+ def setup_llm(api_key, model_name, temperature=0.1, max_tokens=512):
51
+ """Setup the language model"""
52
+ try:
53
+ if not api_key:
54
+ return None, "❌ API key is required"
55
+
56
+ model_id = AVAILABLE_MODELS.get(model_name, "openai/gpt-4o")
57
+
58
+ llm = OpenRouter(
59
+ api_key=api_key,
60
+ max_tokens=max_tokens,
61
+ context_window=4096,
62
+ model=model_id,
63
+ temperature=temperature
64
+ )
65
+
66
+ # Test the connection
67
+ test_response = llm.complete("Hello")
68
+ return llm, f"βœ“ {model_name} configured successfully"
69
+ except Exception as e:
70
+ return None, f"❌ Error setting up LLM: {str(e)}"
71
+
72
+ def process_uploaded_files(files, progress=gr.Progress()):
73
+ """Process uploaded files and create document index"""
74
+ global current_index, temp_doc_dir
75
+
76
+ if not files:
77
+ return "❌ No files uploaded", "", ""
78
+
79
+ try:
80
+ # Create temporary directory for documents
81
+ if temp_doc_dir and os.path.exists(temp_doc_dir):
82
+ shutil.rmtree(temp_doc_dir)
83
+
84
+ temp_doc_dir = tempfile.mkdtemp()
85
+
86
+ # Copy uploaded files to temp directory
87
+ file_info = []
88
+ progress(0, desc="Copying files...")
89
+
90
+ for i, file in enumerate(files):
91
+ if file is not None:
92
+ file_path = Path(file.name)
93
+ dest_path = os.path.join(temp_doc_dir, file_path.name)
94
+ shutil.copy2(file.name, dest_path)
95
+ file_info.append(f"β€’ {file_path.name} ({file_path.suffix})")
96
+ progress((i + 1) / len(files) * 0.3, desc=f"Copying {file_path.name}...")
97
+
98
+ progress(0.3, desc="Loading documents...")
99
+
100
+ # Load documents
101
+ documents = SimpleDirectoryReader(
102
+ input_dir=temp_doc_dir,
103
+ exclude_hidden=True,
104
+ recursive=True
105
+ ).load_data()
106
+
107
+ if not documents:
108
+ return "❌ No readable documents found", "", ""
109
+
110
+ progress(0.5, desc="Creating text chunks...")
111
+
112
+ # Configure text splitting
113
+ text_splitter = SentenceSplitter(
114
+ chunk_size=512,
115
+ chunk_overlap=50
116
+ )
117
+
118
+ progress(0.7, desc="Building vector index...")
119
+
120
+ # Create vector index
121
+ current_index = VectorStoreIndex.from_documents(
122
+ documents,
123
+ transformations=[text_splitter],
124
+ show_progress=False
125
+ )
126
+
127
+ progress(1.0, desc="Index created successfully!")
128
+
129
+ # Calculate statistics
130
+ total_chars = sum(len(doc.text) for doc in documents)
131
+
132
+ status = f"βœ“ Successfully processed {len(documents)} documents"
133
+ file_list = "\n".join(file_info)
134
+ stats = f"πŸ“Š Total content: ~{total_chars:,} characters\nπŸ“ Files processed: {len(files)}"
135
+
136
+ return status, file_list, stats
137
+
138
+ except Exception as e:
139
+ return f"❌ Error processing files: {str(e)}", "", ""
140
+
141
+ def create_query_engine(api_key, model_name, temperature, max_tokens, similarity_k):
142
+ """Create query engine with current settings"""
143
+ global current_query_engine
144
+
145
+ if not current_index:
146
+ return None, "❌ No document index available. Please upload documents first."
147
+
148
+ llm, llm_status = setup_llm(api_key, model_name, temperature, max_tokens)
149
+ if not llm:
150
+ return None, llm_status
151
+
152
+ try:
153
+ current_query_engine = current_index.as_query_engine(
154
+ llm=llm,
155
+ similarity_top_k=similarity_k,
156
+ response_mode="tree_summarize",
157
+ verbose=False
158
+ )
159
+ return current_query_engine, f"βœ“ Query engine ready with {model_name}"
160
+ except Exception as e:
161
+ return None, f"❌ Error creating query engine: {str(e)}"
162
+
163
+ def query_documents(question, api_key, model_name, temperature, max_tokens, similarity_k, show_sources):
164
+ """Query the document index"""
165
+ global query_stats
166
+
167
+ if not question.strip():
168
+ return "Please enter a question.", "", ""
169
+
170
+ if not current_index:
171
+ return "❌ No documents loaded. Please upload documents first.", "", ""
172
+
173
+ # Create/update query engine
174
+ query_engine, status = create_query_engine(api_key, model_name, temperature, max_tokens, similarity_k)
175
+ if not query_engine:
176
+ return status, "", ""
177
+
178
+ try:
179
+ start_time = time.time()
180
+
181
+ # Query the documents
182
+ response = query_engine.query(question)
183
+ query_time = time.time() - start_time
184
+
185
+ # Track statistics
186
+ query_stats['response_times'].append(query_time)
187
+ query_stats['questions'].append(question)
188
+
189
+ # Format response
190
+ answer = str(response)
191
+
192
+ # Format sources if requested
193
+ sources_text = ""
194
+ if show_sources and hasattr(response, 'source_nodes'):
195
+ sources_list = []
196
+ for i, node in enumerate(response.source_nodes, 1):
197
+ file_name = node.metadata.get('file_name', 'Unknown')
198
+ score = getattr(node, 'score', 0)
199
+ content_preview = node.text[:150] + "..." if len(node.text) > 150 else node.text
200
+ sources_list.append(f"**Source {i}:** {file_name} (relevance: {score:.3f})\n{content_preview}")
201
+ sources_text = "\n\n".join(sources_list)
202
+
203
+ # Performance info
204
+ perf_info = f"⏱️ Response time: {query_time:.2f}s | Model: {model_name}"
205
+
206
+ return answer, sources_text, perf_info
207
+
208
+ except Exception as e:
209
+ return f"❌ Error during query: {str(e)}", "", ""
210
+
211
+ def get_performance_stats():
212
+ """Get performance statistics"""
213
+ if not query_stats['response_times']:
214
+ return "No queries performed yet."
215
+
216
+ times = query_stats['response_times']
217
+ stats = f"""πŸ“Š **Performance Statistics** (based on {len(times)} queries)
218
+
219
+ β€’ Average response time: {sum(times)/len(times):.2f}s
220
+ β€’ Fastest response: {min(times):.2f}s
221
+ β€’ Slowest response: {max(times):.2f}s
222
+ β€’ Total queries: {len(times)}
223
+ """
224
+ return stats
225
+
226
+ def clear_all_data():
227
+ """Clear all data and reset the application"""
228
+ global current_index, current_query_engine, query_stats, temp_doc_dir
229
+
230
+ current_index = None
231
+ current_query_engine = None
232
+ query_stats = defaultdict(list)
233
+
234
+ if temp_doc_dir and os.path.exists(temp_doc_dir):
235
+ shutil.rmtree(temp_doc_dir)
236
+ temp_doc_dir = None
237
+
238
+ return "βœ“ All data cleared", "", "", "", ""
239
+
240
+ # Initialize embeddings on startup
241
+ embedding_status = initialize_embeddings()
242
+
243
+ # Create Gradio interface
244
+ with gr.Blocks(title="Document Q&A System", theme=gr.themes.Soft()) as app:
245
+ gr.Markdown("""
246
+ # πŸ“š Document Q&A System
247
+
248
+ Upload your documents and ask questions about them using advanced AI models.
249
+ Built with LlamaIndex and powered by multiple LLM providers through OpenRouter.
250
+ """)
251
+
252
+ with gr.Tab("πŸ“€ Upload Documents"):
253
+ gr.Markdown("### Upload Your Documents")
254
+ gr.Markdown("Supported formats: PDF, TXT, DOCX, MD, and more")
255
+
256
+ file_upload = gr.File(
257
+ label="Choose files",
258
+ file_count="multiple",
259
+ file_types=[".pdf", ".txt", ".docx", ".md", ".csv", ".json"]
260
+ )
261
+
262
+ upload_btn = gr.Button("Process Documents", variant="primary")
263
+
264
+ with gr.Row():
265
+ with gr.Column():
266
+ upload_status = gr.Textbox(label="Status", interactive=False)
267
+ file_list = gr.Textbox(label="Uploaded Files", lines=5, interactive=False)
268
+ with gr.Column():
269
+ doc_stats = gr.Textbox(label="Document Statistics", lines=5, interactive=False)
270
+
271
+ with gr.Tab("πŸ’¬ Ask Questions"):
272
+ gr.Markdown("### Query Your Documents")
273
+
274
+ with gr.Row():
275
+ with gr.Column(scale=2):
276
+ question_input = gr.Textbox(
277
+ label="Your Question",
278
+ placeholder="What would you like to know about the documents?",
279
+ lines=2
280
+ )
281
+
282
+ with gr.Row():
283
+ query_btn = gr.Button("Ask Question", variant="primary")
284
+ clear_btn = gr.Button("Clear All Data", variant="stop")
285
+
286
+ answer_output = gr.Textbox(
287
+ label="Answer",
288
+ lines=10,
289
+ interactive=False
290
+ )
291
+
292
+ performance_info = gr.Textbox(
293
+ label="Performance Info",
294
+ interactive=False
295
+ )
296
+
297
+ with gr.Column(scale=1):
298
+ gr.Markdown("### Settings")
299
+
300
+ api_key_input = gr.Textbox(
301
+ label="OpenRouter API Key",
302
+ placeholder="Enter your API key or leave empty to use HF secret",
303
+ type="password"
304
+ )
305
+
306
+ model_dropdown = gr.Dropdown(
307
+ label="Model",
308
+ choices=list(AVAILABLE_MODELS.keys()),
309
+ value="GPT-4o Mini",
310
+ interactive=True
311
+ )
312
+
313
+ temperature_slider = gr.Slider(
314
+ label="Temperature",
315
+ minimum=0.0,
316
+ maximum=2.0,
317
+ value=0.1,
318
+ step=0.1
319
+ )
320
+
321
+ max_tokens_slider = gr.Slider(
322
+ label="Max Tokens",
323
+ minimum=100,
324
+ maximum=2000,
325
+ value=512,
326
+ step=50
327
+ )
328
+
329
+ similarity_k_slider = gr.Slider(
330
+ label="Sources to Retrieve",
331
+ minimum=1,
332
+ maximum=10,
333
+ value=5,
334
+ step=1
335
+ )
336
+
337
+ show_sources_checkbox = gr.Checkbox(
338
+ label="Show Sources",
339
+ value=True
340
+ )
341
+
342
+ with gr.Accordion("πŸ“– Sources Used", open=False):
343
+ sources_output = gr.Textbox(
344
+ label="Source Documents",
345
+ lines=8,
346
+ interactive=False
347
+ )
348
+
349
+ with gr.Tab("πŸ“Š Performance"):
350
+ gr.Markdown("### Performance Statistics")
351
+
352
+ stats_btn = gr.Button("Refresh Stats")
353
+ performance_stats = gr.Textbox(
354
+ label="Statistics",
355
+ lines=10,
356
+ interactive=False
357
+ )
358
+
359
+ with gr.Tab("ℹ️ Help"):
360
+ gr.Markdown("""
361
+ ### How to Use This Application
362
+
363
+ 1. **Upload Documents**: Go to the "Upload Documents" tab and select your files
364
+ 2. **Process**: Click "Process Documents" to create the searchable index
365
+ 3. **Ask Questions**: Use the "Ask Questions" tab to query your documents
366
+ 4. **Adjust Settings**: Modify model parameters for different response styles
367
+
368
+ ### Best Practices for Questions
369
+
370
+ - 🎯 **Be specific**: "What does Smith say about feminist theology?" vs "Tell me about feminism"
371
+ - πŸ“š **Ask about concepts**: "What is religious authority?" rather than just names
372
+ - πŸ” **Use comparative questions**: "How do different scholars approach this topic?"
373
+ - πŸ“Š **Request analysis**: "What are the main arguments presented?"
374
+ - πŸ›οΈ **Ask about methodology**: "What research methods are discussed?"
375
+
376
+ ### API Key Setup
377
+
378
+ You can provide your OpenRouter API key in two ways:
379
+ 1. Enter it directly in the "API Key" field
380
+ 2. Set it as a Hugging Face Space secret named `OPENROUTER_API_KEY`
381
+
382
+ ### Model Information
383
+
384
+ Different models have different strengths:
385
+ - **GPT-4o**: Best overall performance, most accurate
386
+ - **Claude 3.5 Sonnet**: Excellent reasoning and analysis
387
+ - **Llama models**: Open source, good performance
388
+ - **Mistral**: Strong multilingual capabilities
389
+ """)
390
+
391
+ # Event handlers
392
+ upload_btn.click(
393
+ fn=process_uploaded_files,
394
+ inputs=[file_upload],
395
+ outputs=[upload_status, file_list, doc_stats],
396
+ show_progress=True
397
+ )
398
+
399
+ query_btn.click(
400
+ fn=query_documents,
401
+ inputs=[
402
+ question_input, api_key_input, model_dropdown,
403
+ temperature_slider, max_tokens_slider, similarity_k_slider,
404
+ show_sources_checkbox
405
+ ],
406
+ outputs=[answer_output, sources_output, performance_info]
407
+ )
408
+
409
+ clear_btn.click(
410
+ fn=clear_all_data,
411
+ inputs=[],
412
+ outputs=[upload_status, file_list, doc_stats, answer_output, sources_output]
413
+ )
414
+
415
+ stats_btn.click(
416
+ fn=get_performance_stats,
417
+ inputs=[],
418
+ outputs=[performance_stats]
419
+ )
420
+
421
+ # Auto-refresh API key from environment if not provided
422
+ def get_api_key():
423
+ return os.getenv("OPENROUTER_API_KEY", "")
424
+
425
+ app.load(
426
+ fn=get_api_key,
427
+ inputs=[],
428
+ outputs=[api_key_input]
429
+ )
430
+
431
+ # Launch the app
432
+ if __name__ == "__main__":
433
+ app.launch()
readme.md ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # πŸ“š Document Q&A System
2
+
3
+ A powerful document question-answering system built with LlamaIndex and Gradio. Upload your documents and ask questions about them using state-of-the-art AI models.
4
+
5
+ ## Features
6
+
7
+ πŸ” **Smart Document Processing**: Automatically processes various document formats (PDF, TXT, DOCX, MD, CSV, JSON)
8
+
9
+ πŸ€– **Multiple AI Models**: Choose from GPT-4o, Claude 3.5 Sonnet, Llama 3.1, Mistral, and more
10
+
11
+ πŸ“Š **Performance Monitoring**: Track response times and query statistics
12
+
13
+ 🎯 **Source Attribution**: See which document sections were used to generate answers
14
+
15
+ βš™οΈ **Customizable Settings**: Adjust temperature, token limits, and retrieval parameters
16
+
17
+ πŸ”’ **Secure API Key Management**: Use environment variables or direct input
18
+
19
+ ## How to Use
20
+
21
+ ### 1. Upload Documents
22
+ - Go to the "Upload Documents" tab
23
+ - Select your files (PDF, TXT, DOCX, MD, CSV, JSON)
24
+ - Click "Process Documents" to create the searchable index
25
+
26
+ ### 2. Configure Settings
27
+ - Add your OpenRouter API key (or set as HF Space secret)
28
+ - Choose your preferred AI model
29
+ - Adjust parameters like temperature and max tokens
30
+
31
+ ### 3. Ask Questions
32
+ - Enter your question in the "Ask Questions" tab
33
+ - Click "Ask Question" to get AI-powered answers
34
+ - View sources and performance metrics
35
+
36
+ ## API Key Setup
37
+
38
+ You can provide your OpenRouter API key in two ways:
39
+
40
+ 1. **Direct Input**: Enter it in the "API Key" field in the interface
41
+ 2. **Environment Variable**: Set `OPENROUTER_API_KEY` as a Hugging Face Space secret
42
+
43
+ Get your API key from [OpenRouter](https://openrouter.ai/)
44
+
45
+ ## Best Practices for Questions
46
+
47
+ - 🎯 **Be specific**: "What does the author say about climate change?" vs "Tell me about climate"
48
+ - πŸ“š **Ask about concepts**: "What is the main methodology discussed?"
49
+ - πŸ” **Use comparative questions**: "How do different studies approach this topic?"
50
+ - πŸ“Š **Request analysis**: "What are the key findings presented?"
51
+ - πŸ›οΈ **Ask about methodology**: "What research methods are used?"
52
+
53
+ ## Available Models
54
+
55
+ - **GPT-4o**: Best overall performance, most accurate
56
+ - **GPT-4o Mini**: Faster, cost-effective option
57
+ - **Claude 3.5 Sonnet**: Excellent reasoning and analysis
58
+ - **Claude 3 Haiku**: Fast and efficient
59
+ - **Llama 3.1 70B/8B**: Open source, strong performance
60
+ - **Mistral Large**: Strong multilingual capabilities
61
+ - **Gemini Pro**: Google's advanced model
62
+
63
+ ## Technical Details
64
+
65
+ Built with:
66
+ - **LlamaIndex**: Document indexing and retrieval
67
+ - **Gradio**: Web interface
68
+ - **OpenRouter**: Multi-model API access
69
+ - **HuggingFace Embeddings**: Text vectorization
70
+ - **BGE-small-en-v1.5**: Efficient embedding model
71
+
72
+ ## Performance
73
+
74
+ - Vector-based semantic search for accurate retrieval
75
+ - Cached indexing for fast subsequent queries
76
+ - Configurable chunk sizes and overlap for optimal results
77
+ - Real-time performance monitoring
78
+
79
+ ## Development
80
+
81
+ To run locally:
82
+
83
+ ```bash
84
+ git clone <your-repo>
85
+ cd document-qa-system
86
+ pip install -r requirements.txt
87
+ python app.py
88
+ ```
89
+
90
+ ## License
91
+
92
+ This project is open source and available under the MIT License.
93
+
94
+ ## Support
95
+
96
+ For issues or questions, please check the Help tab in the application or create an issue in the repository.
requirements.txt ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ gradio>=4.0.0
2
+ llama-index>=0.10.0
3
+ llama-index-core>=0.10.0
4
+ llama-index-llms-openrouter>=0.1.0
5
+ llama-index-embeddings-huggingface>=0.2.0
6
+ sentence-transformers>=2.2.0
7
+ torch>=2.0.0
8
+ transformers>=4.30.0
9
+ numpy>=1.24.0
10
+ pandas>=2.0.0
11
+ python-dotenv>=1.0.0
12
+ pathlib
13
+ tempfile
14
+ shutil
15
+ json
16
+ collections