Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
@@ -1,106 +1,206 @@
|
|
1 |
import os
|
2 |
import spaces
|
3 |
import torch
|
4 |
-
|
|
|
|
|
5 |
import gradio as gr
|
6 |
import random
|
7 |
-
import
|
8 |
-
from
|
9 |
-
from transformers import CLIPTextModel, CLIPTokenizer
|
10 |
|
11 |
-
#
|
12 |
-
|
|
|
13 |
|
14 |
-
#
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
|
21 |
-
#
|
22 |
-
|
23 |
-
|
|
|
24 |
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
|
|
|
|
|
|
38 |
|
39 |
-
#
|
40 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
|
42 |
# Function to generate an image
|
43 |
@spaces.GPU
|
44 |
-
def generate_image(
|
45 |
-
|
46 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
if randomize_seed:
|
48 |
-
seed = random.randint(0,
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
|
|
53 |
|
54 |
-
|
55 |
-
|
56 |
-
|
|
|
|
|
|
|
57 |
|
58 |
width, height = map(int, resolution.split('x'))
|
59 |
|
60 |
-
|
61 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
|
63 |
-
image = pipe(
|
64 |
-
prompt,
|
65 |
-
negative_prompt=negative_prompt,
|
66 |
-
width=width,
|
67 |
-
height=height,
|
68 |
-
guidance_scale=guidance_scale,
|
69 |
-
num_inference_steps=num_inference_steps,
|
70 |
-
generator=generator,
|
71 |
-
callback=callback,
|
72 |
-
callback_steps=1,
|
73 |
-
added_cond_kwargs=added_cond_kwargs
|
74 |
-
).images[0]
|
75 |
-
|
76 |
-
torch.cuda.empty_cache()
|
77 |
-
|
78 |
-
metadata_text = f"{prompt}\nNegative prompt: {negative_prompt}\nSteps: {num_inference_steps}, Sampler: Euler a, Size: {width}x{height}, Seed: {seed}, CFG scale: {guidance_scale}"
|
79 |
-
|
80 |
-
return image, seed, metadata_text
|
81 |
-
|
82 |
-
# Define Gradio interface
|
83 |
-
def interface_fn(prompt, negative_prompt, use_defaults, resolution, guidance_scale, num_inference_steps, seed, randomize_seed, progress=gr.Progress()):
|
84 |
try:
|
85 |
-
|
86 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
except Exception as e:
|
88 |
-
|
89 |
-
raise
|
90 |
-
|
91 |
-
|
92 |
-
|
|
|
93 |
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
)
|
99 |
with gr.Row():
|
100 |
with gr.Column():
|
101 |
prompt_input = gr.Textbox(lines=2, placeholder="Enter prompt here", label="Prompt")
|
102 |
negative_prompt_input = gr.Textbox(lines=2, placeholder="Enter negative prompt here", label="Negative Prompt")
|
103 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
104 |
resolution_input = gr.Radio(
|
105 |
choices=[
|
106 |
"1024x1024", "1152x896", "896x1152", "1216x832", "832x1216",
|
@@ -109,50 +209,65 @@ with gr.Blocks(title="AkashicPulse v1.0 Demo", theme="NoCrypt/[email protected]") as de
|
|
109 |
label="Resolution",
|
110 |
value="832x1216"
|
111 |
)
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
116 |
generate_button = gr.Button("Generate")
|
117 |
reset_button = gr.Button("Reset")
|
118 |
|
119 |
with gr.Column():
|
120 |
output_image = gr.Image(type="pil", label="Generated Image")
|
121 |
with gr.Accordion("Parameters", open=False):
|
122 |
-
gr.
|
123 |
-
"""
|
124 |
-
This parameter is compatible with Stable Diffusion WebUI's parameter importer.
|
125 |
-
"""
|
126 |
-
)
|
127 |
-
metadata_textbox = gr.Textbox(lines=6, label="Image Parameters", interactive=False, max_lines=6)
|
128 |
-
gr.Markdown(
|
129 |
-
"""
|
130 |
-
### Recommended prompt formatting:
|
131 |
-
`1girl/1boy, character name, series, by artist name, the rest of the prompt, masterpiece, best quality`
|
132 |
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
- Optional: Enable MaHiRo CFG in reForge or ComfyUI
|
140 |
-
"""
|
141 |
-
)
|
142 |
|
|
|
143 |
generate_button.click(
|
144 |
-
|
145 |
inputs=[
|
146 |
-
prompt_input,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
147 |
],
|
148 |
outputs=[output_image, seed_input, metadata_textbox]
|
149 |
)
|
150 |
-
|
|
|
151 |
reset_button.click(
|
152 |
-
|
153 |
-
|
|
|
|
|
154 |
outputs=[
|
155 |
-
prompt_input, negative_prompt_input,
|
|
|
|
|
|
|
|
|
156 |
]
|
157 |
)
|
158 |
|
|
|
1 |
import os
|
2 |
import spaces
|
3 |
import torch
|
4 |
+
import json
|
5 |
+
import logging
|
6 |
+
from diffusers import StableDiffusionXLPipeline, EulerAncestralDiscreteScheduler, StableDiffusionXLImg2ImgPipeline, AutoencoderKL
|
7 |
import gradio as gr
|
8 |
import random
|
9 |
+
from datetime import datetime
|
10 |
+
from PIL import Image, PngImagePlugin
|
|
|
11 |
|
12 |
+
# Setup logging
|
13 |
+
logging.basicConfig(level=logging.INFO)
|
14 |
+
logger = logging.getLogger(__name__)
|
15 |
|
16 |
+
# Configuration
|
17 |
+
OUTPUT_DIR = os.getenv("OUTPUT_DIR", "./outputs")
|
18 |
+
MAX_SEED = 2**32 - 1
|
19 |
+
|
20 |
+
def seed_everything(seed):
|
21 |
+
if seed is None:
|
22 |
+
seed = random.randint(0, MAX_SEED)
|
23 |
+
torch.manual_seed(seed)
|
24 |
+
random.seed(seed)
|
25 |
+
return torch.Generator(device='cuda').manual_seed(seed)
|
26 |
+
|
27 |
+
def save_image(image, metadata, output_dir, is_colab=False):
|
28 |
+
os.makedirs(output_dir, exist_ok=True)
|
29 |
+
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
30 |
+
filename = f"generated_{timestamp}.png"
|
31 |
+
filepath = os.path.join(output_dir, filename)
|
32 |
|
33 |
+
# Save with metadata
|
34 |
+
png_info = PngImagePlugin.PngInfo()
|
35 |
+
png_info.add_text("parameters", json.dumps(metadata))
|
36 |
+
image.save(filepath, "PNG", pnginfo=png_info)
|
37 |
|
38 |
+
return filepath
|
39 |
+
|
40 |
+
# Load the diffusion pipeline with optimized VAE
|
41 |
+
pipe = StableDiffusionXLPipeline.from_pretrained(
|
42 |
+
"kayfahaarukku/irAsu-1.0",
|
43 |
+
torch_dtype=torch.float16,
|
44 |
+
custom_pipeline="lpw_stable_diffusion_xl",
|
45 |
+
)
|
46 |
+
|
47 |
+
# Load optimized VAE
|
48 |
+
vae = AutoencoderKL.from_pretrained(
|
49 |
+
"madebyollin/sdxl-vae-fp16-fix",
|
50 |
+
torch_dtype=torch.float16,
|
51 |
+
)
|
52 |
+
pipe.vae = vae
|
53 |
+
pipe.scheduler = EulerAncestralDiscreteScheduler.from_config(pipe.scheduler.config)
|
54 |
|
55 |
+
# Style presets
|
56 |
+
styles = {
|
57 |
+
"(None)": ("", ""),
|
58 |
+
"Detailed": ("highly detailed, intricate details, ", ""),
|
59 |
+
"Simple": ("simple style, minimalistic, ", "complex, detailed"),
|
60 |
+
"Soft": ("soft lighting, dreamy atmosphere, ", "harsh lighting, sharp contrast"),
|
61 |
+
}
|
62 |
+
|
63 |
+
# Quality presets
|
64 |
+
quality_presets = {
|
65 |
+
"Standard": (
|
66 |
+
"best quality, amazing quality, very aesthetic",
|
67 |
+
"nsfw, lowres, (bad), text, error, fewer, extra, missing, worst quality, jpeg artifacts"
|
68 |
+
),
|
69 |
+
"High Detail": (
|
70 |
+
"masterpiece, best quality, amazing quality, very aesthetic, highly detailed",
|
71 |
+
"nsfw, lowres, (bad), text, error, fewer, extra, missing, worst quality, jpeg artifacts, low quality"
|
72 |
+
),
|
73 |
+
"Basic": (
|
74 |
+
"good quality",
|
75 |
+
"nsfw, lowres, bad quality"
|
76 |
+
)
|
77 |
+
}
|
78 |
|
79 |
# Function to generate an image
|
80 |
@spaces.GPU
|
81 |
+
def generate_image(
|
82 |
+
prompt,
|
83 |
+
negative_prompt,
|
84 |
+
use_quality_preset,
|
85 |
+
resolution,
|
86 |
+
guidance_scale,
|
87 |
+
num_inference_steps,
|
88 |
+
seed,
|
89 |
+
randomize_seed,
|
90 |
+
style_preset="(None)",
|
91 |
+
use_upscaler=False,
|
92 |
+
upscaler_strength=0.55,
|
93 |
+
upscale_by=1.5,
|
94 |
+
progress=gr.Progress()
|
95 |
+
):
|
96 |
if randomize_seed:
|
97 |
+
seed = random.randint(0, MAX_SEED)
|
98 |
+
|
99 |
+
# Apply style preset
|
100 |
+
style_prompt, style_negative = styles[style_preset]
|
101 |
+
prompt = f"{style_prompt}{prompt}"
|
102 |
+
negative_prompt = f"{negative_prompt}, {style_negative}" if style_negative else negative_prompt
|
103 |
|
104 |
+
if use_quality_preset:
|
105 |
+
quality_prompt, quality_negative = quality_presets["Standard"]
|
106 |
+
prompt = f"{prompt}, {quality_prompt}"
|
107 |
+
negative_prompt = f"{negative_prompt}, {quality_negative}"
|
108 |
+
|
109 |
+
generator = seed_everything(seed)
|
110 |
|
111 |
width, height = map(int, resolution.split('x'))
|
112 |
|
113 |
+
metadata = {
|
114 |
+
"prompt": prompt,
|
115 |
+
"negative_prompt": negative_prompt,
|
116 |
+
"resolution": f"{width} x {height}",
|
117 |
+
"guidance_scale": guidance_scale,
|
118 |
+
"num_inference_steps": num_inference_steps,
|
119 |
+
"seed": seed,
|
120 |
+
"style_preset": style_preset,
|
121 |
+
"use_quality_preset": use_quality_preset
|
122 |
+
}
|
123 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
124 |
try:
|
125 |
+
if use_upscaler:
|
126 |
+
# Initial generation
|
127 |
+
latents = pipe(
|
128 |
+
prompt,
|
129 |
+
negative_prompt=negative_prompt,
|
130 |
+
width=width,
|
131 |
+
height=height,
|
132 |
+
guidance_scale=guidance_scale,
|
133 |
+
num_inference_steps=num_inference_steps,
|
134 |
+
generator=generator,
|
135 |
+
output_type="latent"
|
136 |
+
).images
|
137 |
+
|
138 |
+
# Setup img2img pipeline for upscaling
|
139 |
+
upscaler_pipe = StableDiffusionXLImg2ImgPipeline(**pipe.components)
|
140 |
+
|
141 |
+
# Calculate new dimensions
|
142 |
+
new_width = int(width * upscale_by)
|
143 |
+
new_height = int(height * upscale_by)
|
144 |
+
|
145 |
+
# Upscale
|
146 |
+
image = upscaler_pipe(
|
147 |
+
prompt=prompt,
|
148 |
+
negative_prompt=negative_prompt,
|
149 |
+
image=latents,
|
150 |
+
strength=upscaler_strength,
|
151 |
+
guidance_scale=guidance_scale,
|
152 |
+
num_inference_steps=num_inference_steps,
|
153 |
+
generator=generator
|
154 |
+
).images[0]
|
155 |
+
|
156 |
+
metadata["upscaler"] = {
|
157 |
+
"strength": upscaler_strength,
|
158 |
+
"scale_factor": upscale_by,
|
159 |
+
"final_resolution": f"{new_width}x{new_height}"
|
160 |
+
}
|
161 |
+
else:
|
162 |
+
image = pipe(
|
163 |
+
prompt,
|
164 |
+
negative_prompt=negative_prompt,
|
165 |
+
width=width,
|
166 |
+
height=height,
|
167 |
+
guidance_scale=guidance_scale,
|
168 |
+
num_inference_steps=num_inference_steps,
|
169 |
+
generator=generator,
|
170 |
+
callback=lambda step, timestep, latents: progress(step / num_inference_steps)
|
171 |
+
).images[0]
|
172 |
+
|
173 |
+
# Save image with metadata
|
174 |
+
image_path = save_image(image, metadata, OUTPUT_DIR)
|
175 |
+
logger.info(f"Image saved as {image_path} with metadata")
|
176 |
+
|
177 |
+
return image, seed, json.dumps(metadata, indent=2)
|
178 |
+
|
179 |
except Exception as e:
|
180 |
+
logger.exception(f"An error occurred: {e}")
|
181 |
+
raise
|
182 |
+
finally:
|
183 |
+
if use_upscaler:
|
184 |
+
del upscaler_pipe
|
185 |
+
torch.cuda.empty_cache()
|
186 |
|
187 |
+
# Define Gradio interface
|
188 |
+
with gr.Blocks(title="irAsu 1.0 Enhanced Demo", theme="NoCrypt/[email protected]") as demo:
|
189 |
+
gr.HTML("<h1>irAsu 1.0 Enhanced Demo</h1>")
|
190 |
+
|
|
|
191 |
with gr.Row():
|
192 |
with gr.Column():
|
193 |
prompt_input = gr.Textbox(lines=2, placeholder="Enter prompt here", label="Prompt")
|
194 |
negative_prompt_input = gr.Textbox(lines=2, placeholder="Enter negative prompt here", label="Negative Prompt")
|
195 |
+
|
196 |
+
with gr.Accordion("Style & Quality", open=True):
|
197 |
+
style_selector = gr.Radio(
|
198 |
+
choices=list(styles.keys()),
|
199 |
+
value="(None)",
|
200 |
+
label="Style Preset"
|
201 |
+
)
|
202 |
+
use_quality_preset = gr.Checkbox(label="Use Quality Preset", value=True)
|
203 |
+
|
204 |
resolution_input = gr.Radio(
|
205 |
choices=[
|
206 |
"1024x1024", "1152x896", "896x1152", "1216x832", "832x1216",
|
|
|
209 |
label="Resolution",
|
210 |
value="832x1216"
|
211 |
)
|
212 |
+
|
213 |
+
with gr.Accordion("Advanced Settings", open=False):
|
214 |
+
guidance_scale_input = gr.Slider(minimum=1, maximum=20, step=0.5, label="Guidance Scale", value=4)
|
215 |
+
num_inference_steps_input = gr.Slider(minimum=1, maximum=100, step=1, label="Number of Inference Steps", value=28)
|
216 |
+
seed_input = gr.Slider(minimum=0, maximum=MAX_SEED, step=1, label="Seed", value=0)
|
217 |
+
randomize_seed_input = gr.Checkbox(label="Randomize Seed", value=True)
|
218 |
+
|
219 |
+
use_upscaler_input = gr.Checkbox(label="Use Upscaler", value=False)
|
220 |
+
with gr.Group(visible=False) as upscaler_settings:
|
221 |
+
upscaler_strength_input = gr.Slider(minimum=0, maximum=1, step=0.05, label="Upscaler Strength", value=0.55)
|
222 |
+
upscale_by_input = gr.Slider(minimum=1, maximum=1.5, step=0.1, label="Upscale Factor", value=1.5)
|
223 |
+
|
224 |
generate_button = gr.Button("Generate")
|
225 |
reset_button = gr.Button("Reset")
|
226 |
|
227 |
with gr.Column():
|
228 |
output_image = gr.Image(type="pil", label="Generated Image")
|
229 |
with gr.Accordion("Parameters", open=False):
|
230 |
+
metadata_textbox = gr.Textbox(lines=6, label="Image Parameters", interactive=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
231 |
|
232 |
+
# Handle upscaler visibility
|
233 |
+
use_upscaler_input.change(
|
234 |
+
fn=lambda x: gr.Group(visible=x),
|
235 |
+
inputs=[use_upscaler_input],
|
236 |
+
outputs=[upscaler_settings]
|
237 |
+
)
|
|
|
|
|
|
|
238 |
|
239 |
+
# Generate button click event
|
240 |
generate_button.click(
|
241 |
+
generate_image,
|
242 |
inputs=[
|
243 |
+
prompt_input,
|
244 |
+
negative_prompt_input,
|
245 |
+
use_quality_preset,
|
246 |
+
resolution_input,
|
247 |
+
guidance_scale_input,
|
248 |
+
num_inference_steps_input,
|
249 |
+
seed_input,
|
250 |
+
randomize_seed_input,
|
251 |
+
style_selector,
|
252 |
+
use_upscaler_input,
|
253 |
+
upscaler_strength_input,
|
254 |
+
upscale_by_input
|
255 |
],
|
256 |
outputs=[output_image, seed_input, metadata_textbox]
|
257 |
)
|
258 |
+
|
259 |
+
# Reset button click event
|
260 |
reset_button.click(
|
261 |
+
lambda: (
|
262 |
+
"", "", True, "832x1216", 4, 28, 0, True,
|
263 |
+
"(None)", False, 0.55, 1.5, None
|
264 |
+
),
|
265 |
outputs=[
|
266 |
+
prompt_input, negative_prompt_input, use_quality_preset,
|
267 |
+
resolution_input, guidance_scale_input, num_inference_steps_input,
|
268 |
+
seed_input, randomize_seed_input, style_selector,
|
269 |
+
use_upscaler_input, upscaler_strength_input, upscale_by_input,
|
270 |
+
metadata_textbox
|
271 |
]
|
272 |
)
|
273 |
|