Spaces:
Heartsync
/
Running on Zero

seawolf2357 commited on
Commit
c5944e5
Β·
verified Β·
1 Parent(s): 76dfe53

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +112 -43
app.py CHANGED
@@ -24,7 +24,9 @@ import gradio as gr
24
  import numpy as np
25
  import requests
26
  import torch
27
- from diffusers import DiffusionPipeline
 
 
28
  from PIL import Image
29
 
30
  # ===== OpenAI μ„€μ • =====
@@ -52,24 +54,45 @@ if not os.path.exists(SAVE_DIR):
52
  os.makedirs(SAVE_DIR, exist_ok=True)
53
 
54
  # ===== λ””λ°”μ΄μŠ€ & λͺ¨λΈ λ‘œλ“œ =====
55
- device = "cuda" if torch.cuda.is_available() else "cpu"
56
  print(f"Using device: {device}")
57
 
58
- repo_id = "black-forest-labs/FLUX.1-dev"
59
- adapter_id = "seawolf2357/kim-korea"
60
-
61
  # Add error handling for model loading
62
  try:
63
- pipeline = DiffusionPipeline.from_pretrained(repo_id, torch_dtype=torch.bfloat16)
64
- pipeline.load_lora_weights(adapter_id)
65
- pipeline = pipeline.to(device)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  print("Model loaded successfully")
67
  except Exception as e:
68
  print(f"Error loading model: {e}")
69
  pipeline = None
 
70
 
71
  MAX_SEED = np.iinfo(np.int32).max
72
- MAX_IMAGE_SIZE = 1024
73
 
74
  # ===== ν•œκΈ€ μ—¬λΆ€ νŒλ³„ =====
75
  HANGUL_RE = re.compile(r"[\u3131-\u318E\uAC00-\uD7A3]+")
@@ -182,23 +205,64 @@ def save_generated_image(image: Image.Image, prompt: str) -> str:
182
  f.write(f"{filename}|{prompt}|{timestamp}\n")
183
  return filepath
184
 
 
 
 
 
 
 
 
 
 
 
185
  # ===== Diffusion 호좜 =====
186
 
187
- def run_pipeline(prompt: str, seed: int, width: int, height: int, guidance_scale: float, num_steps: int, lora_scale: float):
188
  if pipeline is None:
189
  raise ValueError("Model pipeline not loaded")
190
 
191
  generator = torch.Generator(device=device).manual_seed(int(seed))
192
- result = pipeline(
193
- prompt=prompt,
194
- guidance_scale=guidance_scale,
195
- num_inference_steps=num_steps,
196
- width=width,
197
- height=height,
198
- generator=generator,
199
- joint_attention_kwargs={"scale": lora_scale},
200
- ).images[0]
201
- return result
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202
 
203
  # ===== Gradio inference 래퍼 =====
204
 
@@ -207,13 +271,13 @@ def generate_image(
207
  user_prompt: str,
208
  style_key: str,
209
  enhance_prompt_enabled: bool = False,
 
210
  seed: int = 42,
211
  randomize_seed: bool = True,
212
  width: int = 1024,
213
- height: int = 768,
214
- guidance_scale: float = 3.5,
215
- num_inference_steps: int = 30,
216
- lora_scale: float = 1.0,
217
  progress=None,
218
  ):
219
  try:
@@ -225,7 +289,7 @@ def generate_image(
225
  print(f"Final prompt: {final_prompt}")
226
 
227
  # 2) νŒŒμ΄ν”„λΌμΈ 호좜
228
- image = run_pipeline(final_prompt, seed, width, height, guidance_scale, num_inference_steps, lora_scale)
229
 
230
  # 3) μ €μž₯
231
  save_generated_image(image, final_prompt)
@@ -241,17 +305,16 @@ def generate_image(
241
  # ===== μ˜ˆμ‹œ ν”„λ‘¬ν”„νŠΈ (ν•œκ΅­μ–΄/μ˜μ–΄ 혼용 ν—ˆμš©) =====
242
 
243
  examples = [
244
- "Mr. KIM이 두 μ†μœΌλ‘œ 'Fighting!' ν˜„μˆ˜λ§‰μ„ λ“€κ³  μžˆλŠ” λͺ¨μŠ΅, 애ꡭ심과 κ΅­κ°€ λ°œμ „μ— λŒ€ν•œ μ˜μ§€λ₯Ό 보여주고 μžˆλ‹€.",
245
- "Mr. KIM이 μ–‘νŒ”μ„ λ“€μ–΄ 올리며 승리의 ν‘œμ •μœΌλ‘œ ν™˜ν˜Έν•˜λŠ” λͺ¨μŠ΅, μŠΉλ¦¬μ™€ λ―Έλž˜μ— λŒ€ν•œ 희망을 보여주고 μžˆλ‹€.",
246
- "Mr. KIM이 μš΄λ™λ³΅μ„ μž…κ³  κ³΅μ›μ—μ„œ μ‘°κΉ…ν•˜λŠ” λͺ¨μŠ΅, κ±΄κ°•ν•œ μƒν™œμŠ΅κ΄€κ³Ό ν™œκΈ°μ°¬ 리더십을 보여주고 μžˆλ‹€.",
247
- "Mr. KIM이 λΆλΉ„λŠ” κ±°λ¦¬μ—μ„œ μ—¬μ„± μ‹œλ―Όλ“€κ³Ό λ”°λœ»ν•˜κ²Œ μ•…μˆ˜ν•˜λŠ” λͺ¨μŠ΅, μ—¬μ„± μœ κΆŒμžλ“€μ— λŒ€ν•œ μ§„μ •ν•œ 관심과 μ†Œν†΅μ„ 보여주고 μžˆλ‹€.",
248
- "Mr. KIM이 μ„ κ±° μœ μ„Έμž₯μ—μ„œ 지평선을 ν–₯ν•΄ μ†κ°€λ½μœΌλ‘œ 가리킀며 μ˜κ°μ„ μ£ΌλŠ” 제슀처λ₯Ό μ·¨ν•˜κ³  있고, μ—¬μ„±λ“€κ³Ό 아이듀이 λ°•μˆ˜λ₯Ό 치고 μžˆλ‹€.",
249
- "Mr. KIM이 μ§€μ—­ 행사에 μ°Έμ—¬ν•˜μ—¬ μ—΄μ •μ μœΌλ‘œ μ‘μ›ν•˜λŠ” μ—¬μ„± μ§€μ§€μžλ“€μ—κ²Œ λ‘˜λŸ¬μ‹Έμ—¬ μžˆλŠ” λͺ¨μŠ΅.",
250
- "Mr. KIM visiting a local market, engaging in friendly conversation with female vendors and shopkeepers.",
251
- "Mr. KIM walking through a university campus, discussing education policies with female students and professors.",
252
- "Mr. KIM delivering a powerful speech in front of a large crowd with confident gestures and determined expression.",
253
- "Mr. KIM in a dynamic interview setting, passionately outlining his visions for the future.",
254
- "Mr. KIM preparing for an important debate, surrounded by paperwork, looking focused and resolute.",
255
  ]
256
 
257
  # ===== μ»€μŠ€ν…€ CSS (μ§„ν•œ 뢉은색 κ³ κΈ‰ λ””μžμΈ) =====
@@ -571,8 +634,8 @@ def create_interface():
571
  with gr.Group(elem_classes="model-description"):
572
  gr.HTML("""
573
  <p>
574
- <strong>Mr. KIM in KOREA</strong><br>
575
- <small style="opacity: 0.8;">λ³Έ λͺ¨λΈμ€ 연ꡬ λͺ©μ μœΌλ‘œ νŠΉμ •μΈμ˜ μ–Όκ΅΄κ³Ό μ™Έλͺ¨λ₯Ό LoRA 기술둜 ν•™μŠ΅ν•œ λͺ¨λΈμž…λ‹ˆλ‹€.λͺ©μ  μ™Έμ˜ μš©λ„λ‘œ 무단 μ‚¬μš©ν•˜μ§€ μ•Šλ„λ‘ μœ μ˜ν•΄ μ£Όμ„Έμš”. ν”„λ‘¬ν”„νŠΈμ— 'kim'을 ν¬ν•¨ν•˜μ—¬ μ£Όμ„Έμš”.</small><br><br>
576
  """)
577
 
578
  # ===== 메인 μž…λ ₯ =====
@@ -615,15 +678,21 @@ def create_interface():
615
 
616
  # ===== κ³ κΈ‰ μ„€μ • =====
617
  with gr.Accordion("Advanced Settings (κ³ κΈ‰ μ„€μ •)", open=False, elem_classes="advanced-settings"):
 
 
 
 
 
 
 
618
  seed = gr.Slider(label="Seed (μ‹œλ“œκ°’)", minimum=0, maximum=MAX_SEED, step=1, value=42)
619
  randomize_seed = gr.Checkbox(label="Randomize seed (μ‹œλ“œκ°’ λ¬΄μž‘μœ„)", value=True)
620
  with gr.Row():
621
  width = gr.Slider(label="Width (κ°€λ‘œ)", minimum=256, maximum=MAX_IMAGE_SIZE, step=32, value=1024)
622
- height = gr.Slider(label="Height (μ„Έλ‘œ)", minimum=256, maximum=MAX_IMAGE_SIZE, step=32, value=768)
623
  with gr.Row():
624
- guidance_scale = gr.Slider(label="Guidance scale (κ°€μ΄λ˜μŠ€ μŠ€μΌ€μΌ)", minimum=0.0, maximum=10.0, step=0.1, value=3.5)
625
- num_inference_steps = gr.Slider(label="Inference steps (μΆ”λ‘  단계)", minimum=1, maximum=50, step=1, value=30)
626
- lora_scale = gr.Slider(label="LoRA scale (LoRA μŠ€μΌ€μΌ)", minimum=0.0, maximum=1.0, step=0.1, value=1.0)
627
 
628
  # ===== μ˜ˆμ‹œ μ˜μ—­ =====
629
  with gr.Group(elem_classes="example-region"):
@@ -637,13 +706,13 @@ def create_interface():
637
  user_prompt,
638
  style_select,
639
  enhance_prompt_checkbox,
 
640
  seed,
641
  randomize_seed,
642
  width,
643
  height,
644
  guidance_scale,
645
  num_inference_steps,
646
- lora_scale,
647
  ],
648
  outputs=[result_image, seed_output],
649
  )
 
24
  import numpy as np
25
  import requests
26
  import torch
27
+ from diffusers import StableDiffusionXLPipeline
28
+ from diffusers import EulerAncestralDiscreteScheduler
29
+ from compel import Compel, ReturnedEmbeddingsType
30
  from PIL import Image
31
 
32
  # ===== OpenAI μ„€μ • =====
 
54
  os.makedirs(SAVE_DIR, exist_ok=True)
55
 
56
  # ===== λ””λ°”μ΄μŠ€ & λͺ¨λΈ λ‘œλ“œ =====
57
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
58
  print(f"Using device: {device}")
59
 
 
 
 
60
  # Add error handling for model loading
61
  try:
62
+ # Make sure to use torch.float16 consistently throughout the pipeline
63
+ pipeline = StableDiffusionXLPipeline.from_pretrained(
64
+ "votepurchase/pornmasterPro_noobV3VAE",
65
+ torch_dtype=torch.float16,
66
+ variant="fp16", # Explicitly use fp16 variant
67
+ use_safetensors=True # Use safetensors if available
68
+ )
69
+
70
+ pipeline.scheduler = EulerAncestralDiscreteScheduler.from_config(pipeline.scheduler.config)
71
+ pipeline.to(device)
72
+
73
+ # Force all components to use the same dtype
74
+ pipeline.text_encoder.to(torch.float16)
75
+ pipeline.text_encoder_2.to(torch.float16)
76
+ pipeline.vae.to(torch.float16)
77
+ pipeline.unet.to(torch.float16)
78
+
79
+ # Initialize Compel for long prompt processing
80
+ compel = Compel(
81
+ tokenizer=[pipeline.tokenizer, pipeline.tokenizer_2],
82
+ text_encoder=[pipeline.text_encoder, pipeline.text_encoder_2],
83
+ returned_embeddings_type=ReturnedEmbeddingsType.PENULTIMATE_HIDDEN_STATES_NON_NORMALIZED,
84
+ requires_pooled=[False, True],
85
+ truncate_long_prompts=False
86
+ )
87
+
88
  print("Model loaded successfully")
89
  except Exception as e:
90
  print(f"Error loading model: {e}")
91
  pipeline = None
92
+ compel = None
93
 
94
  MAX_SEED = np.iinfo(np.int32).max
95
+ MAX_IMAGE_SIZE = 1216
96
 
97
  # ===== ν•œκΈ€ μ—¬λΆ€ νŒλ³„ =====
98
  HANGUL_RE = re.compile(r"[\u3131-\u318E\uAC00-\uD7A3]+")
 
205
  f.write(f"{filename}|{prompt}|{timestamp}\n")
206
  return filepath
207
 
208
+ # ===== Long prompt processing function =====
209
+ def process_long_prompt(prompt, negative_prompt=""):
210
+ """Simple long prompt processing using Compel"""
211
+ try:
212
+ conditioning, pooled = compel([prompt, negative_prompt])
213
+ return conditioning, pooled
214
+ except Exception as e:
215
+ print(f"Long prompt processing failed: {e}, falling back to standard processing")
216
+ return None, None
217
+
218
  # ===== Diffusion 호좜 =====
219
 
220
+ def run_pipeline(prompt: str, negative_prompt: str, seed: int, width: int, height: int, guidance_scale: float, num_steps: int):
221
  if pipeline is None:
222
  raise ValueError("Model pipeline not loaded")
223
 
224
  generator = torch.Generator(device=device).manual_seed(int(seed))
225
+
226
+ # Check if prompt is long
227
+ use_long_prompt = len(prompt.split()) > 60 or len(prompt) > 300
228
+
229
+ try:
230
+ # Try long prompt processing first if prompt is long
231
+ if use_long_prompt and compel is not None:
232
+ print("Using long prompt processing...")
233
+ conditioning, pooled = process_long_prompt(prompt, negative_prompt)
234
+
235
+ if conditioning is not None:
236
+ result = pipeline(
237
+ prompt_embeds=conditioning[0:1],
238
+ pooled_prompt_embeds=pooled[0:1],
239
+ negative_prompt_embeds=conditioning[1:2],
240
+ negative_pooled_prompt_embeds=pooled[1:2],
241
+ guidance_scale=guidance_scale,
242
+ num_inference_steps=num_steps,
243
+ width=width,
244
+ height=height,
245
+ generator=generator
246
+ ).images[0]
247
+ return result
248
+
249
+ # Fall back to standard processing
250
+ result = pipeline(
251
+ prompt=prompt,
252
+ negative_prompt=negative_prompt,
253
+ guidance_scale=guidance_scale,
254
+ num_inference_steps=num_steps,
255
+ width=width,
256
+ height=height,
257
+ generator=generator
258
+ ).images[0]
259
+
260
+ return result
261
+ except RuntimeError as e:
262
+ print(f"Error during generation: {e}")
263
+ # Return a blank image with error message
264
+ error_img = Image.new('RGB', (width, height), color=(0, 0, 0))
265
+ return error_img
266
 
267
  # ===== Gradio inference 래퍼 =====
268
 
 
271
  user_prompt: str,
272
  style_key: str,
273
  enhance_prompt_enabled: bool = False,
274
+ negative_prompt: str = "nsfw, (low quality, worst quality:1.2), very displeasing, 3d, watermark, signature, ugly, poorly drawn",
275
  seed: int = 42,
276
  randomize_seed: bool = True,
277
  width: int = 1024,
278
+ height: int = 1024,
279
+ guidance_scale: float = 7.0,
280
+ num_inference_steps: int = 28,
 
281
  progress=None,
282
  ):
283
  try:
 
289
  print(f"Final prompt: {final_prompt}")
290
 
291
  # 2) νŒŒμ΄ν”„λΌμΈ 호좜
292
+ image = run_pipeline(final_prompt, negative_prompt, seed, width, height, guidance_scale, num_inference_steps)
293
 
294
  # 3) μ €μž₯
295
  save_generated_image(image, final_prompt)
 
305
  # ===== μ˜ˆμ‹œ ν”„λ‘¬ν”„νŠΈ (ν•œκ΅­μ–΄/μ˜μ–΄ 혼용 ν—ˆμš©) =====
306
 
307
  examples = [
308
+ "μ•„λ¦„λ‹€μš΄ ν•œκ΅­ 여성이 전톡 ν•œλ³΅μ„ μž…κ³  경볡ꢁ μ•žμ—μ„œ λ―Έμ†Œ μ§“λŠ” λͺ¨μŠ΅",
309
+ "ν˜„λŒ€μ μΈ μ„œμšΈ λ„μ‹œ 풍경과 λ‚¨μ‚°νƒ€μ›Œκ°€ λ³΄μ΄λŠ” μ•Όκ²½",
310
+ "ν•œκ΅­μ˜ λ΄„, λ²šκ½ƒμ΄ λ§Œκ°œν•œ κ³΅μ›μ—μ„œ μ‚°μ±…ν•˜λŠ” μ‚¬λžŒλ“€",
311
+ "전톡 ν•œμ˜₯λ§ˆμ„μ˜ κ³ μ¦ˆλ„‰ν•œ μ˜€ν›„ 풍경",
312
+ "K-pop μ•„μ΄λŒ μ½˜μ„œνŠΈμ˜ ν™”λ €ν•œ λ¬΄λŒ€μ™€ 열정적인 νŒ¬λ“€",
313
+ "μ„œμšΈμ˜ λ²ˆν™”ν•œ λͺ…동 거리, μ‡Όν•‘ν•˜λŠ” μ‚¬λžŒλ“€κ³Ό λ„€μ˜¨μ‚¬μΈ",
314
+ "Beautiful Korean woman in traditional hanbok dress standing in front of Gyeongbokgung Palace",
315
+ "Modern Seoul cityscape at night with N Seoul Tower illuminated",
316
+ "Korean spring scenery with cherry blossoms in full bloom",
317
+ "Traditional Korean tea ceremony in a peaceful hanok setting",
 
318
  ]
319
 
320
  # ===== μ»€μŠ€ν…€ CSS (μ§„ν•œ 뢉은색 κ³ κΈ‰ λ””μžμΈ) =====
 
634
  with gr.Group(elem_classes="model-description"):
635
  gr.HTML("""
636
  <p>
637
+ <strong>κ³ ν’ˆμ§ˆ 이미지 생성 AI</strong><br>
638
+ <small style="opacity: 0.8;">StableDiffusionXL 기반의 κ³ κΈ‰ 이미지 생성 λͺ¨λΈμž…λ‹ˆλ‹€. ν•œκ΅­μ–΄ ν”„λ‘¬ν”„νŠΈλ₯Ό μžλ™μœΌλ‘œ λ²ˆμ—­ν•˜λ©°, κΈ΄ ν”„λ‘¬ν”„νŠΈλ„ μ§€μ›ν•©λ‹ˆλ‹€.</small><br><br>
639
  """)
640
 
641
  # ===== 메인 μž…λ ₯ =====
 
678
 
679
  # ===== κ³ κΈ‰ μ„€μ • =====
680
  with gr.Accordion("Advanced Settings (κ³ κΈ‰ μ„€μ •)", open=False, elem_classes="advanced-settings"):
681
+ negative_prompt = gr.Text(
682
+ label="Negative prompt (λ„€κ±°ν‹°λΈŒ ν”„λ‘¬ν”„νŠΈ)",
683
+ max_lines=1,
684
+ placeholder="Enter a negative prompt",
685
+ value="nsfw, (low quality, worst quality:1.2), very displeasing, 3d, watermark, signature, ugly, poorly drawn"
686
+ )
687
+
688
  seed = gr.Slider(label="Seed (μ‹œλ“œκ°’)", minimum=0, maximum=MAX_SEED, step=1, value=42)
689
  randomize_seed = gr.Checkbox(label="Randomize seed (μ‹œλ“œκ°’ λ¬΄μž‘μœ„)", value=True)
690
  with gr.Row():
691
  width = gr.Slider(label="Width (κ°€λ‘œ)", minimum=256, maximum=MAX_IMAGE_SIZE, step=32, value=1024)
692
+ height = gr.Slider(label="Height (μ„Έλ‘œ)", minimum=256, maximum=MAX_IMAGE_SIZE, step=32, value=1024)
693
  with gr.Row():
694
+ guidance_scale = gr.Slider(label="Guidance scale (κ°€μ΄λ˜μŠ€ μŠ€μΌ€μΌ)", minimum=0.0, maximum=20.0, step=0.1, value=7.0)
695
+ num_inference_steps = gr.Slider(label="Inference steps (μΆ”λ‘  단계)", minimum=1, maximum=50, step=1, value=28)
 
696
 
697
  # ===== μ˜ˆμ‹œ μ˜μ—­ =====
698
  with gr.Group(elem_classes="example-region"):
 
706
  user_prompt,
707
  style_select,
708
  enhance_prompt_checkbox,
709
+ negative_prompt,
710
  seed,
711
  randomize_seed,
712
  width,
713
  height,
714
  guidance_scale,
715
  num_inference_steps,
 
716
  ],
717
  outputs=[result_image, seed_output],
718
  )