OminduAnjana commited on
Commit
cb9126f
·
verified ·
1 Parent(s): d0b1ac6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +277 -114
app.py CHANGED
@@ -1,154 +1,317 @@
 
 
 
1
  import gradio as gr
2
  import numpy as np
3
- import random
4
-
5
- # import spaces #[uncomment to use ZeroGPU]
6
- from diffusers import DiffusionPipeline
7
  import torch
 
 
8
 
9
- device = "cuda" if torch.cuda.is_available() else "cpu"
10
- model_repo_id = "stabilityai/sdxl-turbo" # Replace to the model you would like to use
11
-
12
- if torch.cuda.is_available():
13
- torch_dtype = torch.float16
14
- else:
15
- torch_dtype = torch.float32
16
 
17
- pipe = DiffusionPipeline.from_pretrained(model_repo_id, torch_dtype=torch_dtype)
18
- pipe = pipe.to(device)
19
 
20
- MAX_SEED = np.iinfo(np.int32).max
21
- MAX_IMAGE_SIZE = 1024
22
-
23
-
24
- # @spaces.GPU #[uncomment to use ZeroGPU]
25
- def infer(
26
- prompt,
27
- negative_prompt,
28
- seed,
29
- randomize_seed,
30
- width,
31
- height,
32
- guidance_scale,
33
- num_inference_steps,
34
- progress=gr.Progress(track_tqdm=True),
35
- ):
36
- if randomize_seed:
37
- seed = random.randint(0, MAX_SEED)
38
 
39
- generator = torch.Generator().manual_seed(seed)
 
 
 
 
 
40
 
41
- image = pipe(
42
- prompt=prompt,
43
- negative_prompt=negative_prompt,
44
- guidance_scale=guidance_scale,
45
- num_inference_steps=num_inference_steps,
46
- width=width,
47
- height=height,
48
- generator=generator,
49
- ).images[0]
50
 
51
- return image, seed
 
 
 
52
 
 
53
 
54
- examples = [
55
- "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k",
56
- "An astronaut riding a green horse",
57
- "A delicious ceviche cheesecake slice",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  ]
59
 
60
- css = """
61
- #col-container {
62
- margin: 0 auto;
63
- max-width: 640px;
64
- }
65
- """
66
 
67
- with gr.Blocks(css=css) as demo:
68
- with gr.Column(elem_id="col-container"):
69
- gr.Markdown(" # Text-to-Image Gradio Template")
 
 
70
 
71
- with gr.Row():
72
- prompt = gr.Text(
73
- label="Prompt",
74
- show_label=False,
75
- max_lines=1,
76
- placeholder="Enter your prompt",
77
- container=False,
78
- )
79
 
80
- run_button = gr.Button("Run", scale=0, variant="primary")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
 
82
- result = gr.Image(label="Result", show_label=False)
 
83
 
84
- with gr.Accordion("Advanced Settings", open=False):
85
- negative_prompt = gr.Text(
86
- label="Negative prompt",
87
- max_lines=1,
88
- placeholder="Enter a negative prompt",
89
- visible=False,
90
- )
91
 
92
- seed = gr.Slider(
93
- label="Seed",
94
- minimum=0,
95
- maximum=MAX_SEED,
96
- step=1,
97
- value=0,
98
- )
99
 
100
- randomize_seed = gr.Checkbox(label="Randomize seed", value=True)
 
 
 
101
 
102
- with gr.Row():
103
- width = gr.Slider(
104
- label="Width",
105
- minimum=256,
106
- maximum=MAX_IMAGE_SIZE,
107
- step=32,
108
- value=1024, # Replace with defaults that work for your model
109
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
110
 
111
- height = gr.Slider(
112
- label="Height",
113
- minimum=256,
114
- maximum=MAX_IMAGE_SIZE,
115
- step=32,
116
- value=1024, # Replace with defaults that work for your model
117
- )
118
 
119
- with gr.Row():
120
- guidance_scale = gr.Slider(
121
- label="Guidance scale",
122
- minimum=0.0,
123
- maximum=10.0,
124
- step=0.1,
125
- value=0.0, # Replace with defaults that work for your model
126
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
 
128
- num_inference_steps = gr.Slider(
129
- label="Number of inference steps",
130
- minimum=1,
131
- maximum=50,
132
- step=1,
133
- value=2, # Replace with defaults that work for your model
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
134
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135
 
136
- gr.Examples(examples=examples, inputs=[prompt])
 
 
 
 
 
 
 
 
 
 
 
 
137
  gr.on(
138
- triggers=[run_button.click, prompt.submit],
139
- fn=infer,
 
 
 
 
140
  inputs=[
 
141
  prompt,
142
  negative_prompt,
 
 
143
  seed,
144
- randomize_seed,
145
  width,
146
  height,
147
  guidance_scale,
148
  num_inference_steps,
 
 
149
  ],
150
  outputs=[result, seed],
151
  )
152
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153
  if __name__ == "__main__":
154
- demo.launch()
 
1
+ import os
2
+ import random
3
+ import uuid
4
  import gradio as gr
5
  import numpy as np
6
+ from PIL import Image
7
+ import spaces
 
 
8
  import torch
9
+ from diffusers import StableDiffusionXLPipeline, EulerAncestralDiscreteScheduler
10
+ from typing import Tuple
11
 
12
+ css = '''
13
+ .gradio-container{max-width: 575px !important}
14
+ h1{text-align:center}
15
+ footer {
16
+ visibility: hidden
17
+ }
18
+ '''
19
 
20
+ DESCRIPTIONXX = """## LENNOX TEXT 2 IMAGE🥠"""
 
21
 
22
+ examples = [
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
 
24
+ "Neon-lit futuristic city at night, towering skyscrapers, flying cars, and glowing billboards. People in cyberpunk attire walk below a starry sky.",
25
+ "Mystical forest with glowing plants, bioluminescent trees, and magical creatures like fairies and fireflies. Mist and soft light create a dreamlike feel.",
26
+ "Medieval knight in detailed armor on a cliff, sword in hand, sunset light highlighting a kingdom and castle in the background.",
27
+ "Modern, minimalist living room with soft gray and wood tones, large window with natural light, a simple couch, and potted plants for a cozy vibe.",
28
+ "Majestic lion on a rock in the African savanna at sunrise, mane blowing in the wind, with acacia trees and golden grass under warm light."
29
+ ]
30
 
31
+ MODEL_OPTIONS = {
32
+
33
+ "LENNOX-AI V2.0": "SG161222/RealVisXL_V5.0_Lightning",
34
+ "LENNOX-AI V1.0": "SG161222/RealVisXL_V4.0_Lightning",
35
+ }
 
 
 
 
36
 
37
+ MAX_IMAGE_SIZE = int(os.getenv("MAX_IMAGE_SIZE", "4096"))
38
+ USE_TORCH_COMPILE = os.getenv("USE_TORCH_COMPILE", "0") == "1"
39
+ ENABLE_CPU_OFFLOAD = os.getenv("ENABLE_CPU_OFFLOAD", "0") == "1"
40
+ BATCH_SIZE = int(os.getenv("BATCH_SIZE", "1"))
41
 
42
+ device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
43
 
44
+ style_list = [
45
+ {
46
+ "name": "3840 x 2160",
47
+ "prompt": "hyper-realistic 8K image of {prompt}. ultra-detailed, lifelike, high-resolution, sharp, vibrant colors, photorealistic",
48
+ "negative_prompt": "cartoonish, low resolution, blurry, simplistic, abstract, deformed, ugly",
49
+ },
50
+ {
51
+ "name": "2560 x 1440",
52
+ "prompt": "hyper-realistic 4K image of {prompt}. ultra-detailed, lifelike, high-resolution, sharp, vibrant colors, photorealistic",
53
+ "negative_prompt": "cartoonish, low resolution, blurry, simplistic, abstract, deformed, ugly",
54
+ },
55
+ {
56
+ "name": "HD+",
57
+ "prompt": "hyper-realistic 2K image of {prompt}. ultra-detailed, lifelike, high-resolution, sharp, vibrant colors, photorealistic",
58
+ "negative_prompt": "cartoonish, low resolution, blurry, simplistic, abstract, deformed, ugly",
59
+ },
60
+ {
61
+ "name": "Style Zero",
62
+ "prompt": "{prompt}",
63
+ "negative_prompt": "",
64
+ },
65
  ]
66
 
67
+ styles = {k["name"]: (k["prompt"], k["negative_prompt"]) for k in style_list}
68
+ DEFAULT_STYLE_NAME = "3840 x 2160"
69
+ STYLE_NAMES = list(styles.keys())
 
 
 
70
 
71
+ def apply_style(style_name: str, positive: str, negative: str = "") -> Tuple[str, str]:
72
+ if style_name in styles:
73
+ p, n = styles.get(style_name, styles[DEFAULT_STYLE_NAME])
74
+ else:
75
+ p, n = styles[DEFAULT_STYLE_NAME]
76
 
77
+ if not negative:
78
+ negative = ""
79
+ return p.replace("{prompt}", positive), n + negative
 
 
 
 
 
80
 
81
+ def load_and_prepare_model(model_id):
82
+ pipe = StableDiffusionXLPipeline.from_pretrained(
83
+ model_id,
84
+ torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
85
+ use_safetensors=True,
86
+ add_watermarker=False,
87
+ ).to(device)
88
+ pipe.scheduler = EulerAncestralDiscreteScheduler.from_config(pipe.scheduler.config)
89
+
90
+ if USE_TORCH_COMPILE:
91
+ pipe.compile()
92
+
93
+ if ENABLE_CPU_OFFLOAD:
94
+ pipe.enable_model_cpu_offload()
95
+
96
+ return pipe
97
 
98
+ # Preload and compile both models
99
+ models = {key: load_and_prepare_model(value) for key, value in MODEL_OPTIONS.items()}
100
 
101
+ MAX_SEED = np.iinfo(np.int32).max
 
 
 
 
 
 
102
 
103
+ def save_image(img):
104
+ unique_name = str(uuid.uuid4()) + ".png"
105
+ img.save(unique_name)
106
+ return unique_name
 
 
 
107
 
108
+ def randomize_seed_fn(seed: int, randomize_seed: bool) -> int:
109
+ if randomize_seed:
110
+ seed = random.randint(0, MAX_SEED)
111
+ return seed
112
 
113
+ @spaces.GPU(duration=60, enable_queue=True)
114
+ def generate(
115
+ model_choice: str,
116
+ prompt: str,
117
+ negative_prompt: str = "",
118
+ use_negative_prompt: bool = False,
119
+ style_selection: str = DEFAULT_STYLE_NAME,
120
+ seed: int = 1,
121
+ width: int = 1024,
122
+ height: int = 1024,
123
+ guidance_scale: float = 3,
124
+ num_inference_steps: int = 25,
125
+ randomize_seed: bool = False,
126
+ use_resolution_binning: bool = True,
127
+ num_images: int = 1,
128
+ progress=gr.Progress(track_tqdm=True),
129
+ ):
130
+ global models
131
+ pipe = models[model_choice]
132
+
133
+ seed = int(randomize_seed_fn(seed, randomize_seed))
134
+ generator = torch.Generator(device=device).manual_seed(seed)
135
 
136
+ prompt, negative_prompt = apply_style(style_selection, prompt, negative_prompt)
 
 
 
 
 
 
137
 
138
+ options = {
139
+ "prompt": [prompt] * num_images,
140
+ "negative_prompt": [negative_prompt] * num_images if use_negative_prompt else None,
141
+ "width": width,
142
+ "height": height,
143
+ "guidance_scale": guidance_scale,
144
+ "num_inference_steps": num_inference_steps,
145
+ "generator": generator,
146
+ "output_type": "pil",
147
+ }
148
+
149
+ if use_resolution_binning:
150
+ options["use_resolution_binning"] = True
151
+
152
+ images = []
153
+ for i in range(0, num_images, BATCH_SIZE):
154
+ batch_options = options.copy()
155
+ batch_options["prompt"] = options["prompt"][i:i+BATCH_SIZE]
156
+ if "negative_prompt" in batch_options:
157
+ batch_options["negative_prompt"] = options["negative_prompt"][i:i+BATCH_SIZE]
158
+ images.extend(pipe(**batch_options).images)
159
+
160
+ image_paths = [save_image(img) for img in images]
161
+ return image_paths, seed
162
+
163
+
164
+ with gr.Blocks(css=css, theme="bethecloud/storj_theme") as demo:
165
+ gr.Markdown(DESCRIPTIONXX)
166
+ with gr.Row():
167
+ prompt = gr.Text(
168
+ label="Prompt",
169
+ show_label=False,
170
+ max_lines=1,
171
+ placeholder="Enter your prompt",
172
+ container=False,
173
+ )
174
+ run_button = gr.Button("Run", scale=0)
175
+ result = gr.Gallery(label="Result", columns=1, show_label=False)
176
 
177
+ with gr.Row():
178
+ model_choice = gr.Dropdown(
179
+ label="Model Selection⬇️",
180
+ choices=list(MODEL_OPTIONS.keys()),
181
+ value="LENNOX-AI V2.0"
182
+ )
183
+
184
+ with gr.Accordion("Advanced options", open=False, visible=False):
185
+ style_selection = gr.Radio(
186
+ show_label=True,
187
+ container=True,
188
+ interactive=True,
189
+ choices=STYLE_NAMES,
190
+ value=DEFAULT_STYLE_NAME,
191
+ label="Quality Style",
192
+ )
193
+ num_images = gr.Slider(
194
+ label="Number of Images",
195
+ minimum=1,
196
+ maximum=5,
197
+ step=1,
198
+ value=1,
199
+ )
200
+ with gr.Row():
201
+ with gr.Column(scale=1):
202
+ use_negative_prompt = gr.Checkbox(label="Use negative prompt", value=True)
203
+ negative_prompt = gr.Text(
204
+ label="Negative prompt",
205
+ max_lines=5,
206
+ lines=4,
207
+ placeholder="Enter a negative prompt",
208
+ 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",
209
+ visible=True,
210
  )
211
+ seed = gr.Slider(
212
+ label="Seed",
213
+ minimum=0,
214
+ maximum=MAX_SEED,
215
+ step=1,
216
+ value=0,
217
+ )
218
+ randomize_seed = gr.Checkbox(label="Randomize seed", value=True)
219
+ with gr.Row():
220
+ width = gr.Slider(
221
+ label="Width",
222
+ minimum=512,
223
+ maximum=MAX_IMAGE_SIZE,
224
+ step=8,
225
+ value=1024,
226
+ )
227
+ height = gr.Slider(
228
+ label="Height",
229
+ minimum=512,
230
+ maximum=MAX_IMAGE_SIZE,
231
+ step=8,
232
+ value=1024,
233
+ )
234
+ with gr.Row():
235
+ guidance_scale = gr.Slider(
236
+ label="Guidance Scale",
237
+ minimum=0.1,
238
+ maximum=6,
239
+ step=0.1,
240
+ value=3.0,
241
+ )
242
+ num_inference_steps = gr.Slider(
243
+ label="Number of inference steps",
244
+ minimum=1,
245
+ maximum=60,
246
+ step=1,
247
+ value=28,
248
+ )
249
 
250
+ gr.Examples(
251
+ examples=examples,
252
+ inputs=prompt,
253
+ cache_examples=False
254
+ )
255
+
256
+ use_negative_prompt.change(
257
+ fn=lambda x: gr.update(visible=x),
258
+ inputs=use_negative_prompt,
259
+ outputs=negative_prompt,
260
+ api_name=False,
261
+ )
262
+
263
  gr.on(
264
+ triggers=[
265
+ prompt.submit,
266
+ negative_prompt.submit,
267
+ run_button.click,
268
+ ],
269
+ fn=generate,
270
  inputs=[
271
+ model_choice,
272
  prompt,
273
  negative_prompt,
274
+ use_negative_prompt,
275
+ style_selection,
276
  seed,
 
277
  width,
278
  height,
279
  guidance_scale,
280
  num_inference_steps,
281
+ randomize_seed,
282
+ num_images,
283
  ],
284
  outputs=[result, seed],
285
  )
286
 
287
+
288
+ #gr.Markdown("### Image Gallery")
289
+ #predefined_gallery = gr.Gallery(label="Image Gallery", columns=3, show_label=False, value=load_predefined_images())
290
+
291
+ gr.Markdown(
292
+ """
293
+ <div style="text-align: justify;">
294
+ 🖌️ Image Generation by Omindu Dissanayaka: Using LENNOX-AI V2.0 and LENNOX-AI V1.0 models for high-quality images. This demo space showcases image generation with the Stable Diffusion XL model variants, available for experimenting with different styles and models.
295
+ </div>
296
+ """
297
+ )
298
+
299
+ gr.Markdown(
300
+ """
301
+ <div style="text-align: justify;">
302
+ 🎨 Explore the demo space for Stable Diffusion XL, designed by Omindu Dissanayaka. Generate images with diverse styles and models for higher-quality results. Experiment with sample prompts to create unique, high-quality images.
303
+ </div>
304
+ """
305
+ )
306
+
307
+ gr.Markdown(
308
+ """
309
+ <div style="text-align: justify;">
310
+ ⚠️ Disclaimer: Users are responsible for ensuring that generated content complies with ethical standards.
311
+ </div>
312
+ """
313
+ )
314
+
315
+
316
  if __name__ == "__main__":
317
+ demo.queue(max_size=50).launch(show_api=True)