seawolf2357 commited on
Commit
4a1aee0
·
verified ·
1 Parent(s): f7cf58f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +91 -50
app.py CHANGED
@@ -1,3 +1,4 @@
 
1
  import spaces
2
  import gradio as gr
3
  import numpy as np
@@ -8,10 +9,18 @@ import torch
8
  from transformers import pipeline as transformers_pipeline
9
  import re
10
 
11
- # Device selection for image generation (GPU if available)
 
 
 
 
 
 
12
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
13
 
14
- # Stable Diffusion XL pipeline
 
 
15
  pipe = StableDiffusionXLPipeline.from_pretrained(
16
  "votepurchase/waiNSFWIllustrious_v120",
17
  torch_dtype=torch.float16,
@@ -21,37 +30,72 @@ pipe = StableDiffusionXLPipeline.from_pretrained(
21
  pipe.scheduler = EulerAncestralDiscreteScheduler.from_config(pipe.scheduler.config)
22
  pipe.to(device)
23
 
24
- # Force modules to fp16 for memory efficiency
25
- pipe.text_encoder.to(torch.float16)
26
- pipe.text_encoder_2.to(torch.float16)
27
- pipe.vae.to(torch.float16)
28
- pipe.unet.to(torch.float16)
29
-
30
- # Korean → English translator (CPU only)
31
- translator = transformers_pipeline(
32
- "translation",
33
- model="Helsinki-NLP/opus-mt-ko-en",
34
- device=-1, # -1 forces CPU
35
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
 
37
- MAX_SEED = np.iinfo(np.int32).max
38
- MAX_IMAGE_SIZE = 1216
39
- korean_regex = re.compile("[\uac00-\ud7af]+")
40
 
41
  def maybe_translate(text: str) -> str:
42
- """Translate Korean text to English if Korean characters are detected."""
43
- if korean_regex.search(text):
44
- translation = translator(text, max_length=256, clean_up_tokenization_spaces=True)
45
- return translation[0]["translation_text"]
 
 
 
46
  return text
47
 
 
 
 
 
 
 
48
  @spaces.GPU
49
  def infer(prompt, negative_prompt, seed, randomize_seed, width, height, guidance_scale, num_inference_steps):
50
  prompt = maybe_translate(prompt)
51
  negative_prompt = maybe_translate(negative_prompt)
52
 
53
  if len(prompt.split()) > 60:
54
- print("Warning: Prompt may be too long and will be truncated by the model")
55
 
56
  if randomize_seed:
57
  seed = random.randint(0, MAX_SEED)
@@ -70,24 +114,30 @@ def infer(prompt, negative_prompt, seed, randomize_seed, width, height, guidance
70
  ).images[0]
71
  return output_image
72
  except RuntimeError as e:
73
- print(f"Error during generation: {e}")
74
- error_img = Image.new("RGB", (width, height), color=(0, 0, 0))
75
- return error_img
76
 
77
- # Custom styling – bright pastel theme
 
 
78
  css = """
79
  body {background: #f2f1f7; color: #222; font-family: 'Noto Sans', sans-serif;}
80
  #col-container {margin: 0 auto; max-width: 640px;}
81
- .gr-button {background: #7fbdf6; color: #ffffff; border-radius: 8px;}
82
- #prompt-box textarea {font-size: 1.1rem; height: 3rem; background: #ffffff; color: #222;}
83
  """
84
 
 
 
 
 
 
 
85
  with gr.Blocks(css=css, theme=gr.themes.Soft()) as demo:
86
  gr.Markdown(
87
- """
88
  ## 🖌️ Stable Diffusion XL Playground
89
- Generate high‑quality illustrations with a single prompt.
90
- **Tip:** Write in Korean or English. Korean will be translated automatically.
91
  """
92
  )
93
 
@@ -98,20 +148,19 @@ with gr.Blocks(css=css, theme=gr.themes.Soft()) as demo:
98
  elem_id="prompt-box",
99
  show_label=False,
100
  max_lines=1,
101
- placeholder="Enter your prompt (60 words max)",
102
  )
103
  run_button = gr.Button("Generate", scale=0)
104
 
105
  result = gr.Image(label="", show_label=False)
106
 
107
- # Adult anime‑style example prompts
108
  examples = gr.Examples(
109
  examples=[
110
- ["Seductive anime woman lounging in a dimly lit bar, adult anime style, ultra‑detail"],
111
- ["Moody mature anime scene of two lovers kissing under neon rain, sensual atmosphere"],
112
- ["기모노를 입은 일본 여자를 남자가 뒤에서 강간한다 , candlelit boudoir, adult anime aesthetic"],
113
- ["속옷만 입은 남녀가 격정적인 키스를 하고있다, vibrant neon, adult anime"],
114
- ["아름다운 러시아 여자가 섹시한 속옷을 입고 묘한 포즈로 침대에 앉아있다, dramatic spotlight, adult anime style"],
115
  ],
116
  inputs=[prompt],
117
  )
@@ -128,20 +177,12 @@ with gr.Blocks(css=css, theme=gr.themes.Soft()) as demo:
128
  randomize_seed = gr.Checkbox(label="Randomize seed", value=True)
129
 
130
  with gr.Row():
131
- width = gr.Slider(
132
- label="Width", minimum=256, maximum=MAX_IMAGE_SIZE, step=32, value=1024
133
- )
134
- height = gr.Slider(
135
- label="Height", minimum=256, maximum=MAX_IMAGE_SIZE, step=32, value=1024
136
- )
137
 
138
  with gr.Row():
139
- guidance_scale = gr.Slider(
140
- label="Guidance scale", minimum=0.0, maximum=20.0, step=0.1, value=7
141
- )
142
- num_inference_steps = gr.Slider(
143
- label="Inference steps", minimum=1, maximum=28, step=1, value=28
144
- )
145
 
146
  run_button.click(
147
  fn=infer,
 
1
+ import os
2
  import spaces
3
  import gradio as gr
4
  import numpy as np
 
9
  from transformers import pipeline as transformers_pipeline
10
  import re
11
 
12
+ # ------------------------------------------------------------
13
+ # DEVICE SETUP
14
+ # ------------------------------------------------------------
15
+ # Prefer GPU when the Space provides it, otherwise CPU
16
+ # `@spaces.GPU` takes care of binding the call itself, but we still
17
+ # need a device handle for manual ops.
18
+
19
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
20
 
21
+ # ------------------------------------------------------------
22
+ # STABLE DIFFUSION XL PIPELINE
23
+ # ------------------------------------------------------------
24
  pipe = StableDiffusionXLPipeline.from_pretrained(
25
  "votepurchase/waiNSFWIllustrious_v120",
26
  torch_dtype=torch.float16,
 
30
  pipe.scheduler = EulerAncestralDiscreteScheduler.from_config(pipe.scheduler.config)
31
  pipe.to(device)
32
 
33
+ # Force important sub-modules to fp16 for VRAM efficiency (GPU) or
34
+ # reduce RAM (CPU). The model itself already sits in fp16, we just
35
+ # mirror that for sub-components explicitly to avoid silent fp32
36
+ # promotions that eat memory on ZeroGPU.
37
+ for sub in (pipe.text_encoder, pipe.text_encoder_2, pipe.vae, pipe.unet):
38
+ sub.to(torch.float16)
39
+
40
+ # ------------------------------------------------------------
41
+ # LIGHTWEIGHT KOR→ENG TRANSLATOR (CPU-ONLY)
42
+ # ------------------------------------------------------------
43
+ # * Hugging Face Spaces occasionally trips over the full MarianMT
44
+ # weights on ZeroGPU, resulting in the _untyped_storage_new_register
45
+ # error you just saw. We wrap initialisation in try/except and fall
46
+ # back to an identity function if the model cannot be loaded.
47
+ # * If you need translation and have a custom HF token, set the env
48
+ # HF_API_TOKEN so the smaller *small100* model can be pulled.
49
+ #
50
+ translator = None # default stub → "no translator"
51
+ try:
52
+ # First try the 60 MB Marian model.
53
+ translator = transformers_pipeline(
54
+ "translation",
55
+ model="Helsinki-NLP/opus-mt-ko-en",
56
+ device=-1, # force CPU so CUDA never initialises in the main proc
57
+ )
58
+ except Exception as marian_err:
59
+ print("[WARN] MarianMT load failed →", marian_err)
60
+ # Second chance: use compact multilingual SMaLL-100 (≈35 MB).
61
+ try:
62
+ translator = transformers_pipeline(
63
+ "translation",
64
+ model="alirezamsh/small100",
65
+ src_lang="ko_Kore",
66
+ tgt_lang="en_XX",
67
+ device=-1,
68
+ )
69
+ except Exception as small_err:
70
+ print("[WARN] SMaLL-100 load failed →", small_err)
71
+ # Final fallback: identity – no translation, but the app still runs.
72
+ translator = None
73
 
74
+ korean_regex = re.compile(r"[\uac00-\ud7af]+")
 
 
75
 
76
  def maybe_translate(text: str) -> str:
77
+ """Translate Korean English if Korean chars present and translator ready."""
78
+ if translator is not None and korean_regex.search(text):
79
+ try:
80
+ out = translator(text, max_length=256, clean_up_tokenization_spaces=True)
81
+ return out[0]["translation_text"]
82
+ except Exception as e:
83
+ print("[WARN] Translation failed at runtime →", e)
84
  return text
85
 
86
+ # ------------------------------------------------------------
87
+ # SDXL INFERENCE WRAPPER
88
+ # ------------------------------------------------------------
89
+ MAX_SEED = np.iinfo(np.int32).max
90
+ MAX_IMAGE_SIZE = 1216
91
+
92
  @spaces.GPU
93
  def infer(prompt, negative_prompt, seed, randomize_seed, width, height, guidance_scale, num_inference_steps):
94
  prompt = maybe_translate(prompt)
95
  negative_prompt = maybe_translate(negative_prompt)
96
 
97
  if len(prompt.split()) > 60:
98
+ print("[WARN] Prompt >60 words CLIP may truncate it.")
99
 
100
  if randomize_seed:
101
  seed = random.randint(0, MAX_SEED)
 
114
  ).images[0]
115
  return output_image
116
  except RuntimeError as e:
117
+ print(f"[ERROR] Diffusion failed {e}")
118
+ return Image.new("RGB", (width, height), color=(0, 0, 0))
 
119
 
120
+ # ------------------------------------------------------------
121
+ # UI LAYOUT + THEME (Pastel Lavender Background)
122
+ # ------------------------------------------------------------
123
  css = """
124
  body {background: #f2f1f7; color: #222; font-family: 'Noto Sans', sans-serif;}
125
  #col-container {margin: 0 auto; max-width: 640px;}
126
+ .gr-button {background: #7fbdf6; color: #fff; border-radius: 8px;}
127
+ #prompt-box textarea {font-size: 1.1rem; height: 3rem; background: #fff; color: #222;}
128
  """
129
 
130
+ author_note = (
131
+ "**ℹ️ Automatic translation** — Korean prompts are translated to English "
132
+ "only if translation weights could be loaded. If not, Korean input will be "
133
+ "sent unchanged."
134
+ )
135
+
136
  with gr.Blocks(css=css, theme=gr.themes.Soft()) as demo:
137
  gr.Markdown(
138
+ f"""
139
  ## 🖌️ Stable Diffusion XL Playground
140
+ {author_note}
 
141
  """
142
  )
143
 
 
148
  elem_id="prompt-box",
149
  show_label=False,
150
  max_lines=1,
151
+ placeholder="Enter your prompt (Korean or English, 60 words max)",
152
  )
153
  run_button = gr.Button("Generate", scale=0)
154
 
155
  result = gr.Image(label="", show_label=False)
156
 
 
157
  examples = gr.Examples(
158
  examples=[
159
+ ["성인용 애니메 캐릭터가 검은 고양이와 함께 달빛 아래에 서있는 장면, 관능적, 4K"],
160
+ ["Seductive anime woman lounging in a dimly lit bar, adult anime style, ultra-detail"],
161
+ ["Elegant vampire countess in gothic lingerie, candle-lit boudoir, adult anime aesthetic"],
162
+ ["Futuristic nightclub stage with a curvaceous android dancer, vibrant neon, adult anime"],
163
+ ["Dark fantasy warrior queen in revealing armor, dramatic spotlight, adult anime style"],
164
  ],
165
  inputs=[prompt],
166
  )
 
177
  randomize_seed = gr.Checkbox(label="Randomize seed", value=True)
178
 
179
  with gr.Row():
180
+ width = gr.Slider(label="Width", minimum=256, maximum=MAX_IMAGE_SIZE, step=32, value=1024)
181
+ height = gr.Slider(label="Height", minimum=256, maximum=MAX_IMAGE_SIZE, step=32, value=1024)
 
 
 
 
182
 
183
  with gr.Row():
184
+ guidance_scale = gr.Slider(label="Guidance scale", minimum=0.0, maximum=20.0, step=0.1, value=7)
185
+ num_inference_steps = gr.Slider(label="Inference steps", minimum=1, maximum=28, step=1, value=28)
 
 
 
 
186
 
187
  run_button.click(
188
  fn=infer,