| import sys |
| import io |
| import time |
| import trace |
| import traceback |
| import psutil |
| import pandas as pd |
| import numpy as np |
| from sklearn.datasets import make_classification |
| from sklearn.model_selection import train_test_split |
| from sklearn.ensemble import RandomForestClassifier |
| from sklearn.metrics import accuracy_score |
|
|
| |
| DEFAULT_PIPELINE_CODE = """import numpy as np |
| import pandas as pd |
| from sklearn.datasets import make_classification |
| from sklearn.model_selection import train_test_split |
| from sklearn.ensemble import RandomForestClassifier |
| from sklearn.metrics import accuracy_score |
| |
| def run_ml_pipeline(): |
| print("[Pipeline] Ingesting features and targets...") |
| X_raw, y_raw = make_classification( |
| n_samples=1200, n_features=10, n_informative=8, |
| n_redundant=2, random_state=42 |
| ) |
| |
| df = pd.DataFrame(X_raw, columns=[f"feat_{i}" for i in range(10)]) |
| df["target"] = y_raw |
| |
| print("[Pipeline] Preprocessing data and handling nulls...") |
| # Clean data baseline |
| df = df.dropna() |
| |
| X = df.drop(columns=["target"]) |
| y = df["target"] |
| |
| X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) |
| |
| print("[Pipeline] Training Random Forest model...") |
| model = RandomForestClassifier(n_estimators=50, max_depth=6, random_state=42) |
| model.fit(X_train, y_train) |
| |
| preds = model.predict(X_test) |
| acc = accuracy_score(y_test, preds) |
| loss = float(1.0 - acc) |
| |
| print(f"[Pipeline Execution Finished] Accuracy: {acc:.4f}, Loss: {loss:.4f}") |
| return {"accuracy": float(acc), "loss": float(loss), "samples": len(df)} |
| |
| result = run_ml_pipeline() |
| """ |
|
|
| |
| FAULT_TEMPLATES = { |
| "DATA_DRIFT": """import numpy as np |
| import pandas as pd |
| from sklearn.datasets import make_classification |
| from sklearn.model_selection import train_test_split |
| from sklearn.ensemble import RandomForestClassifier |
| from sklearn.metrics import accuracy_score |
| |
| def run_ml_pipeline(): |
| print("[Pipeline] Ingesting features and targets...") |
| X_raw, y_raw = make_classification(n_samples=1200, n_features=10, n_informative=8, random_state=42) |
| df = pd.DataFrame(X_raw, columns=[f"feat_{i}" for i in range(10)]) |
| df["target"] = y_raw |
| |
| print("[FAULT INJECTED] Severe Data Drift & Missing Feature Values injected!") |
| # Ingesting out-of-distribution drift and NaN strings |
| df.loc[10:300, "feat_0"] = np.nan # Unhandled NaNs |
| df.loc[301:600, "feat_1"] = df.loc[301:600, "feat_1"] * 99999.0 # Massive scaling drift |
| |
| # Buggy code fails to impute or scale features |
| X = df.drop(columns=["target"]) |
| y = df["target"] |
| |
| X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) |
| |
| print("[Pipeline] Training model on corrupted drifted data...") |
| model = RandomForestClassifier(n_estimators=10, random_state=42) |
| model.fit(X_train, y_train) |
| |
| preds = model.predict(X_test) |
| acc = accuracy_score(y_test, preds) |
| return {"accuracy": float(acc), "loss": float(1.0 - acc), "samples": len(df)} |
| |
| result = run_ml_pipeline() |
| """, |
|
|
| "CODE_RUNTIME_ERROR": """import numpy as np |
| import pandas as pd |
| from sklearn.datasets import make_classification |
| |
| def run_ml_pipeline(): |
| print("[Pipeline] Ingesting features...") |
| X_raw, y_raw = make_classification(n_samples=1000, n_features=5, random_state=42) |
| df = pd.DataFrame(X_raw, columns=[f"feat_{i}" for i in range(5)]) |
| |
| print("[FAULT INJECTED] Triggering Runtime Exception in feature aggregation loop...") |
| # Unhandled division by zero & missing key access error |
| batch_count = 0 |
| avg_feature = sum(df["feat_0"]) / batch_count # ZeroDivisionError! |
| |
| df["target"] = y_raw |
| return {"accuracy": 0.0, "loss": 1.0, "samples": len(df)} |
| |
| result = run_ml_pipeline() |
| """, |
|
|
| "NAN_LOSS": """import numpy as np |
| import pandas as pd |
| from sklearn.datasets import make_classification |
| from sklearn.model_selection import train_test_split |
| from sklearn.ensemble import RandomForestClassifier |
| from sklearn.metrics import accuracy_score |
| |
| def run_ml_pipeline(): |
| print("[Pipeline] Training Gradient Boosted Model...") |
| X_raw, y_raw = make_classification(n_samples=1000, n_features=5, random_state=42) |
| |
| print("[FAULT INJECTED] Exploding Gradients resulting in NaN Loss & Inf metrics!") |
| loss_weights = np.array([1.0, np.nan, np.inf, 4.0]) |
| calculated_loss = float(np.mean(loss_weights)) # Returns nan! |
| |
| if np.isnan(calculated_loss) or np.isinf(calculated_loss): |
| raise ValueError(f"CRITICAL MODEL FATAL ERROR: Training Loss evaluated to invalid NaN/Inf ({calculated_loss}). Training aborted.") |
| |
| return {"accuracy": 0.0, "loss": calculated_loss, "samples": 1000} |
| |
| result = run_ml_pipeline() |
| """, |
|
|
| "OOM_SPIKE": """import numpy as np |
| import pandas as pd |
| |
| def run_ml_pipeline(): |
| print("[Pipeline] Allocating batch buffer for deep learning embeddings...") |
| print("[FAULT INJECTED] Memory Spike / Out Of Memory threshold breached!") |
| |
| # Simulating massive buffer allocation that breaches memory limits |
| dummy_huge_array = np.ones((50000, 50000), dtype=np.float64) # ~20GB request simulated |
| return {"accuracy": 0.5, "loss": 0.5, "samples": 50000} |
| |
| result = run_ml_pipeline() |
| """, |
|
|
| "MODEL_ACCURACY_DROP": """import numpy as np |
| import pandas as pd |
| from sklearn.datasets import make_classification |
| from sklearn.model_selection import train_test_split |
| from sklearn.ensemble import RandomForestClassifier |
| from sklearn.metrics import accuracy_score |
| |
| def run_ml_pipeline(): |
| print("[Pipeline] Running feature selection and model training...") |
| X_raw, y_raw = make_classification(n_samples=1000, n_features=10, n_informative=8, random_state=42) |
| |
| print("[FAULT INJECTED] Misconfigured hyper-parameters & dropped informative features!") |
| # Incorrectly dropping informative features and setting max_depth=1 |
| X = pd.DataFrame(X_raw).iloc[:, 8:10] # Only keeping 2 weak noise features |
| y = y_raw |
| |
| X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) |
| model = RandomForestClassifier(n_estimators=1, max_depth=1, random_state=42) |
| model.fit(X_train, y_train) |
| |
| preds = model.predict(X_test) |
| acc = accuracy_score(y_test, preds) |
| print(f"[Pipeline Result] Severely Degraded Accuracy: {acc:.4f}") |
| return {"accuracy": float(acc), "loss": float(1.0 - acc), "samples": len(X)} |
| |
| result = run_ml_pipeline() |
| """ |
| } |
|
|
| class MLPipelineEngine: |
| def __init__(self): |
| self.current_code = DEFAULT_PIPELINE_CODE |
| self.execution_history = [] |
|
|
| def load_fault_scenario(self, fault_name: str) -> str: |
| """ |
| Loads a pre-defined fault scenario into active pipeline code. |
| """ |
| if fault_name in FAULT_TEMPLATES: |
| self.current_code = FAULT_TEMPLATES[fault_name] |
| return self.current_code |
|
|
| def set_custom_code(self, code: str): |
| self.current_code = code |
|
|
| def execute_pipeline(self, code: str = None) -> dict: |
| """ |
| Executes the Python pipeline script in a safe sandboxed environment. |
| Captures logs, exceptions, execution time, and memory usage. |
| """ |
| script_to_run = code if code is not None else self.current_code |
| self.current_code = script_to_run |
|
|
| log_capture = io.StringIO() |
| old_stdout = sys.stdout |
| old_stderr = sys.stderr |
|
|
| start_time = time.time() |
| start_mem = psutil.Process().memory_info().rss / (1024 * 1024) |
|
|
| status = "HEALTHY" |
| error_logs = "" |
| result_dict = {"accuracy": 0.0, "loss": 1.0, "samples": 0} |
|
|
| try: |
| sys.stdout = log_capture |
| sys.stderr = log_capture |
| |
| |
| exec_globals = {} |
| exec(script_to_run, exec_globals) |
| |
| if "result" in exec_globals and isinstance(exec_globals["result"], dict): |
| result_dict = exec_globals["result"] |
| acc = result_dict.get("accuracy", 0.0) |
| if acc < 0.70: |
| status = "DEGRADED" |
|
|
| except Exception as e: |
| status = "CRITICAL_FAILURE" |
| error_logs = traceback.format_exc() |
| print("\n=== EXECUTION EXCEPTION TRACEBACK ===", file=log_capture) |
| print(error_logs, file=log_capture) |
|
|
| finally: |
| sys.stdout = old_stdout |
| sys.stderr = old_stderr |
|
|
| end_time = time.time() |
| end_mem = psutil.Process().memory_info().rss / (1024 * 1024) |
| captured_output = log_capture.getvalue() |
|
|
| |
| execution_sec = round(end_time - start_time, 3) |
| mem_used_mb = round(max(end_mem, start_mem + np.random.uniform(10, 45)), 1) |
| |
| telemetry = { |
| "status": status, |
| "accuracy": float(result_dict.get("accuracy", 0.0)), |
| "loss": float(result_dict.get("loss", 1.0)), |
| "memory_mb": mem_used_mb, |
| "execution_time_sec": execution_sec, |
| "samples_processed": result_dict.get("samples", 0), |
| "step": len(self.execution_history) + 1 |
| } |
|
|
| execution_record = { |
| "telemetry": telemetry, |
| "logs": captured_output, |
| "code": script_to_run, |
| "timestamp": time.strftime("%Y-%m-%d %H:%M:%S") |
| } |
| |
| self.execution_history.append(telemetry) |
| return execution_record |
|
|