Dinusha-Ekanayake commited on
Commit
39da5bf
·
verified ·
1 Parent(s): 2c99994

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +116 -29
app.py CHANGED
@@ -1,11 +1,20 @@
1
  import gradio as gr
2
  import os
 
3
  import torch
 
 
 
4
  from transformers import AutoModelForSequenceClassification, AutoTokenizer, AutoModelForSeq2SeqLM
 
 
5
 
6
- print("Booting up PredictiX Inference API (Direct Model Load)...")
7
 
8
  hf_token = os.environ.get("HF_TOKEN")
 
 
 
9
 
10
  # 1. Load Ticket Categorization Model
11
  try:
@@ -13,79 +22,157 @@ try:
13
  cat_id = cat_path if os.path.exists(cat_path) else "Dinusha-Ekanayake/predictix-ticket_categorization_model"
14
  cat_tokenizer = AutoTokenizer.from_pretrained(cat_id, token=hf_token)
15
  cat_model = AutoModelForSequenceClassification.from_pretrained(cat_id, token=hf_token)
 
 
16
  except Exception as e:
17
  cat_model = None
18
  print(f"Failed to load categorizer: {e}")
19
 
20
- # 2. Load Ticket Summarization Model
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  try:
22
  sum_path = "./predictix-ticket_summarization_model"
23
  ts_id = sum_path if os.path.exists(sum_path) else "Dinusha-Ekanayake/predictix-ticket_summarization_model"
24
  ts_tokenizer = AutoTokenizer.from_pretrained(ts_id, token=hf_token)
25
  ts_model = AutoModelForSeq2SeqLM.from_pretrained(ts_id, token=hf_token)
 
26
  except Exception as e:
27
  ts_model = None
28
  print(f"Failed to load ticket summarizer: {e}")
29
 
30
- # 3. Load Asset Summarization Model
31
  try:
32
  as_id = "Dinusha-Ekanayake/predictix-asset_summarization_model"
33
  as_tokenizer = AutoTokenizer.from_pretrained(as_id, token=hf_token)
34
  as_model = AutoModelForSeq2SeqLM.from_pretrained(as_id, token=hf_token)
 
35
  except Exception as e:
36
  as_model = None
37
  print(f"Failed to load asset summarizer: {e}")
38
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  # --- API Functions ---
40
  def categorize(text):
41
- if not cat_model: return {"error": "Categorization model not loaded."}
 
42
  inputs = cat_tokenizer(text, return_tensors="pt", truncation=True, max_length=512)
43
  with torch.no_grad():
44
- logits = cat_model(**inputs).logits
45
- # Get highest score
46
- probs = torch.nn.functional.softmax(logits, dim=-1)[0]
47
- best_idx = torch.argmax(probs).item()
48
- label = cat_model.config.id2label[best_idx]
49
- score = probs[best_idx].item()
50
- return [{"label": label, "score": score}]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
  def summarize_ticket(text):
53
- if not ts_model: return {"error": "Ticket Summarization model not loaded."}
 
54
  inputs = ts_tokenizer(text, return_tensors="pt", truncation=True, max_length=1024)
55
  with torch.no_grad():
56
  outputs = ts_model.generate(**inputs, min_length=15, max_length=150, num_beams=4, early_stopping=True)
57
- summary = ts_tokenizer.decode(outputs[0], skip_special_tokens=True)
58
- return {"summary": summary}
59
 
60
  def summarize_asset(text):
61
- if not as_model: return {"error": "Asset Summarization model not loaded."}
 
62
  inputs = as_tokenizer(text, return_tensors="pt", truncation=True, max_length=1024)
63
  with torch.no_grad():
64
  outputs = as_model.generate(**inputs, min_length=20, max_length=150, num_beams=4, early_stopping=True)
65
- summary = as_tokenizer.decode(outputs[0], skip_special_tokens=True)
66
- return {"summary": summary}
67
 
68
- # --- Server API Interface ---
69
  with gr.Blocks(title="PredictiX API") as demo:
70
- gr.Markdown("# PredictiX Internal Inference Server 🚀")
71
-
72
  with gr.Tab("Ticket Categorization"):
73
  cat_in = gr.Textbox(label="Ticket Title & Description")
74
  cat_out = gr.JSON(label="Categorization Result")
75
- cat_btn = gr.Button("Categorize")
76
- cat_btn.click(categorize, inputs=cat_in, outputs=cat_out, api_name="categorize")
77
-
 
 
 
 
78
  with gr.Tab("Ticket Summarization"):
79
  ts_in = gr.Textbox(label="Ticket Details")
80
  ts_out = gr.JSON(label="Summary")
81
- ts_btn = gr.Button("Summarize Ticket")
82
- ts_btn.click(summarize_ticket, inputs=ts_in, outputs=ts_out, api_name="summarize_ticket")
83
-
84
  with gr.Tab("Asset Summarization"):
85
  as_in = gr.Textbox(label="Asset Details")
86
  as_out = gr.JSON(label="Summary")
87
- as_btn = gr.Button("Summarize Asset")
88
- as_btn.click(summarize_asset, inputs=as_in, outputs=as_out, api_name="summarize_asset")
89
 
90
  if __name__ == "__main__":
91
- demo.launch()
 
1
  import gradio as gr
2
  import os
3
+ import re
4
  import torch
5
+ import joblib
6
+ import pandas as pd
7
+ import nltk
8
  from transformers import AutoModelForSequenceClassification, AutoTokenizer, AutoModelForSeq2SeqLM
9
+ from nltk.corpus import stopwords
10
+ from nltk.stem import PorterStemmer
11
 
12
+ print("Booting up PredictiX Inference API...")
13
 
14
  hf_token = os.environ.get("HF_TOKEN")
15
+ nltk.download("stopwords", quiet=True)
16
+ _stop_words = set(stopwords.words("english"))
17
+ _stemmer = PorterStemmer()
18
 
19
  # 1. Load Ticket Categorization Model
20
  try:
 
22
  cat_id = cat_path if os.path.exists(cat_path) else "Dinusha-Ekanayake/predictix-ticket_categorization_model"
23
  cat_tokenizer = AutoTokenizer.from_pretrained(cat_id, token=hf_token)
24
  cat_model = AutoModelForSequenceClassification.from_pretrained(cat_id, token=hf_token)
25
+ cat_model.eval()
26
+ print("Categorization model loaded.")
27
  except Exception as e:
28
  cat_model = None
29
  print(f"Failed to load categorizer: {e}")
30
 
31
+ # 2. Load Ticket Priority Model
32
+ try:
33
+ pri_path = "./ticket_priority_classification_model"
34
+ model_file = os.path.join(pri_path, "xgboost_vehicle_priority_model_3class.pkl")
35
+ encoder_file = os.path.join(pri_path, "priority_label_encoder.pkl")
36
+ pri_model = joblib.load(model_file)
37
+ pri_encoder = joblib.load(encoder_file)
38
+ print("Priority model loaded.")
39
+ except Exception as e:
40
+ pri_model = None
41
+ pri_encoder = None
42
+ print(f"Failed to load priority model: {e}")
43
+
44
+ # 3. Load Ticket Summarization Model
45
  try:
46
  sum_path = "./predictix-ticket_summarization_model"
47
  ts_id = sum_path if os.path.exists(sum_path) else "Dinusha-Ekanayake/predictix-ticket_summarization_model"
48
  ts_tokenizer = AutoTokenizer.from_pretrained(ts_id, token=hf_token)
49
  ts_model = AutoModelForSeq2SeqLM.from_pretrained(ts_id, token=hf_token)
50
+ print("Ticket summarization model loaded.")
51
  except Exception as e:
52
  ts_model = None
53
  print(f"Failed to load ticket summarizer: {e}")
54
 
55
+ # 4. Load Asset Summarization Model
56
  try:
57
  as_id = "Dinusha-Ekanayake/predictix-asset_summarization_model"
58
  as_tokenizer = AutoTokenizer.from_pretrained(as_id, token=hf_token)
59
  as_model = AutoModelForSeq2SeqLM.from_pretrained(as_id, token=hf_token)
60
+ print("Asset summarization model loaded.")
61
  except Exception as e:
62
  as_model = None
63
  print(f"Failed to load asset summarizer: {e}")
64
 
65
+
66
+ # --- Priority helpers ---
67
+ def _clean_text(text):
68
+ text = str(text).lower()
69
+ text = text.replace("pls", "please").replace("asap", "as soon as possible")
70
+ text = re.sub(r"[^a-zA-Z\s]", " ", text)
71
+ text = re.sub(r"\s+", " ", text).strip()
72
+ important = {"ac", "abs", "rpm"}
73
+ out = []
74
+ for tok in text.split():
75
+ if tok in important:
76
+ out.append(tok)
77
+ elif tok not in _stop_words and len(tok) > 2:
78
+ out.append(_stemmer.stem(tok))
79
+ return " ".join(out)
80
+
81
+ _HIGH_KEYWORDS = {
82
+ "fire", "smoke", "explosion", "fuel leak", "brake failure", "no brakes",
83
+ "engine seized", "total failure", "accident", "crash", "rollover",
84
+ "unsafe to drive", "cannot drive", "vehicle stopped", "complete breakdown",
85
+ "coolant leak", "overheating", "electrical fire", "cannot start",
86
+ }
87
+ _LOW_KEYWORDS = {
88
+ "scratch", "dent", "cosmetic", "minor", "small crack", "paint", "sticker",
89
+ "mirror", "wiper", "next service", "no rush", "low urgency",
90
+ "seat cover", "floor mat", "trim", "logo", "decal", "cleaning",
91
+ }
92
+
93
+
94
  # --- API Functions ---
95
  def categorize(text):
96
+ if not cat_model:
97
+ return {"error": "Categorization model not loaded."}
98
  inputs = cat_tokenizer(text, return_tensors="pt", truncation=True, max_length=512)
99
  with torch.no_grad():
100
+ probs = torch.softmax(cat_model(**inputs).logits, dim=-1)[0]
101
+ scores = [
102
+ {"label": cat_model.config.id2label[i], "score": round(float(s), 4)}
103
+ for i, s in enumerate(probs.tolist())
104
+ ]
105
+ scores.sort(key=lambda x: x["score"], reverse=True)
106
+ return scores
107
+
108
+
109
+ def prioritize(text):
110
+ if not pri_model:
111
+ return {"error": "Priority model not loaded."}
112
+ lower = text.lower()
113
+ if any(kw in lower for kw in _HIGH_KEYWORDS):
114
+ return {"priority": "High"}
115
+ if any(kw in lower for kw in _LOW_KEYWORDS):
116
+ return {"priority": "Low"}
117
+ row = pd.DataFrame([{
118
+ "combined_text": _clean_text(text),
119
+ "vehicle_type": "Truck",
120
+ "issue_category": "Engine",
121
+ "sensor_alert": "Check engine light",
122
+ "operating_environment": "Urban",
123
+ "weather_condition": "Normal",
124
+ "vehicle_age": 5,
125
+ "mileage_km": 100000,
126
+ "downtime_hours": 0.0,
127
+ "maintenance_overdue_days": 0,
128
+ "previous_failures": 0,
129
+ }])
130
+ pred = pri_model.predict(row)[0]
131
+ label = pri_encoder.inverse_transform([pred])[0]
132
+ return {"priority": label}
133
+
134
 
135
  def summarize_ticket(text):
136
+ if not ts_model:
137
+ return {"error": "Ticket Summarization model not loaded."}
138
  inputs = ts_tokenizer(text, return_tensors="pt", truncation=True, max_length=1024)
139
  with torch.no_grad():
140
  outputs = ts_model.generate(**inputs, min_length=15, max_length=150, num_beams=4, early_stopping=True)
141
+ return {"summary": ts_tokenizer.decode(outputs[0], skip_special_tokens=True)}
142
+
143
 
144
  def summarize_asset(text):
145
+ if not as_model:
146
+ return {"error": "Asset Summarization model not loaded."}
147
  inputs = as_tokenizer(text, return_tensors="pt", truncation=True, max_length=1024)
148
  with torch.no_grad():
149
  outputs = as_model.generate(**inputs, min_length=20, max_length=150, num_beams=4, early_stopping=True)
150
+ return {"summary": as_tokenizer.decode(outputs[0], skip_special_tokens=True)}
151
+
152
 
153
+ # --- Gradio UI ---
154
  with gr.Blocks(title="PredictiX API") as demo:
155
+ gr.Markdown("# PredictiX Internal Inference Server")
156
+
157
  with gr.Tab("Ticket Categorization"):
158
  cat_in = gr.Textbox(label="Ticket Title & Description")
159
  cat_out = gr.JSON(label="Categorization Result")
160
+ gr.Button("Categorize").click(categorize, inputs=cat_in, outputs=cat_out, api_name="categorize")
161
+
162
+ with gr.Tab("Ticket Priority"):
163
+ pri_in = gr.Textbox(label="Ticket Title & Description")
164
+ pri_out = gr.JSON(label="Priority Result")
165
+ gr.Button("Prioritize").click(prioritize, inputs=pri_in, outputs=pri_out, api_name="prioritize")
166
+
167
  with gr.Tab("Ticket Summarization"):
168
  ts_in = gr.Textbox(label="Ticket Details")
169
  ts_out = gr.JSON(label="Summary")
170
+ gr.Button("Summarize Ticket").click(summarize_ticket, inputs=ts_in, outputs=ts_out, api_name="summarize_ticket")
171
+
 
172
  with gr.Tab("Asset Summarization"):
173
  as_in = gr.Textbox(label="Asset Details")
174
  as_out = gr.JSON(label="Summary")
175
+ gr.Button("Summarize Asset").click(summarize_asset, inputs=as_in, outputs=as_out, api_name="summarize_asset")
 
176
 
177
  if __name__ == "__main__":
178
+ demo.launch()