ajsbsd commited on
Commit
c02b5d2
Β·
verified Β·
1 Parent(s): 4858646

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +138 -25
app.py CHANGED
@@ -1,13 +1,16 @@
1
  import gradio as gr
2
  import torch
3
  from diffusers import StableDiffusionXLPipeline, StableDiffusionXLImg2ImgPipeline
4
- from PIL import Image
 
5
  import os
6
  import gc
7
  import time
8
  import spaces
9
  from typing import Optional, Tuple
10
  from huggingface_hub import hf_hub_download
 
 
11
 
12
  # Global pipeline variables
13
  txt2img_pipe = None
@@ -17,6 +20,14 @@ device = "cuda" if torch.cuda.is_available() else "cpu"
17
  # Hugging Face model configuration
18
  MODEL_REPO = "ajsbsd/CyberRealistic-Pony"
19
  MODEL_FILENAME = "cyberrealisticPony_v110.safetensors"
 
 
 
 
 
 
 
 
20
 
21
  def clear_memory():
22
  """Clear GPU memory"""
@@ -24,6 +35,24 @@ def clear_memory():
24
  torch.cuda.empty_cache()
25
  gc.collect()
26
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  def load_models():
28
  """Load both text2img and img2img pipelines optimized for Spaces"""
29
  global txt2img_pipe, img2img_pipe
@@ -108,6 +137,22 @@ def validate_dimensions(width: int, height: int) -> Tuple[int, int]:
108
 
109
  return width, height
110
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  @spaces.GPU(duration=60) # GPU decorator for Spaces
112
  def generate_txt2img(prompt, negative_prompt, num_steps, guidance_scale, width, height, seed, add_quality_tags):
113
  """Generate image from text prompt with Spaces GPU support"""
@@ -127,10 +172,12 @@ def generate_txt2img(prompt, negative_prompt, num_steps, guidance_scale, width,
127
  # Validate dimensions
128
  width, height = validate_dimensions(width, height)
129
 
 
 
 
 
130
  # Set seed
131
- generator = None
132
- if seed != -1:
133
- generator = torch.Generator(device=device).manual_seed(int(seed))
134
 
135
  # Enhance prompt
136
  enhanced_prompt = enhance_prompt(prompt, add_quality_tags)
@@ -151,7 +198,19 @@ def generate_txt2img(prompt, negative_prompt, num_steps, guidance_scale, width,
151
  )
152
 
153
  generation_time = time.time() - start_time
154
- status = f"Generated in {generation_time:.1f}s ({width}x{height})"
 
 
 
 
 
 
 
 
 
 
 
 
155
 
156
  return result.images[0], status
157
 
@@ -179,10 +238,12 @@ def generate_img2img(input_image, prompt, negative_prompt, num_steps, guidance_s
179
  try:
180
  clear_memory()
181
 
 
 
 
 
182
  # Set seed
183
- generator = None
184
- if seed != -1:
185
- generator = torch.Generator(device=device).manual_seed(int(seed))
186
 
187
  # Enhance prompt
188
  enhanced_prompt = enhance_prompt(prompt, add_quality_tags)
@@ -215,7 +276,19 @@ def generate_img2img(input_image, prompt, negative_prompt, num_steps, guidance_s
215
  )
216
 
217
  generation_time = time.time() - start_time
218
- status = f"Transformed in {generation_time:.1f}s (Strength: {strength})"
 
 
 
 
 
 
 
 
 
 
 
 
219
 
220
  return result.images[0], status
221
 
@@ -224,10 +297,26 @@ def generate_img2img(input_image, prompt, negative_prompt, num_steps, guidance_s
224
  finally:
225
  clear_memory()
226
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
  # Simplified negative prompt for better performance
228
  DEFAULT_NEGATIVE = """
229
- (low quality:1.3), (worst quality:1.3), (bad quality:1.2), blurry, noisy, ugly, deformed,
230
- (text, watermark:1.4), (extra limbs:1.3), (bad hands:1.3), (bad anatomy:1.2)
231
  """
232
 
233
  # Gradio interface optimized for Spaces
@@ -241,17 +330,21 @@ with gr.Blocks(
241
  Generate high-quality images using the CyberRealistic Pony SDXL model.
242
 
243
  ⚠️ **Note**: First generation may take longer as the model loads. GPU time is limited on Spaces.
 
244
  """)
245
 
246
  with gr.Tabs():
247
  with gr.TabItem("🎨 Text to Image"):
248
  with gr.Row():
249
  with gr.Column():
250
- txt2img_prompt = gr.Textbox(
251
- label="Prompt",
252
- placeholder="beautiful landscape, mountains, sunset",
253
- lines=2
254
- )
 
 
 
255
 
256
  with gr.Accordion("Advanced Settings", open=False):
257
  txt2img_negative = gr.Textbox(
@@ -273,24 +366,30 @@ with gr.Blocks(
273
  txt2img_width = gr.Slider(512, 1024, 768, step=64, label="Width")
274
  txt2img_height = gr.Slider(512, 1024, 768, step=64, label="Height")
275
 
276
- txt2img_seed = gr.Number(label="Seed (-1 for random)", value=-1, precision=0)
 
 
 
277
 
278
  txt2img_btn = gr.Button("🎨 Generate", variant="primary", size="lg")
279
 
280
  with gr.Column():
281
  txt2img_output = gr.Image(label="Generated Image", height=400)
282
- txt2img_status = gr.Textbox(label="Status", interactive=False)
283
 
284
  with gr.TabItem("πŸ–ΌοΈ Image to Image"):
285
  with gr.Row():
286
  with gr.Column():
287
  img2img_input = gr.Image(label="Input Image", type="pil", height=250)
288
 
289
- img2img_prompt = gr.Textbox(
290
- label="Prompt",
291
- placeholder="digital painting style, vibrant colors",
292
- lines=2
293
- )
 
 
 
294
 
295
  with gr.Accordion("Advanced Settings", open=False):
296
  img2img_negative = gr.Textbox(
@@ -313,13 +412,16 @@ with gr.Blocks(
313
  label="Strength (Higher = more creative)"
314
  )
315
 
316
- img2img_seed = gr.Number(label="Seed (-1 for random)", value=-1, precision=0)
 
 
 
317
 
318
  img2img_btn = gr.Button("πŸ–ΌοΈ Transform", variant="primary", size="lg")
319
 
320
  with gr.Column():
321
  img2img_output = gr.Image(label="Generated Image", height=400)
322
- img2img_status = gr.Textbox(label="Status", interactive=False)
323
 
324
  # Event handlers
325
  txt2img_btn.click(
@@ -335,6 +437,17 @@ with gr.Blocks(
335
  img2img_strength, img2img_seed, img2img_quality_tags],
336
  outputs=[img2img_output, img2img_status]
337
  )
 
 
 
 
 
 
 
 
 
 
 
338
 
339
  print(f"πŸš€ CyberRealistic Pony Generator initialized on {device}")
340
 
 
1
  import gradio as gr
2
  import torch
3
  from diffusers import StableDiffusionXLPipeline, StableDiffusionXLImg2ImgPipeline
4
+ from PIL import Image, PngImagePlugin
5
+ from datetime import datetime
6
  import os
7
  import gc
8
  import time
9
  import spaces
10
  from typing import Optional, Tuple
11
  from huggingface_hub import hf_hub_download
12
+ import tempfile
13
+ import random
14
 
15
  # Global pipeline variables
16
  txt2img_pipe = None
 
20
  # Hugging Face model configuration
21
  MODEL_REPO = "ajsbsd/CyberRealistic-Pony"
22
  MODEL_FILENAME = "cyberrealisticPony_v110.safetensors"
23
+ model_id = f"{MODEL_REPO}/{MODEL_FILENAME}"
24
+
25
+ # Generation configuration for metadata
26
+ generation_config = {
27
+ "vae": "SDXL VAE",
28
+ "sampler": "DPM++ 2M Karras",
29
+ "steps": 20
30
+ }
31
 
32
  def clear_memory():
33
  """Clear GPU memory"""
 
35
  torch.cuda.empty_cache()
36
  gc.collect()
37
 
38
+ def add_metadata_and_save(image: Image.Image, filepath: str, prompt: str, negative_prompt: str, seed: int, steps: int, guidance: float, strength: Optional[float] = None):
39
+ """Embed generation metadata into a PNG and save it."""
40
+ meta = PngImagePlugin.PngInfo()
41
+ meta.add_text("Prompt", prompt)
42
+ meta.add_text("NegativePrompt", negative_prompt)
43
+ meta.add_text("Model", model_id)
44
+ meta.add_text("VAE", generation_config["vae"])
45
+ meta.add_text("Sampler", generation_config["sampler"])
46
+ meta.add_text("Steps", str(steps))
47
+ meta.add_text("CFG_Scale", str(guidance))
48
+ if strength is not None:
49
+ meta.add_text("Strength", str(strength))
50
+ meta.add_text("Seed", str(seed))
51
+ meta.add_text("Date", datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
52
+
53
+ image.save(filepath, "PNG", pnginfo=meta)
54
+ return filepath
55
+
56
  def load_models():
57
  """Load both text2img and img2img pipelines optimized for Spaces"""
58
  global txt2img_pipe, img2img_pipe
 
137
 
138
  return width, height
139
 
140
+ def format_status_with_metadata(generation_time: float, width: int, height: int, prompt: str, negative_prompt: str, seed: int, steps: int, guidance: float, strength: Optional[float] = None):
141
+ """Format status message with generation metadata"""
142
+ status_parts = [
143
+ f"βœ… Generated in {generation_time:.1f}s ({width}Γ—{height})",
144
+ f"🎯 Prompt: {prompt[:50]}..." if len(prompt) > 50 else f"🎯 Prompt: {prompt}",
145
+ f"🚫 Negative: {negative_prompt[:30]}..." if negative_prompt and len(negative_prompt) > 30 else f"🚫 Negative: {negative_prompt or 'None'}",
146
+ f"🎲 Seed: {seed}",
147
+ f"πŸ“ Steps: {steps}",
148
+ f"πŸŽ›οΈ CFG: {guidance}"
149
+ ]
150
+
151
+ if strength is not None:
152
+ status_parts.append(f"πŸ’ͺ Strength: {strength}")
153
+
154
+ return "\n".join(status_parts)
155
+
156
  @spaces.GPU(duration=60) # GPU decorator for Spaces
157
  def generate_txt2img(prompt, negative_prompt, num_steps, guidance_scale, width, height, seed, add_quality_tags):
158
  """Generate image from text prompt with Spaces GPU support"""
 
172
  # Validate dimensions
173
  width, height = validate_dimensions(width, height)
174
 
175
+ # Handle seed
176
+ if seed == -1:
177
+ seed = random.randint(0, 2147483647)
178
+
179
  # Set seed
180
+ generator = torch.Generator(device=device).manual_seed(int(seed))
 
 
181
 
182
  # Enhance prompt
183
  enhanced_prompt = enhance_prompt(prompt, add_quality_tags)
 
198
  )
199
 
200
  generation_time = time.time() - start_time
201
+
202
+ # Save with metadata
203
+ temp_path = tempfile.mktemp(suffix=".png")
204
+ add_metadata_and_save(
205
+ result.images[0], temp_path, enhanced_prompt, negative_prompt or "",
206
+ seed, num_steps, guidance_scale
207
+ )
208
+
209
+ # Format status with metadata
210
+ status = format_status_with_metadata(
211
+ generation_time, width, height, enhanced_prompt,
212
+ negative_prompt or "", seed, num_steps, guidance_scale
213
+ )
214
 
215
  return result.images[0], status
216
 
 
238
  try:
239
  clear_memory()
240
 
241
+ # Handle seed
242
+ if seed == -1:
243
+ seed = random.randint(0, 2147483647)
244
+
245
  # Set seed
246
+ generator = torch.Generator(device=device).manual_seed(int(seed))
 
 
247
 
248
  # Enhance prompt
249
  enhanced_prompt = enhance_prompt(prompt, add_quality_tags)
 
276
  )
277
 
278
  generation_time = time.time() - start_time
279
+
280
+ # Save with metadata
281
+ temp_path = tempfile.mktemp(suffix=".png")
282
+ add_metadata_and_save(
283
+ result.images[0], temp_path, enhanced_prompt, negative_prompt or "",
284
+ seed, num_steps, guidance_scale, strength
285
+ )
286
+
287
+ # Format status with metadata
288
+ status = format_status_with_metadata(
289
+ generation_time, w, h, enhanced_prompt,
290
+ negative_prompt or "", seed, num_steps, guidance_scale, strength
291
+ )
292
 
293
  return result.images[0], status
294
 
 
297
  finally:
298
  clear_memory()
299
 
300
+ # Example prompts for inspiration
301
+ EXAMPLE_PROMPTS = [
302
+ "beautiful anime girl with long flowing hair, cherry blossoms, soft lighting",
303
+ "cyberpunk cityscape at night, neon lights, rain reflections, detailed architecture",
304
+ "majestic dragon flying over mountains, fantasy landscape, dramatic clouds",
305
+ "cute anthropomorphic fox character, forest background, magical atmosphere",
306
+ "elegant woman in Victorian dress, portrait, ornate background, vintage style",
307
+ "futuristic robot with glowing eyes, metallic surface, sci-fi environment",
308
+ "mystical unicorn in enchanted forest, rainbow mane, sparkles, ethereal lighting",
309
+ "steampunk airship floating in sky, gears and brass, adventure scene"
310
+ ]
311
+
312
+ def set_example_prompt():
313
+ """Return a random example prompt"""
314
+ return random.choice(EXAMPLE_PROMPTS)
315
+
316
  # Simplified negative prompt for better performance
317
  DEFAULT_NEGATIVE = """
318
+ (low quality:1.3), (worst quality:1.3), (bad quality:1.2), (nsfw:1.5), (easynegative:1.3) (bad_prompt:1.3) badhandv4 bad-hands-5 (negative_hand-neg) (bad-picture-chill-75v), (worst quality:1.3), (low quality:1.3), (bad quality:1.3), (a shadow on skin:1.3), (a shaded skin:1.3), (a dark skin:1.3), (blush:1.3), (signature, watermark, username, letter, copyright name,
319
+ copyright, chinese text, artist name, name tag, company name, name tag, text, error:1.5), (bad anatomy:1.5), (low quality hand:1.5), (worst quality hand:1.5)
320
  """
321
 
322
  # Gradio interface optimized for Spaces
 
330
  Generate high-quality images using the CyberRealistic Pony SDXL model.
331
 
332
  ⚠️ **Note**: First generation may take longer as the model loads. GPU time is limited on Spaces.
333
+ πŸ“‹ **Metadata**: All generated images include embedded metadata (prompt, settings, seed, etc.)
334
  """)
335
 
336
  with gr.Tabs():
337
  with gr.TabItem("🎨 Text to Image"):
338
  with gr.Row():
339
  with gr.Column():
340
+ with gr.Row():
341
+ txt2img_prompt = gr.Textbox(
342
+ label="Prompt",
343
+ placeholder="beautiful landscape, mountains, sunset",
344
+ lines=2,
345
+ scale=4
346
+ )
347
+ txt2img_example_btn = gr.Button("🎲 Random Example", scale=1)
348
 
349
  with gr.Accordion("Advanced Settings", open=False):
350
  txt2img_negative = gr.Textbox(
 
366
  txt2img_width = gr.Slider(512, 1024, 768, step=64, label="Width")
367
  txt2img_height = gr.Slider(512, 1024, 768, step=64, label="Height")
368
 
369
+ txt2img_seed = gr.Slider(
370
+ minimum=-1, maximum=2147483647, value=-1, step=1,
371
+ label="Seed (-1 for random)"
372
+ )
373
 
374
  txt2img_btn = gr.Button("🎨 Generate", variant="primary", size="lg")
375
 
376
  with gr.Column():
377
  txt2img_output = gr.Image(label="Generated Image", height=400)
378
+ txt2img_status = gr.Textbox(label="Generation Info", interactive=False, lines=6)
379
 
380
  with gr.TabItem("πŸ–ΌοΈ Image to Image"):
381
  with gr.Row():
382
  with gr.Column():
383
  img2img_input = gr.Image(label="Input Image", type="pil", height=250)
384
 
385
+ with gr.Row():
386
+ img2img_prompt = gr.Textbox(
387
+ label="Prompt",
388
+ placeholder="digital painting style, vibrant colors",
389
+ lines=2,
390
+ scale=4
391
+ )
392
+ img2img_example_btn = gr.Button("🎲 Random Example", scale=1)
393
 
394
  with gr.Accordion("Advanced Settings", open=False):
395
  img2img_negative = gr.Textbox(
 
412
  label="Strength (Higher = more creative)"
413
  )
414
 
415
+ img2img_seed = gr.Slider(
416
+ minimum=-1, maximum=2147483647, value=-1, step=1,
417
+ label="Seed (-1 for random)"
418
+ )
419
 
420
  img2img_btn = gr.Button("πŸ–ΌοΈ Transform", variant="primary", size="lg")
421
 
422
  with gr.Column():
423
  img2img_output = gr.Image(label="Generated Image", height=400)
424
+ img2img_status = gr.Textbox(label="Generation Info", interactive=False, lines=6)
425
 
426
  # Event handlers
427
  txt2img_btn.click(
 
437
  img2img_strength, img2img_seed, img2img_quality_tags],
438
  outputs=[img2img_output, img2img_status]
439
  )
440
+
441
+ # Example prompt buttons
442
+ txt2img_example_btn.click(
443
+ fn=set_example_prompt,
444
+ outputs=[txt2img_prompt]
445
+ )
446
+
447
+ img2img_example_btn.click(
448
+ fn=set_example_prompt,
449
+ outputs=[img2img_prompt]
450
+ )
451
 
452
  print(f"πŸš€ CyberRealistic Pony Generator initialized on {device}")
453