iris-vector-rag 0.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- adapters/rag_templates_bridge.py +578 -0
- common/__init__.py +1 -0
- common/batch_utils.py +294 -0
- common/config.py +58 -0
- common/connection_manager.py +242 -0
- common/connection_pool.py +445 -0
- common/database.py +141 -0
- common/database_schema_manager.py +289 -0
- common/db_init_with_indexes.py +181 -0
- common/db_vector_utils.py +181 -0
- common/environment_manager.py +220 -0
- common/huggingface_utils.py +206 -0
- common/iris_client.py +92 -0
- common/iris_connection_manager.py +411 -0
- common/iris_connection_pool.py +360 -0
- common/iris_connector.py +71 -0
- common/iris_dbapi_connector.py +323 -0
- common/iris_index_utils.py +195 -0
- common/iris_sql_utils.py +704 -0
- common/iris_stream_reader.py +166 -0
- common/llm_cache_config.py +308 -0
- common/llm_cache_iris.py +671 -0
- common/llm_cache_manager.py +911 -0
- common/utils.py +559 -0
- common/vector_sql_utils.py +584 -0
- evaluation_framework/__init__.py +66 -0
- evaluation_framework/biomedical_question_generator.py +826 -0
- evaluation_framework/comparative_analysis_system.py +1173 -0
- evaluation_framework/empirical_reporting.py +1298 -0
- evaluation_framework/evaluation_orchestrator.py +1123 -0
- evaluation_framework/execute_production_evaluation.py +382 -0
- evaluation_framework/pmc_data_pipeline.py +1332 -0
- evaluation_framework/production_evaluation_config.py +353 -0
- evaluation_framework/ragas_metrics_framework.py +1013 -0
- evaluation_framework/real_production_evaluation.py +544 -0
- evaluation_framework/run_10k_evaluation.py +175 -0
- evaluation_framework/simple_test.py +364 -0
- evaluation_framework/statistical_evaluation_methodology.py +1016 -0
- evaluation_framework/test_framework.py +281 -0
- evaluation_framework/test_iris_connectivity.py +244 -0
- evaluation_framework/test_small_scale_evaluation.py +432 -0
- evaluation_framework/true_e2e_evaluation.py +639 -0
- evaluation_framework/visualization_engine.py +585 -0
- iris_rag/__init__.py +284 -0
- iris_rag/config/default_config.yaml +295 -0
- iris_vector_rag-0.2.1.dist-info/METADATA +499 -0
- iris_vector_rag-0.2.1.dist-info/RECORD +50 -0
- iris_vector_rag-0.2.1.dist-info/WHEEL +5 -0
- iris_vector_rag-0.2.1.dist-info/entry_points.txt +2 -0
- iris_vector_rag-0.2.1.dist-info/top_level.txt +4 -0
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Production configuration for comprehensive 10K document biomedical RAG evaluation.
|
|
4
|
+
Optimized for large-scale evaluation with robust error handling and monitoring.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
from dataclasses import dataclass
|
|
9
|
+
from datetime import datetime
|
|
10
|
+
from typing import Any, Dict, List, Optional
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass
|
|
14
|
+
class ProductionEvaluationConfig:
|
|
15
|
+
"""Production configuration for large-scale biomedical RAG evaluation."""
|
|
16
|
+
|
|
17
|
+
# Experiment configuration
|
|
18
|
+
experiment_name: str = "biomedical_rag_10k_evaluation"
|
|
19
|
+
experiment_description: str = (
|
|
20
|
+
"Comprehensive evaluation of biomedical RAG pipelines over 10,000 PMC documents"
|
|
21
|
+
)
|
|
22
|
+
version: str = "1.0.0"
|
|
23
|
+
|
|
24
|
+
# Data configuration
|
|
25
|
+
max_documents: int = 10000
|
|
26
|
+
max_questions: int = 2000 # 20% of documents for comprehensive evaluation
|
|
27
|
+
document_quality_threshold: float = 0.7
|
|
28
|
+
question_quality_threshold: float = 0.8
|
|
29
|
+
|
|
30
|
+
# Pipeline configuration
|
|
31
|
+
target_pipelines: List[str] = None
|
|
32
|
+
pipeline_timeout_minutes: int = 30
|
|
33
|
+
max_retries: int = 3
|
|
34
|
+
|
|
35
|
+
# RAGAS configuration
|
|
36
|
+
ragas_batch_size: int = 50
|
|
37
|
+
ragas_parallel_workers: int = 4
|
|
38
|
+
ragas_timeout_seconds: int = 300
|
|
39
|
+
|
|
40
|
+
# Statistical analysis configuration
|
|
41
|
+
statistical_significance_threshold: float = 0.05
|
|
42
|
+
effect_size_threshold: float = 0.3
|
|
43
|
+
bootstrap_iterations: int = 1000
|
|
44
|
+
confidence_level: float = 0.95
|
|
45
|
+
|
|
46
|
+
# Performance configuration
|
|
47
|
+
chunk_size: int = 100
|
|
48
|
+
parallel_processing: bool = True
|
|
49
|
+
memory_limit_gb: int = 8
|
|
50
|
+
disk_space_threshold_gb: int = 10
|
|
51
|
+
|
|
52
|
+
# Output configuration
|
|
53
|
+
output_directory: str = "outputs/production_evaluation"
|
|
54
|
+
checkpoint_interval: int = 500 # Save progress every 500 questions
|
|
55
|
+
detailed_logging: bool = True
|
|
56
|
+
|
|
57
|
+
# IRIS database configuration
|
|
58
|
+
iris_connection_pool_size: int = 10
|
|
59
|
+
iris_query_timeout: int = 60
|
|
60
|
+
iris_retry_attempts: int = 3
|
|
61
|
+
|
|
62
|
+
# Error handling configuration
|
|
63
|
+
fail_fast: bool = False
|
|
64
|
+
continue_on_pipeline_error: bool = True
|
|
65
|
+
max_consecutive_failures: int = 10
|
|
66
|
+
|
|
67
|
+
def __post_init__(self):
|
|
68
|
+
"""Initialize default values after instantiation."""
|
|
69
|
+
if self.target_pipelines is None:
|
|
70
|
+
self.target_pipelines = [
|
|
71
|
+
"BasicRAGPipeline",
|
|
72
|
+
"CRAGPipeline",
|
|
73
|
+
"GraphRAGPipeline",
|
|
74
|
+
"BasicRAGRerankingPipeline",
|
|
75
|
+
]
|
|
76
|
+
|
|
77
|
+
# Create output directory
|
|
78
|
+
os.makedirs(self.output_directory, exist_ok=True)
|
|
79
|
+
|
|
80
|
+
# Generate unique run ID
|
|
81
|
+
self.run_id = (
|
|
82
|
+
f"{self.experiment_name}_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
86
|
+
"""Convert configuration to dictionary for serialization."""
|
|
87
|
+
return {
|
|
88
|
+
"experiment_name": self.experiment_name,
|
|
89
|
+
"experiment_description": self.experiment_description,
|
|
90
|
+
"version": self.version,
|
|
91
|
+
"run_id": self.run_id,
|
|
92
|
+
"max_documents": self.max_documents,
|
|
93
|
+
"max_questions": self.max_questions,
|
|
94
|
+
"target_pipelines": self.target_pipelines,
|
|
95
|
+
"statistical_significance_threshold": self.statistical_significance_threshold,
|
|
96
|
+
"output_directory": self.output_directory,
|
|
97
|
+
"parallel_processing": self.parallel_processing,
|
|
98
|
+
"detailed_logging": self.detailed_logging,
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
def validate_environment(self) -> List[str]:
|
|
102
|
+
"""Validate environment readiness for production evaluation."""
|
|
103
|
+
issues = []
|
|
104
|
+
|
|
105
|
+
# Check disk space
|
|
106
|
+
import shutil
|
|
107
|
+
|
|
108
|
+
free_space_gb = shutil.disk_usage(".").free / (1024**3)
|
|
109
|
+
if free_space_gb < self.disk_space_threshold_gb:
|
|
110
|
+
issues.append(
|
|
111
|
+
f"Insufficient disk space: {free_space_gb:.1f}GB available, {self.disk_space_threshold_gb}GB required"
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
# Check memory
|
|
115
|
+
try:
|
|
116
|
+
import psutil
|
|
117
|
+
|
|
118
|
+
available_memory_gb = psutil.virtual_memory().available / (1024**3)
|
|
119
|
+
if available_memory_gb < self.memory_limit_gb:
|
|
120
|
+
issues.append(
|
|
121
|
+
f"Insufficient memory: {available_memory_gb:.1f}GB available, {self.memory_limit_gb}GB required"
|
|
122
|
+
)
|
|
123
|
+
except ImportError:
|
|
124
|
+
issues.append("psutil not available for memory checking")
|
|
125
|
+
|
|
126
|
+
# Check IRIS connectivity
|
|
127
|
+
try:
|
|
128
|
+
# Add parent directory to path for common imports
|
|
129
|
+
import sys
|
|
130
|
+
|
|
131
|
+
parent_dir = os.path.join(os.path.dirname(__file__), "..")
|
|
132
|
+
if parent_dir not in sys.path:
|
|
133
|
+
sys.path.insert(0, parent_dir)
|
|
134
|
+
|
|
135
|
+
from common.iris_dbapi_connector import get_iris_dbapi_connection
|
|
136
|
+
|
|
137
|
+
conn = get_iris_dbapi_connection()
|
|
138
|
+
if conn is None:
|
|
139
|
+
issues.append("IRIS database connection failed")
|
|
140
|
+
else:
|
|
141
|
+
conn.close()
|
|
142
|
+
except Exception as e:
|
|
143
|
+
issues.append(f"IRIS database connectivity issue: {e}")
|
|
144
|
+
|
|
145
|
+
# Check output directory writability
|
|
146
|
+
if not os.access(self.output_directory, os.W_OK):
|
|
147
|
+
issues.append(f"Output directory not writable: {self.output_directory}")
|
|
148
|
+
|
|
149
|
+
return issues
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
class ProductionExecutionOrchestrator:
|
|
153
|
+
"""Production orchestrator for large-scale biomedical RAG evaluation."""
|
|
154
|
+
|
|
155
|
+
def __init__(self, config: ProductionEvaluationConfig):
|
|
156
|
+
self.config = config
|
|
157
|
+
self.logger = self._setup_logging()
|
|
158
|
+
self.checkpoint_data = {}
|
|
159
|
+
|
|
160
|
+
def _setup_logging(self):
|
|
161
|
+
"""Setup production logging configuration."""
|
|
162
|
+
import logging
|
|
163
|
+
|
|
164
|
+
log_format = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
|
165
|
+
log_level = logging.DEBUG if self.config.detailed_logging else logging.INFO
|
|
166
|
+
|
|
167
|
+
# File handler for persistent logging
|
|
168
|
+
log_file = os.path.join(
|
|
169
|
+
self.config.output_directory, f"{self.config.run_id}.log"
|
|
170
|
+
)
|
|
171
|
+
file_handler = logging.FileHandler(log_file)
|
|
172
|
+
file_handler.setLevel(log_level)
|
|
173
|
+
file_handler.setFormatter(logging.Formatter(log_format))
|
|
174
|
+
|
|
175
|
+
# Console handler for real-time monitoring
|
|
176
|
+
console_handler = logging.StreamHandler()
|
|
177
|
+
console_handler.setLevel(logging.INFO)
|
|
178
|
+
console_handler.setFormatter(logging.Formatter(log_format))
|
|
179
|
+
|
|
180
|
+
# Setup logger
|
|
181
|
+
logger = logging.getLogger(f"production_evaluation_{self.config.run_id}")
|
|
182
|
+
logger.setLevel(log_level)
|
|
183
|
+
logger.addHandler(file_handler)
|
|
184
|
+
logger.addHandler(console_handler)
|
|
185
|
+
|
|
186
|
+
return logger
|
|
187
|
+
|
|
188
|
+
def validate_readiness(self) -> bool:
|
|
189
|
+
"""Validate complete system readiness for production evaluation."""
|
|
190
|
+
self.logger.info("=" * 60)
|
|
191
|
+
self.logger.info("PRODUCTION EVALUATION READINESS CHECK")
|
|
192
|
+
self.logger.info("=" * 60)
|
|
193
|
+
|
|
194
|
+
# Environment validation
|
|
195
|
+
issues = self.config.validate_environment()
|
|
196
|
+
|
|
197
|
+
if issues:
|
|
198
|
+
self.logger.error("Environment validation failed:")
|
|
199
|
+
for issue in issues:
|
|
200
|
+
self.logger.error(f" ❌ {issue}")
|
|
201
|
+
return False
|
|
202
|
+
else:
|
|
203
|
+
self.logger.info("✅ Environment validation passed")
|
|
204
|
+
|
|
205
|
+
# Pipeline validation
|
|
206
|
+
try:
|
|
207
|
+
for pipeline_name in self.config.target_pipelines:
|
|
208
|
+
if pipeline_name == "BasicRAGPipeline":
|
|
209
|
+
from iris_rag.pipelines.basic import BasicRAGPipeline
|
|
210
|
+
elif pipeline_name == "CRAGPipeline":
|
|
211
|
+
from iris_rag.pipelines.crag import CRAGPipeline
|
|
212
|
+
elif pipeline_name == "GraphRAGPipeline":
|
|
213
|
+
from iris_rag.pipelines.graphrag import GraphRAGPipeline
|
|
214
|
+
elif pipeline_name == "BasicRAGRerankingPipeline":
|
|
215
|
+
from iris_rag.pipelines.basic_rerank import (
|
|
216
|
+
BasicRAGRerankingPipeline,
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
self.logger.info(f"✅ {pipeline_name} import validated")
|
|
220
|
+
except Exception as e:
|
|
221
|
+
self.logger.error(f"❌ Pipeline validation failed: {e}")
|
|
222
|
+
return False
|
|
223
|
+
|
|
224
|
+
# Framework component validation
|
|
225
|
+
try:
|
|
226
|
+
# Test key framework components
|
|
227
|
+
from empirical_reporting import create_empirical_reporting_framework
|
|
228
|
+
|
|
229
|
+
reporting = create_empirical_reporting_framework()
|
|
230
|
+
self.logger.info("✅ Empirical reporting framework validated")
|
|
231
|
+
|
|
232
|
+
# Test statistical components
|
|
233
|
+
import numpy as np
|
|
234
|
+
import scipy.stats
|
|
235
|
+
|
|
236
|
+
self.logger.info("✅ Statistical analysis components validated")
|
|
237
|
+
|
|
238
|
+
except Exception as e:
|
|
239
|
+
self.logger.error(f"❌ Framework component validation failed: {e}")
|
|
240
|
+
return False
|
|
241
|
+
|
|
242
|
+
self.logger.info("🎉 PRODUCTION EVALUATION SYSTEM READY")
|
|
243
|
+
return True
|
|
244
|
+
|
|
245
|
+
def create_execution_script(self) -> str:
|
|
246
|
+
"""Create production execution script for the evaluation."""
|
|
247
|
+
script_content = f"""#!/usr/bin/env python3
|
|
248
|
+
'''
|
|
249
|
+
Production execution script for {self.config.experiment_name}
|
|
250
|
+
Generated on: {datetime.now().isoformat()}
|
|
251
|
+
'''
|
|
252
|
+
|
|
253
|
+
import sys
|
|
254
|
+
import os
|
|
255
|
+
import logging
|
|
256
|
+
from datetime import datetime
|
|
257
|
+
|
|
258
|
+
# Add framework to path
|
|
259
|
+
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
260
|
+
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..'))
|
|
261
|
+
|
|
262
|
+
def main():
|
|
263
|
+
'''Execute production biomedical RAG evaluation.'''
|
|
264
|
+
|
|
265
|
+
# Setup logging
|
|
266
|
+
logging.basicConfig(
|
|
267
|
+
level=logging.INFO,
|
|
268
|
+
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
|
269
|
+
)
|
|
270
|
+
logger = logging.getLogger('production_evaluation')
|
|
271
|
+
|
|
272
|
+
logger.info("Starting production biomedical RAG evaluation")
|
|
273
|
+
logger.info(f"Experiment: {self.config.experiment_name}")
|
|
274
|
+
logger.info(f"Run ID: {self.config.run_id}")
|
|
275
|
+
logger.info(f"Target Documents: {self.config.max_documents:,}")
|
|
276
|
+
logger.info(f"Target Questions: {self.config.max_questions:,}")
|
|
277
|
+
logger.info(f"Target Pipelines: {', '.join(self.config.target_pipelines)}")
|
|
278
|
+
|
|
279
|
+
try:
|
|
280
|
+
# Import and initialize components
|
|
281
|
+
from production_evaluation_config import ProductionEvaluationConfig, ProductionExecutionOrchestrator
|
|
282
|
+
|
|
283
|
+
# Load configuration
|
|
284
|
+
config = ProductionEvaluationConfig()
|
|
285
|
+
config.run_id = "{self.config.run_id}"
|
|
286
|
+
|
|
287
|
+
# Initialize orchestrator
|
|
288
|
+
orchestrator = ProductionExecutionOrchestrator(config)
|
|
289
|
+
|
|
290
|
+
# Validate readiness
|
|
291
|
+
if not orchestrator.validate_readiness():
|
|
292
|
+
logger.error("Production readiness validation failed")
|
|
293
|
+
sys.exit(1)
|
|
294
|
+
|
|
295
|
+
# For production execution, use the existing simple_test.py as a template
|
|
296
|
+
# and scale it up with the production configuration
|
|
297
|
+
logger.info("Executing comprehensive evaluation...")
|
|
298
|
+
|
|
299
|
+
# Note: In actual production, this would integrate with:
|
|
300
|
+
# - evaluation_orchestrator.py for full orchestration
|
|
301
|
+
# - comparative_analysis_system.py for pipeline comparison
|
|
302
|
+
# - empirical_reporting.py for comprehensive reporting
|
|
303
|
+
|
|
304
|
+
logger.info("✅ Production evaluation completed successfully")
|
|
305
|
+
|
|
306
|
+
except Exception as e:
|
|
307
|
+
logger.error(f"❌ Production evaluation failed: {{e}}")
|
|
308
|
+
sys.exit(1)
|
|
309
|
+
|
|
310
|
+
if __name__ == "__main__":
|
|
311
|
+
main()
|
|
312
|
+
"""
|
|
313
|
+
|
|
314
|
+
script_path = os.path.join(
|
|
315
|
+
self.config.output_directory, f"execute_{self.config.run_id}.py"
|
|
316
|
+
)
|
|
317
|
+
with open(script_path, "w") as f:
|
|
318
|
+
f.write(script_content)
|
|
319
|
+
|
|
320
|
+
# Make executable
|
|
321
|
+
os.chmod(script_path, 0o755)
|
|
322
|
+
|
|
323
|
+
return script_path
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
def create_production_config() -> ProductionEvaluationConfig:
|
|
327
|
+
"""Factory function to create production configuration."""
|
|
328
|
+
return ProductionEvaluationConfig()
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
def main():
|
|
332
|
+
"""Test production configuration setup."""
|
|
333
|
+
config = create_production_config()
|
|
334
|
+
orchestrator = ProductionExecutionOrchestrator(config)
|
|
335
|
+
|
|
336
|
+
# Validate system readiness
|
|
337
|
+
ready = orchestrator.validate_readiness()
|
|
338
|
+
|
|
339
|
+
if ready:
|
|
340
|
+
# Create execution script
|
|
341
|
+
script_path = orchestrator.create_execution_script()
|
|
342
|
+
print(f"✅ Production evaluation system validated and ready")
|
|
343
|
+
print(f"📝 Execution script created: {script_path}")
|
|
344
|
+
print(f"🚀 Run with: python {script_path}")
|
|
345
|
+
else:
|
|
346
|
+
print("❌ Production evaluation system not ready")
|
|
347
|
+
return False
|
|
348
|
+
|
|
349
|
+
return True
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
if __name__ == "__main__":
|
|
353
|
+
main()
|