KingNish commited on
Commit
0556cb5
1 Parent(s): 1ec1d44

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +85 -233
app.py CHANGED
@@ -1,174 +1,44 @@
1
- from __future__ import annotations
2
- import os
3
- import random
4
- import uuid
5
- import gradio as gr
6
  import spaces
7
- import numpy as np
8
- import uuid
9
- from diffusers import PixArtAlphaPipeline, LCMScheduler
10
- import torch
11
- from typing import Tuple
12
- from datetime import datetime
13
-
14
-
15
- DESCRIPTION = """ # Instant Image
16
- ### Super fast text to Image Generator.
17
- ### <span style='color: red;'>You may change the steps from 4 to 8, if you didn't get satisfied results.
18
- ### First Image processing takes time then images generate faster.
19
- """
20
- if not torch.cuda.is_available():
21
- DESCRIPTION += "\n<p>Running on CPU 🥶 This demo does not work on CPU.</p>"
22
-
23
- MAX_SEED = np.iinfo(np.int32).max
24
- CACHE_EXAMPLES = torch.cuda.is_available() and os.getenv("CACHE_EXAMPLES", "1") == "1"
25
- MAX_IMAGE_SIZE = int(os.getenv("MAX_IMAGE_SIZE", "3000"))
26
- USE_TORCH_COMPILE = os.getenv("USE_TORCH_COMPILE", "0") == "1"
27
- ENABLE_CPU_OFFLOAD = os.getenv("ENABLE_CPU_OFFLOAD", "0") == "1"
28
- PORT = int(os.getenv("DEMO_PORT", "15432"))
29
-
30
- device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
31
-
32
-
33
- style_list = [
34
- {
35
- "name": "(No style)",
36
- "prompt": "{prompt}",
37
- "negative_prompt": "",
38
- },
39
- {
40
- "name": "Cinematic",
41
- "prompt": "cinematic still {prompt} . emotional, harmonious, vignette, highly detailed, high budget, bokeh, cinemascope, moody, epic, gorgeous, film grain, grainy",
42
- "negative_prompt": "anime, cartoon, graphic, text, painting, crayon, graphite, abstract, glitch, deformed, mutated, ugly, disfigured",
43
- },
44
- {
45
- "name": "Realistic",
46
- "prompt": "Photorealistic {prompt} . Ulta-realistic, professional, 4k, highly detailed",
47
- "negative_prompt": "drawing, painting, crayon, sketch, graphite, impressionist, noisy, blurry, soft, deformed, ugly, disfigured",
48
- },
49
- {
50
- "name": "Anime",
51
- "prompt": "anime artwork {prompt} . anime style, key visual, vibrant, studio anime, highly detailed",
52
- "negative_prompt": "photo, deformed, black and white, realism, disfigured, low contrast",
53
- },
54
- {
55
- "name": "Digital Art",
56
- "prompt": "concept art {prompt} . digital artwork, illustrative, painterly, matte painting, highly detailed",
57
- "negative_prompt": "photo, photorealistic, realism, ugly",
58
- },
59
- {
60
- "name": "Pixel art",
61
- "prompt": "pixel-art {prompt} . low-res, blocky, pixel art style, 8-bit graphics",
62
- "negative_prompt": "sloppy, messy, blurry, noisy, highly detailed, ultra textured, photo, realistic",
63
- },
64
- {
65
- "name": "Fantasy art",
66
- "prompt": "ethereal fantasy concept art of {prompt} . magnificent, celestial, ethereal, painterly, epic, majestic, magical, fantasy art, cover art, dreamy",
67
- "negative_prompt": "photographic, realistic, realism, 35mm film, dslr, cropped, frame, text, deformed, glitch, noise, noisy, off-center, deformed, cross-eyed, closed eyes, bad anatomy, ugly, disfigured, sloppy, duplicate, mutated, black and white",
68
- },
69
- {
70
- "name": "3D Model",
71
- "prompt": "professional 3d model {prompt} . octane render, highly detailed, volumetric, dramatic lighting",
72
- "negative_prompt": "ugly, deformed, noisy, low poly, blurry, painting",
73
- },
74
- ]
75
-
76
-
77
- styles = {k["name"]: (k["prompt"], k["negative_prompt"]) for k in style_list}
78
- STYLE_NAMES = list(styles.keys())
79
- DEFAULT_STYLE_NAME = "(No style)"
80
- NUM_IMAGES_PER_PROMPT = 1
81
-
82
- def apply_style(style_name: str, positive: str, negative: str = "") -> Tuple[str, str]:
83
- p, n = styles.get(style_name, styles[DEFAULT_STYLE_NAME])
84
- if not negative:
85
- negative = ""
86
- return p.replace("{prompt}", positive), n + negative
87
-
88
- if torch.cuda.is_available():
89
-
90
- pipe = PixArtAlphaPipeline.from_pretrained(
91
- "PixArt-alpha/PixArt-LCM-XL-2-1024-MS",
92
- torch_dtype=torch.float16,
93
- use_safetensors=True,
94
- )
95
-
96
- if os.getenv('CONSISTENCY_DECODER', False):
97
- print("Using DALL-E 3 Consistency Decoder")
98
- pipe.vae = ConsistencyDecoderVAE.from_pretrained("openai/consistency-decoder", torch_dtype=torch.float16)
99
-
100
- if ENABLE_CPU_OFFLOAD:
101
- pipe.enable_model_cpu_offload()
102
- else:
103
- pipe.to(device)
104
- print("Loaded on Device!")
105
-
106
- # speed-up T5
107
- pipe.text_encoder.to_bettertransformer()
108
 
109
- if USE_TORCH_COMPILE:
110
- pipe.transformer = torch.compile(pipe.transformer, mode="reduce-overhead", fullgraph=True)
111
- print("Model Compiled!")
 
112
 
 
 
 
113
 
114
- def save_image(img):
115
- unique_name = str(uuid.uuid4()) + ".png"
116
- img.save(unique_name)
117
- return unique_name
118
 
 
119
 
120
- def randomize_seed_fn(seed: int, randomize_seed: bool) -> int:
121
- if randomize_seed:
122
- seed = random.randint(0, MAX_SEED)
123
- return seed
124
 
125
- @spaces.GPU(duration=30)
126
- def generate(
127
- prompt: str,
128
- negative_prompt: str = "",
129
- style: str = DEFAULT_STYLE_NAME,
130
- use_negative_prompt: bool = False,
131
- seed: int = 0,
132
- width: int = 1024,
133
- height: int = 1024,
134
- inference_steps: int = 4,
135
- randomize_seed: bool = False,
136
- use_resolution_binning: bool = True,
137
- progress=gr.Progress(track_tqdm=True),
138
- ):
139
- seed = int(randomize_seed_fn(seed, randomize_seed))
140
- generator = torch.Generator().manual_seed(seed)
141
-
142
- if not use_negative_prompt:
143
- negative_prompt = None # type: ignore
144
- prompt, negative_prompt = apply_style(style, prompt, negative_prompt)
145
 
146
- images = pipe(
147
- prompt=prompt,
148
- negative_prompt=negative_prompt,
149
- width=width,
150
- height=height,
151
- guidance_scale=0,
152
- num_inference_steps=inference_steps,
153
- generator=generator,
154
- num_images_per_prompt=NUM_IMAGES_PER_PROMPT,
155
- use_resolution_binning=use_resolution_binning,
156
- output_type="pil",
157
- ).images
158
 
159
- image_paths = [save_image(img) for img in images]
160
- print(image_paths)
161
- return image_paths, seed
162
 
163
-
164
- examples = [
165
- "A Monkey with a happy face in the Sahara desert.",
166
- "Eiffel Tower was Made up of ICE.",
167
- "Color photo of a corgi made of transparent glass, standing on the riverside in Yosemite National Park.",
168
- "A close-up photo of a woman. She wore a blue coat with a gray dress underneath and has blue eyes.",
169
- "A litter of golden retriever puppies playing in the snow. Their heads pop out of the snow, covered in.",
170
- "an astronaut sitting in a diner, eating fries, cinematic, analog film",
171
- ]
172
 
173
  with gr.Blocks() as demo:
174
  gr.Markdown(DESCRIPTION)
@@ -188,29 +58,6 @@ with gr.Blocks() as demo:
188
  with gr.Accordion("Advanced options", open=False):
189
  with gr.Group():
190
  with gr.Row():
191
- use_negative_prompt = gr.Checkbox(label="Use negative prompt", value=False, visible=True)
192
- negative_prompt = gr.Text(
193
- label="Negative prompt",
194
- max_lines=1,
195
- placeholder="Enter a negative prompt",
196
- visible=True,
197
- )
198
-
199
- # num_imgs = gr.Slider(
200
- # label="Num Images",
201
- # minimum=1,
202
- # maximum=8,
203
- # step=1,
204
- # value=1,
205
- # )
206
- style_selection = gr.Radio(
207
- show_label=True,
208
- container=True,
209
- interactive=True,
210
- choices=STYLE_NAMES,
211
- value=DEFAULT_STYLE_NAME,
212
- label="Image Style",
213
- )
214
  seed = gr.Slider(
215
  label="Seed",
216
  minimum=0,
@@ -223,64 +70,69 @@ with gr.Blocks() as demo:
223
  width = gr.Slider(
224
  label="Width",
225
  minimum=256,
226
- maximum=MAX_IMAGE_SIZE,
227
  step=32,
228
- value=1024,
229
  )
230
  height = gr.Slider(
231
  label="Height",
232
  minimum=256,
233
- maximum=MAX_IMAGE_SIZE,
234
  step=32,
235
- value=1024,
236
  )
237
- with gr.Row():
238
- inference_steps = gr.Slider(
239
- label="Steps",
240
- minimum=4,
241
- maximum=20,
242
- step=1,
243
- value=4,
244
- )
245
 
246
- gr.Examples(
247
- examples=examples,
248
- inputs=prompt,
249
- outputs=[result, seed],
250
- fn=generate,
251
- cache_examples=CACHE_EXAMPLES,
252
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253
 
254
- use_negative_prompt.change(
255
- fn=lambda x: gr.update(visible=x),
256
- inputs=use_negative_prompt,
257
- outputs=negative_prompt,
258
- api_name=False,
259
- )
260
 
261
- gr.on(
262
- triggers=[
263
- prompt.submit,
264
- negative_prompt.submit,
265
- run_button.click,
266
- ],
267
- fn=generate,
268
- inputs=[
269
- prompt,
270
- negative_prompt,
271
- style_selection,
272
- use_negative_prompt,
273
- # num_imgs,
274
- seed,
275
- width,
276
- height,
277
- inference_steps,
278
- randomize_seed,
279
- ],
280
- outputs=[result, seed],
281
- api_name="run",
282
- )
283
 
284
  if __name__ == "__main__":
285
- demo.queue(max_size=20).launch()
286
- # demo.queue(max_size=20).launch(server_name="0.0.0.0", server_port=11900, debug=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import spaces
2
+ import argparse
3
+ import os
4
+ import time
5
+ from os import path
6
+ from safetensors.torch import load_file
7
+ from huggingface_hub import hf_hub_download
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
+ cache_path = path.join(path.dirname(path.abspath(__file__)), "models")
10
+ os.environ["TRANSFORMERS_CACHE"] = cache_path
11
+ os.environ["HF_HUB_CACHE"] = cache_path
12
+ os.environ["HF_HOME"] = cache_path
13
 
14
+ import gradio as gr
15
+ import torch
16
+ from diffusers import StableDiffusionXLPipeline, LCMScheduler
17
 
18
+ # from scheduling_tcd import TCDScheduler
 
 
 
19
 
20
+ torch.backends.cuda.matmul.allow_tf32 = True
21
 
22
+ class timer:
23
+ def __init__(self, method_name="timed process"):
24
+ self.method = method_name
 
25
 
26
+ def __enter__(self):
27
+ self.start = time.time()
28
+ print(f"{self.method} starts")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
+ def __exit__(self, exc_type, exc_val, exc_tb):
31
+ end = time.time()
32
+ print(f"{self.method} took {str(round(end - self.start, 2))}s")
 
 
 
 
 
 
 
 
 
33
 
34
+ if not path.exists(cache_path):
35
+ os.makedirs(cache_path, exist_ok=True)
 
36
 
37
+ pipe = StableDiffusionXLPipeline.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0", torch_dtype=torch.bfloat16)
38
+ pipe.to(device="cuda", dtype=torch.bfloat16)
39
+ unet_state = load_file(hf_hub_download("ByteDance/Hyper-SD", "Hyper-SDXL-1step-Unet.safetensors"), device="cuda")
40
+ pipe.unet.load_state_dict(unet_state)
41
+ pipe.scheduler = LCMScheduler.from_config(pipe.scheduler.config, timestep_spacing ="trailing")
 
 
 
 
42
 
43
  with gr.Blocks() as demo:
44
  gr.Markdown(DESCRIPTION)
 
58
  with gr.Accordion("Advanced options", open=False):
59
  with gr.Group():
60
  with gr.Row():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  seed = gr.Slider(
62
  label="Seed",
63
  minimum=0,
 
70
  width = gr.Slider(
71
  label="Width",
72
  minimum=256,
73
+ maximum=8192,
74
  step=32,
75
+ value=2048,
76
  )
77
  height = gr.Slider(
78
  label="Height",
79
  minimum=256,
80
+ maximum=8192,
81
  step=32,
82
+ value=2048,
83
  )
 
 
 
 
 
 
 
 
84
 
85
+ def randomize_seed_fn(seed: int, randomize_seed: bool) -> int:
86
+ if randomize_seed:
87
+ seed = random.randint(0, MAX_SEED)
88
+ return seed
89
+
90
+ @spaces.GPU(duration=10)
91
+ def process_image( height, width, prompt, seed, randomize_seed):
92
+ global pipe
93
+ with torch.inference_mode(), torch.autocast("cuda", dtype=torch.bfloat16), timer("inference"):
94
+ return pipe(
95
+ prompt=str,,
96
+ generator=torch.Generator().manual_seed(int(seed)),
97
+ num_inference_steps=1,
98
+ guidance_scale=0.,
99
+ height=int(height),
100
+ width=int(width),
101
+ timesteps=[800],
102
+ randomize_seed: bool = False,
103
+ use_resolution_binning: bool = True,
104
+ progress=gr.Progress(track_tqdm=True),
105
+ ).images
106
+
107
+ seed = int(randomize_seed_fn(seed, randomize_seed))
108
+ generator = torch.Generator().manual_seed(seed)
109
+
110
+ reactive_controls = [ height, width, prompt, seed, randomize_seed]
111
 
 
 
 
 
 
 
112
 
113
+ btn.click(process_image, inputs=reactive_controls, outputs=[output])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
 
115
  if __name__ == "__main__":
116
+ demo.launch()
117
+
118
+
119
+ DESCRIPTION = """ # Instant Image
120
+ ### Super fast text to Image Generator.
121
+ ### <span style='color: red;'>You may change the steps from 4 to 8, if you didn't get satisfied results.
122
+ ### First Image processing takes time then images generate faster.
123
+ """
124
+ if not torch.cuda.is_available():
125
+ DESCRIPTION += "\n<p>Running on CPU 🥶 This demo does not work on CPU.</p>"
126
+
127
+
128
+ CACHE_EXAMPLES = torch.cuda.is_available() and os.getenv("CACHE_EXAMPLES", "1") == "1"
129
+
130
+ examples = [
131
+ "A Monkey with a happy face in the Sahara desert.",
132
+ "Eiffel Tower was Made up of ICE.",
133
+ "Color photo of a corgi made of transparent glass, standing on the riverside in Yosemite National Park.",
134
+ "A close-up photo of a woman. She wore a blue coat with a gray dress underneath and has blue eyes.",
135
+ "A litter of golden retriever puppies playing in the snow. Their heads pop out of the snow, covered in.",
136
+ "an astronaut sitting in a diner, eating fries, cinematic, analog film",
137
+ ]
138
+