Spaces:
Running
on
Zero
Running
on
Zero
Update app.py
Browse files
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
|
|
|
|
|
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 |
-
|
64 |
-
pipeline.
|
65 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 =
|
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
|
188 |
if pipeline is None:
|
189 |
raise ValueError("Model pipeline not loaded")
|
190 |
|
191 |
generator = torch.Generator(device=device).manual_seed(int(seed))
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 =
|
214 |
-
guidance_scale: float =
|
215 |
-
num_inference_steps: int =
|
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
|
229 |
|
230 |
# 3) μ μ₯
|
231 |
save_generated_image(image, final_prompt)
|
@@ -241,17 +305,16 @@ def generate_image(
|
|
241 |
# ===== μμ ν둬ννΈ (νκ΅μ΄/μμ΄ νΌμ© νμ©) =====
|
242 |
|
243 |
examples = [
|
244 |
-
"
|
245 |
-
"
|
246 |
-
"
|
247 |
-
"
|
248 |
-
"
|
249 |
-
"
|
250 |
-
"
|
251 |
-
"
|
252 |
-
"
|
253 |
-
"
|
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
|
575 |
-
<small style="opacity: 0.8;"
|
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=
|
623 |
with gr.Row():
|
624 |
-
guidance_scale = gr.Slider(label="Guidance scale (κ°μ΄λμ€ μ€μΌμΌ)", minimum=0.0, maximum=
|
625 |
-
num_inference_steps = gr.Slider(label="Inference steps (μΆλ‘ λ¨κ³)", minimum=1, maximum=50, step=1, value=
|
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 |
)
|