Tulitula commited on
Commit
fed88b2
Β·
verified Β·
1 Parent(s): 7bffaa8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +129 -161
app.py CHANGED
@@ -2,82 +2,73 @@ import re
2
  import gradio as gr
3
  import torch
4
  from PIL import Image
5
- from transformers import pipeline, AutoProcessor, AutoModelForVision2Seq, AutoTokenizer, AutoModelForSeq2SeqLM
 
 
 
 
 
 
6
 
7
  # Auto-detect CPU/GPU
8
- device = 0 if torch.cuda.is_available() else -1
9
-
10
- # 1) BLIP captioner - Fixed tokenizer usage
11
- try:
12
- processor = AutoProcessor.from_pretrained("Salesforce/blip-image-captioning-large")
13
- model = AutoModelForVision2Seq.from_pretrained("Salesforce/blip-image-captioning-large")
14
-
15
- caption_pipe = pipeline(
16
- "image-to-text",
17
- model=model,
18
- tokenizer=processor.tokenizer,
19
- image_processor=processor.image_processor,
20
- device=device
21
- )
22
- print("βœ… BLIP model loaded successfully")
23
- except Exception as e:
24
- print(f"❌ Error loading BLIP model: {e}")
25
- raise
26
-
27
- # 2) Flan-T5 for text-to-text - Fixed tokenizer initialization
28
  FLAN_MODEL = "google/flan-t5-large"
29
- try:
30
- # Load tokenizer and model separately for better control
31
- flan_tokenizer = AutoTokenizer.from_pretrained(FLAN_MODEL)
32
- flan_model = AutoModelForSeq2SeqLM.from_pretrained(FLAN_MODEL)
33
-
34
- # Create pipelines with explicit tokenizer
35
- category_pipe = pipeline(
36
- "text2text-generation",
37
- model=flan_model,
38
- tokenizer=flan_tokenizer,
39
- device=device,
40
- max_new_tokens=32,
41
- do_sample=True,
42
- temperature=1.0,
43
- )
44
-
45
- analysis_pipe = pipeline(
46
- "text2text-generation",
47
- model=flan_model,
48
- tokenizer=flan_tokenizer,
49
- device=device,
50
- max_new_tokens=256,
51
- do_sample=True,
52
- temperature=1.0,
53
- )
54
-
55
- suggestion_pipe = pipeline(
56
- "text2text-generation",
57
- model=flan_model,
58
- tokenizer=flan_tokenizer,
59
- device=device,
60
- max_new_tokens=256,
61
- do_sample=True,
62
- temperature=1.0,
63
- )
64
-
65
- # Expander when BLIP caption is too short
66
- expansion_pipe = pipeline(
67
- "text2text-generation",
68
- model=flan_model,
69
- tokenizer=flan_tokenizer,
70
- device=device,
71
- max_new_tokens=128,
72
- do_sample=False,
73
- )
74
-
75
- print("βœ… Flan-T5 model loaded successfully")
76
- except Exception as e:
77
- print(f"❌ Error loading Flan-T5 model: {e}")
78
- raise
79
-
80
- # Example gallery helper returns 10 example ad URLs
81
  def get_recommendations():
82
  return [
83
  "https://i.imgur.com/InC88PP.jpeg",
@@ -92,110 +83,87 @@ def get_recommendations():
92
  "https://i.imgur.com/Xj92Cjv.jpeg",
93
  ]
94
 
95
- # Main processing function with error handling
 
96
  def process(image: Image):
97
- try:
98
- if image is None:
99
- return "", "", "", get_recommendations()
100
-
101
- # 1) BLIP caption
102
- caption_result = caption_pipe(image, max_new_tokens=64)
103
- caption = caption_result[0]['generated_text'].strip()
104
-
105
- # 1a) Expand caption if too short
106
- if len(caption.split()) < 3:
107
- desc_result = expansion_pipe(f"Expand into a detailed description: {caption}")
108
- desc = desc_result[0]['generated_text'].strip()
109
- else:
110
- desc = caption
111
-
112
- # 2) Ad category
113
- cat_prompt = (
114
- f"Description: {desc}\n\n"
115
- "Provide a concise category label for this ad (e.g. 'Food', 'Fitness'):"
116
- )
117
- category_result = category_pipe(cat_prompt)
118
- category = category_result[0]['generated_text'].splitlines()[0].strip()
119
 
120
- # 3) Five-sentence analysis
121
- ana_prompt = (
122
- f"Based on this advertisement description: {desc}\n\n"
123
- "Write exactly 5 detailed sentences analyzing this advertisement. Cover: 1) What product/service is being advertised, 2) The main visual elements and design, 3) The target audience, 4) The marketing message or value proposition, 5) The emotional appeal or persuasion technique used. Make each sentence substantial and informative."
124
- )
125
- raw_ana_result = analysis_pipe(ana_prompt)
126
- raw_ana = raw_ana_result[0]['generated_text'].strip()
127
- sentences = re.split(r'(?<=[.!?])\s+', raw_ana)
128
- # Take first 5 sentences and ensure they're substantial
129
- analysis_sentences = []
130
- for i, sentence in enumerate(sentences[:8]): # Look at more sentences to find 5 good ones
131
- if len(sentence.strip()) > 20 and len(analysis_sentences) < 5: # Filter short sentences
132
- analysis_sentences.append(sentence.strip())
133
- analysis = " ".join(analysis_sentences[:5])
134
-
135
- # 4) Five bullet-point suggestions
136
- sug_prompt = (
137
- f"Based on this advertisement: {desc}\n\n"
138
- "Provide exactly 5 specific, actionable improvement suggestions for this advertisement. Focus on concrete changes like: visual design improvements, clearer messaging, better call-to-action, enhanced targeting, or stronger emotional appeal. Each suggestion should be one clear sentence starting with '- ' and be practical to implement."
139
- )
140
- raw_sug_result = suggestion_pipe(sug_prompt)
141
- raw_sug = raw_sug_result[0]['generated_text'].strip()
142
-
143
- # Better parsing of suggestions
144
- lines = raw_sug.split('\n')
145
- suggestions_list = []
146
- for line in lines:
147
- line = line.strip()
148
- if line.startswith('-'):
149
- suggestions_list.append(line)
150
- elif line and not line.startswith('-') and len(suggestions_list) < 5:
151
- suggestions_list.append(f"- {line}")
152
-
153
- # Ensure we have exactly 5 suggestions
154
- while len(suggestions_list) < 5:
155
- suggestions_list.append(f"- Improve visual hierarchy and readability")
156
-
157
- suggestions = '\n'.join(suggestions_list[:5])
158
-
159
- return category, analysis, suggestions, get_recommendations()
160
-
161
- except Exception as e:
162
- error_msg = f"Error analyzing advertisement: {str(e)}"
163
- print(error_msg)
164
- return "Analysis failed", error_msg, "", get_recommendations()
165
-
166
- # Gradio UI definition
167
  def main():
168
  with gr.Blocks(title="Smart Ad Analyzer") as demo:
169
  gr.Markdown("## πŸ“’ Smart Ad Analyzer")
170
  gr.Markdown(
171
- "Transform your advertising with AI-powered insights! Upload any advertisement image to receive:\n\n"
172
- "🎯 **Smart Categorization** - Automatically classify your ad type\n\n"
173
- "πŸ” **Deep Analysis** - Get a comprehensive 5-sentence breakdown of your ad's message, visual elements, and emotional impact\n\n"
174
- "πŸ’‘ **Actionable Improvements** - Receive 5 specific, practical suggestions to enhance your ad's effectiveness\n\n"
175
- "πŸ“Έ **Inspiration Gallery** - Discover example ads after your analysis\n\n"
176
- "Perfect for marketers, business owners, and creative professionals looking to optimize their advertising campaigns!"
177
  )
178
-
179
  with gr.Row():
180
  inp = gr.Image(type='pil', label='Upload Ad Image')
181
  with gr.Column():
 
182
  cat_out = gr.Textbox(label='πŸ“‚ Ad Category', interactive=False)
183
- ana_out = gr.Textbox(label='πŸ“Š Ad Analysis', lines=8, interactive=False)
184
- sug_out = gr.Textbox(label='πŸš€ Improvement Suggestions', lines=8, interactive=False)
185
- btn = gr.Button('Analyze Ad', size='sm', variant='primary')
186
-
187
- gallery = gr.Gallery(label='Example Ads') # Empty initially
188
-
189
  btn.click(
190
  fn=process,
191
  inputs=[inp],
192
- outputs=[cat_out, ana_out, sug_out, gallery],
193
  )
194
-
195
  gr.Markdown('Made by Simon Thalmay')
196
-
197
  return demo
198
 
199
- if __name__ == '__main__':
200
  demo = main()
201
- demo.launch()
 
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",
 
83
  "https://i.imgur.com/Xj92Cjv.jpeg",
84
  ]
85
 
86
+ # Main processing function
87
+
88
  def process(image: Image):
89
+ if image is None:
90
+ return "", "", "", "", get_recommendations()
91
+
92
+ # 1) BLIP caption
93
+ caption_res = caption_pipe(image, max_new_tokens=64)
94
+ raw_caption = caption_res[0]["generated_text"].strip()
95
+
96
+ # 1a) Expand if too short
97
+ if len(raw_caption.split()) < 3:
98
+ exp = expansion_pipe(f"Expand into a detailed description: {raw_caption}")
99
+ desc = exp[0]["generated_text"].strip()
100
+ else:
101
+ desc = raw_caption
102
+
103
+ # 2) Category
104
+ cat_prompt = (
105
+ f"Description: {desc}\n\n"
106
+ "Provide a concise category label for this ad (e.g. 'Food', 'Fitness'):"
107
+ )
108
+ cat_out = category_pipe(cat_prompt)[0]["generated_text"].splitlines()[0].strip()
 
 
109
 
110
+ # 3) Five-sentence analysis
111
+ ana_prompt = (
112
+ f"Description: {desc}\n\n"
113
+ "Write exactly five sentences explaining what this ad communicates and its emotional impact."
114
+ )
115
+ ana_raw = analysis_pipe(ana_prompt)[0]["generated_text"].strip()
116
+ sentences = re.split(r'(?<=[.!?])\s+', ana_raw)
117
+ analysis = " ".join(sentences[:5])
118
+
119
+ # 4) Five bullet-point suggestions
120
+ sug_prompt = (
121
+ f"Description: {desc}\n\n"
122
+ "Provide five distinct improvement suggestions, each starting with '- '."
123
+ )
124
+ sug_raw = suggestion_pipe(sug_prompt)[0]["generated_text"].strip()
125
+ bullets = [l for l in sug_raw.splitlines() if l.startswith("-")]
126
+ if len(bullets) < 5:
127
+ for line in sug_raw.splitlines():
128
+ if len(bullets) >= 5:
129
+ break
130
+ if line and not line.startswith("-"):
131
+ bullets.append("- " + line)
132
+ while len(bullets) < 5:
133
+ bullets.append("- Improve visual appeal and clarity.")
134
+ suggestions = "\n".join(bullets[:5])
135
+
136
+ return raw_caption, cat_out, analysis, suggestions, get_recommendations()
137
+
138
+ # Gradio UI
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  def main():
140
  with gr.Blocks(title="Smart Ad Analyzer") as demo:
141
  gr.Markdown("## πŸ“’ Smart Ad Analyzer")
142
  gr.Markdown(
143
+ "Upload an ad image to get:\n"
144
+ "- πŸ” **BLIP Caption**\n"
145
+ "- πŸ“‚ **Ad Category**\n"
146
+ "- πŸ“Š **Five-sentence Analysis**\n"
147
+ "- πŸš€ **Five Improvement Suggestions**\n"
148
+ "- πŸ“Έ **Example Ads**"
149
  )
 
150
  with gr.Row():
151
  inp = gr.Image(type='pil', label='Upload Ad Image')
152
  with gr.Column():
153
+ cap_out = gr.Textbox(label='πŸ” BLIP Caption', interactive=False)
154
  cat_out = gr.Textbox(label='πŸ“‚ Ad Category', interactive=False)
155
+ ana_out = gr.Textbox(label='πŸ“Š Ad Analysis', lines=5, interactive=False)
156
+ sug_out = gr.Textbox(label='πŸš€ Improvement Suggestions', lines=5, interactive=False)
157
+ btn = gr.Button('Analyze Ad', variant='primary')
158
+ gallery = gr.Gallery(label='Example Ads')
 
 
159
  btn.click(
160
  fn=process,
161
  inputs=[inp],
162
+ outputs=[cap_out, cat_out, ana_out, sug_out, gallery],
163
  )
 
164
  gr.Markdown('Made by Simon Thalmay')
 
165
  return demo
166
 
167
+ if __name__ == "__main__":
168
  demo = main()
169
+ demo.launch()