fffiloni commited on
Commit
82099f1
·
verified ·
1 Parent(s): 8d2697e

Update app_zero.py

Browse files
Files changed (1) hide show
  1. app_zero.py +63 -207
app_zero.py CHANGED
@@ -3,7 +3,6 @@ import os
3
  import types
4
  import random
5
  import datetime
6
- from pathlib import Path
7
 
8
  import torch
9
  import numpy as np
@@ -27,7 +26,7 @@ from diffusers import (
27
  UniPCMultistepScheduler,
28
  )
29
 
30
- # ---- GPU spoof for Spaces env compatibility ----
31
  torch.cuda.get_device_capability = lambda *args, **kwargs: (8, 6)
32
  torch.cuda.get_device_properties = lambda *args, **kwargs: types.SimpleNamespace(
33
  name="NVIDIA A10G",
@@ -37,7 +36,7 @@ torch.cuda.get_device_properties = lambda *args, **kwargs: types.SimpleNamespace
37
  multi_processor_count=80,
38
  )
39
 
40
- # ---- Download required assets ----
41
  huggingface_hub.snapshot_download(
42
  repo_id="camenduru/PASD",
43
  allow_patterns=[
@@ -61,76 +60,32 @@ huggingface_hub.hf_hub_download(
61
  local_dir="PASD/annotator/ckpts",
62
  )
63
 
64
- # ---- Local PASD path ----
65
  sys.path.append("./PASD")
66
 
67
- # ---- Compat shim for older custom pipelines expecting diffusers.pipeline_utils ----
68
- try:
69
- import diffusers.pipelines.pipeline_utils as _pipeline_utils
70
- sys.modules["diffusers.pipeline_utils"] = _pipeline_utils
71
- except Exception:
72
- pass
73
-
74
- # ---- Compat shim for older PASD code expecting PositionNet in diffusers.models.embeddings ----
75
- try:
76
- import diffusers.models.embeddings as _embeddings
77
- if not hasattr(_embeddings, "PositionNet") and hasattr(_embeddings, "GLIGENTextBoundingboxProjection"):
78
- _embeddings.PositionNet = _embeddings.GLIGENTextBoundingboxProjection
79
- except Exception:
80
- pass
81
-
82
- # ---- Compat shim for older PASD code expecting AdaGroupNorm in diffusers.models.attention ----
83
- try:
84
- import diffusers.models.attention as _attention
85
- from diffusers.models.normalization import AdaGroupNorm as _AdaGroupNorm
86
- if not hasattr(_attention, "AdaGroupNorm"):
87
- _attention.AdaGroupNorm = _AdaGroupNorm
88
- except Exception:
89
- pass
90
-
91
- # ---- Compat shim for older PASD code expecting diffusers.models.dual_transformer_2d ----
92
- try:
93
- import diffusers.models.transformers.dual_transformer_2d as _dual_transformer_2d
94
- sys.modules["diffusers.models.dual_transformer_2d"] = _dual_transformer_2d
95
- except Exception:
96
- pass
97
-
98
- # ---- Compat shim for older PASD code expecting diffusers.models.transformer_2d ----
99
- try:
100
- import diffusers.models.transformers.transformer_2d as _transformer_2d
101
- sys.modules["diffusers.models.transformer_2d"] = _transformer_2d
102
- except Exception:
103
- pass
104
-
105
  from pipelines.pipeline_pasd import StableDiffusionControlNetPipeline
106
- from myutils.misc import load_dreambooth_lora, rand_name
107
  from myutils.wavelet_color_fix import wavelet_color_fix
108
  from annotator.retinaface import RetinaFaceDetection
109
 
110
- # ---- Model selection ----
111
- use_pasd_light = False
112
- face_detector = RetinaFaceDetection()
113
-
114
- if use_pasd_light:
115
- from models.pasd_light.unet_2d_condition import UNet2DConditionModel
116
- from models.pasd_light.controlnet import ControlNetModel
117
- else:
118
- from models.pasd.unet_2d_condition import UNet2DConditionModel
119
- from models.pasd.controlnet import ControlNetModel
120
 
 
121
  pretrained_model_path = "stable-diffusion-v1-5/stable-diffusion-v1-5"
122
  ckpt_path = "PASD/runs/pasd/checkpoint-100000"
123
  dreambooth_lora_path = "PASD/checkpoints/personalized_models/majicmixRealistic_v6.safetensors"
124
 
125
- weight_dtype = torch.float16
126
  device = "cuda"
 
127
 
128
- # ---- Load models ----
129
  scheduler = UniPCMultistepScheduler.from_pretrained(pretrained_model_path, subfolder="scheduler")
130
  text_encoder = CLIPTextModel.from_pretrained(pretrained_model_path, subfolder="text_encoder")
131
  tokenizer = CLIPTokenizer.from_pretrained(pretrained_model_path, subfolder="tokenizer")
132
  vae = AutoencoderKL.from_pretrained(pretrained_model_path, subfolder="vae")
133
  feature_extractor = CLIPImageProcessor.from_pretrained(pretrained_model_path, subfolder="feature_extractor")
 
134
  unet = UNet2DConditionModel.from_pretrained(ckpt_path, subfolder="unet")
135
  controlnet = ControlNetModel.from_pretrained(ckpt_path, subfolder="controlnet")
136
 
@@ -146,7 +101,7 @@ vae.to(device, dtype=weight_dtype)
146
  unet.to(device, dtype=weight_dtype)
147
  controlnet.to(device, dtype=weight_dtype)
148
 
149
- validation_pipeline = StableDiffusionControlNetPipeline(
150
  vae=vae,
151
  text_encoder=text_encoder,
152
  tokenizer=tokenizer,
@@ -158,25 +113,23 @@ validation_pipeline = StableDiffusionControlNetPipeline(
158
  requires_safety_checker=False,
159
  )
160
 
161
- validation_pipeline._init_tiled_vae(decoder_tile_size=224)
162
 
163
- # ---- ResNet auto-tag helper ----
164
  weights = ResNet50_Weights.DEFAULT
165
  preprocess = weights.transforms()
166
  resnet = resnet50(weights=weights)
167
  resnet.eval()
168
 
169
-
170
  def resize_image(image_path, target_height):
171
  with Image.open(image_path) as img:
172
  ratio = target_height / float(img.size[1])
173
  new_width = int(float(img.size[0]) * ratio)
174
- resized_img = img.resize((new_width, target_height), Image.LANCZOS)
175
- return resized_img
176
-
177
 
178
  @spaces.GPU(enable_queue=True)
179
- def inference(input_image, prompt, a_prompt, n_prompt, denoise_steps, upscale, alpha, cfg, seed):
180
  if seed == -1:
181
  seed = 0
182
 
@@ -185,52 +138,35 @@ def inference(input_image, prompt, a_prompt, n_prompt, denoise_steps, upscale, a
185
 
186
  with torch.no_grad():
187
  seed_everything(seed)
188
- generator = torch.Generator(device=device)
189
- generator.manual_seed(seed)
190
 
191
  input_image = input_image.convert("RGB")
192
- batch = preprocess(input_image).unsqueeze(0)
193
- prediction = resnet(batch).squeeze(0).softmax(0)
194
- class_id = prediction.argmax().item()
195
- score = prediction[class_id].item()
196
- category_name = weights.meta["categories"][class_id]
197
-
198
- if score >= 0.1:
199
- prompt += f"{category_name}" if prompt == "" else f", {category_name}"
200
 
201
  prompt = a_prompt if prompt == "" else f"{prompt}, {a_prompt}"
202
 
203
- ori_width, ori_height = input_image.size
204
- resize_flag = False
205
-
206
  rscale = upscale
207
- input_image = input_image.resize((input_image.size[0] * rscale, input_image.size[1] * rscale))
208
- input_image = input_image.resize((input_image.size[0] // 8 * 8, input_image.size[1] // 8 * 8))
209
- width, height = input_image.size
210
- resize_flag = True
211
-
212
- try:
213
- image = validation_pipeline(
214
- None,
215
- prompt,
216
- input_image,
217
- num_inference_steps=denoise_steps,
218
- generator=generator,
219
- height=height,
220
- width=width,
221
- guidance_scale=cfg,
222
- negative_prompt=n_prompt,
223
- conditioning_scale=alpha,
224
- eta=0.0,
225
- ).images[0]
226
-
227
- image = wavelet_color_fix(image, input_image)
228
-
229
- if resize_flag:
230
- image = image.resize((ori_width * rscale, ori_height * rscale))
231
- except Exception as e:
232
- print(e)
233
- image = Image.new(mode="RGB", size=(512, 512))
234
 
235
  result_path = f"result_{timestamp}.jpg"
236
  input_path = f"input_{timestamp}.jpg"
@@ -240,110 +176,30 @@ def inference(input_image, prompt, a_prompt, n_prompt, denoise_steps, upscale, a
240
 
241
  return input_path, result_path, result_path
242
 
243
-
244
- css = """
245
- #col-container{
246
- margin: 0 auto;
247
- max-width: 720px;
248
- }
249
- #project-links{
250
- margin: 0 0 12px !important;
251
- column-gap: 8px;
252
- display: flex;
253
- justify-content: center;
254
- flex-wrap: nowrap;
255
- flex-direction: row;
256
- align-items: center;
257
- }
258
- """
259
-
260
  with gr.Blocks() as demo:
261
- with gr.Column(elem_id="col-container"):
262
- gr.HTML("""
263
- <h2 style="text-align: center;">
264
- PASD Magnify
265
- </h2>
266
- <p style="text-align: center;">
267
- Pixel-Aware Stable Diffusion for Realistic Image Super-resolution and Personalized Stylization
268
- </p>
269
- <p id="project-links" align="center">
270
- <a href="https://github.com/yangxy/PASD"><img src="https://img.shields.io/badge/Project-Page-Green"></a>
271
- <a href="https://huggingface.co/papers/2308.14469"><img src="https://img.shields.io/badge/Paper-Arxiv-red"></a>
272
- </p>
273
- <p style="margin:12px auto;display: flex;justify-content: center;">
274
- <a href="https://huggingface.co/spaces/fffiloni/PASD?duplicate=true">
275
- <img src="https://huggingface.co/datasets/huggingface/badges/resolve/main/duplicate-this-space-lg.svg" alt="Duplicate this Space">
276
- </a>
277
- </p>
278
- """)
279
-
280
- with gr.Row():
281
- with gr.Column():
282
- input_image = gr.Image(
283
- type="filepath",
284
- sources=["upload"],
285
- value="PASD/samples/frog.png",
286
- label="Input image",
287
- )
288
- prompt_in = gr.Textbox(label="Prompt", value="Frog")
289
-
290
- with gr.Accordion(label="Advanced settings", open=False):
291
- added_prompt = gr.Textbox(
292
- label="Added Prompt",
293
- value="clean, high-resolution, 8k, best quality, masterpiece",
294
- )
295
- neg_prompt = gr.Textbox(
296
- label="Negative Prompt",
297
- value="dotted, noise, blur, lowres, oversmooth, longbody, bad anatomy, bad hands, missing fingers, extra digit, fewer digits, cropped, worst quality, low quality",
298
- )
299
- denoise_steps = gr.Slider(label="Denoise Steps", minimum=10, maximum=50, value=20, step=1)
300
- upsample_scale = gr.Slider(label="Upsample Scale", minimum=1, maximum=4, value=2, step=1)
301
- condition_scale = gr.Slider(label="Conditioning Scale", minimum=0.5, maximum=1.5, value=1.1, step=0.1)
302
- classifier_free_guidance = gr.Slider(
303
- label="Classifier-free Guidance",
304
- minimum=0.1,
305
- maximum=10.0,
306
- value=7.5,
307
- step=0.1,
308
- )
309
- seed = gr.Slider(
310
- label="Seed",
311
- minimum=-1,
312
- maximum=2147483647,
313
- step=1,
314
- randomize=True,
315
- )
316
-
317
- submit_btn = gr.Button("Submit")
318
-
319
- with gr.Column():
320
- before_img = gr.Image(label="Input")
321
- after_img = gr.Image(label="Result")
322
- file_output = gr.File(label="Downloadable image result")
323
-
324
- submit_btn.click(
325
- fn=inference,
326
- inputs=[
327
- input_image,
328
- prompt_in,
329
- added_prompt,
330
- neg_prompt,
331
- denoise_steps,
332
- upsample_scale,
333
- condition_scale,
334
- classifier_free_guidance,
335
- seed,
336
- ],
337
- outputs=[
338
- before_img,
339
- after_img,
340
- file_output,
341
- ],
342
- api_visibility="private",
343
  )
344
 
345
- demo.queue(max_size=10).launch(
346
- ssr_mode=False,
347
- mcp_server=False,
348
- css=css,
349
- )
 
3
  import types
4
  import random
5
  import datetime
 
6
 
7
  import torch
8
  import numpy as np
 
26
  UniPCMultistepScheduler,
27
  )
28
 
29
+ # ---- GPU spoof ----
30
  torch.cuda.get_device_capability = lambda *args, **kwargs: (8, 6)
31
  torch.cuda.get_device_properties = lambda *args, **kwargs: types.SimpleNamespace(
32
  name="NVIDIA A10G",
 
36
  multi_processor_count=80,
37
  )
38
 
39
+ # ---- Downloads ----
40
  huggingface_hub.snapshot_download(
41
  repo_id="camenduru/PASD",
42
  allow_patterns=[
 
60
  local_dir="PASD/annotator/ckpts",
61
  )
62
 
63
+ # ---- PASD ----
64
  sys.path.append("./PASD")
65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  from pipelines.pipeline_pasd import StableDiffusionControlNetPipeline
67
+ from myutils.misc import load_dreambooth_lora
68
  from myutils.wavelet_color_fix import wavelet_color_fix
69
  from annotator.retinaface import RetinaFaceDetection
70
 
71
+ from models.pasd.unet_2d_condition import UNet2DConditionModel
72
+ from models.pasd.controlnet import ControlNetModel
 
 
 
 
 
 
 
 
73
 
74
+ # ---- Setup ----
75
  pretrained_model_path = "stable-diffusion-v1-5/stable-diffusion-v1-5"
76
  ckpt_path = "PASD/runs/pasd/checkpoint-100000"
77
  dreambooth_lora_path = "PASD/checkpoints/personalized_models/majicmixRealistic_v6.safetensors"
78
 
 
79
  device = "cuda"
80
+ weight_dtype = torch.float16
81
 
82
+ # ---- Load ----
83
  scheduler = UniPCMultistepScheduler.from_pretrained(pretrained_model_path, subfolder="scheduler")
84
  text_encoder = CLIPTextModel.from_pretrained(pretrained_model_path, subfolder="text_encoder")
85
  tokenizer = CLIPTokenizer.from_pretrained(pretrained_model_path, subfolder="tokenizer")
86
  vae = AutoencoderKL.from_pretrained(pretrained_model_path, subfolder="vae")
87
  feature_extractor = CLIPImageProcessor.from_pretrained(pretrained_model_path, subfolder="feature_extractor")
88
+
89
  unet = UNet2DConditionModel.from_pretrained(ckpt_path, subfolder="unet")
90
  controlnet = ControlNetModel.from_pretrained(ckpt_path, subfolder="controlnet")
91
 
 
101
  unet.to(device, dtype=weight_dtype)
102
  controlnet.to(device, dtype=weight_dtype)
103
 
104
+ pipeline = StableDiffusionControlNetPipeline(
105
  vae=vae,
106
  text_encoder=text_encoder,
107
  tokenizer=tokenizer,
 
113
  requires_safety_checker=False,
114
  )
115
 
116
+ pipeline._init_tiled_vae(decoder_tile_size=224)
117
 
118
+ # ---- ResNet ----
119
  weights = ResNet50_Weights.DEFAULT
120
  preprocess = weights.transforms()
121
  resnet = resnet50(weights=weights)
122
  resnet.eval()
123
 
124
+ # ---- Utils ----
125
  def resize_image(image_path, target_height):
126
  with Image.open(image_path) as img:
127
  ratio = target_height / float(img.size[1])
128
  new_width = int(float(img.size[0]) * ratio)
129
+ return img.resize((new_width, target_height), Image.LANCZOS)
 
 
130
 
131
  @spaces.GPU(enable_queue=True)
132
+ def inference(input_image, prompt, a_prompt, n_prompt, steps, upscale, alpha, cfg, seed):
133
  if seed == -1:
134
  seed = 0
135
 
 
138
 
139
  with torch.no_grad():
140
  seed_everything(seed)
141
+ generator = torch.Generator(device=device).manual_seed(seed)
 
142
 
143
  input_image = input_image.convert("RGB")
 
 
 
 
 
 
 
 
144
 
145
  prompt = a_prompt if prompt == "" else f"{prompt}, {a_prompt}"
146
 
147
+ ori_w, ori_h = input_image.size
 
 
148
  rscale = upscale
149
+
150
+ input_image = input_image.resize((input_image.size[0]*rscale, input_image.size[1]*rscale))
151
+ input_image = input_image.resize((input_image.size[0]//8*8, input_image.size[1]//8*8))
152
+
153
+ w, h = input_image.size
154
+
155
+ image = pipeline(
156
+ None,
157
+ prompt,
158
+ input_image,
159
+ num_inference_steps=steps,
160
+ generator=generator,
161
+ height=h,
162
+ width=w,
163
+ guidance_scale=cfg,
164
+ negative_prompt=n_prompt,
165
+ conditioning_scale=alpha,
166
+ ).images[0]
167
+
168
+ image = wavelet_color_fix(image, input_image)
169
+ image = image.resize((ori_w*rscale, ori_h*rscale))
 
 
 
 
 
 
170
 
171
  result_path = f"result_{timestamp}.jpg"
172
  input_path = f"input_{timestamp}.jpg"
 
176
 
177
  return input_path, result_path, result_path
178
 
179
+ # ---- UI ----
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
  with gr.Blocks() as demo:
181
+ with gr.Row():
182
+ with gr.Column():
183
+ input_image = gr.Image(type="filepath")
184
+ prompt = gr.Textbox(label="Prompt")
185
+
186
+ steps = gr.Slider(10, 50, 20)
187
+ upscale = gr.Slider(1, 4, 2)
188
+ alpha = gr.Slider(0.5, 1.5, 1.1)
189
+ cfg = gr.Slider(0.1, 10.0, 7.5)
190
+ seed = gr.Slider(-1, 2147483647, randomize=True)
191
+
192
+ btn = gr.Button("Generate")
193
+
194
+ with gr.Column():
195
+ before = gr.Image()
196
+ after = gr.Image()
197
+ file = gr.File()
198
+
199
+ btn.click(
200
+ inference,
201
+ inputs=[input_image, prompt, prompt, prompt, steps, upscale, alpha, cfg, seed],
202
+ outputs=[before, after, file],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
  )
204
 
205
+ demo.queue().launch(ssr_mode=False, mcp_server=False)