File size: 11,017 Bytes
57218c8
0edd51d
 
 
d5cdaf8
0edd51d
 
 
 
 
8a50ffc
793156d
d49eeee
57218c8
 
d5cdaf8
 
d49eeee
57218c8
fabbd5e
0edd51d
d5cdaf8
0edd51d
 
41548b6
89539f7
 
0edd51d
89539f7
0edd51d
 
 
 
 
 
5b8ee78
8a50ffc
89539f7
57218c8
89539f7
 
 
 
 
 
d8fa9a9
57218c8
b6711e8
d49eeee
d5cdaf8
099787c
d5cdaf8
d49eeee
52ca30c
d49eeee
d5cdaf8
57218c8
41548b6
d5cdaf8
57218c8
099787c
57218c8
 
099787c
57218c8
 
 
 
 
4dc3375
57218c8
 
 
 
a74433e
 
 
 
 
 
 
 
4dc3375
57218c8
d49eeee
57218c8
 
099787c
 
 
 
 
 
 
 
 
 
 
f8301d9
20eb88b
 
 
 
 
 
3a88736
0c0b5eb
2fe4fe9
4bf44b8
3a88736
7e9d235
cc1cae8
229d8d7
cc1cae8
3ab9228
f864b44
bfe822e
65e21e2
099787c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51faa3e
 
 
0c2dc83
51faa3e
 
 
 
0edd51d
 
d5cdaf8
89539f7
0edd51d
 
4d87d48
0edd51d
89539f7
 
 
f864b44
7b0f2e1
5cfd0a4
 
89539f7
4fc5e3b
4612ee1
ef2ac8b
 
 
 
 
 
 
 
 
 
 
 
 
 
099787c
89539f7
d5cdaf8
 
89539f7
 
0c2dc83
89539f7
 
099787c
4fc5e3b
 
 
 
0aacca4
 
4fc5e3b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0edd51d
 
 
 
 
 
 
57218c8
 
 
099787c
57218c8
 
 
b6711e8
099787c
 
 
0edd51d
 
 
099787c
 
 
 
57218c8
 
 
0edd51d
59bd43d
 
 
 
 
 
0edd51d
 
 
 
 
 
 
59bd43d
 
 
 
 
 
 
 
 
57218c8
b6711e8
d49eeee
1ea0405
099787c
41548b6
d49eeee
52ca30c
d49eeee
59bd43d
0edd51d
89539f7
0edd51d
89539f7
 
57218c8
1
2
3
4
5
6
7
8
9
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
#!/usr/bin/env python

from __future__ import annotations

import requests
import os
import random

import gradio as gr
import numpy as np
import spaces
import torch
import cv2
import xformers
import triton
from PIL import Image
from io import BytesIO
from diffusers.utils import load_image
from diffusers import StableDiffusionXLControlNetPipeline, StableDiffusionXLControlNetInpaintPipeline, ControlNetModel, AutoencoderKL, DiffusionPipeline, AutoPipelineForImage2Image, AutoPipelineForInpainting, EulerDiscreteScheduler, DPMSolverMultistepScheduler

if not torch.cuda.is_available():
    DESCRIPTION += "\n<p>⚠️ This space is running on the CPU. This demo doesn't work on CPU 😞! Run on a GPU by duplicating this space or test our website for free and unlimited by <a href='https://squaadai.com'>clicking here</a>, which provides these and more options.</p>"

MAX_SEED = np.iinfo(np.int32).max
MAX_IMAGE_SIZE = int(os.getenv("MAX_IMAGE_SIZE", "1824"))
USE_TORCH_COMPILE = os.getenv("USE_TORCH_COMPILE") == "1"
ENABLE_CPU_OFFLOAD = os.getenv("ENABLE_CPU_OFFLOAD") == "1"

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

def randomize_seed_fn(seed: int, randomize_seed: bool) -> int:
    if randomize_seed:
        seed = random.randint(0, MAX_SEED)
    return seed


@spaces.GPU
def generate(
    prompt: str,
    negative_prompt: str = "",
    use_negative_prompt: bool = False,
    seed: int = 0,
    width: int = 1024,
    height: int = 1024,
    guidance_scale_base: float = 5.0,
    num_inference_steps_base: int = 25,
    use_vae: bool = False,
    use_lora: bool = False,
    use_lora2: bool = False,
    model = 'stabilityai/stable-diffusion-xl-base-1.0',
    vaemodel = 'madebyollin/sdxl-vae-fp16-fix',
    lora = '',
    lora2 = '',
    lora_scale: float = 0.7,
    lora_scale2: float = 0.7,
    use_img2img: bool = False,
):
    if torch.cuda.is_available():

        if not use_img2img:
            pipe = DiffusionPipeline.from_pretrained(model, torch_dtype=torch.float16)
            
            if use_vae:  
                vae = AutoencoderKL.from_pretrained(vaemodel, torch_dtype=torch.float16)
                pipe = DiffusionPipeline.from_pretrained(model, vae=vae, torch_dtype=torch.float16)
                
        if use_lora:
            pipe.load_lora_weights(lora)
            pipe.fuse_lora(lora_scale)
        
        if use_lora2:
            pipe.load_lora_weights(lora, adapter_name="1")
            pipe.load_lora_weights(lora2, adapter_name="2")
            pipe.set_adapters(["1", "2"], adapter_weights=[lora_scale, lora_scale2])

    if ENABLE_CPU_OFFLOAD:
        pipe.enable_model_cpu_offload()
    else:
        pipe.to(device)

    if USE_TORCH_COMPILE:
        pipe.unet = torch.compile(pipe.unet, mode="reduce-overhead", fullgraph=True)
            
    generator = torch.Generator().manual_seed(seed)
    
    if not use_negative_prompt:
        negative_prompt = None  # type: ignore
        
    return pipe(
        prompt=prompt,
        negative_prompt=negative_prompt,
        width=width,
        height=height,
        guidance_scale=guidance_scale_base,
        num_inference_steps=num_inference_steps_base,
        generator=generator,
        output_type="pil",
    ).images[0]

theme = gr.themes.Monochrome(
    text_size=gr.themes.Size(lg="18px", md="15px", sm="13px", xl="22px", xs="12px", xxl="24px", xxs="9px"),
    font=[gr.themes.GoogleFont('Source Sans Pro'), 'ui-sans-serif', 'system-ui', 'sans-serif'],
)

with gr.Blocks(theme=theme, css="style.css") as demo:
    gr.HTML()
    gr.Markdown("""# Squaad AI πŸ§™
### Run Stable Diffusion for free, in seconds
<small>Squaad AI was a free Artificial Intelligence website that brought together the best of the AI world in one place. Unfortunately, it had to temporarily cease operations after encountering compatibility issues. While it makes its comeback, this account sponsored by Hugging Face aims to make parts of its legacy available as open-source code and enable anyone to run SD easily and for free. We are currently adapting Squaad AI for Gradio... Controlnet, Img2Img, and Inpaint coming soon.</small> 

<div style="display: flex; flex-direction: column; align-items: flex-start;">
    <a target="_blank" href="https://discord.gg/CqXVwGDqFC"><img src="https://img.shields.io/badge/discord-join%20now-blue.svg?logo=discord" alt="discord.gg/CqXVwGDqFC"></a>
    <a href="https://www.buymeacoffee.com/squaadai" target="_blank" style="margin-top: 10px;"><img src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" alt="Buy Me A Coffee" style="height: auto !important;width: 130px !important;" ></a>
</div>""", elem_id="main_title")
    
    with gr.Group():
        model = gr.Text(label='Model', value='stabilityai/stable-diffusion-xl-base-1.0', placeholder='e.g. stabilityai/stable-diffusion-xl-base-1.0', info='Enter the HUB path for this model! The model must be converted to diffusers to work. We recommend SG161222/RealVisXL_V4.0 for realistic generations, for example. By default, SDXL 1.0 (stabilityai/stable-diffusion-xl-base-1.0) will be used.')
        vaemodel = gr.Text(label='VAE', placeholder='e.g. madebyollin/sdxl-vae-fp16-fix', info='You can use the VAE that suits you best! Using an unfamiliar VAE or one that is not from the same base model mentioned above will result in errors or distorted images. You must enable "Use VAE" in advanced settings if you want to use a VAE.', visible=False)
        with gr.Row():
            width = gr.Slider(
                label="Width",
                minimum=256,
                maximum=MAX_IMAGE_SIZE,
                step=32,
                value=1024,
            )
            height = gr.Slider(
                label="Height",
                minimum=256,
                maximum=MAX_IMAGE_SIZE,
                step=32,
                value=1024,
            )
        num_inference_steps_base = gr.Slider(
                info="Number of denoising steps",
                label="Number of inference steps",
                minimum=1,
                maximum=100,
                step=1,
                value=25,
            )
        with gr.Row():
            prompt = gr.Text(
                placeholder="Input prompt",
                label="Prompt",
                show_label=False,
                max_lines=1,
                container=False,
            )
            run_button = gr.Button("Run", scale=0)
        result = gr.Image(label="Result", show_label=False)
    with gr.Accordion("Advanced options", open=False):
        with gr.Row():
            use_vae = gr.Checkbox(label='Use VAE', value=False)
            use_lora = gr.Checkbox(label='Use 1 LoRA', value=False)
            use_lora2 = gr.Checkbox(label='Use 2 LoRAs', value=False)
            use_negative_prompt = gr.Checkbox(label="Use negative prompt", value=False)

        with gr.Group():
            negative_prompt = gr.Text(
                placeholder="Input Negative Prompt",
                label="Negative prompt",
                max_lines=1,
                visible=False,
            )
            seed = gr.Slider(
                label="Seed",
                minimum=0,
                maximum=MAX_SEED,
                step=1,
                value=0,
            )
            randomize_seed = gr.Checkbox(label="Randomize seed", value=True)
        with gr.Group():
            guidance_scale_base = gr.Slider(
                info="Scale for classifier-free guidance",
                label="Guidance scale",
                minimum=1,
                maximum=20,
                step=0.01,
                value=5.0,
            )
            
        with gr.Group():
            gr.Markdown("""### LoRAs
                        <small>To activate the use of LoRAs, you should check only the 'Use 1 LoRA' checkbox if you want to use just one LoRA, and only the 'Use 2 LoRAs' checkbox if you want to use 2 LoRAs (i.e., blend styles)! It's important that all LoRAs are from the same base version of the selected model. For example, if the model is SDXL 1.0, the LoRA must also be.</small>"""
                       )
            lora = gr.Text(label='LoRA 1', info='Make sure you are using the configured trigger word for the chosen LoRA, otherwise the style, person, object, animal... may not be applied correctly', placeholder='e.g. nerijs/pixel-art-xl', visible=False)
            lora2 = gr.Text(label='LoRA 2', info='Make sure you are using the configured trigger word for the chosen LoRA, otherwise the style, person, object, animal... may not be applied correctly', placeholder='e.g. nerijs/pixel-art-xl', visible=False)
            lora_scale = gr.Slider(
                info="The closer to 1, the more it will resemble LoRA, but errors may be visible.",
                label="Lora Scale 1",
                minimum=0.01,
                maximum=1,
                step=0.01,
                value=0.7,
                visible=False,
                )
            lora_scale2 = gr.Slider(
                info="The closer to 1, the more it will resemble LoRA, but errors may be visible.",
                label="Lora Scale 2",
                minimum=0.01,
                maximum=1,
                step=0.01,
                value=0.7,
                visible=False,
                )
            
    use_negative_prompt.change(
        fn=lambda x: gr.update(visible=x),
        inputs=use_negative_prompt,
        outputs=negative_prompt,
        queue=False,
        api_name=False,
    )
    use_vae.change(
        fn=lambda x: gr.update(visible=x),
        inputs=use_vae,
        outputs=vaemodel,
        queue=False,
        api_name=False,
    )
    use_lora.change(
        fn=lambda x: [gr.update(visible=x), gr.update(visible=x)],
        inputs=use_lora,
        outputs=[lora, lora_scale],
        queue=False,
        api_name=False,
    )
    use_lora2.change(
        fn=lambda x: [gr.update(visible=x), gr.update(visible=x), gr.update(visible=x), gr.update(visible=x)],
        inputs=use_lora2,
        outputs=[lora, lora2, lora_scale, lora_scale2],
        queue=False,
        api_name=False,
    )

    gr.on(
        triggers=[
            prompt.submit,
            negative_prompt.submit,
            run_button.click,
        ],
        fn=randomize_seed_fn,
        inputs=[seed, randomize_seed],
        outputs=seed,
        queue=False,
        api_name=False,
    ).then(
        fn=generate,
        inputs=[
            prompt,
            negative_prompt,
            use_negative_prompt,
            seed,
            width,
            height,
            guidance_scale_base,
            num_inference_steps_base,
            use_vae,
            use_lora,
            use_lora2,
            model,
            vaemodel,
            lora,
            lora2,
            lora_scale,
            lora_scale2,
        ],
        outputs=result,
        api_name="run",
    )

if __name__ == "__main__":
    demo.queue(max_size=20).launch()