import os import pandas as pd import gradio as gr from huggingface_hub import hf_hub_download from llama_cpp import Llama # GGUF inference on CPU # ---------- model loading (done once at startup) ---------- MODEL_REPO = "TheBloke/phi-2-GGUF" # fully open 2.7 B model MODEL_FILE = "phi-2.Q4_K_M.gguf" # 4‑bit, 3.5 GB RAM CTX_SIZE = 2048 # ample for prompt+answer model_path = hf_hub_download(repo_id=MODEL_REPO, filename=MODEL_FILE) llm = Llama(model_path=model_path, n_ctx=CTX_SIZE, n_threads=os.cpu_count() or 2) # use all CPUs # ---------- analysis + generation ---------- def analyze_ads(file): df = pd.read_csv(file.name) req = {"headline","description","impressions","CTR","form_opens","spend"} if not req.issubset(df.columns): return f"Missing columns: {', '.join(req - set(df.columns))}" # numeric conversions for col in ["impressions","CTR","form_opens","spend"]: df[col] = pd.to_numeric(df[col], errors="coerce") df = df.dropna() df["engagement_rate"] = df["form_opens"] / df["impressions"] df["CPC"] = df["spend"] / (df["CTR"] * df["impressions"]).replace(0, pd.NA) df["cost_per_form_open"] = df["spend"] / df["form_opens"].replace(0, pd.NA) top = df.sort_values("CTR", ascending=False).head(3) worst = df.sort_values("CTR").head(3) def rows_to_text(sub): out = "" for _, r in sub.iterrows(): out += (f"Headline: {r.headline}\n" f"Description: {r.description}\n" f"Imp: {int(r.impressions)}, CTR: {r.CTR:.3f}, " f"Form Opens: {int(r.form_opens)}, ER: {r.engagement_rate:.3f}\n" f"Spend: ${r.spend:.2f}, CPC: ${r.CPC:.2f}, CPF: ${r.cost_per_form_open:.2f}\n\n") return out prompt = ( "You are a senior digital marketer.\n" "Analyse the high‑ and low‑performing ads below and deliver:\n" "1. Key patterns of winners.\n" "2. Weak points of losers.\n" "3. Three actionable creative improvements.\n\n" f"--- HIGH CTR ADS ---\n{rows_to_text(top)}" f"--- LOW CTR ADS ---\n{rows_to_text(worst)}" ) # generate (stream=False -> returns dict) answer = llm(prompt, max_tokens=320, temperature=0.7, top_p=0.9)["choices"][0]["text"] return answer.strip() # ---------- Gradio UI ---------- demo = gr.Interface( fn=analyze_ads, inputs=gr.File(label="CSV with: headline, description, impressions, CTR, form_opens, spend"), outputs=gr.Textbox(label="AI‑generated analysis & recommendations"), title="Ad Performance Analyzer (Phi‑2 4‑bit, CPU‑only)", description="Upload your ad data and get actionable insights without paid APIs." ) if __name__ == "__main__": demo.launch()