ClaireOzzz commited on
Commit
44effca
1 Parent(s): 6cc3d67

added sdxl

Browse files
sdxl/.gitattributes ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
sdxl/README.md ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: SD-XL + Control LoRas
3
+ emoji: 🦀
4
+ colorFrom: green
5
+ colorTo: indigo
6
+ sdk: gradio
7
+ sdk_version: 3.44.4
8
+ app_file: app.py
9
+ pinned: false
10
+ ---
11
+
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
sdxl/app_inference.py ADDED
@@ -0,0 +1,363 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from huggingface_hub import login, HfFileSystem, HfApi, ModelCard
3
+ import os
4
+ import spaces
5
+ import random
6
+ import torch
7
+
8
+ is_shared_ui = False
9
+
10
+ hf_token = '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'
11
+ login(token=hf_token)
12
+
13
+ fs = HfFileSystem(token=hf_token)
14
+ api = HfApi()
15
+
16
+ device="cuda" if torch.cuda.is_available() else "cpu"
17
+
18
+ from diffusers import ControlNetModel, StableDiffusionXLControlNetPipeline, AutoencoderKL
19
+ from diffusers.utils import load_image
20
+ from PIL import Image
21
+ import torch
22
+ import numpy as np
23
+ import cv2
24
+
25
+ vae = AutoencoderKL.from_pretrained("madebyollin/sdxl-vae-fp16-fix", torch_dtype=torch.float16)
26
+
27
+ controlnet = ControlNetModel.from_pretrained(
28
+ "diffusers/controlnet-canny-sdxl-1.0",
29
+ torch_dtype=torch.float16
30
+ )
31
+
32
+ def check_use_custom_or_no(value):
33
+ if value is True:
34
+ return gr.update(visible=True)
35
+ else:
36
+ return gr.update(visible=False)
37
+
38
+ def get_files(file_paths):
39
+ last_files = {} # Dictionary to store the last file for each path
40
+
41
+ for file_path in file_paths:
42
+ # Split the file path into directory and file components
43
+ directory, file_name = file_path.rsplit('/', 1)
44
+
45
+ # Update the last file for the current path
46
+ last_files[directory] = file_name
47
+
48
+ # Extract the last files from the dictionary
49
+ result = list(last_files.values())
50
+
51
+ return result
52
+
53
+ def load_model(model_name):
54
+
55
+ if model_name == "":
56
+ gr.Warning("If you want to use a private model, you need to duplicate this space on your personal account.")
57
+ raise gr.Error("You forgot to define Model ID.")
58
+
59
+ # Get instance_prompt a.k.a trigger word
60
+ card = ModelCard.load(model_name)
61
+ repo_data = card.data.to_dict()
62
+ instance_prompt = repo_data.get("instance_prompt")
63
+
64
+ if instance_prompt is not None:
65
+ print(f"Trigger word: {instance_prompt}")
66
+ else:
67
+ instance_prompt = "no trigger word needed"
68
+ print(f"Trigger word: no trigger word needed")
69
+
70
+ # List all ".safetensors" files in repo
71
+ sfts_available_files = fs.glob(f"{model_name}/*safetensors")
72
+ sfts_available_files = get_files(sfts_available_files)
73
+
74
+ if sfts_available_files == []:
75
+ sfts_available_files = ["NO SAFETENSORS FILE"]
76
+
77
+ print(f"Safetensors available: {sfts_available_files}")
78
+
79
+ return model_name, "Model Ready", gr.update(choices=sfts_available_files, value=sfts_available_files[0], visible=True), gr.update(value=instance_prompt, visible=True)
80
+
81
+ def custom_model_changed(model_name, previous_model):
82
+ if model_name == "" and previous_model == "" :
83
+ status_message = ""
84
+ elif model_name != previous_model:
85
+ status_message = "model changed, please reload before any new run"
86
+ else:
87
+ status_message = "model ready"
88
+ return status_message
89
+
90
+ def resize_image(input_path, output_path, target_height):
91
+ # Open the input image
92
+ img = Image.open(input_path)
93
+
94
+ # Calculate the aspect ratio of the original image
95
+ original_width, original_height = img.size
96
+ original_aspect_ratio = original_width / original_height
97
+
98
+ # Calculate the new width while maintaining the aspect ratio and the target height
99
+ new_width = int(target_height * original_aspect_ratio)
100
+
101
+ # Resize the image while maintaining the aspect ratio and fixing the height
102
+ img = img.resize((new_width, target_height), Image.LANCZOS)
103
+
104
+ # Save the resized image
105
+ img.save(output_path)
106
+
107
+ return output_path
108
+
109
+ @spaces.GPU
110
+ def infer(use_custom_model, model_name, weight_name, custom_lora_weight, image_in, prompt, negative_prompt, preprocessor, controlnet_conditioning_scale, guidance_scale, inf_steps, seed, progress=gr.Progress(track_tqdm=True)):
111
+
112
+ pipe = StableDiffusionXLControlNetPipeline.from_pretrained(
113
+ "stabilityai/stable-diffusion-xl-base-1.0",
114
+ controlnet=controlnet,
115
+ vae=vae,
116
+ torch_dtype=torch.float16,
117
+ variant="fp16",
118
+ use_safetensors=True
119
+ )
120
+
121
+ pipe.to(device)
122
+
123
+ prompt = prompt
124
+ negative_prompt = negative_prompt
125
+
126
+ if seed < 0 :
127
+ seed = random.randint(0, 423538377342)
128
+
129
+ generator = torch.Generator(device=device).manual_seed(seed)
130
+
131
+ if image_in == None:
132
+ raise gr.Error("You forgot to upload a source image.")
133
+
134
+ image_in = resize_image(image_in, "resized_input.jpg", 1024)
135
+
136
+ if preprocessor == "canny":
137
+
138
+ image = load_image(image_in)
139
+
140
+ image = np.array(image)
141
+ image = cv2.Canny(image, 100, 200)
142
+ image = image[:, :, None]
143
+ image = np.concatenate([image, image, image], axis=2)
144
+ image = Image.fromarray(image)
145
+
146
+ if use_custom_model:
147
+
148
+ if model_name == "":
149
+ raise gr.Error("you forgot to set a custom model name.")
150
+
151
+ custom_model = model_name
152
+
153
+ # This is where you load your trained weights
154
+ if weight_name == "NO SAFETENSORS FILE":
155
+ pipe.load_lora_weights(
156
+ custom_model,
157
+ low_cpu_mem_usage = True,
158
+ use_auth_token = True
159
+ )
160
+
161
+ else:
162
+ pipe.load_lora_weights(
163
+ custom_model,
164
+ weight_name = weight_name,
165
+ low_cpu_mem_usage = True,
166
+ use_auth_token = True
167
+ )
168
+
169
+ lora_scale=custom_lora_weight
170
+
171
+ images = pipe(
172
+ prompt,
173
+ negative_prompt=negative_prompt,
174
+ image=image,
175
+ controlnet_conditioning_scale=float(controlnet_conditioning_scale),
176
+ guidance_scale = float(guidance_scale),
177
+ num_inference_steps=inf_steps,
178
+ generator=generator,
179
+ cross_attention_kwargs={"scale": lora_scale}
180
+ ).images
181
+ else:
182
+ images = pipe(
183
+ prompt,
184
+ negative_prompt=negative_prompt,
185
+ image=image,
186
+ controlnet_conditioning_scale=float(controlnet_conditioning_scale),
187
+ guidance_scale = float(guidance_scale),
188
+ num_inference_steps=inf_steps,
189
+ generator=generator,
190
+ ).images
191
+
192
+ images[0].save(f"result.png")
193
+
194
+ return f"result.png", seed
195
+
196
+ css="""
197
+ #col-container{
198
+ margin: 0 auto;
199
+ max-width: 720px;
200
+ text-align: left;
201
+ }
202
+ div#warning-duplicate {
203
+ background-color: #ebf5ff;
204
+ padding: 0 10px 5px;
205
+ margin: 20px 0;
206
+ }
207
+ div#warning-duplicate > .gr-prose > h2, div#warning-duplicate > .gr-prose > p {
208
+ color: #0f4592!important;
209
+ }
210
+ div#warning-duplicate strong {
211
+ color: #0f4592;
212
+ }
213
+ p.actions {
214
+ display: flex;
215
+ align-items: center;
216
+ margin: 20px 0;
217
+ }
218
+ div#warning-duplicate .actions a {
219
+ display: inline-block;
220
+ margin-right: 10px;
221
+ }
222
+ button#load_model_btn{
223
+ height: 46px;
224
+ }
225
+ #status_info{
226
+ font-size: 0.9em;
227
+ }
228
+ """
229
+ def create_inference_demo() -> gr.Blocks:
230
+
231
+ with gr.Blocks(css=css) as demo:
232
+ with gr.Column(elem_id="col-container"):
233
+ if is_shared_ui:
234
+ top_description = gr.HTML(f'''
235
+ <div class="gr-prose">
236
+ <h2><svg xmlns="http://www.w3.org/2000/svg" width="18px" height="18px" style="margin-right: 0px;display: inline-block;"fill="none"><path fill="#fff" d="M7 13.2a6.3 6.3 0 0 0 4.4-10.7A6.3 6.3 0 0 0 .6 6.9 6.3 6.3 0 0 0 7 13.2Z"/><path fill="#fff" fill-rule="evenodd" d="M7 0a6.9 6.9 0 0 1 4.8 11.8A6.9 6.9 0 0 1 0 7 6.9 6.9 0 0 1 7 0Zm0 0v.7V0ZM0 7h.6H0Zm7 6.8v-.6.6ZM13.7 7h-.6.6ZM9.1 1.7c-.7-.3-1.4-.4-2.2-.4a5.6 5.6 0 0 0-4 1.6 5.6 5.6 0 0 0-1.6 4 5.6 5.6 0 0 0 1.6 4 5.6 5.6 0 0 0 4 1.7 5.6 5.6 0 0 0 4-1.7 5.6 5.6 0 0 0 1.7-4 5.6 5.6 0 0 0-1.7-4c-.5-.5-1.1-.9-1.8-1.2Z" clip-rule="evenodd"/><path fill="#000" fill-rule="evenodd" d="M7 2.9a.8.8 0 1 1 0 1.5A.8.8 0 0 1 7 3ZM5.8 5.7c0-.4.3-.6.6-.6h.7c.3 0 .6.2.6.6v3.7h.5a.6.6 0 0 1 0 1.3H6a.6.6 0 0 1 0-1.3h.4v-3a.6.6 0 0 1-.6-.7Z" clip-rule="evenodd"/></svg>
237
+ Note: you might want to use a <strong>private</strong> custom LoRa model</h2>
238
+ <p class="main-message">
239
+ To do so, <strong>duplicate the Space</strong> and run it on your own profile using <strong>your own access token</strong> and eventually a GPU (T4-small or A10G-small) for faster inference without waiting in the queue.<br />
240
+ </p>
241
+ <p class="actions">
242
+ <a href="https://huggingface.co/spaces/{os.environ['SPACE_ID']}?duplicate=true">
243
+ <img src="https://huggingface.co/datasets/huggingface/badges/resolve/main/duplicate-this-space-lg-dark.svg" alt="Duplicate this Space" />
244
+ </a>
245
+ to start using private models and skip the queue
246
+ </p>
247
+ </div>
248
+ ''', elem_id="warning-duplicate")
249
+ gr.HTML("""
250
+ <h2 style="text-align: center;">SD-XL Control LoRas</h2>
251
+ <p style="text-align: center;">Use StableDiffusion XL with <a href="https://huggingface.co/collections/diffusers/sdxl-controlnets-64f9c35846f3f06f5abe351f">Diffusers' SDXL ControlNets</a></p>
252
+
253
+ """)
254
+
255
+ use_custom_model = gr.Checkbox(label="Use a custom pre-trained LoRa model ? (optional)", value=False, info="To use a private model, you'll need to duplicate the space with your own access token.")
256
+
257
+ with gr.Box(visible=False) as custom_model_box:
258
+ with gr.Row():
259
+ with gr.Column():
260
+ if not is_shared_ui:
261
+ your_username = api.whoami()["name"]
262
+ my_models = api.list_models(author=your_username, filter=["diffusers", "stable-diffusion-xl", 'lora'])
263
+ model_names = [item.modelId for item in my_models]
264
+
265
+ if not is_shared_ui:
266
+ custom_model = gr.Dropdown(
267
+ label = "Your custom model ID",
268
+ info="You can pick one of your private models",
269
+ choices = model_names,
270
+ allow_custom_value = True
271
+ #placeholder = "username/model_id"
272
+ )
273
+ else:
274
+ custom_model = gr.Textbox(
275
+ label="Your custom model ID",
276
+ placeholder="your_username/your_trained_model_name",
277
+ info="Make sure your model is set to PUBLIC"
278
+ )
279
+
280
+ weight_name = gr.Dropdown(
281
+ label="Safetensors file",
282
+ #value="pytorch_lora_weights.safetensors",
283
+ info="specify which one if model has several .safetensors files",
284
+ allow_custom_value=True,
285
+ visible = False
286
+ )
287
+ with gr.Column():
288
+ with gr.Group():
289
+ load_model_btn = gr.Button("Load my model", elem_id="load_model_btn")
290
+ previous_model = gr.Textbox(
291
+ visible = False
292
+ )
293
+ model_status = gr.Textbox(
294
+ label = "model status",
295
+ show_label = False,
296
+ elem_id = "status_info"
297
+ )
298
+ trigger_word = gr.Textbox(label="Trigger word", interactive=False, visible=False)
299
+
300
+ image_in = gr.Image(source="upload", type="filepath")
301
+
302
+ with gr.Row():
303
+
304
+ with gr.Column():
305
+ with gr.Group():
306
+ prompt = gr.Textbox(label="Prompt")
307
+ negative_prompt = gr.Textbox(label="Negative prompt", value="extra digit, fewer digits, cropped, worst quality, low quality, glitch, deformed, mutated, ugly, disfigured")
308
+ with gr.Group():
309
+ guidance_scale = gr.Slider(label="Guidance Scale", minimum=1.0, maximum=10.0, step=0.1, value=7.5)
310
+ inf_steps = gr.Slider(label="Inference Steps", minimum="25", maximum="50", step=1, value=25)
311
+ custom_lora_weight = gr.Slider(label="Custom model weights", minimum=0.1, maximum=0.9, step=0.1, value=0.9)
312
+
313
+ with gr.Column():
314
+ with gr.Group():
315
+ preprocessor = gr.Dropdown(label="Preprocessor", choices=["canny"], value="canny", interactive=False, info="For the moment, only canny is available")
316
+ controlnet_conditioning_scale = gr.Slider(label="Controlnet conditioning Scale", minimum=0.1, maximum=0.9, step=0.01, value=0.5)
317
+ with gr.Group():
318
+ seed = gr.Slider(
319
+ label="Seed",
320
+ info = "-1 denotes a random seed",
321
+ minimum=-1,
322
+ maximum=423538377342,
323
+ step=1,
324
+ value=-1
325
+ )
326
+ last_used_seed = gr.Number(
327
+ label = "Last used seed",
328
+ info = "the seed used in the last generation",
329
+ )
330
+
331
+
332
+ submit_btn = gr.Button("Submit")
333
+
334
+ result = gr.Image(label="Result")
335
+
336
+ use_custom_model.change(
337
+ fn = check_use_custom_or_no,
338
+ inputs =[use_custom_model],
339
+ outputs = [custom_model_box],
340
+ queue = False
341
+ )
342
+ custom_model.blur(
343
+ fn=custom_model_changed,
344
+ inputs = [custom_model, previous_model],
345
+ outputs = [model_status],
346
+ queue = False
347
+ )
348
+ load_model_btn.click(
349
+ fn = load_model,
350
+ inputs=[custom_model],
351
+ outputs = [previous_model, model_status, weight_name, trigger_word],
352
+ queue = False
353
+ )
354
+ submit_btn.click(
355
+ fn = infer,
356
+ inputs = [use_custom_model, custom_model, weight_name, custom_lora_weight, image_in, prompt, negative_prompt, preprocessor, controlnet_conditioning_scale, guidance_scale, inf_steps, seed],
357
+ outputs = [result, last_used_seed]
358
+ )
359
+
360
+ return demo
361
+
362
+
363
+ #demo.queue(max_size=12).launch(share=True)
sdxl/requirements.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ torch==2.0.1
2
+ torchvision==0.15.2
3
+ invisible_watermark
4
+ accelerate
5
+ transformers
6
+ safetensors
7
+ opencv-python
8
+ git+https://github.com/huggingface/diffusers.git