Barisha commited on
Commit
b817834
Β·
verified Β·
1 Parent(s): 563f077

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +59 -91
app.py CHANGED
@@ -1,140 +1,108 @@
1
  import gradio as gr
2
- import numpy as np
3
  import pandas as pd
4
- import torch
5
  import time
6
- from transformers import AutoTokenizer, AutoModelForCausalLM
7
-
8
- # ---------- Model ----------
9
- MODEL_NAME = "microsoft/Phi-3-mini-4k-instruct"
10
 
11
- tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
12
- model = AutoModelForCausalLM.from_pretrained(
13
- MODEL_NAME,
14
- device_map="cpu",
15
- torch_dtype=torch.float32
16
- )
17
 
18
- # ---------- Trend Logic ----------
19
  def detect_trend(values):
20
- diffs = np.diff(values)
21
- if len(diffs) == 0:
22
- return "FLAT"
23
- if all(d > 0 for d in diffs):
 
 
24
  return "INCREASING"
25
- elif all(d < 0 for d in diffs):
26
  return "DECREASING"
27
- else:
28
- return "MIXED"
29
-
30
 
31
  def change_score(values):
32
- values = np.array(values, dtype=float)
33
  if len(values) < 2:
34
  return 0
35
- std = np.std(values)
36
- change = abs(values[-1] - values[0])
37
- return round((change / (std + 1e-6)), 4)
38
 
39
- # ---------- LLM Explanation ----------
40
  def explain(kpi, values, trend):
41
- # βœ… limit values to max 50 numbers
42
- short_values = values[:50]
43
-
44
  prompt = f"""
45
- You are a telecom KPI expert.
46
- KPI name: {kpi}
47
- Values (sample): {short_values}
48
- Detected trend: {trend}
49
-
50
- In 2 short sentences explain what this trend might mean.
51
  """
52
- inputs = tokenizer(prompt, return_tensors="pt", truncation=True, max_length=2048)
53
- output = model.generate(**inputs, max_new_tokens=120)
54
- return tokenizer.decode(output[0], skip_special_tokens=True)
 
 
 
 
55
 
56
- # ---------- File Loader ----------
57
- def load_csv(file):
58
  if file is None:
59
- return None, gr.update(choices=[])
60
 
61
  df = pd.read_csv(file.name)
62
- numeric_cols = df.select_dtypes(include=np.number).columns.tolist()
63
-
64
- return df, gr.update(choices=numeric_cols, value=numeric_cols[:5])
65
 
66
- # ---------- Main Analysis ----------
67
- def analyze(df, selected_kpis, progress=gr.Progress()):
68
- start = time.time()
69
- print("βœ… Analyze function triggered")
70
-
71
- if df is None or not selected_kpis:
72
- return "❌ Upload CSV and select KPI columns"
73
 
74
- progress(0, desc="Starting analysis...")
 
75
 
76
  results = []
77
- explanations = []
78
- total = len(selected_kpis)
79
 
80
- for i, kpi in enumerate(selected_kpis):
81
- progress((i + 1) / total, desc=f"Analyzing {kpi}...")
 
82
 
83
- vals = df[kpi].dropna().values.tolist()
84
  trend = detect_trend(vals)
85
  score = change_score(vals)
86
 
87
  results.append((kpi, trend, score, vals))
88
 
 
89
  ranked = sorted(results, key=lambda x: x[2], reverse=True)
90
 
91
- # LLM step
92
  progress(0.9, desc="Generating LLM explanations...")
93
 
 
94
  for kpi, trend, score, vals in ranked[:5]:
95
- short_vals = vals[:50] # βœ… FIX TOKEN OVERFLOW
96
  try:
97
- exp = explain(kpi, short_vals, trend)
98
  except Exception as e:
99
- exp = f"⚠️ LLM Error: {str(e)}"
100
  explanations.append(f"**{kpi}** β†’ {exp}")
101
 
102
- progress(1.0, desc="Done βœ…")
103
-
104
- elapsed = round(time.time() - start, 2)
105
-
106
- text = f"⏱ Time taken: {elapsed}s\n\n"
107
- text += "## πŸ”₯ Top 5 KPIs\n"
108
 
 
 
 
109
  for kpi, trend, score, _ in ranked[:5]:
110
- text += f"**{kpi}** β†’ {trend} (Score: {score})\n\n"
111
 
112
- text += "## 🧠 LLM Explanations\n"
113
  for e in explanations:
114
- text += f"{e}\n\n"
115
-
116
- return text
117
-
118
- # ---------- UI ----------
119
- with gr.Blocks() as demo:
120
- gr.Markdown("# πŸ€– KPI Trend Analyzer with LLM Explanation")
121
-
122
- file = gr.File(label="Upload CSV")
123
- kpi_select = gr.CheckboxGroup(label="Select KPI columns", choices=[])
124
 
125
- df_state = gr.State()
126
 
127
- file.upload(fn=load_csv, inputs=file, outputs=[df_state, kpi_select])
 
 
128
 
129
- analyze_btn = gr.Button("Analyze")
130
- output = gr.Markdown()
 
131
 
132
- analyze_btn.click(
133
- fn=analyze,
134
- inputs=[df_state, kpi_select],
135
- outputs=output,
136
- show_progress=True
137
- )
138
 
139
- # βœ… Share link required in HF Spaces
140
- demo.launch(share=True)
 
1
  import gradio as gr
 
2
  import pandas as pd
3
+ import numpy as np
4
  import time
5
+ from transformers import pipeline
 
 
 
6
 
7
+ # ---- LLM ----
8
+ MODEL_NAME = "google/flan-t5-base"
9
+ llm = pipeline("text2text-generation", model=MODEL_NAME)
 
 
 
10
 
11
+ # ---- Helpers ----
12
  def detect_trend(values):
13
+ if len(values) < 2:
14
+ return "NO DATA"
15
+ x = np.arange(len(values))
16
+ y = np.array(values)
17
+ slope = np.polyfit(x, y, 1)[0]
18
+ if slope > 0:
19
  return "INCREASING"
20
+ elif slope < 0:
21
  return "DECREASING"
22
+ return "STABLE"
 
 
23
 
24
  def change_score(values):
 
25
  if len(values) < 2:
26
  return 0
27
+ return float(np.std(values))
 
 
28
 
 
29
  def explain(kpi, values, trend):
30
+ values = values[:50] # prevent token overflow
 
 
31
  prompt = f"""
32
+ Explain KPI trend.
33
+ KPI: {kpi}
34
+ Trend: {trend}
35
+ Values: {values}
36
+ Explain shortly.
 
37
  """
38
+ out = llm(prompt, max_new_tokens=80)
39
+ return out[0]["generated_text"]
40
+
41
+ # ---- MAIN FUNCTION ----
42
+ def analyze(file, progress=gr.Progress()):
43
+ start_time = time.time()
44
+ print("βœ… Analyze function triggered")
45
 
 
 
46
  if file is None:
47
+ return "❌ Upload a CSV file"
48
 
49
  df = pd.read_csv(file.name)
 
 
 
50
 
51
+ # Auto-detect numeric KPIs
52
+ kpis = df.select_dtypes(include=np.number).columns.tolist()
 
 
 
 
 
53
 
54
+ if not kpis:
55
+ return "❌ No numeric KPI columns found"
56
 
57
  results = []
58
+ total = len(kpis)
 
59
 
60
+ # ---- Spinner + Progress ----
61
+ for i, kpi in enumerate(kpis):
62
+ progress((i+1)/total, desc=f"Analyzing {kpi}...")
63
 
64
+ vals = df[kpi].dropna().tolist()
65
  trend = detect_trend(vals)
66
  score = change_score(vals)
67
 
68
  results.append((kpi, trend, score, vals))
69
 
70
+ # Rank KPIs
71
  ranked = sorted(results, key=lambda x: x[2], reverse=True)
72
 
73
+ # ---- LLM explanations ----
74
  progress(0.9, desc="Generating LLM explanations...")
75
 
76
+ explanations = []
77
  for kpi, trend, score, vals in ranked[:5]:
 
78
  try:
79
+ exp = explain(kpi, vals, trend)
80
  except Exception as e:
81
+ exp = f"LLM error: {e}"
82
  explanations.append(f"**{kpi}** β†’ {exp}")
83
 
84
+ elapsed = round(time.time() - start_time, 2)
 
 
 
 
 
85
 
86
+ # ---- Final Output ----
87
+ output = f"⏱ Time taken: {elapsed} sec\n\n"
88
+ output += "πŸ”₯ Top 5 KPIs with most change:\n\n"
89
  for kpi, trend, score, _ in ranked[:5]:
90
+ output += f"- {kpi}: {trend} (Οƒ={round(score,2)})\n"
91
 
92
+ output += "\n🧠 LLM Insights:\n\n"
93
  for e in explanations:
94
+ output += e + "\n\n"
 
 
 
 
 
 
 
 
 
95
 
96
+ return output
97
 
98
+ # ---- UI ----
99
+ with gr.Blocks() as app:
100
+ gr.Markdown("## πŸ“Š KPI Trend Analyzer (LLM Powered)")
101
 
102
+ file_input = gr.File(label="Upload CSV")
103
+ analyze_btn = gr.Button("Analyze KPIs")
104
+ output_box = gr.Markdown()
105
 
106
+ analyze_btn.click(fn=analyze, inputs=[file_input], outputs=[output_box])
 
 
 
 
 
107
 
108
+ app.launch() # ⚠️ no share=True