gaur3009 commited on
Commit
7c4529a
Β·
verified Β·
1 Parent(s): dde297b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +131 -119
app.py CHANGED
@@ -1,19 +1,24 @@
1
- import re
 
 
 
 
 
 
 
2
  import tempfile
3
  from fpdf import FPDF
4
-
5
  import gradio as gr
6
  from transformers import pipeline
7
 
8
  # -----------------------------
9
- # Model: FLAN-T5-XL
10
  # -----------------------------
11
- # Keep Flan-T5-XL as requested. If you want to run on CPU-only, remove device arg.
12
- # On systems with GPU change device to 0 (cuda) for speed.
13
  generator = pipeline(
14
  "text2text-generation",
15
  model="google/flan-t5-xl",
16
- # device=0, # uncomment if running on a GPU
17
  )
18
 
19
  # -----------------------------
@@ -25,115 +30,122 @@ brand_memory = {
25
  }
26
 
27
  # -----------------------------
28
- # Helper: Robust extractor
29
  # -----------------------------
30
- def extract_section(section_name: str, text: str) -> str:
31
- """
32
- Extract section block that follows a header like:
33
- Section Name:
34
- <content possibly multiline>
35
-
36
- Uses a DOTALL regex and anchors looking for the next header line that
37
- starts with a capitalized word and colon.
38
- """
39
- # Ensure we match the exact header plus colon, allow optional whitespace
40
- pattern = rf"^{re.escape(section_name)}:\s*(.*?)(?=^\w[\w\d \-']+:\s*$|$\Z)"
41
- match = re.search(pattern, text, flags=re.MULTILINE | re.DOTALL | re.IGNORECASE)
42
- if match:
43
- return match.group(1).strip()
44
- return "Not found."
45
 
46
  # -----------------------------
47
- # Prompt template + fallback wrapper
48
  # -----------------------------
49
- BASE_OUTPUT_FORMAT = """
50
- OUTPUT FORMAT (FOLLOW EXACTLY):
51
 
52
- Creative Direction:
53
- <3–5 line vision>
 
 
 
 
54
 
55
- Emotional Tone:
56
- <deep emotional personality + brand resonance>
 
 
 
57
 
58
- Ad Script:
59
- <Cinematic script with labeled Intro, Body, CTA>
60
 
61
- Poster Prompt:
62
- <Highly visual Stable Diffusion / SDXL style prompt describing lighting, color palette, environment, camera angle, people, clothing, props, mood, and typography>
 
 
 
 
63
 
64
- Taglines:
65
- - <Tagline 1>
66
- - <Tagline 2>
67
  """
68
 
69
- def call_generator_with_format(prompt_text, max_new_tokens=650, temperature=0.8, retry_if_bad=True):
70
  """
71
- Calls the HF pipeline and ensures output contains the required section headers.
72
- If not, does one lightweight re-prompt to ask the model to reformat the previous answer
73
- strictly following the OUTPUT FORMAT. (Helps Flan-T5-XL follow strict formatting.)
74
  """
75
- full_response = generator(prompt_text, max_new_tokens=max_new_tokens, do_sample=True, temperature=temperature)[0]["generated_text"]
76
-
77
- # quick check: does it contain the main headers?
78
- required_headers = ["Creative Direction:", "Emotional Tone:", "Ad Script:", "Poster Prompt:", "Taglines:"]
79
- if all(h.lower() in full_response.lower() for h in required_headers):
80
- return full_response
81
-
82
- if retry_if_bad:
83
- # concise reformat request appended to previous model output
84
- reformat_prompt = (
85
- full_response
86
- + "\n\nThe above answer is good, but you MUST re-output it following the exact OUTPUT FORMAT below. "
87
- + BASE_OUTPUT_FORMAT
88
- + "\n\nReformat now and include the same content but strictly follow the headings and colons."
89
- )
90
- full_response = generator(reformat_prompt, max_new_tokens=500, do_sample=False, temperature=0.0)[0]["generated_text"]
91
- return full_response
92
 
93
- # -----------------------------
94
- # Core Campaign Generator
95
- # -----------------------------
96
- def generate_campaign(brand_name, product_type, goal, tone, audience, region):
97
- # Compose combined tone with brand memory hint
98
- combined_tone = f"{tone}. The brand historically sounds like this: {brand_memory.get('tone')}."
99
-
100
- prompt = f"""
101
- You are an expert creative strategist hired to design a world-class campaign for a premium brand.
102
- Input details:
103
- Brand Name: {brand_name}
104
- Product Type: {product_type}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  Goal: {goal}
106
- Tone: {combined_tone}
107
- Target Audience: {audience}
108
  Region: {region}
109
 
110
- {BASE_OUTPUT_FORMAT}
 
 
111
 
112
- Write full content under each heading only (do NOT include extra commentary).
113
  """
114
- llm_output = call_generator_with_format(prompt)
115
-
116
- # Extract sections
117
- creative_direction = extract_section("Creative Direction", llm_output)
118
- emotional_tone = extract_section("Emotional Tone", llm_output)
119
- ad_script = extract_section("Ad Script", llm_output)
120
- poster_prompt = extract_section("Poster Prompt", llm_output)
121
- taglines = extract_section("Taglines", llm_output)
122
-
123
- # If extractor failed for any section, give fallback message with raw output for debugging
124
- # (This helps users see what the model actually returned.)
125
- fallback_debug = ""
126
- for name, value in [
127
- ("Creative Direction", creative_direction),
128
- ("Emotional Tone", emotional_tone),
129
- ("Ad Script", ad_script),
130
- ("Poster Prompt", poster_prompt),
131
- ("Taglines", taglines),
132
- ]:
133
- if value == "Not found.":
134
- fallback_debug += f"\n---\nSection '{name}' not parsed. Raw model output was:\n{llm_output}\n"
135
-
136
- # Markdown to display in Gradio
 
 
 
137
  md = f"""
138
  # 🎨 **Enterprise Creative Campaign Output**
139
  ---
@@ -156,27 +168,24 @@ Write full content under each heading only (do NOT include extra commentary).
156
  {taglines}
157
  ---
158
  """
159
- if fallback_debug:
160
- md += "\n\n**Parsing debug:** The model output didn't strictly match expected headings for at least one section. See raw output below.\n\n```\n" + llm_output[:4000] + ("\n... (truncated)\n" if len(llm_output) > 4000 else "\n") + "```\n"
161
-
162
  return md, creative_direction, emotional_tone, ad_script, poster_prompt, taglines
163
 
164
  # -----------------------------
165
- # Poster prompt generator (single-purpose)
166
  # -----------------------------
167
- def generate_poster_prompt(brand, mood, theme, audience):
168
- prompt = f"""
169
- Create a cinematic AI poster prompt for use with Stable Diffusion / SDXL.
170
  Brand: {brand}
171
  Mood: {mood}
172
  Theme: {theme}
173
  Audience: {audience}
 
174
 
175
- OUTPUT (single paragraph, no headings):
176
- Describe lighting, color palette, environment, camera angle, people (appearance, clothing, poses), props, depth of field, mood, and recommended typography placement. Keep it compact but highly descriptive.
177
  """
178
- result = generator(prompt, max_new_tokens=300, do_sample=True, temperature=0.8)[0]["generated_text"]
179
- return result
180
 
181
  # -----------------------------
182
  # Update Brand Memory
@@ -186,22 +195,18 @@ def update_brand_memory(new_tone, new_style):
186
  brand_memory["tone"] = new_tone
187
  if new_style:
188
  brand_memory["style"] = new_style
189
- # Return status + memory snapshot
190
  return "βœ… Brand memory updated successfully!", str(brand_memory)
191
 
192
  # -----------------------------
193
- # Export as PDF (keeps the multi-line layout)
194
  # -----------------------------
195
  def export_pdf(text):
196
  pdf = FPDF()
197
  pdf.set_auto_page_break(auto=True, margin=15)
198
  pdf.add_page()
199
  pdf.set_font("Arial", size=12)
200
-
201
- # split by lines and write using multi_cell to handle wrapping
202
  for line in text.split("\n"):
203
  pdf.multi_cell(0, 7, line)
204
-
205
  tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".pdf")
206
  pdf.output(tmp.name)
207
  return tmp.name
@@ -213,7 +218,7 @@ with gr.Blocks(theme=gr.themes.Monochrome()) as demo:
213
  gr.HTML("""
214
  <div style='text-align:center; padding:20px'>
215
  <h1 style='font-size:40px;'>πŸš€ Enterprise Creative Campaign Suite</h1>
216
- <p style='font-size:18px; color:#ddd;'>Powered by HuggingFace + Rookus Reasoning Core</p>
217
  </div>
218
  """)
219
 
@@ -223,16 +228,20 @@ with gr.Blocks(theme=gr.themes.Monochrome()) as demo:
223
  with gr.Row():
224
  brand_name = gr.Textbox(label="Brand Name", value="Chessy")
225
  product_type = gr.Textbox(label="Product Type", value="Premium Chess Set")
226
-
227
  goal = gr.Textbox(label="Campaign Goal", value="Increase D2C sales by 30% in 3 months")
228
  tone = gr.Textbox(label="Tone / Voice", value="Warm, aspirational, cinematic")
229
  audience = gr.Textbox(label="Target Audience", value="Young professionals, 25-40, India")
230
  region = gr.Textbox(label="Region", value="India")
231
 
 
 
 
 
 
232
  run_btn = gr.Button("πŸš€ Generate Full Campaign", variant="primary")
233
- output_md = gr.Markdown("Your campaign will appear here…")
234
 
235
- # Hidden textboxes to store raw pieces for later export/use
236
  cd = gr.Textbox(visible=False)
237
  et = gr.Textbox(visible=False)
238
  ad = gr.Textbox(visible=False)
@@ -241,7 +250,7 @@ with gr.Blocks(theme=gr.themes.Monochrome()) as demo:
241
 
242
  run_btn.click(
243
  fn=generate_campaign,
244
- inputs=[brand_name, product_type, goal, tone, audience, region],
245
  outputs=[output_md, cd, et, ad, pp, tg]
246
  )
247
 
@@ -251,12 +260,15 @@ with gr.Blocks(theme=gr.themes.Monochrome()) as demo:
251
  mood = gr.Textbox(label="Mood & Emotion", value="Epic, reflective")
252
  themep = gr.Textbox(label="Theme", value="Master vs Newcomer")
253
  audp = gr.Textbox(label="Audience", value="Players & collectors")
 
 
 
254
  gen_poster_btn = gr.Button("🎨 Generate Poster Prompt")
255
  poster_out = gr.Textbox(label="Poster Prompt", lines=8)
256
 
257
  gen_poster_btn.click(
258
  generate_poster_prompt,
259
- [brandp, mood, themep, audp],
260
  poster_out
261
  )
262
 
@@ -275,7 +287,7 @@ with gr.Blocks(theme=gr.themes.Monochrome()) as demo:
275
  gr.Markdown("### Export your full campaign as PDF")
276
  export_btn = gr.Button("πŸ“„ Export Campaign as PDF")
277
  export_file = gr.File()
278
- # When exporting, use the Markdown content (output_md)
279
  export_btn.click(export_pdf, inputs=output_md, outputs=export_file)
280
 
281
  demo.launch()
 
1
+ """
2
+ Enterprise Creative Campaign Suite - Separate-section generation (FLAN-T5-XL)
3
+ Author: Assistant (adapted for your needs)
4
+ Notes:
5
+ - This script calls the HF pipeline 5 times (one per section).
6
+ - If you have GPU, set device=0 inside the pipeline(...) call for speed.
7
+ """
8
+
9
  import tempfile
10
  from fpdf import FPDF
 
11
  import gradio as gr
12
  from transformers import pipeline
13
 
14
  # -----------------------------
15
+ # MODEL SETUP - FLAN-T5-XL
16
  # -----------------------------
17
+ # If you have GPU, set device=0
 
18
  generator = pipeline(
19
  "text2text-generation",
20
  model="google/flan-t5-xl",
21
+ # device=0, # uncomment if you want to use the first CUDA GPU
22
  )
23
 
24
  # -----------------------------
 
30
  }
31
 
32
  # -----------------------------
33
+ # Low-level wrapper to call model
34
  # -----------------------------
35
+ def gen_one(prompt: str, max_new_tokens: int = 220, temperature: float = 0.8, do_sample: bool = True):
36
+ """Call the HF pipeline and return generated text (stripped)."""
37
+ out = generator(prompt, max_new_tokens=max_new_tokens, do_sample=do_sample, temperature=temperature)
38
+ # Pipeline returns a list of dicts; take first
39
+ return out[0]["generated_text"].strip()
 
 
 
 
 
 
 
 
 
 
40
 
41
  # -----------------------------
42
+ # Per-section prompt builders
43
  # -----------------------------
44
+ def build_creative_direction_prompt(brand, product, goal, tone, audience, region):
45
+ return f"""You are an expert creative strategist. Write a **3–5 line Creative Direction** for a premium brand campaign.
46
 
47
+ Brand: {brand}
48
+ Product: {product}
49
+ Goal: {goal}
50
+ Tone: {tone}. Brand historically sounds like: {brand_memory.get('tone')}
51
+ Audience: {audience}
52
+ Region: {region}
53
 
54
+ Constraints:
55
+ - Output ONLY the creative direction text (3-5 lines).
56
+ - No headings, no extra commentary.
57
+ - Make it cinematic, emotionally resonant, and brand-forward.
58
+ """
59
 
60
+ def build_emotional_tone_prompt(brand, product, goal, tone, audience, region):
61
+ return f"""Write the Emotional Tone of the campaign in 4-6 lines.
62
 
63
+ Brand: {brand}
64
+ Product: {product}
65
+ Goal: {goal}
66
+ Tone: {tone}. Brand memory: {brand_memory.get('tone')}
67
+ Audience: {audience}
68
+ Region: {region}
69
 
70
+ Explain: emotional personality, core feelings to evoke, voice, and how it should make the audience feel.
71
+ Output ONLY the emotional tone paragraph(s). No headings.
 
72
  """
73
 
74
+ def build_ad_script_prompt(brand, product, goal, tone, audience, region, script_style="Hybrid"):
75
  """
76
+ Hybrid = cinematic storytelling + marketing clarity.
77
+ We'll ask for labeled sections inside the script: Intro, Body, CTA.
 
78
  """
79
+ return f"""Write a cinematic + marketing hybrid Ad Script for a 30-60 second film ad. Include labeled sections: "Intro:", "Body:", "CTA:".
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
 
81
+ Brand: {brand}
82
+ Product: {product}
83
+ Goal: {goal}
84
+ Tone: {tone}. Brand memory: {brand_memory.get('tone')}
85
+ Audience: {audience}
86
+ Region: {region}
87
+
88
+ Style: Hybrid (mix cinematic imagery and short marketing beats). Keep each labeled section concise (Intro: 2-4 lines, Body: 6-10 lines, CTA: 1-2 lines). Use vivid sensory details and short punch lines for the CTA.
89
+
90
+ Output only the script text with the labeled sections (Intro:, Body:, CTA:). No extra headings or commentary.
91
+ """
92
+
93
+ def build_poster_prompt_prompt(brand, product, goal, tone, audience, region):
94
+ return f"""Generate a single-paragraph Stable Diffusion / SDXL poster prompt for the campaign.
95
+
96
+ Brand: {brand}
97
+ Product: {product}
98
+ Goal: {goal}
99
+ Tone: {tone}. Brand memory: {brand_memory.get('tone')}
100
+ Audience: {audience}
101
+ Region: {region}
102
+
103
+ Include: lighting, color palette, environment, camera angle, characters (appearance, clothing, pose), props, mood, depth of field suggestions, and where to place typography.
104
+ Output only one descriptive paragraph (no headings).
105
+ """
106
+
107
+ def build_taglines_prompt(brand, product, goal, tone, audience, region):
108
+ return f"""Write **two** powerful taglines for the campaign. Keep them short, memorable, and emotionally resonant.
109
+
110
+ Brand: {brand}
111
+ Product: {product}
112
  Goal: {goal}
113
+ Tone: {tone}. Brand memory: {brand_memory.get('tone')}
114
+ Audience: {audience}
115
  Region: {region}
116
 
117
+ Format (exact):
118
+ - <Tagline 1>
119
+ - <Tagline 2>
120
 
121
+ Output only the two lines prefixed with a dash as shown.
122
  """
123
+
124
+ # -----------------------------
125
+ # Combined generator that calls the model for each section
126
+ # -----------------------------
127
+ def generate_campaign(brand_name, product_type, goal, tone, audience, region, temperature=0.8, do_sample=True):
128
+ """
129
+ Calls the model separately for each section and returns assembled markdown plus raw sections.
130
+ """
131
+ # Ensure brand memory hint appended to tone
132
+ tone_hint = f"{tone}. The brand historically sounds like: {brand_memory.get('tone')}"
133
+
134
+ # Build prompts
135
+ p_cd = build_creative_direction_prompt(brand_name, product_type, goal, tone_hint, audience, region)
136
+ p_et = build_emotional_tone_prompt(brand_name, product_type, goal, tone_hint, audience, region)
137
+ p_ad = build_ad_script_prompt(brand_name, product_type, goal, tone_hint, audience, region, script_style="Hybrid")
138
+ p_pp = build_poster_prompt_prompt(brand_name, product_type, goal, tone_hint, audience, region)
139
+ p_tg = build_taglines_prompt(brand_name, product_type, goal, tone_hint, audience, region)
140
+
141
+ # Generate each section (separate calls)
142
+ creative_direction = gen_one(p_cd, max_new_tokens=200, temperature=temperature, do_sample=do_sample)
143
+ emotional_tone = gen_one(p_et, max_new_tokens=180, temperature=temperature, do_sample=do_sample)
144
+ ad_script = gen_one(p_ad, max_new_tokens=420, temperature=temperature, do_sample=do_sample)
145
+ poster_prompt = gen_one(p_pp, max_new_tokens=200, temperature=temperature, do_sample=do_sample)
146
+ taglines = gen_one(p_tg, max_new_tokens=80, temperature=temperature, do_sample=do_sample)
147
+
148
+ # Assemble markdown
149
  md = f"""
150
  # 🎨 **Enterprise Creative Campaign Output**
151
  ---
 
168
  {taglines}
169
  ---
170
  """
171
+ # Return markdown plus each piece so UI can store/use them
 
 
172
  return md, creative_direction, emotional_tone, ad_script, poster_prompt, taglines
173
 
174
  # -----------------------------
175
+ # Poster prompt single-call helper (tab 2)
176
  # -----------------------------
177
+ def generate_poster_prompt(brand, mood, theme, audience, temperature=0.8, do_sample=True):
178
+ prompt = f"""Create a cinematic AI poster prompt for Stable Diffusion / SDXL.
179
+
180
  Brand: {brand}
181
  Mood: {mood}
182
  Theme: {theme}
183
  Audience: {audience}
184
+ Brand memory: {brand_memory.get('tone')}
185
 
186
+ OUTPUT: Single paragraph describing lighting, color palette, environment, camera angle, people (appearance, clothing, poses), props, depth of field, mood, and typography placement.
 
187
  """
188
+ return gen_one(prompt, max_new_tokens=240, temperature=temperature, do_sample=do_sample)
 
189
 
190
  # -----------------------------
191
  # Update Brand Memory
 
195
  brand_memory["tone"] = new_tone
196
  if new_style:
197
  brand_memory["style"] = new_style
 
198
  return "βœ… Brand memory updated successfully!", str(brand_memory)
199
 
200
  # -----------------------------
201
+ # Export to PDF
202
  # -----------------------------
203
  def export_pdf(text):
204
  pdf = FPDF()
205
  pdf.set_auto_page_break(auto=True, margin=15)
206
  pdf.add_page()
207
  pdf.set_font("Arial", size=12)
 
 
208
  for line in text.split("\n"):
209
  pdf.multi_cell(0, 7, line)
 
210
  tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".pdf")
211
  pdf.output(tmp.name)
212
  return tmp.name
 
218
  gr.HTML("""
219
  <div style='text-align:center; padding:20px'>
220
  <h1 style='font-size:40px;'>πŸš€ Enterprise Creative Campaign Suite</h1>
221
+ <p style='font-size:18px; color:#ddd;'>FLAN-T5-XL β€’ Sectioned generation (Hybrid script)</p>
222
  </div>
223
  """)
224
 
 
228
  with gr.Row():
229
  brand_name = gr.Textbox(label="Brand Name", value="Chessy")
230
  product_type = gr.Textbox(label="Product Type", value="Premium Chess Set")
 
231
  goal = gr.Textbox(label="Campaign Goal", value="Increase D2C sales by 30% in 3 months")
232
  tone = gr.Textbox(label="Tone / Voice", value="Warm, aspirational, cinematic")
233
  audience = gr.Textbox(label="Target Audience", value="Young professionals, 25-40, India")
234
  region = gr.Textbox(label="Region", value="India")
235
 
236
+ # Sampling controls
237
+ with gr.Row():
238
+ temperature = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, value=0.8, label="Temperature")
239
+ sampling_toggle = gr.Checkbox(value=True, label="Use sampling (do_sample)")
240
+
241
  run_btn = gr.Button("πŸš€ Generate Full Campaign", variant="primary")
242
+ output_md = gr.Markdown("Your campaign will appear here…", elem_id="campaign_output_md")
243
 
244
+ # Hidden outputs for each section
245
  cd = gr.Textbox(visible=False)
246
  et = gr.Textbox(visible=False)
247
  ad = gr.Textbox(visible=False)
 
250
 
251
  run_btn.click(
252
  fn=generate_campaign,
253
+ inputs=[brand_name, product_type, goal, tone, audience, region, temperature, sampling_toggle],
254
  outputs=[output_md, cd, et, ad, pp, tg]
255
  )
256
 
 
260
  mood = gr.Textbox(label="Mood & Emotion", value="Epic, reflective")
261
  themep = gr.Textbox(label="Theme", value="Master vs Newcomer")
262
  audp = gr.Textbox(label="Audience", value="Players & collectors")
263
+ # sampling controls local for poster
264
+ poster_temp = gr.Slider(minimum=0.0, maximum=1.0, step=0.05, value=0.8, label="Temperature (poster)")
265
+ poster_sample = gr.Checkbox(value=True, label="Use sampling for poster")
266
  gen_poster_btn = gr.Button("🎨 Generate Poster Prompt")
267
  poster_out = gr.Textbox(label="Poster Prompt", lines=8)
268
 
269
  gen_poster_btn.click(
270
  generate_poster_prompt,
271
+ [brandp, mood, themep, audp, poster_temp, poster_sample],
272
  poster_out
273
  )
274
 
 
287
  gr.Markdown("### Export your full campaign as PDF")
288
  export_btn = gr.Button("πŸ“„ Export Campaign as PDF")
289
  export_file = gr.File()
290
+
291
  export_btn.click(export_pdf, inputs=output_md, outputs=export_file)
292
 
293
  demo.launch()