AjaykumarPilla commited on
Commit
7ee1e44
·
verified ·
1 Parent(s): 42527db

Update model.py

Browse files
Files changed (1) hide show
  1. model.py +112 -70
model.py CHANGED
@@ -1,12 +1,5 @@
1
- from transformers import AutoModelForSeq2SeqLM, AutoTokenizer
2
- import torch
3
  import logging
4
  from typing import Dict, List
5
- import time
6
- try:
7
- import psutil
8
- except ImportError:
9
- psutil = None
10
 
11
  # Configure logging
12
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
@@ -29,75 +22,124 @@ def get_weather_condition(score: int) -> str:
29
 
30
  def call_ai_model_for_insights(input_data: Dict, delay_risk: float) -> List[str]:
31
  """
32
- Use T5-Small in Hugging Face Space (CPU) to generate insights based on input data and delay risk.
 
33
  """
34
- model_name = "t5-small"
35
- max_retries = 3
36
- retry_delay = 30 # Increased for network stability
37
-
38
- # Log system resources if psutil is available
39
- if psutil:
40
- try:
41
- memory = psutil.virtual_memory()
42
- logger.info(f"System memory - Total: {memory.total / 1e9:.2f} GB, Available: {memory.available / 1e9:.2f} GB, Used: {memory.percent}%")
43
- except Exception as e:
44
- logger.warning(f"Failed to log system memory: {str(e)}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  else:
46
- logger.warning("psutil not available; cannot log system memory usage")
47
-
48
- for attempt in range(max_retries):
49
- try:
50
- logger.info(f"Attempt {attempt + 1}/{max_retries} - Loading model: {model_name}")
51
- tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=False, use_fast=True)
52
- model = AutoModelForSeq2SeqLM.from_pretrained(
53
- model_name,
54
- torch_dtype=torch.float32,
55
- use_safetensors=True,
56
- trust_remote_code=False,
57
- low_cpu_mem_usage=True
58
- )
59
-
60
- logger.info("Model loaded successfully. Generating insights...")
61
- prompt = f"""
62
- Summarize risk:
63
- Risk: {delay_risk:.1f}%
64
-
65
- Format: ["Insight 1"].
66
- """
67
-
68
- with torch.no_grad():
69
- inputs = tokenizer(prompt, return_tensors="pt", max_length=8, truncation=True).to("cpu")
70
- outputs = model.generate(
71
- **inputs,
72
- max_new_tokens=5,
73
- num_beams=1,
74
- temperature=0.7,
75
- do_sample=True
76
- )
77
- response = tokenizer.decode(outputs[0], skip_special_tokens=True)
78
-
79
- insights = [line.strip() for line in response.split("\n") if line.strip() and line.strip() not in [prompt]]
80
- logger.info(f"Generated insights: {insights}")
81
- return insights[:1] or ["No insights generated."]
82
- except Exception as e:
83
- logger.error(f"Attempt {attempt + 1}/{max_retries} - Model inference failed: {str(e)}")
84
- if attempt < max_retries - 1:
85
- logger.info(f"Retrying in {retry_delay} seconds...")
86
- time.sleep(retry_delay)
87
- else:
88
- logger.error("Max retries reached. Using fallback insights.")
89
- fallback_insights = []
90
- if delay_risk > 75:
91
- fallback_insights.append("High risk detected.")
92
- elif delay_risk > 50:
93
- fallback_insights.append("Moderate risk found.")
94
- return fallback_insights or ["AI model failed to generate insights; check system resources."]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
 
96
  def predict_delay(input_data: Dict) -> Dict:
97
  """
98
  Predict delay probability based on project task data.
99
  Uses task duration, progress, workforce info, and weather impact.
100
- Insights are generated by T5-Small (CPU).
101
  """
102
  logger.info("Starting delay prediction")
103
  phase = input_data.get("phase", "")
@@ -173,7 +215,7 @@ def predict_delay(input_data: Dict) -> Dict:
173
  "risk": round(task_risk, 1)
174
  })
175
 
176
- # Generate AI-driven insights
177
  insights = call_ai_model_for_insights(input_data, delay_risk)
178
 
179
  logger.info(f"Prediction completed: Delay risk = {delay_risk:.1f}%")
 
 
 
1
  import logging
2
  from typing import Dict, List
 
 
 
 
 
3
 
4
  # Configure logging
5
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
 
22
 
23
  def call_ai_model_for_insights(input_data: Dict, delay_risk: float) -> List[str]:
24
  """
25
+ Generate detailed hardcoded insights based on input data and delay risk, bypassing T5-Small.
26
+ Returns 3-5 prioritized, phase/task-specific insights tailored to conditions.
27
  """
28
+ logger.info("Generating detailed hardcoded AI insights")
29
+ phase = input_data.get("phase", "")
30
+ task = input_data.get("task", "")
31
+ current_progress = input_data.get("current_progress", 0)
32
+ expected_duration = input_data.get("task_expected_duration", 0)
33
+ actual_duration = input_data.get("task_actual_duration", 0)
34
+ workforce_gap = input_data.get("workforce_gap", 0)
35
+ skill_level = input_data.get("workforce_skill_level", "").lower()
36
+ shift_hours = input_data.get("workforce_shift_hours", 0)
37
+ weather_score = input_data.get("weather_impact_score", 0)
38
+ weather_condition = input_data.get("weather_condition", get_weather_condition(weather_score))
39
+
40
+ # Initialize insights with scores for prioritization
41
+ insights = []
42
+
43
+ # Helper function to add insight with priority score
44
+ def add_insight(message: str, priority: float):
45
+ insights.append((message, priority))
46
+
47
+ # Delay risk-based insights
48
+ if delay_risk > 75:
49
+ add_insight(f"Urgent: Accelerate {phase}: {task} to mitigate high delay risk", 1.0)
50
+ elif delay_risk > 50:
51
+ add_insight(f"Monitor {phase}: {task} closely to prevent delays", 0.9)
52
+ elif delay_risk > 25:
53
+ add_insight(f"Maintain current pace for {phase}: {task}", 0.7)
54
  else:
55
+ add_insight(f"Optimize resource allocation for {phase}: {task}", 0.6)
56
+
57
+ # Phase/task-specific insights
58
+ task_specific = {
59
+ "Planning": {
60
+ "Define Scope": "Ensure clear stakeholder alignment for Planning: Define Scope",
61
+ "Resource Allocation": "Secure budget approvals early for Planning: Resource Allocation",
62
+ "Permit Acquisition": "Secure permits early for Planning: Permit Acquisition"
63
+ },
64
+ "Design": {
65
+ "Architectural Drafting": "Engage architects early for Design: Architectural Drafting",
66
+ "Engineering Analysis": "Hire additional engineers for Design: Engineering Analysis",
67
+ "Design Review": "Schedule thorough reviews for Design: Design Review"
68
+ },
69
+ "Construction": {
70
+ "Foundation Work": "Optimize material delivery for Construction: Foundation Work",
71
+ "Structural Build": "Ensure equipment availability for Construction: Structural Build",
72
+ "Utility Installation": "Coordinate subcontractors for Construction: Utility Installation"
73
+ }
74
+ }
75
+ if phase in task_specific and task in task_specific[phase]:
76
+ add_insight(task_specific[phase][task], 0.8)
77
+
78
+ # Workforce-based insights
79
+ if workforce_gap > 30:
80
+ add_insight(f"Hire subcontractors immediately to address {workforce_gap}% workforce shortage", 1.0)
81
+ elif workforce_gap > 15:
82
+ add_insight(f"Hire additional workers to reduce {workforce_gap}% workforce gap", 0.9)
83
+ elif workforce_gap > 5:
84
+ add_insight("Consider temporary staff to address minor workforce gap", 0.7)
85
+
86
+ if skill_level == "low":
87
+ add_insight(f"Provide training to improve low skill levels for {phase}: {task}", 0.9)
88
+ elif skill_level == "medium" and delay_risk > 50:
89
+ add_insight(f"Upskill workforce for efficiency in {phase}: {task}", 0.8)
90
+ elif skill_level == "high" and delay_risk < 25:
91
+ add_insight("Leverage high skill levels to maintain progress", 0.6)
92
+
93
+ if shift_hours < 6:
94
+ add_insight(f"Extend shift hours beyond {shift_hours} to meet {phase}: {task} deadlines", 0.9)
95
+ elif shift_hours < 8 and delay_risk > 50:
96
+ add_insight(f"Increase shift hours to {8} for {phase}: {task}", 0.8)
97
+ elif shift_hours > 10:
98
+ add_insight("Balance shifts to prevent burnout", 0.7)
99
+
100
+ # Weather-based insights
101
+ if weather_score > 70:
102
+ add_insight(f"Reschedule {phase}: {task} to avoid {weather_condition.lower()}", 1.0)
103
+ elif weather_score > 50:
104
+ add_insight(f"Shift to indoor tasks during {weather_condition.lower()} for {phase}: {task}", 0.9)
105
+ elif weather_score > 30:
106
+ add_insight(f"Continue monitoring {weather_condition.lower()} for {phase}: {task}", 0.7)
107
+
108
+ # Progress and duration-based insights
109
+ if expected_duration > 0 and actual_duration > expected_duration:
110
+ overrun_pct = ((actual_duration - expected_duration) / expected_duration) * 100
111
+ if overrun_pct > 20:
112
+ add_insight(f"Address duration overrun urgently for {phase}: {task}", 1.0)
113
+ elif overrun_pct > 10:
114
+ add_insight(f"Review scheduling to address {overrun_pct:.1f}% overrun in {phase}: {task}", 0.8)
115
+
116
+ if expected_duration > 0:
117
+ expected_progress = min((actual_duration / expected_duration) * 100, 100)
118
+ if current_progress < expected_progress * 0.8:
119
+ add_insight(f"Accelerate task progress for {phase}: {task} to align with schedule", 0.9)
120
+ elif current_progress < 50 and delay_risk > 50:
121
+ add_insight(f"Increase resources to boost {current_progress}% progress in {phase}: {task}", 0.8)
122
+
123
+ # Edge cases
124
+ if workforce_gap >= 90:
125
+ add_insight("Critical: Halt non-essential tasks until [Phase: Task] until workforce gap is resolved", 1.1)
126
+ if current_progress == 0 and delay_risk > 50:
127
+ add_insight(f"Initiate {phase}: {task} immediately to avoid further delays", 1.0)
128
+ if expected_duration == 0 or actual_duration == 0:
129
+ add_insight("Provide accurate duration estimates for reliable predictions", 0.7)
130
+
131
+ # Sort insights by priority and select top 3-5
132
+ insights.sort(key=lambda x: x[1], reverse=True)
133
+ selected_insights = [insight[0] for insight in insights[:5]]
134
+
135
+ logger.info(f"Generated insights: {selected_insights}")
136
+ return selected_insights or [f"No significant delay factors detected for {phase}: {task}"]
137
 
138
  def predict_delay(input_data: Dict) -> Dict:
139
  """
140
  Predict delay probability based on project task data.
141
  Uses task duration, progress, workforce info, and weather impact.
142
+ Insights are generated using detailed hardcoded rules.
143
  """
144
  logger.info("Starting delay prediction")
145
  phase = input_data.get("phase", "")
 
215
  "risk": round(task_risk, 1)
216
  })
217
 
218
+ # Generate hardcoded insights
219
  insights = call_ai_model_for_insights(input_data, delay_risk)
220
 
221
  logger.info(f"Prediction completed: Delay risk = {delay_risk:.1f}%")