TastyRice commited on
Commit
56b96ad
·
verified ·
1 Parent(s): acee391

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +396 -0
app.py ADDED
@@ -0,0 +1,396 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ '''from Cagliostro Research Lab'''
2
+ import os
3
+ import gc
4
+ import gradio as gr
5
+ import numpy as np
6
+ import torch
7
+ import json
8
+ import spaces
9
+ import config
10
+ import utils
11
+ import logging
12
+ from PIL import Image, PngImagePlugin
13
+ from datetime import datetime
14
+ from diffusers.models import AutoencoderKL
15
+ from diffusers import StableDiffusionXLPipeline, StableDiffusionXLImg2ImgPipeline
16
+
17
+ logging.basicConfig(level=logging.INFO)
18
+ logger = logging.getLogger(__name__)
19
+
20
+ DESCRIPTION = "Animagine XL 3.1"
21
+ if not torch.cuda.is_available():
22
+ DESCRIPTION += "\n<p>Running on CPU 🥶 This demo does not work on CPU. </p>"
23
+ IS_COLAB = utils.is_google_colab() or os.getenv("IS_COLAB") == "1"
24
+ HF_TOKEN = os.getenv("HF_TOKEN")
25
+ CACHE_EXAMPLES = torch.cuda.is_available() and os.getenv("CACHE_EXAMPLES") == "1"
26
+ MIN_IMAGE_SIZE = int(os.getenv("MIN_IMAGE_SIZE", "512"))
27
+ MAX_IMAGE_SIZE = int(os.getenv("MAX_IMAGE_SIZE", "2048"))
28
+ USE_TORCH_COMPILE = os.getenv("USE_TORCH_COMPILE") == "1"
29
+ ENABLE_CPU_OFFLOAD = os.getenv("ENABLE_CPU_OFFLOAD") == "1"
30
+ OUTPUT_DIR = os.getenv("OUTPUT_DIR", "./outputs")
31
+
32
+ MODEL = os.getenv(
33
+ "MODEL",
34
+ "https://huggingface.co/Tasty-Rice/Magic_on_paper/blob/main/Magic_on_paper-SDXL-v3.safetensors",
35
+ )
36
+
37
+ torch.backends.cudnn.deterministic = True
38
+ torch.backends.cudnn.benchmark = False
39
+
40
+ device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
41
+
42
+
43
+ def load_pipeline(model_name):
44
+ vae = AutoencoderKL.from_pretrained(
45
+ "madebyollin/sdxl-vae-fp16-fix",
46
+ torch_dtype=torch.float16,
47
+ )
48
+ pipeline = (
49
+ StableDiffusionXLPipeline.from_single_file
50
+ if MODEL.endswith(".safetensors")
51
+ else StableDiffusionXLPipeline.from_pretrained
52
+ )
53
+
54
+ pipe = pipeline(
55
+ model_name,
56
+ vae=vae,
57
+ torch_dtype=torch.float16,
58
+ custom_pipeline="lpw_stable_diffusion_xl",
59
+ use_safetensors=True,
60
+ add_watermarker=False,
61
+ use_auth_token=HF_TOKEN,
62
+ )
63
+
64
+ pipe.to(device)
65
+ return pipe
66
+
67
+
68
+ @spaces.GPU
69
+ def generate(
70
+ prompt: str,
71
+ negative_prompt: str = "",
72
+ seed: int = 0,
73
+ custom_width: int = 1024,
74
+ custom_height: int = 1024,
75
+ guidance_scale: float = 7.0,
76
+ num_inference_steps: int = 28,
77
+ sampler: str = "Euler a",
78
+ aspect_ratio_selector: str = "768 x 1344",
79
+ style_selector: str = "(None)",
80
+ quality_selector: str = "Standard v3.1",
81
+ use_upscaler: bool = False,
82
+ upscaler_strength: float = 0.55,
83
+ upscale_by: float = 1.5,
84
+ add_quality_tags: bool = True,
85
+ progress=gr.Progress(track_tqdm=True),
86
+ ):
87
+ generator = utils.seed_everything(seed)
88
+
89
+ width, height = utils.aspect_ratio_handler(
90
+ aspect_ratio_selector,
91
+ custom_width,
92
+ custom_height,
93
+ )
94
+
95
+ prompt = utils.add_wildcard(prompt, wildcard_files)
96
+
97
+ prompt, negative_prompt = utils.preprocess_prompt(
98
+ quality_prompt, quality_selector, prompt, negative_prompt, add_quality_tags
99
+ )
100
+ prompt, negative_prompt = utils.preprocess_prompt(
101
+ styles, style_selector, prompt, negative_prompt
102
+ )
103
+
104
+ width, height = utils.preprocess_image_dimensions(width, height)
105
+
106
+ backup_scheduler = pipe.scheduler
107
+ pipe.scheduler = utils.get_scheduler(pipe.scheduler.config, sampler)
108
+
109
+ if use_upscaler:
110
+ upscaler_pipe = StableDiffusionXLImg2ImgPipeline(**pipe.components)
111
+ metadata = {
112
+ "prompt": prompt,
113
+ "negative_prompt": negative_prompt,
114
+ "resolution": f"{width} x {height}",
115
+ "guidance_scale": guidance_scale,
116
+ "num_inference_steps": num_inference_steps,
117
+ "seed": seed,
118
+ "sampler": sampler,
119
+ "sdxl_style": style_selector,
120
+ "add_quality_tags": add_quality_tags,
121
+ "quality_tags": quality_selector,
122
+ }
123
+
124
+ if use_upscaler:
125
+ new_width = int(width * upscale_by)
126
+ new_height = int(height * upscale_by)
127
+ metadata["use_upscaler"] = {
128
+ "upscale_method": "nearest-exact",
129
+ "upscaler_strength": upscaler_strength,
130
+ "upscale_by": upscale_by,
131
+ "new_resolution": f"{new_width} x {new_height}",
132
+ }
133
+ else:
134
+ metadata["use_upscaler"] = None
135
+ metadata["Model"] = {
136
+ "Model": DESCRIPTION,
137
+ "Model hash": "e3c47aedb0",
138
+ }
139
+
140
+ logger.info(json.dumps(metadata, indent=4))
141
+
142
+ try:
143
+ if use_upscaler:
144
+ latents = pipe(
145
+ prompt=prompt,
146
+ negative_prompt=negative_prompt,
147
+ width=width,
148
+ height=height,
149
+ guidance_scale=guidance_scale,
150
+ num_inference_steps=num_inference_steps,
151
+ generator=generator,
152
+ output_type="latent",
153
+ ).images
154
+ upscaled_latents = utils.upscale(latents, "nearest-exact", upscale_by)
155
+ images = upscaler_pipe(
156
+ prompt=prompt,
157
+ negative_prompt=negative_prompt,
158
+ image=upscaled_latents,
159
+ guidance_scale=guidance_scale,
160
+ num_inference_steps=num_inference_steps,
161
+ strength=upscaler_strength,
162
+ generator=generator,
163
+ output_type="pil",
164
+ ).images
165
+ else:
166
+ images = pipe(
167
+ prompt=prompt,
168
+ negative_prompt=negative_prompt,
169
+ width=width,
170
+ height=height,
171
+ guidance_scale=guidance_scale,
172
+ num_inference_steps=num_inference_steps,
173
+ generator=generator,
174
+ output_type="pil",
175
+ ).images
176
+
177
+ if images:
178
+ image_paths = [
179
+ utils.save_image(image, metadata, OUTPUT_DIR, IS_COLAB)
180
+ for image in images
181
+ ]
182
+
183
+ for image_path in image_paths:
184
+ logger.info(f"Image saved as {image_path} with metadata")
185
+
186
+ return image_paths, metadata
187
+ except Exception as e:
188
+ logger.exception(f"An error occurred: {e}")
189
+ raise
190
+ finally:
191
+ if use_upscaler:
192
+ del upscaler_pipe
193
+ pipe.scheduler = backup_scheduler
194
+ utils.free_memory()
195
+
196
+
197
+ if torch.cuda.is_available():
198
+ pipe = load_pipeline(MODEL)
199
+ logger.info("Loaded on Device!")
200
+ else:
201
+ pipe = None
202
+
203
+ styles = {k["name"]: (k["prompt"], k["negative_prompt"]) for k in config.style_list}
204
+ quality_prompt = {
205
+ k["name"]: (k["prompt"], k["negative_prompt"]) for k in config.quality_prompt_list
206
+ }
207
+
208
+ wildcard_files = utils.load_wildcard_files("wildcard")
209
+
210
+ with gr.Blocks(css="style.css", theme="NoCrypt/miku@1.2.1") as demo:
211
+ title = gr.HTML(
212
+ f"""<h1><span>{DESCRIPTION}</span></h1>""",
213
+ elem_id="title",
214
+ )
215
+ gr.Markdown(
216
+ f"""Gradio demo for [Tasty-Rice/Magic_on_paper](https://huggingface.co/Tasty-Rice/Magic_on_paper)""",
217
+ elem_id="subtitle",
218
+ )
219
+ gr.DuplicateButton(
220
+ value="Duplicate Space for private use",
221
+ elem_id="duplicate-button",
222
+ visible=os.getenv("SHOW_DUPLICATE_BUTTON") == "1",
223
+ )
224
+ with gr.Row():
225
+ with gr.Column(scale=2):
226
+ with gr.Tab("Txt2img"):
227
+ with gr.Group():
228
+ prompt = gr.Text(
229
+ label="Prompt",
230
+ max_lines=5,
231
+ placeholder="Enter your prompt",
232
+ )
233
+ negative_prompt = gr.Text(
234
+ label="Negative Prompt",
235
+ max_lines=5,
236
+ placeholder="Enter a negative prompt",
237
+ )
238
+ with gr.Accordion(label="Quality Tags", open=True):
239
+ add_quality_tags = gr.Checkbox(
240
+ label="Add Quality Tags", value=True
241
+ )
242
+ quality_selector = gr.Dropdown(
243
+ label="Quality Tags Presets",
244
+ interactive=True,
245
+ choices=list(quality_prompt.keys()),
246
+ value="Standard v3.1",
247
+ )
248
+ with gr.Tab("Advanced Settings"):
249
+ with gr.Group():
250
+ style_selector = gr.Radio(
251
+ label="Style Preset",
252
+ container=True,
253
+ interactive=True,
254
+ choices=list(styles.keys()),
255
+ value="(None)",
256
+ )
257
+ with gr.Group():
258
+ aspect_ratio_selector = gr.Radio(
259
+ label="Aspect Ratio",
260
+ choices=config.aspect_ratios,
261
+ value="896 x 1152",
262
+ container=True,
263
+ )
264
+ with gr.Group(visible=False) as custom_resolution:
265
+ with gr.Row():
266
+ custom_width = gr.Slider(
267
+ label="Width",
268
+ minimum=MIN_IMAGE_SIZE,
269
+ maximum=MAX_IMAGE_SIZE,
270
+ step=8,
271
+ value=1024,
272
+ )
273
+ custom_height = gr.Slider(
274
+ label="Height",
275
+ minimum=MIN_IMAGE_SIZE,
276
+ maximum=MAX_IMAGE_SIZE,
277
+ step=8,
278
+ value=1024,
279
+ )
280
+ with gr.Group():
281
+ use_upscaler = gr.Checkbox(label="Use Upscaler", value=False)
282
+ with gr.Row() as upscaler_row:
283
+ upscaler_strength = gr.Slider(
284
+ label="Strength",
285
+ minimum=0,
286
+ maximum=1,
287
+ step=0.05,
288
+ value=0.55,
289
+ visible=False,
290
+ )
291
+ upscale_by = gr.Slider(
292
+ label="Upscale by",
293
+ minimum=1,
294
+ maximum=1.5,
295
+ step=0.1,
296
+ value=1.5,
297
+ visible=False,
298
+ )
299
+ with gr.Group():
300
+ sampler = gr.Dropdown(
301
+ label="Sampler",
302
+ choices=config.sampler_list,
303
+ interactive=True,
304
+ value="Euler a",
305
+ )
306
+ with gr.Group():
307
+ seed = gr.Slider(
308
+ label="Seed", minimum=0, maximum=utils.MAX_SEED, step=1, value=0
309
+ )
310
+ randomize_seed = gr.Checkbox(label="Randomize seed", value=True)
311
+ with gr.Group():
312
+ with gr.Row():
313
+ guidance_scale = gr.Slider(
314
+ label="Guidance scale",
315
+ minimum=1,
316
+ maximum=12,
317
+ step=0.1,
318
+ value=7.0,
319
+ )
320
+ num_inference_steps = gr.Slider(
321
+ label="Number of inference steps",
322
+ minimum=1,
323
+ maximum=50,
324
+ step=1,
325
+ value=28,
326
+ )
327
+ with gr.Column(scale=3):
328
+ with gr.Blocks():
329
+ run_button = gr.Button("Generate", variant="primary")
330
+ result = gr.Gallery(
331
+ label="Result",
332
+ columns=1,
333
+ height='100%',
334
+ preview=True,
335
+ show_label=False
336
+ )
337
+ with gr.Accordion(label="Generation Parameters", open=False):
338
+ gr_metadata = gr.JSON(label="metadata", show_label=False)
339
+ gr.Examples(
340
+ examples=config.examples,
341
+ inputs=prompt,
342
+ outputs=[result, gr_metadata],
343
+ fn=lambda *args, **kwargs: generate(*args, use_upscaler=True, **kwargs),
344
+ cache_examples=CACHE_EXAMPLES,
345
+ )
346
+ use_upscaler.change(
347
+ fn=lambda x: [gr.update(visible=x), gr.update(visible=x)],
348
+ inputs=use_upscaler,
349
+ outputs=[upscaler_strength, upscale_by],
350
+ queue=False,
351
+ api_name=False,
352
+ )
353
+ aspect_ratio_selector.change(
354
+ fn=lambda x: gr.update(visible=x == "Custom"),
355
+ inputs=aspect_ratio_selector,
356
+ outputs=custom_resolution,
357
+ queue=False,
358
+ api_name=False,
359
+ )
360
+
361
+ gr.on(
362
+ triggers=[
363
+ prompt.submit,
364
+ negative_prompt.submit,
365
+ run_button.click,
366
+ ],
367
+ fn=utils.randomize_seed_fn,
368
+ inputs=[seed, randomize_seed],
369
+ outputs=seed,
370
+ queue=False,
371
+ api_name=False,
372
+ ).then(
373
+ fn=generate,
374
+ inputs=[
375
+ prompt,
376
+ negative_prompt,
377
+ seed,
378
+ custom_width,
379
+ custom_height,
380
+ guidance_scale,
381
+ num_inference_steps,
382
+ sampler,
383
+ aspect_ratio_selector,
384
+ style_selector,
385
+ quality_selector,
386
+ use_upscaler,
387
+ upscaler_strength,
388
+ upscale_by,
389
+ add_quality_tags,
390
+ ],
391
+ outputs=[result, gr_metadata],
392
+ api_name="run",
393
+ )
394
+
395
+ if __name__ == "__main__":
396
+ demo.queue(max_size=20).launch(debug=IS_COLAB, share=IS_COLAB)