astonn commited on
Commit
864f922
·
verified ·
1 Parent(s): a464e51

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +71 -0
app.py ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import pandas as pd
3
+ import gradio as gr
4
+ from huggingface_hub import hf_hub_download
5
+ from llama_cpp import Llama # GGUF inference on CPU
6
+
7
+ # ---------- model loading (done once at startup) ----------
8
+ MODEL_REPO = "TheBloke/phi-2-GGUF" # fully open 2.7 B model
9
+ MODEL_FILE = "phi-2.Q4_K_M.gguf" # 4‑bit, 3.5 GB RAM
10
+ CTX_SIZE = 2048 # ample for prompt+answer
11
+
12
+ model_path = hf_hub_download(repo_id=MODEL_REPO, filename=MODEL_FILE)
13
+ llm = Llama(model_path=model_path,
14
+ n_ctx=CTX_SIZE,
15
+ n_threads=os.cpu_count() or 2) # use all CPUs
16
+
17
+ # ---------- analysis + generation ----------
18
+ def analyze_ads(file):
19
+ df = pd.read_csv(file.name)
20
+
21
+ req = {"headline","description","impressions","CTR","form_opens","spend"}
22
+ if not req.issubset(df.columns):
23
+ return f"Missing columns: {', '.join(req - set(df.columns))}"
24
+
25
+ # numeric conversions
26
+ for col in ["impressions","CTR","form_opens","spend"]:
27
+ df[col] = pd.to_numeric(df[col], errors="coerce")
28
+ df = df.dropna()
29
+
30
+ df["engagement_rate"] = df["form_opens"] / df["impressions"]
31
+ df["CPC"] = df["spend"] / (df["CTR"] * df["impressions"]).replace(0, pd.NA)
32
+ df["cost_per_form_open"] = df["spend"] / df["form_opens"].replace(0, pd.NA)
33
+
34
+ top = df.sort_values("CTR", ascending=False).head(3)
35
+ worst = df.sort_values("CTR").head(3)
36
+
37
+ def rows_to_text(sub):
38
+ out = ""
39
+ for _, r in sub.iterrows():
40
+ out += (f"Headline: {r.headline}\n"
41
+ f"Description: {r.description}\n"
42
+ f"Imp: {int(r.impressions)}, CTR: {r.CTR:.3f}, "
43
+ f"Form Opens: {int(r.form_opens)}, ER: {r.engagement_rate:.3f}\n"
44
+ f"Spend: ${r.spend:.2f}, CPC: ${r.CPC:.2f}, CPF: ${r.cost_per_form_open:.2f}\n\n")
45
+ return out
46
+
47
+ prompt = (
48
+ "You are a senior digital marketer.\n"
49
+ "Analyse the high‑ and low‑performing ads below and deliver:\n"
50
+ "1. Key patterns of winners.\n"
51
+ "2. Weak points of losers.\n"
52
+ "3. Three actionable creative improvements.\n\n"
53
+ f"--- HIGH CTR ADS ---\n{rows_to_text(top)}"
54
+ f"--- LOW CTR ADS ---\n{rows_to_text(worst)}"
55
+ )
56
+
57
+ # generate (stream=False -> returns dict)
58
+ answer = llm(prompt, max_tokens=320, temperature=0.7, top_p=0.9)["choices"][0]["text"]
59
+ return answer.strip()
60
+
61
+ # ---------- Gradio UI ----------
62
+ demo = gr.Interface(
63
+ fn=analyze_ads,
64
+ inputs=gr.File(label="CSV with: headline, description, impressions, CTR, form_opens, spend"),
65
+ outputs=gr.Textbox(label="AI‑generated analysis & recommendations"),
66
+ title="Ad Performance Analyzer (Phi‑2 4‑bit, CPU‑only)",
67
+ description="Upload your ad data and get actionable insights without paid APIs."
68
+ )
69
+
70
+ if __name__ == "__main__":
71
+ demo.launch()