kayfahaarukku commited on
Commit
9443c74
·
verified ·
1 Parent(s): 5272b56

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +221 -106
app.py CHANGED
@@ -1,106 +1,206 @@
1
  import os
2
  import spaces
3
  import torch
4
- from diffusers import StableDiffusionPipeline, EulerAncestralDiscreteScheduler
 
 
5
  import gradio as gr
6
  import random
7
- import tqdm
8
- from huggingface_hub import hf_hub_download
9
- from transformers import CLIPTextModel, CLIPTokenizer
10
 
11
- # Enable TQDM progress tracking
12
- tqdm.monitor_interval = 0
 
13
 
14
- # Load the model from safetensors file
15
- def load_model():
16
- model_path = hf_hub_download(
17
- repo_id="kayfahaarukku/AkashicPulse-v1.0",
18
- filename="AkashicPulse-v1.0-ft-ft.safetensors"
19
- )
 
 
 
 
 
 
 
 
 
 
20
 
21
- # Initialize tokenizer and text encoder from standard SD 1.5
22
- tokenizer = CLIPTokenizer.from_pretrained("runwayml/stable-diffusion-v1-5", subfolder="tokenizer")
23
- text_encoder = CLIPTextModel.from_pretrained("runwayml/stable-diffusion-v1-5", subfolder="text_encoder")
 
24
 
25
- # Initialize pipeline with text encoder and tokenizer
26
- pipe = StableDiffusionPipeline.from_single_file(
27
- model_path,
28
- torch_dtype=torch.float16,
29
- use_safetensors=True,
30
- tokenizer=tokenizer,
31
- text_encoder=text_encoder,
32
- requires_safety_checker=False,
33
- safety_checker=None
34
- )
35
-
36
- pipe.scheduler = EulerAncestralDiscreteScheduler.from_config(pipe.scheduler.config)
37
- return pipe
 
 
 
38
 
39
- # Load the pipeline
40
- pipe = load_model()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
  # Function to generate an image
43
  @spaces.GPU
44
- def generate_image(prompt, negative_prompt, use_defaults, resolution, guidance_scale, num_inference_steps, seed, randomize_seed, progress=gr.Progress()):
45
- pipe.to('cuda')
46
-
 
 
 
 
 
 
 
 
 
 
 
 
47
  if randomize_seed:
48
- seed = random.randint(0, 99999999)
49
- if use_defaults:
50
- prompt = f"{prompt}, masterpiece, best quality"
51
- negative_prompt = f"lowres, bad anatomy, bad hands, text, error, missing fingers, extra digit, fewer digits, cropped, worst quality, low quality, signature, watermark, username, blurry, {negative_prompt}"
52
- generator = torch.manual_seed(seed)
 
53
 
54
- def callback(step, timestep, latents):
55
- progress(step / num_inference_steps)
56
- return
 
 
 
57
 
58
  width, height = map(int, resolution.split('x'))
59
 
60
- # Add empty dict for additional kwargs
61
- added_cond_kwargs = {"text_embeds": None, "time_ids": None}
 
 
 
 
 
 
 
 
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
- image, seed, metadata_text = generate_image(prompt, negative_prompt, use_defaults, resolution, guidance_scale, num_inference_steps, seed, randomize_seed, progress)
86
- return image, seed, gr.update(value=metadata_text)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  except Exception as e:
88
- print(f"Error generating image: {str(e)}")
89
- raise e
90
-
91
- def reset_inputs():
92
- return gr.update(value=''), gr.update(value=''), gr.update(value=True), gr.update(value='832x1216'), gr.update(value=7), gr.update(value=28), gr.update(value=0), gr.update(value=True), gr.update(value='')
 
93
 
94
- with gr.Blocks(title="AkashicPulse v1.0 Demo", theme="NoCrypt/[email protected]") as demo:
95
- gr.HTML(
96
- "<h1>AkashicPulse v1.0 Demo</h1>"
97
- "This demo showcases the AkashicPulse v1.0 model capabilities. For best results, it's recommended to run the model in Stable Diffusion WebUI or ComfyUI with MaHiRo CFG enabled."
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
- use_defaults_input = gr.Checkbox(label="Use Default Quality Tags and Negative Prompt", value=True)
 
 
 
 
 
 
 
 
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
- guidance_scale_input = gr.Slider(minimum=4, maximum=10, step=0.5, label="Guidance Scale (CFG)", value=7)
113
- num_inference_steps_input = gr.Slider(minimum=20, maximum=30, step=1, label="Number of Steps", value=28)
114
- seed_input = gr.Slider(minimum=0, maximum=999999999, step=1, label="Seed", value=0, interactive=True)
115
- randomize_seed_input = gr.Checkbox(label="Randomize Seed", value=True)
 
 
 
 
 
 
 
 
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.Markdown(
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
- **PS:** `masterpiece, best quality` is automatically added when "Use Default Quality Tags and Negative Prompt" is enabled
134
-
135
- ### Current settings (recommended):
136
- - Sampler: Euler a (fixed)
137
- - Steps: 20-30 (sweet spot: 28)
138
- - CFG: 4-10 (sweet spot: 7)
139
- - Optional: Enable MaHiRo CFG in reForge or ComfyUI
140
- """
141
- )
142
 
 
143
  generate_button.click(
144
- interface_fn,
145
  inputs=[
146
- prompt_input, negative_prompt_input, use_defaults_input, resolution_input, guidance_scale_input, num_inference_steps_input, seed_input, randomize_seed_input
 
 
 
 
 
 
 
 
 
 
 
147
  ],
148
  outputs=[output_image, seed_input, metadata_textbox]
149
  )
150
-
 
151
  reset_button.click(
152
- reset_inputs,
153
- inputs=[],
 
 
154
  outputs=[
155
- prompt_input, negative_prompt_input, use_defaults_input, resolution_input, guidance_scale_input, num_inference_steps_input, seed_input, randomize_seed_input, metadata_textbox
 
 
 
 
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