prithivMLmods commited on
Commit
1096b40
1 Parent(s): f02cdb3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +102 -84
app.py CHANGED
@@ -1,9 +1,7 @@
1
- #!/usr/bin/env python
2
- # Patch3.09
3
  import os
4
  import random
5
  import uuid
6
- import gdown
7
 
8
  import gradio as gr
9
  import numpy as np
@@ -12,7 +10,32 @@ import spaces
12
  import torch
13
  from diffusers import StableDiffusionXLPipeline, EulerAncestralDiscreteScheduler
14
 
15
- DESCRIPTION = """ """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
  def save_image(img):
18
  unique_name = str(uuid.uuid4()) + ".png"
@@ -24,90 +47,71 @@ def randomize_seed_fn(seed: int, randomize_seed: bool) -> int:
24
  seed = random.randint(0, MAX_SEED)
25
  return seed
26
 
27
- MAX_SEED = np.iinfo(np.int32).max
28
-
29
- if not torch.cuda.is_available():
30
- DESCRIPTION += "\n<p>Running on CPU, This Space may not work on CPU.</p>"
31
-
32
- USE_TORCH_COMPILE = 0
33
- ENABLE_CPU_OFFLOAD = 0
34
-
35
- if torch.cuda.is_available():
36
- pipe = StableDiffusionXLPipeline.from_pretrained(
37
- "stabilityai/stable-diffusion-xl-base-1.0",
38
- torch_dtype=torch.float16,
39
- use_safetensors=True,
40
- )
41
- pipe.scheduler = EulerAncestralDiscreteScheduler.from_config(pipe.scheduler.config)
42
-
43
- # Download the LoRA weights from Google Drive
44
- drive_folder_url = "https://drive.google.com/drive/folders/1ExL5VNChyYWXho1QbgNbOkTK3xc8mhHW"
45
- weight_file_id = "18n6gF7Jda92MpqK7cYs0Gv2IqLAVnltZ"
46
- weight_file_name = "pytorch_lora_weights.safetensors"
47
- # Use gdown to download the file
48
- gdown.download(f"https://drive.google.com/uc?id={weight_file_id}", weight_file_name, quiet=False)
49
-
50
- pipe.load_lora_weights(weight_file_name, adapter_name="icon")
51
- pipe.set_adapters("icon")
52
-
53
- pipe.to("cuda")
54
-
55
- @spaces.GPU(enable_queue=True)
56
  def generate(
57
  prompt: str,
58
  negative_prompt: str = "",
59
  use_negative_prompt: bool = False,
60
- seed: int = 0,
61
  width: int = 1024,
62
  height: int = 1024,
63
  guidance_scale: float = 3,
 
64
  randomize_seed: bool = False,
 
 
65
  progress=gr.Progress(track_tqdm=True),
66
  ):
67
  seed = int(randomize_seed_fn(seed, randomize_seed))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
 
69
- if not use_negative_prompt:
70
- negative_prompt = "" # type: ignore
71
-
72
- images = pipe(
73
- prompt=prompt,
74
- negative_prompt=negative_prompt,
75
- width=width,
76
- height=height,
77
- guidance_scale=guidance_scale,
78
- num_inference_steps=25,
79
- num_images_per_prompt=1,
80
- cross_attention_kwargs={"scale": 0.65},
81
- output_type="pil",
82
- ).images
83
  image_paths = [save_image(img) for img in images]
84
- print(image_paths)
85
  return image_paths, seed
86
 
87
  examples = [
88
- "1boy, male focus, sky, star (sky), night, pointing up, night sky, hood down, starry sky, hood, blue theme, outdoors, long sleeves, shooting star, hoodie, short hair, jacket, scenery, cloud, from behind, blue eyes, best quality, amazing quality, best aesthetic, absurdres",
89
- "1boy, male focus, bishounen, holding sword, holding weapon, katana, sword, japanese clothes, haori, east asian architecture, solo, looking at viewer, expressionless, blue hair, purple eyes, long hair, best quality, amazing quality, best aesthetic, absurdres",
90
- "1boy, male focus, holding drink, holding, drink, toned male, toned, pectorals, jacket, open jacket, open clothes, tank top, chain necklace, necklace, stud earrings, earrings, jewelry, cafe, plant, indoors, lens flare, solo, looking at viewer, open mouth, fang, white hair, yellow eyes, short hair, best quality, amazing quality, best aesthetic, absurdres, year 2023",
91
- "1boy, male focus, dark-skinned male, dark skin, squatting, heart hands, bara, wooden floor, floor, indoors, gym uniform, sneakers, shoes, solo, looking at viewer, frown, sweatdrop, very short hair, best quality, amazing quality, best aesthetic, absurdres, year 2023",
92
- "1boy, male focus, short hair, blue hair, blue eyes, graphic t-shirt, punk t-shirt, digital illustration, cyan and black, looking at viewer, busy city street, belt, black pants, atmospheric lighting, midriff peek, night, blurry, best quality, amazing quality, best aesthetic, absurdres",
93
- "Ultra realistic close up portrait ((beautiful pale cyberpunk female with heavy black eyeliner)), blue eyes, shaved side haircut, hyper detail, cinematic lighting, magic neon, dark red city, Canon EOS R3, nikon, f/1.4, ISO 200, 1/160s, 8K, RAW, unedited, symmetrical balance, in-frame, 8K"
94
  ]
95
 
96
  css = '''
97
- .gradio-container{max-width: 600px !important}
98
  h1{text-align:center}
99
  footer {
100
  visibility: hidden
101
  }
102
  '''
103
- with gr.Blocks(css=css, theme="ParityError/Anime") as demo:
104
- gr.Markdown(DESCRIPTION)
105
- gr.DuplicateButton(
106
- value="Duplicate Space for private use",
107
- elem_id="duplicate-button",
108
- visible=False,
109
- )
110
 
 
 
111
  with gr.Group():
112
  with gr.Row():
113
  prompt = gr.Text(
@@ -118,56 +122,68 @@ with gr.Blocks(css=css, theme="ParityError/Anime") as demo:
118
  container=False,
119
  )
120
  run_button = gr.Button("Run", scale=0)
121
- result = gr.Gallery(label="Result", columns=1, preview=True, show_label=False)
122
  with gr.Accordion("Advanced options", open=False):
123
- use_negative_prompt = gr.Checkbox(label="Use negative prompt", value=True)
124
- negative_prompt = gr.Text(
125
- label="Negative prompt",
126
- lines=4,
127
- max_lines=6,
128
- value="""(deformed, distorted, disfigured:1.3), poorly drawn, bad anatomy, wrong anatomy, extra limb, missing limb, floating limbs, (mutated hands and fingers:1.4), disconnected limbs, mutation, mutated, ugly, disgusting, blurry, amputation""",
129
- placeholder="Enter a negative prompt",
130
- visible=True,
131
  )
 
 
 
 
 
 
 
 
 
 
132
  seed = gr.Slider(
133
  label="Seed",
134
  minimum=0,
135
  maximum=MAX_SEED,
136
  step=1,
137
  value=0,
138
- visible=True
139
  )
140
  randomize_seed = gr.Checkbox(label="Randomize seed", value=True)
141
  with gr.Row(visible=True):
142
  width = gr.Slider(
143
  label="Width",
144
  minimum=512,
145
- maximum=2048,
146
- step=8,
147
  value=1024,
148
  )
149
  height = gr.Slider(
150
  label="Height",
151
  minimum=512,
152
- maximum=2048,
153
- step=8,
154
  value=1024,
155
  )
156
  with gr.Row():
157
  guidance_scale = gr.Slider(
158
  label="Guidance Scale",
159
  minimum=0.1,
160
- maximum=20.0,
161
  step=0.1,
162
- value=6,
 
 
 
 
 
 
 
163
  )
164
 
165
  gr.Examples(
166
  examples=examples,
167
  inputs=prompt,
168
- outputs=[result, seed],
169
- fn=generate,
170
- cache_examples=False,
171
  )
172
 
173
  use_negative_prompt.change(
@@ -192,11 +208,13 @@ with gr.Blocks(css=css, theme="ParityError/Anime") as demo:
192
  width,
193
  height,
194
  guidance_scale,
 
195
  randomize_seed,
 
196
  ],
197
  outputs=[result, seed],
198
  api_name="run",
199
  )
200
-
201
  if __name__ == "__main__":
202
- demo.queue(max_size=20).launch(show_api=False, debug=False)
 
 
 
1
  import os
2
  import random
3
  import uuid
4
+ import json
5
 
6
  import gradio as gr
7
  import numpy as np
 
10
  import torch
11
  from diffusers import StableDiffusionXLPipeline, EulerAncestralDiscreteScheduler
12
 
13
+ # Use environment variables for flexibility
14
+ MODEL_ID = os.getenv("MODEL_ID", "SG161222/RealVisXL_V4.0_Lightning")
15
+ MAX_IMAGE_SIZE = int(os.getenv("MAX_IMAGE_SIZE", "4096"))
16
+ USE_TORCH_COMPILE = os.getenv("USE_TORCH_COMPILE", "0") == "1"
17
+ ENABLE_CPU_OFFLOAD = os.getenv("ENABLE_CPU_OFFLOAD", "0") == "1"
18
+ BATCH_SIZE = int(os.getenv("BATCH_SIZE", "1")) # Allow generating multiple images at once
19
+
20
+ # Determine device and load model outside of function for efficiency
21
+ device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
22
+ pipe = StableDiffusionXLPipeline.from_pretrained(
23
+ MODEL_ID,
24
+ torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
25
+ use_safetensors=True,
26
+ add_watermarker=False,
27
+ ).to(device)
28
+ pipe.scheduler = EulerAncestralDiscreteScheduler.from_config(pipe.scheduler.config)
29
+
30
+ # Torch compile for potential speedup (experimental)
31
+ if USE_TORCH_COMPILE:
32
+ pipe.compile()
33
+
34
+ # CPU offloading for larger RAM capacity (experimental)
35
+ if ENABLE_CPU_OFFLOAD:
36
+ pipe.enable_model_cpu_offload()
37
+
38
+ MAX_SEED = np.iinfo(np.int32).max
39
 
40
  def save_image(img):
41
  unique_name = str(uuid.uuid4()) + ".png"
 
47
  seed = random.randint(0, MAX_SEED)
48
  return seed
49
 
50
+ @spaces.GPU(duration=35, enable_queue=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  def generate(
52
  prompt: str,
53
  negative_prompt: str = "",
54
  use_negative_prompt: bool = False,
55
+ seed: int = 1,
56
  width: int = 1024,
57
  height: int = 1024,
58
  guidance_scale: float = 3,
59
+ num_inference_steps: int = 30,
60
  randomize_seed: bool = False,
61
+ use_resolution_binning: bool = True,
62
+ num_images: int = 1, # Number of images to generate
63
  progress=gr.Progress(track_tqdm=True),
64
  ):
65
  seed = int(randomize_seed_fn(seed, randomize_seed))
66
+ generator = torch.Generator(device=device).manual_seed(seed)
67
+
68
+ # Improved options handling
69
+ options = {
70
+ "prompt": [prompt] * num_images,
71
+ "negative_prompt": [negative_prompt] * num_images if use_negative_prompt else None,
72
+ "width": width,
73
+ "height": height,
74
+ "guidance_scale": guidance_scale,
75
+ "num_inference_steps": num_inference_steps,
76
+ "generator": generator,
77
+ "output_type": "pil",
78
+ }
79
+
80
+ # Use resolution binning for faster generation with less VRAM usage
81
+ if use_resolution_binning:
82
+ options["use_resolution_binning"] = True
83
+
84
+ # Generate images potentially in batches
85
+ images = []
86
+ for i in range(0, num_images, BATCH_SIZE):
87
+ batch_options = options.copy()
88
+ batch_options["prompt"] = options["prompt"][i:i+BATCH_SIZE]
89
+ if "negative_prompt" in batch_options:
90
+ batch_options["negative_prompt"] = options["negative_prompt"][i:i+BATCH_SIZE]
91
+ images.extend(pipe(**batch_options).images)
92
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  image_paths = [save_image(img) for img in images]
 
94
  return image_paths, seed
95
 
96
  examples = [
97
+ "a cat eating a piece of cheese",
98
+ "a ROBOT riding a BLUE horse on Mars, photorealistic, 4k",
99
+ "Ironman VS Hulk, ultrarealistic",
100
+ "Astronaut in a jungle, cold color palette, oil pastel, detailed, 8k",
101
+ "An alien holding a sign board containing the word 'Flash', futuristic, neonpunk",
102
+ "Kids going to school, Anime style"
103
  ]
104
 
105
  css = '''
106
+ .gradio-container{max-width: 700px !important}
107
  h1{text-align:center}
108
  footer {
109
  visibility: hidden
110
  }
111
  '''
 
 
 
 
 
 
 
112
 
113
+ with gr.Blocks(css=css) as demo:
114
+ gr.Markdown("""# SDXL Flash""")
115
  with gr.Group():
116
  with gr.Row():
117
  prompt = gr.Text(
 
122
  container=False,
123
  )
124
  run_button = gr.Button("Run", scale=0)
125
+ result = gr.Gallery(label="Result", columns=1, show_label=False)
126
  with gr.Accordion("Advanced options", open=False):
127
+ num_images = gr.Slider(
128
+ label="Number of Images",
129
+ minimum=1,
130
+ maximum=4,
131
+ step=1,
132
+ value=1,
 
 
133
  )
134
+ with gr.Row():
135
+ use_negative_prompt = gr.Checkbox(label="Use negative prompt", value=True)
136
+ negative_prompt = gr.Text(
137
+ label="Negative prompt",
138
+ max_lines=5,
139
+ lines=4,
140
+ placeholder="Enter a negative prompt",
141
+ value="(deformed, distorted, disfigured:1.3), poorly drawn, bad anatomy, wrong anatomy, extra limb, missing limb, floating limbs, (mutated hands and fingers:1.4), disconnected limbs, mutation, mutated, ugly, disgusting, blurry, amputation, NSFW",
142
+ visible=True,
143
+ )
144
  seed = gr.Slider(
145
  label="Seed",
146
  minimum=0,
147
  maximum=MAX_SEED,
148
  step=1,
149
  value=0,
 
150
  )
151
  randomize_seed = gr.Checkbox(label="Randomize seed", value=True)
152
  with gr.Row(visible=True):
153
  width = gr.Slider(
154
  label="Width",
155
  minimum=512,
156
+ maximum=MAX_IMAGE_SIZE,
157
+ step=64,
158
  value=1024,
159
  )
160
  height = gr.Slider(
161
  label="Height",
162
  minimum=512,
163
+ maximum=MAX_IMAGE_SIZE,
164
+ step=64,
165
  value=1024,
166
  )
167
  with gr.Row():
168
  guidance_scale = gr.Slider(
169
  label="Guidance Scale",
170
  minimum=0.1,
171
+ maximum=6,
172
  step=0.1,
173
+ value=3.0,
174
+ )
175
+ num_inference_steps = gr.Slider(
176
+ label="Number of inference steps",
177
+ minimum=1,
178
+ maximum=15,
179
+ step=1,
180
+ value=8,
181
  )
182
 
183
  gr.Examples(
184
  examples=examples,
185
  inputs=prompt,
186
+ cache_examples=False
 
 
187
  )
188
 
189
  use_negative_prompt.change(
 
208
  width,
209
  height,
210
  guidance_scale,
211
+ num_inference_steps,
212
  randomize_seed,
213
+ num_images
214
  ],
215
  outputs=[result, seed],
216
  api_name="run",
217
  )
218
+
219
  if __name__ == "__main__":
220
+ demo.queue(max_size=50).launch()