SyedaArisha/predictive-maintenance-rag-system
0
1"""2Phase 2 Runner — FAISS Indexing, RAG Semantic Retrieval, LLM Explanation, and Scheduling3Author: Antigravity AI4Date: August 20265 6This script coordinates:71. Synthesizing logs and building/saving the local FAISS index82. Initializing the LLM Explainer and Log Retriever93. Mocking telemetry anomalies based on classification/RUL alerts104. Querying the FAISS index for past cases (RAG context)115. Generating natural language explanations for the production manager126. Executing scheduling reassignments to mitigate risk13"""14 15import os16import sys17import logging18 19# Ensure src/ is in the import path20BASE_DIR = os.path.abspath(os.path.dirname(__file__))21sys.path.insert(0, os.path.join(BASE_DIR, 'src'))22 23from utils import set_seeds, ProductionScheduler24from rag import build_and_save_index, LogRetriever, LLMExplainer25 26# Setup logging27logging.basicConfig(28 level=logging.INFO,29 format='%(asctime)s [%(levelname)s] %(message)s',30 handlers=[31 logging.StreamHandler()32 ]33)34logger = logging.getLogger(__name__)35 36 37def main():38 set_seeds(42)39 40 # Define directories according to clean architecture41 data_raw_dir = os.path.join(BASE_DIR, 'data', 'raw')42 data_processed_dir = os.path.join(BASE_DIR, 'data', 'processed')43 models_rag_dir = os.path.join(BASE_DIR, 'models', 'rag')44 reports_dir = os.path.join(BASE_DIR, 'reports')45 46 os.makedirs(data_raw_dir, exist_ok=True)47 os.makedirs(data_processed_dir, exist_ok=True)48 os.makedirs(models_rag_dir, exist_ok=True)49 os.makedirs(reports_dir, exist_ok=True)50 51 # Paths52 sch_path = os.path.join(data_raw_dir, 'production_schedule.csv')53 mach_path = os.path.join(data_raw_dir, 'PdM_machines.csv')54 adj_path = os.path.join(data_processed_dir, 'adjusted_schedule.csv')55 56 logger.info("=========================================")57 logger.info("STARTING PHASE 2: FAISS, LLM, AND OPERATION SCHEDULING")58 logger.info("=========================================")59 60 # ----------------------------------------------------61 # STEP 1: BUILD FAISS INDEX62 # ----------------------------------------------------63 logger.info("\n--- STEP 1: Building local FAISS vector database index ---")64 build_and_save_index(data_raw_dir, models_rag_dir)65 66 # ----------------------------------------------------67 # STEP 2: INITIALIZE RETRIEVER AND EXPLAINER68 # ----------------------------------------------------69 logger.info("\n--- STEP 2: Loading retriever and explainer modules ---")70 retriever = LogRetriever(models_rag_dir)71 72 # To run instantly without waiting to download the 270MB LLM locally,73 # set use_fallback=True. Set to False if you want to download and test SmolLM2-135M.74 use_fallback = True75 if use_fallback:76 logger.info("Using rule-based fallback explainer template for instant local test.")77 else:78 logger.info("Downloading and loading SmolLM2-135M locally...")79 80 explainer = LLMExplainer(force_fallback=use_fallback)81 82 # ----------------------------------------------------83 # STEP 3: SIMULATE ANOMALOUS TELEMETRY & RUN RAG84 # ----------------------------------------------------85 logger.info("\n--- STEP 3: Simulating machine anomaly alerts & executing RAG queries ---")86 87 critical_alerts = {88 3: {'failure_probability': 0.88, 'rul': 12.5}, # Machine 3 high failure risk, low RUL89 12: {'failure_probability': 0.94, 'rul': 8.0} # Machine 12 high failure risk, low RUL90 }91 92 reports = {}93 for mid, alert in critical_alerts.items():94 query_str = f"Machine ID: {mid} component error telemetry anomalies"95 logger.info(f"Querying FAISS for: '{query_str}'")96 97 # Retrieve top 2 matching historical records98 hits = retriever.query(query_str, k=2)99 100 # Generate LLM explanation using retrieved records as context101 report = explainer.generate_explanation(102 machine_id=mid,103 failure_prob=alert['failure_probability'],104 rul=alert['rul'],105 historical_logs=hits106 )107 reports[mid] = report108 109 # Save report to reports folder110 report_path = os.path.join(reports_dir, f"machine_{mid}_explanation_report.md")111 with open(report_path, 'w', encoding='utf-8') as f:112 f.write(report)113 114 logger.info(f"Report for Machine {mid} saved to {report_path}")115 print("\n" + "="*50)116 print(f"EXPLANATION REPORT FOR MACHINE {mid}:")117 print("="*50)118 print(report)119 print("="*50 + "\n")120 121 # ----------------------------------------------------122 # STEP 4: RUN CLOSED-LOOP PRODUCTION SCHEDULER123 # ----------------------------------------------------124 logger.info("\n--- STEP 4: Running Production Scheduler to adjust operations ---")125 scheduler = ProductionScheduler(sch_path, mach_path)126 127 # Reroute jobs scheduled on at-risk machines (3 and 12) to healthy backups128 adjusted_schedule = scheduler.adjust_schedule(129 predictions=critical_alerts,130 output_adjusted_path=adj_path,131 failure_threshold=0.7,132 min_rul_hours=48.0133 )134 135 logger.info("=========================================")136 logger.info("PHASE 2 COMPLETED SUCCESSFULLY.")137 logger.info("=========================================")138 139 140if __name__ == '__main__':141 main()142 