| import gradio as gr |
| import pandas as pd |
| from transformers import pipeline |
|
|
| |
| |
| |
| generator = pipeline( |
| "text-generation", |
| model="Qwen/Qwen2.5-3B-Instruct", |
| device_map="auto", |
| trust_remote_code=True |
| ) |
|
|
| |
| |
| |
| def magnitude_bucket(x): |
| if x < 0.05: |
| return "low" |
| elif x < 0.2: |
| return "medium" |
| else: |
| return "high" |
|
|
| def direction_bucket(diff): |
| if diff > 0: |
| return "increase" |
| elif diff < 0: |
| return "decrease" |
| else: |
| return "no_change" |
|
|
| |
| |
| |
| def analyze_kpi(csv_file, top_n): |
| df = pd.read_csv(csv_file.name) |
|
|
| dates = df.columns[1:] |
| prev_date, curr_date = dates[-2], dates[-1] |
|
|
| df["diff"] = df[curr_date] - df[prev_date] |
| df["abs_diff"] = df["diff"].abs() |
|
|
| ranked = df.sort_values("abs_diff", ascending=False) |
|
|
| top_kpis = ranked.head(3) |
| other_kpis = ranked.iloc[3:] |
|
|
| |
| |
| |
| top_facts = [] |
| for _, row in top_kpis.iterrows(): |
| top_facts.append({ |
| "KPI": row["Kpi"], |
| "DIRECTION": direction_bucket(row["diff"]), |
| "CHANGE_VALUE": round(row["abs_diff"], 2), |
| "MAGNITUDE": magnitude_bucket(row["abs_diff"]), |
| "UNIT": "percentage points" if "%" in row["Kpi"] else "units" |
| }) |
|
|
| |
| |
| |
| if len(other_kpis) > 0: |
| other_facts = { |
| "KPI_COUNT": len(other_kpis), |
| "AVG_CHANGE": round(other_kpis["abs_diff"].mean(), 2), |
| "MAGNITUDE": magnitude_bucket(other_kpis["abs_diff"].mean()), |
| "DIRECTION_BALANCE": ( |
| "mostly_increase" if (other_kpis["diff"] > 0).mean() > 0.7 |
| else "mostly_decrease" if (other_kpis["diff"] > 0).mean() < 0.3 |
| else "mixed" |
| ) |
| } |
| else: |
| other_facts = None |
|
|
| |
| |
| |
| |
| model_input = ( |
| "Write a short insight-style summary using only the facts below.\n\n" |
| "TOP_KPI_FACTS:\n" |
| f"{top_facts}\n\n" |
| "OTHER_KPI_FACTS:\n" |
| f"{other_facts}" |
| ) |
|
|
| |
| |
| |
| output = generator( |
| model_input, |
| max_new_tokens=120, |
| do_sample=True, |
| temperature=0.6, |
| top_p=0.85, |
| repetition_penalty=1.1 |
| )[0]["generated_text"] |
|
|
| return ranked.head(top_n)[["Kpi", "abs_diff"]], output |
|
|
| |
| |
| |
| with gr.Blocks(title="Network Insight Summary") as demo: |
| gr.Markdown("## 📊 Network Insight Summary") |
| gr.Markdown( |
| "Upload KPI CSV to generate a concise, insight-style summary " |
| "highlighting the most significant KPI changes." |
| ) |
|
|
| csv_input = gr.File(file_types=[".csv"]) |
| top_n_input = gr.Slider( |
| minimum=3, |
| maximum=6, |
| value=5, |
| step=1, |
| label="KPIs to Display" |
| ) |
|
|
| btn = gr.Button("Generate Insight") |
|
|
| table = gr.Dataframe(label="Top KPI Changes") |
| summary = gr.Textbox(label="Insight Summary", lines=4) |
|
|
| btn.click( |
| analyze_kpi, |
| inputs=[csv_input, top_n_input], |
| outputs=[table, summary] |
| ) |
|
|
| demo.launch() |