el-el-san commited on
Commit
191ea97
1 Parent(s): f50d2cc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +35 -107
app.py CHANGED
@@ -1,14 +1,9 @@
1
  import gradio as gr
2
  import numpy as np
3
- import PIL.Image
4
- from PIL import Image, ImageOps
5
  import random
6
- #from diffusers import DiffusionPipeline
7
- #from diffusers import StableDiffusionXLPipeline
8
  from diffusers import ControlNetModel, StableDiffusionXLControlNetPipeline, AutoencoderKL
9
  from diffusers import DDIMScheduler, EulerAncestralDiscreteScheduler
10
- from controlnet_aux import PidiNetDetector, HEDdetector
11
- from diffusers.utils import load_image
12
  import cv2
13
  import torch
14
  import spaces
@@ -30,126 +25,63 @@ def nms(x, t, s):
30
  z[y > t] = 255
31
  return z
32
 
33
- def HWC3(x):
34
- assert x.dtype == np.uint8
35
- if x.ndim == 2:
36
- x = x[:, :, None]
37
- assert x.ndim == 3
38
- H, W, C = x.shape
39
- assert C == 1 or C == 3 or C == 4
40
- if C == 3:
41
- return x
42
- if C == 1:
43
- return np.concatenate([x, x, x], axis=2)
44
- if C == 4:
45
- color = x[:, :, 0:3].astype(np.float32)
46
- alpha = x[:, :, 3:4].astype(np.float32) / 255.0
47
- y = color * alpha + 255.0 * (1.0 - alpha)
48
- y = y.clip(0, 255).astype(np.uint8)
49
- return y
50
-
51
-
52
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
53
 
54
- # eulera_scheduler = EulerAncestralDiscreteScheduler.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0", subfolder="scheduler")
55
-
56
-
57
  controlnet = ControlNetModel.from_pretrained(
58
  "xinsir/controlnet-scribble-sdxl-1.0",
59
- #"2vXpSwA7/test_controlnet2/CN-anytest_v4-marged_am_dim256.safetensors"
60
-
61
  torch_dtype=torch.float16
62
  )
63
 
64
  vae = AutoencoderKL.from_pretrained("madebyollin/sdxl-vae-fp16-fix", torch_dtype=torch.float16)
65
 
66
  pipe = StableDiffusionXLControlNetPipeline.from_pretrained(
67
- #"sd-community/sdxl-flash",
68
- #"yodayo-ai/kivotos-xl-2.0",
69
- "yodayo-ai/holodayo-xl-2.1",
70
  controlnet=controlnet,
71
  vae=vae,
72
  torch_dtype=torch.float16,
73
- # scheduler=eulera_scheduler,
74
  )
75
- pipe.scheduler = EulerAncestralDiscreteScheduler.from_config(pipe.scheduler.config)
76
 
 
77
  pipe.to(device)
78
 
79
-
80
  MAX_SEED = np.iinfo(np.int32).max
81
  MAX_IMAGE_SIZE = 1216
82
 
83
- #pipe = StableDiffusionXLPipeline.from_pretrained(
84
- # #"yodayo-ai/kivotos-xl-2.0",
85
- # "yodayo-ai/holodayo-xl-2.1",
86
- # torch_dtype=torch.float16,
87
- # use_safetensors=True,
88
- # custom_pipeline="lpw_stable_diffusion_xl",
89
- # add_watermarker=False,
90
- # variant="fp16"
91
- #)
92
- #pipe.to('cuda')
93
-
94
- prompt = "1girl, solo, upper body, v, smile, looking at viewer, outdoors, night, masterpiece, best quality, very aesthetic, absurdres"
95
- negative_prompt = "nsfw, (low quality, worst quality:1.2), very displeasing, 3d, watermark, signature, ugly, poorly drawn"
96
-
97
- def nms(x, t, s):
98
- x = cv2.GaussianBlur(x.astype(np.float32), (0, 0), s)
99
-
100
- f1 = np.array([[0, 0, 0], [1, 1, 1], [0, 0, 0]], dtype=np.uint8)
101
- f2 = np.array([[0, 1, 0], [0, 1, 0], [0, 1, 0]], dtype=np.uint8)
102
- f3 = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]], dtype=np.uint8)
103
- f4 = np.array([[0, 0, 1], [0, 1, 0], [1, 0, 0]], dtype=np.uint8)
104
-
105
- y = np.zeros_like(x)
106
-
107
- for f in [f1, f2, f3, f4]:
108
- np.putmask(y, cv2.dilate(x, kernel=f) == x, x)
109
-
110
- z = np.zeros_like(y, dtype=np.uint8)
111
- z[y > t] = 255
112
- return z
113
-
114
  @spaces.GPU
115
- def infer(image: PIL.Image.Image,prompt, negative_prompt, seed, randomize_seed, width, height, guidance_scale, num_inference_steps)-> PIL.Image.Image:
116
 
117
- width, height = image['composite'].size
118
  ratio = np.sqrt(1024. * 1024. / (width * height))
119
  new_width, new_height = int(width * ratio), int(height * ratio)
120
- image = image['composite'].resize((new_width, new_height))
121
 
122
-
123
  if randomize_seed:
124
  seed = random.randint(0, MAX_SEED)
125
 
126
- controlnet_img = image
127
- # following is some processing to simulate human sketch draw, different threshold can generate different width of lines
128
- controlnet_img = np.array(controlnet_img)
129
  controlnet_img = nms(controlnet_img, 127, 3)
130
  controlnet_img = cv2.GaussianBlur(controlnet_img, (0, 0), 3)
131
 
132
- # higher threshold, thiner line
133
  random_val = int(round(random.uniform(0.01, 0.10), 2) * 255)
134
  controlnet_img[controlnet_img > random_val] = 255
135
  controlnet_img[controlnet_img < 255] = 0
136
  image = Image.fromarray(controlnet_img)
137
-
138
  generator = torch.Generator().manual_seed(seed)
139
-
140
  output_image = pipe(
141
- prompt = prompt+", masterpiece, best quality, very aesthetic, absurdres",
142
- negative_prompt = negative_prompt,
143
- guidance_scale = guidance_scale,
144
- num_inference_steps = num_inference_steps,
145
- width = width,
146
- height = height,
147
- generator = generator
148
- ).images[0]
149
-
150
  return output_image
151
 
152
- css="""
153
  #col-container {
154
  margin: 0 auto;
155
  max-width: 520px;
@@ -157,15 +89,14 @@ css="""
157
  """
158
 
159
  with gr.Blocks(css=css) as demo:
160
-
161
  with gr.Column(elem_id="col-container"):
162
- gr.Markdown(f"""
163
  # Text-to-Image Demo
164
  using [Holodayo XL 2.1](https://huggingface.co/yodayo-ai/holodayo-xl-2.1)
165
  """)
166
-
167
  with gr.Row():
168
-
169
  prompt = gr.Text(
170
  label="Prompt",
171
  show_label=False,
@@ -173,22 +104,21 @@ with gr.Blocks(css=css) as demo:
173
  placeholder="Enter your prompt",
174
  container=False,
175
  )
176
-
177
  run_button = gr.Button("Run", scale=0)
178
-
179
  image = gr.ImageEditor(type="pil", image_mode="L", crop_size=(512, 512))
180
  result = gr.Image(label="Result", show_label=False)
181
 
182
  with gr.Accordion("Advanced Settings", open=False):
183
-
184
  negative_prompt = gr.Text(
185
  label="Negative prompt",
186
  max_lines=1,
187
  placeholder="Enter a negative prompt",
188
- #visible=False,
189
  value="nsfw, (low quality, worst quality:1.2), very displeasing, 3d, watermark, signature, ugly, poorly drawn"
190
  )
191
-
192
  seed = gr.Slider(
193
  label="Seed",
194
  minimum=0,
@@ -196,11 +126,10 @@ with gr.Blocks(css=css) as demo:
196
  step=1,
197
  value=0,
198
  )
199
-
200
  randomize_seed = gr.Checkbox(label="Randomize seed", value=True)
201
-
202
  with gr.Row():
203
-
204
  width = gr.Slider(
205
  label="Width",
206
  minimum=256,
@@ -208,7 +137,7 @@ with gr.Blocks(css=css) as demo:
208
  step=32,
209
  value=832,
210
  )
211
-
212
  height = gr.Slider(
213
  label="Height",
214
  minimum=256,
@@ -216,9 +145,8 @@ with gr.Blocks(css=css) as demo:
216
  step=32,
217
  value=1216,
218
  )
219
-
220
  with gr.Row():
221
-
222
  guidance_scale = gr.Slider(
223
  label="Guidance scale",
224
  minimum=0.0,
@@ -226,7 +154,7 @@ with gr.Blocks(css=css) as demo:
226
  step=0.1,
227
  value=7,
228
  )
229
-
230
  num_inference_steps = gr.Slider(
231
  label="Number of inference steps",
232
  minimum=1,
@@ -236,9 +164,9 @@ with gr.Blocks(css=css) as demo:
236
  )
237
 
238
  run_button.click(
239
- fn = infer,
240
- inputs = [image,prompt, negative_prompt, seed, randomize_seed, width, height, guidance_scale, num_inference_steps],
241
- outputs = [result]
242
  )
243
 
244
- demo.queue().launch()
 
1
  import gradio as gr
2
  import numpy as np
3
+ from PIL import Image
 
4
  import random
 
 
5
  from diffusers import ControlNetModel, StableDiffusionXLControlNetPipeline, AutoencoderKL
6
  from diffusers import DDIMScheduler, EulerAncestralDiscreteScheduler
 
 
7
  import cv2
8
  import torch
9
  import spaces
 
25
  z[y > t] = 255
26
  return z
27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
29
 
 
 
 
30
  controlnet = ControlNetModel.from_pretrained(
31
  "xinsir/controlnet-scribble-sdxl-1.0",
 
 
32
  torch_dtype=torch.float16
33
  )
34
 
35
  vae = AutoencoderKL.from_pretrained("madebyollin/sdxl-vae-fp16-fix", torch_dtype=torch.float16)
36
 
37
  pipe = StableDiffusionXLControlNetPipeline.from_pretrained(
38
+ "yodayo-ai/holodayo-xl-2.1",
 
 
39
  controlnet=controlnet,
40
  vae=vae,
41
  torch_dtype=torch.float16,
 
42
  )
 
43
 
44
+ pipe.scheduler = EulerAncestralDiscreteScheduler.from_config(pipe.scheduler.config)
45
  pipe.to(device)
46
 
 
47
  MAX_SEED = np.iinfo(np.int32).max
48
  MAX_IMAGE_SIZE = 1216
49
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  @spaces.GPU
51
+ def infer(image: Image, prompt, negative_prompt, seed, randomize_seed, width, height, guidance_scale, num_inference_steps) -> Image:
52
 
53
+ width, height = image.size
54
  ratio = np.sqrt(1024. * 1024. / (width * height))
55
  new_width, new_height = int(width * ratio), int(height * ratio)
56
+ image = image.resize((new_width, new_height))
57
 
 
58
  if randomize_seed:
59
  seed = random.randint(0, MAX_SEED)
60
 
61
+ controlnet_img = np.array(image)
 
 
62
  controlnet_img = nms(controlnet_img, 127, 3)
63
  controlnet_img = cv2.GaussianBlur(controlnet_img, (0, 0), 3)
64
 
 
65
  random_val = int(round(random.uniform(0.01, 0.10), 2) * 255)
66
  controlnet_img[controlnet_img > random_val] = 255
67
  controlnet_img[controlnet_img < 255] = 0
68
  image = Image.fromarray(controlnet_img)
69
+
70
  generator = torch.Generator().manual_seed(seed)
71
+
72
  output_image = pipe(
73
+ prompt=prompt + ", masterpiece, best quality, very aesthetic, absurdres",
74
+ negative_prompt=negative_prompt,
75
+ guidance_scale=guidance_scale,
76
+ num_inference_steps=num_inference_steps,
77
+ width=width,
78
+ height=height,
79
+ generator=generator
80
+ ).images[0]
81
+
82
  return output_image
83
 
84
+ css = """
85
  #col-container {
86
  margin: 0 auto;
87
  max-width: 520px;
 
89
  """
90
 
91
  with gr.Blocks(css=css) as demo:
92
+
93
  with gr.Column(elem_id="col-container"):
94
+ gr.Markdown("""
95
  # Text-to-Image Demo
96
  using [Holodayo XL 2.1](https://huggingface.co/yodayo-ai/holodayo-xl-2.1)
97
  """)
98
+
99
  with gr.Row():
 
100
  prompt = gr.Text(
101
  label="Prompt",
102
  show_label=False,
 
104
  placeholder="Enter your prompt",
105
  container=False,
106
  )
107
+
108
  run_button = gr.Button("Run", scale=0)
109
+
110
  image = gr.ImageEditor(type="pil", image_mode="L", crop_size=(512, 512))
111
  result = gr.Image(label="Result", show_label=False)
112
 
113
  with gr.Accordion("Advanced Settings", open=False):
114
+
115
  negative_prompt = gr.Text(
116
  label="Negative prompt",
117
  max_lines=1,
118
  placeholder="Enter a negative prompt",
 
119
  value="nsfw, (low quality, worst quality:1.2), very displeasing, 3d, watermark, signature, ugly, poorly drawn"
120
  )
121
+
122
  seed = gr.Slider(
123
  label="Seed",
124
  minimum=0,
 
126
  step=1,
127
  value=0,
128
  )
129
+
130
  randomize_seed = gr.Checkbox(label="Randomize seed", value=True)
131
+
132
  with gr.Row():
 
133
  width = gr.Slider(
134
  label="Width",
135
  minimum=256,
 
137
  step=32,
138
  value=832,
139
  )
140
+
141
  height = gr.Slider(
142
  label="Height",
143
  minimum=256,
 
145
  step=32,
146
  value=1216,
147
  )
148
+
149
  with gr.Row():
 
150
  guidance_scale = gr.Slider(
151
  label="Guidance scale",
152
  minimum=0.0,
 
154
  step=0.1,
155
  value=7,
156
  )
157
+
158
  num_inference_steps = gr.Slider(
159
  label="Number of inference steps",
160
  minimum=1,
 
164
  )
165
 
166
  run_button.click(
167
+ fn=infer,
168
+ inputs=[image, prompt, negative_prompt, seed, randomize_seed, width, height, guidance_scale, num_inference_steps],
169
+ outputs=[result]
170
  )
171
 
172
+ demo.queue().launch()