Tulitula commited on
Commit
8453cad
Β·
verified Β·
1 Parent(s): 345306a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +133 -32
app.py CHANGED
@@ -1,12 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  def process(image: Image):
2
  if image is None:
3
- return "", "", "", get_recommendations()
4
 
5
  # 1) BLIP caption
6
  caption_res = caption_pipe(image, max_new_tokens=64)
7
  raw_caption = caption_res[0]["generated_text"].strip()
8
 
9
- # 1a) Expand caption if too short
10
  if len(raw_caption.split()) < 3:
11
  exp = expansion_pipe(f"Expand into a detailed description: {raw_caption}")
12
  desc = exp[0]["generated_text"].strip()
@@ -29,39 +115,54 @@ def process(image: Image):
29
  sentences = re.split(r'(?<=[.!?])\s+', ana_raw)
30
  analysis = " ".join(sentences[:5])
31
 
32
- # 4) Five bullet-point suggestions, filter for unique & not empty
33
  sug_prompt = (
34
  f"Description: {desc}\n\n"
35
- "Suggest five unique, practical improvements for this ad. Each must address a different aspect (such as message, visuals, CTA, targeting, layout, or design). Each suggestion must be only one sentence and start with '- '. Do NOT repeat suggestions."
36
  )
37
  sug_raw = suggestion_pipe(sug_prompt)[0]["generated_text"].strip()
38
- bullets = []
39
- seen = set()
40
- for line in sug_raw.splitlines():
41
- if line.startswith("-"):
42
- suggestion = line.strip()
43
- # Remove duplicates and ignore empty lines
44
- if suggestion and suggestion not in seen:
45
- bullets.append(suggestion)
46
- seen.add(suggestion)
47
- elif line.strip():
48
- suggestion = "- " + line.strip()
49
- if suggestion and suggestion not in seen:
50
- bullets.append(suggestion)
51
- seen.add(suggestion)
52
- if len(bullets) == 5:
53
- break
54
- # Add defaults if needed
55
- defaults = [
56
- "- Make the main headline more eye-catching.",
57
- "- Add a clear and visible call-to-action button.",
58
- "- Use contrasting colors for better readability.",
59
- "- Highlight the unique selling point of the product.",
60
- "- Simplify the design to reduce clutter."
61
- ]
62
- for default in defaults:
63
- if len(bullets) < 5 and default not in seen:
64
- bullets.append(default)
65
  suggestions = "\n".join(bullets[:5])
66
 
67
- return cat_out, analysis, suggestions, get_recommendations()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import re
2
+ import gradio as gr
3
+ import torch
4
+ from PIL import Image
5
+ from transformers import (
6
+ pipeline,
7
+ AutoProcessor,
8
+ AutoModelForVision2Seq,
9
+ AutoTokenizer,
10
+ AutoModelForSeq2SeqLM,
11
+ )
12
+
13
+ # Auto-detect CPU/GPU
14
+ DEVICE = 0 if torch.cuda.is_available() else -1
15
+
16
+ # 1) BLIP captioner
17
+ processor = AutoProcessor.from_pretrained("Salesforce/blip-image-captioning-large")
18
+ blip_model = AutoModelForVision2Seq.from_pretrained("Salesforce/blip-image-captioning-large")
19
+ caption_pipe = pipeline(
20
+ task="image-to-text",
21
+ model=blip_model,
22
+ tokenizer=processor.tokenizer,
23
+ image_processor=processor.image_processor,
24
+ device=DEVICE,
25
+ )
26
+
27
+ # 2) FLAN-T5 for text-to-text
28
+ FLAN_MODEL = "google/flan-t5-large"
29
+ flan_tokenizer = AutoTokenizer.from_pretrained(FLAN_MODEL)
30
+ flan_model = AutoModelForSeq2SeqLM.from_pretrained(FLAN_MODEL)
31
+
32
+ category_pipe = pipeline(
33
+ "text2text-generation",
34
+ model=flan_model,
35
+ tokenizer=flan_tokenizer,
36
+ device=DEVICE,
37
+ max_new_tokens=32,
38
+ do_sample=True,
39
+ temperature=1.0,
40
+ )
41
+
42
+ analysis_pipe = pipeline(
43
+ "text2text-generation",
44
+ model=flan_model,
45
+ tokenizer=flan_tokenizer,
46
+ device=DEVICE,
47
+ max_new_tokens=256,
48
+ do_sample=True,
49
+ temperature=1.0,
50
+ )
51
+
52
+ suggestion_pipe = pipeline(
53
+ "text2text-generation",
54
+ model=flan_model,
55
+ tokenizer=flan_tokenizer,
56
+ device=DEVICE,
57
+ max_new_tokens=256,
58
+ do_sample=True,
59
+ temperature=1.0,
60
+ )
61
+
62
+ expansion_pipe = pipeline(
63
+ "text2text-generation",
64
+ model=flan_model,
65
+ tokenizer=flan_tokenizer,
66
+ device=DEVICE,
67
+ max_new_tokens=128,
68
+ do_sample=False,
69
+ )
70
+
71
+ # Example gallery helper
72
+ def get_recommendations():
73
+ return [
74
+ "https://i.imgur.com/InC88PP.jpeg",
75
+ "https://i.imgur.com/7BHfv4T.png",
76
+ "https://i.imgur.com/wp3Wzc4.jpeg",
77
+ "https://i.imgur.com/5e2xOA4.jpeg",
78
+ "https://i.imgur.com/txjRk98.jpeg",
79
+ "https://i.imgur.com/rQ4AYl0.jpeg",
80
+ "https://i.imgur.com/bDzwD04.jpeg",
81
+ "https://i.imgur.com/fLMngXI.jpeg",
82
+ "https://i.imgur.com/nYEJzxt.png",
83
+ "https://i.imgur.com/Xj92Cjv.jpeg",
84
+ ]
85
+
86
+ # Main processing function
87
  def process(image: Image):
88
  if image is None:
89
+ return "", "", "", "", get_recommendations()
90
 
91
  # 1) BLIP caption
92
  caption_res = caption_pipe(image, max_new_tokens=64)
93
  raw_caption = caption_res[0]["generated_text"].strip()
94
 
95
+ # 1a) Expand if too short
96
  if len(raw_caption.split()) < 3:
97
  exp = expansion_pipe(f"Expand into a detailed description: {raw_caption}")
98
  desc = exp[0]["generated_text"].strip()
 
115
  sentences = re.split(r'(?<=[.!?])\s+', ana_raw)
116
  analysis = " ".join(sentences[:5])
117
 
118
+ # 4) Five bullet-point suggestions
119
  sug_prompt = (
120
  f"Description: {desc}\n\n"
121
+ "Provide five distinct improvement suggestions, each starting with '- '."
122
  )
123
  sug_raw = suggestion_pipe(sug_prompt)[0]["generated_text"].strip()
124
+ bullets = [l for l in sug_raw.splitlines() if l.startswith("-")]
125
+ if len(bullets) < 5:
126
+ for line in sug_raw.splitlines():
127
+ if len(bullets) >= 5:
128
+ break
129
+ if line and not line.startswith("-"):
130
+ bullets.append("- " + line)
131
+ while len(bullets) < 5:
132
+ bullets.append("- Improve visual appeal and clarity.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
  suggestions = "\n".join(bullets[:5])
134
 
135
+ return raw_caption, cat_out, analysis, suggestions, get_recommendations()
136
+
137
+ # Gradio UI
138
+ def main():
139
+ with gr.Blocks(title="Smart Ad Analyzer") as demo:
140
+ gr.Markdown("## πŸ“’ Smart Ad Analyzer")
141
+ gr.Markdown(
142
+ "Upload an ad image to get:\n"
143
+ "- πŸ” **BLIP Caption**\n"
144
+ "- πŸ“‚ **Ad Category**\n"
145
+ "- πŸ“Š **Five-sentence Analysis**\n"
146
+ "- πŸš€ **Five Improvement Suggestions**\n"
147
+ "- πŸ“Έ **Example Ads**"
148
+ )
149
+ with gr.Row():
150
+ inp = gr.Image(type='pil', label='Upload Ad Image')
151
+ with gr.Column():
152
+ cap_out = gr.Textbox(label='πŸ” BLIP Caption', interactive=False)
153
+ cat_out = gr.Textbox(label='πŸ“‚ Ad Category', interactive=False)
154
+ ana_out = gr.Textbox(label='πŸ“Š Ad Analysis', lines=5, interactive=False)
155
+ sug_out = gr.Textbox(label='πŸš€ Improvement Suggestions', lines=5, interactive=False)
156
+ btn = gr.Button('Analyze Ad', variant='primary')
157
+ gallery = gr.Gallery(label='Example Ads')
158
+ btn.click(
159
+ fn=process,
160
+ inputs=[inp],
161
+ outputs=[cap_out, cat_out, ana_out, sug_out, gallery],
162
+ )
163
+ gr.Markdown('Made by Simon Thalmay')
164
+ return demo
165
+
166
+ if __name__ == "__main__":
167
+ demo = main()
168
+ demo.launch()