fffiloni commited on
Commit
4c31ad4
1 Parent(s): 084d930

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +170 -23
app.py CHANGED
@@ -1,6 +1,8 @@
1
  import gradio as gr
2
- from huggingface_hub import login
3
  import os
 
 
4
  import torch
5
 
6
  is_shared_ui = True if "fffiloni/sdxl-control-loras" in os.environ['SPACE_ID'] else False
@@ -8,6 +10,9 @@ is_shared_ui = True if "fffiloni/sdxl-control-loras" in os.environ['SPACE_ID'] e
8
  hf_token = os.environ.get("HF_TOKEN")
9
  login(token=hf_token)
10
 
 
 
 
11
  device="cuda" if torch.cuda.is_available() else "cpu"
12
 
13
  from diffusers import ControlNetModel, StableDiffusionXLControlNetPipeline, AutoencoderKL
@@ -24,22 +29,57 @@ controlnet = ControlNetModel.from_pretrained(
24
  torch_dtype=torch.float16
25
  )
26
 
27
- pipe = StableDiffusionXLControlNetPipeline.from_pretrained(
28
- "stabilityai/stable-diffusion-xl-base-1.0",
29
- controlnet=controlnet,
30
- vae=vae,
31
- torch_dtype=torch.float16,
32
- variant="fp16",
33
- use_safetensors=True
34
- )
 
 
 
 
35
 
36
- pipe.to(device)
37
 
 
38
 
 
 
 
39
 
40
- #pipe.enable_model_cpu_offload()
 
 
 
41
 
42
- from PIL import Image
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
 
44
  def resize_image(input_path, output_path, target_height):
45
  # Open the input image
@@ -61,8 +101,24 @@ def resize_image(input_path, output_path, target_height):
61
  return output_path
62
 
63
  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)):
 
 
 
 
 
 
 
 
 
 
 
 
64
  prompt = prompt
65
  negative_prompt = negative_prompt
 
 
 
 
66
  generator = torch.Generator(device=device).manual_seed(seed)
67
 
68
  if image_in == None:
@@ -88,7 +144,20 @@ def infer(use_custom_model, model_name, weight_name, custom_lora_weight, image_i
88
  custom_model = model_name
89
 
90
  # This is where you load your trained weights
91
- pipe.load_lora_weights(custom_model, weight_name=weight_name, use_auth_token=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
92
 
93
  lora_scale=custom_lora_weight
94
 
@@ -115,7 +184,7 @@ def infer(use_custom_model, model_name, weight_name, custom_lora_weight, image_i
115
 
116
  images[0].save(f"result.png")
117
 
118
- return f"result.png"
119
 
120
  css="""
121
  #col-container{
@@ -143,6 +212,12 @@ div#warning-duplicate .actions a {
143
  display: inline-block;
144
  margin-right: 10px;
145
  }
 
 
 
 
 
 
146
  """
147
 
148
  with gr.Blocks(css=css) as demo:
@@ -170,28 +245,100 @@ with gr.Blocks(css=css) as demo:
170
  """)
171
 
172
  image_in = gr.Image(source="upload", type="filepath")
 
173
  with gr.Row():
 
174
  with gr.Column():
175
  prompt = gr.Textbox(label="Prompt")
176
  negative_prompt = gr.Textbox(label="Negative prompt", value="extra digit, fewer digits, cropped, worst quality, low quality, glitch, deformed, mutated, ugly, disfigured")
177
  guidance_scale = gr.Slider(label="Guidance Scale", minimum=1.0, maximum=10.0, step=0.1, value=7.5)
178
  inf_steps = gr.Slider(label="Inference Steps", minimum="25", maximum="50", step=1, value=25)
 
179
  with gr.Column():
180
- preprocessor = gr.Dropdown(label="Preprocessor", choices=["canny"], value="canny", interactive=False, info="For the moment, only canny is available")
181
- controlnet_conditioning_scale = gr.Slider(label="Controlnet conditioning Scale", minimum=0.1, maximum=0.9, step=0.01, value=0.5)
182
- seed = gr.Slider(label="seed", minimum=0, maximum=500000, step=1, value=42)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
  use_custom_model = gr.Checkbox(label="Use a public custom model ?(optional)", value=False, info="To use a private model, you'll prefer to duplicate the space with your own access token.")
184
- with gr.Row():
185
- model_name = gr.Textbox(label="Custom Model to use", placeholder="username/my_custom_public_model")
186
- weight_name = gr.Textbox(label="Specific safetensor", value="pytorch_lora_weights.safetensors",info="specify which one if model has several .safetensors files" )
187
- custom_lora_weight = gr.Slider(label="Custom model weights", minimum=0.1, maximum=0.9, step=0.1, value=0.9)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
188
  submit_btn = gr.Button("Submit")
 
189
  result = gr.Image(label="Result")
190
 
 
 
 
 
 
 
 
 
 
 
 
 
191
  submit_btn.click(
192
  fn = infer,
193
- inputs = [use_custom_model, model_name, weight_name, custom_lora_weight, image_in, prompt, negative_prompt, preprocessor, controlnet_conditioning_scale, guidance_scale, inf_steps, seed],
194
- outputs = [result]
195
  )
196
 
197
  demo.queue(max_size=12).launch()
 
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 = True if "fffiloni/sdxl-control-loras" in os.environ['SPACE_ID'] else False
 
10
  hf_token = os.environ.get("HF_TOKEN")
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
 
29
  torch_dtype=torch.float16
30
  )
31
 
32
+ def get_files(file_paths):
33
+ last_files = {} # Dictionary to store the last file for each path
34
+
35
+ for file_path in file_paths:
36
+ # Split the file path into directory and file components
37
+ directory, file_name = file_path.rsplit('/', 1)
38
+
39
+ # Update the last file for the current path
40
+ last_files[directory] = file_name
41
+
42
+ # Extract the last files from the dictionary
43
+ result = list(last_files.values())
44
 
45
+ return result
46
 
47
+ def load_model(model_name):
48
 
49
+ if model_name == "":
50
+ gr.Warning("If you want to use a private model, you need to duplicate this space on your personal account.")
51
+ raise gr.Error("You forgot to define Model ID.")
52
 
53
+ # Get instance_prompt a.k.a trigger word
54
+ card = ModelCard.load(model_name)
55
+ repo_data = card.data.to_dict()
56
+ instance_prompt = repo_data.get("instance_prompt")
57
 
58
+ if instance_prompt is not None:
59
+ print(f"Trigger word: {instance_prompt}")
60
+ else:
61
+ instance_prompt = "no trigger word needed"
62
+ print(f"Trigger word: no trigger word needed")
63
+
64
+ # List all ".safetensors" files in repo
65
+ sfts_available_files = fs.glob(f"{model_name}/*safetensors")
66
+ sfts_available_files = get_files(sfts_available_files)
67
+
68
+ if sfts_available_files == []:
69
+ sfts_available_files = ["NO SAFETENSORS FILE"]
70
+
71
+ print(f"Safetensors available: {sfts_available_files}")
72
+
73
+ 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)
74
+
75
+ def custom_model_changed(model_name, previous_model):
76
+ if model_name == "" and previous_model == "" :
77
+ status_message = ""
78
+ elif model_name != previous_model:
79
+ status_message = "model changed, please reload before any new run"
80
+ else:
81
+ status_message = "model ready"
82
+ return status_message
83
 
84
  def resize_image(input_path, output_path, target_height):
85
  # Open the input image
 
101
  return output_path
102
 
103
  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)):
104
+
105
+ pipe = StableDiffusionXLControlNetPipeline.from_pretrained(
106
+ "stabilityai/stable-diffusion-xl-base-1.0",
107
+ controlnet=controlnet,
108
+ vae=vae,
109
+ torch_dtype=torch.float16,
110
+ variant="fp16",
111
+ use_safetensors=True
112
+ )
113
+
114
+ pipe.to(device)
115
+
116
  prompt = prompt
117
  negative_prompt = negative_prompt
118
+
119
+ if seed < 0 :
120
+ seed = random.randint(0, 423538377342)
121
+
122
  generator = torch.Generator(device=device).manual_seed(seed)
123
 
124
  if image_in == None:
 
144
  custom_model = model_name
145
 
146
  # This is where you load your trained weights
147
+ if weight_name == "NO SAFETENSORS FILE":
148
+ pipe.load_lora_weights(
149
+ custom_model,
150
+ low_cpu_mem_usage = True,
151
+ use_auth_token = True
152
+ )
153
+
154
+ else:
155
+ pipe.load_lora_weights(
156
+ custom_model,
157
+ weight_name = weight_name,
158
+ low_cpu_mem_usage = True,
159
+ use_auth_token = True
160
+ )
161
 
162
  lora_scale=custom_lora_weight
163
 
 
184
 
185
  images[0].save(f"result.png")
186
 
187
+ return f"result.png", seed
188
 
189
  css="""
190
  #col-container{
 
212
  display: inline-block;
213
  margin-right: 10px;
214
  }
215
+ button#load_model_btn{
216
+ height: 46px;
217
+ }
218
+ #status_info{
219
+ font-size: 0.9em;
220
+ }
221
  """
222
 
223
  with gr.Blocks(css=css) as demo:
 
245
  """)
246
 
247
  image_in = gr.Image(source="upload", type="filepath")
248
+
249
  with gr.Row():
250
+
251
  with gr.Column():
252
  prompt = gr.Textbox(label="Prompt")
253
  negative_prompt = gr.Textbox(label="Negative prompt", value="extra digit, fewer digits, cropped, worst quality, low quality, glitch, deformed, mutated, ugly, disfigured")
254
  guidance_scale = gr.Slider(label="Guidance Scale", minimum=1.0, maximum=10.0, step=0.1, value=7.5)
255
  inf_steps = gr.Slider(label="Inference Steps", minimum="25", maximum="50", step=1, value=25)
256
+
257
  with gr.Column():
258
+ with gr.Group():
259
+ preprocessor = gr.Dropdown(label="Preprocessor", choices=["canny"], value="canny", interactive=False, info="For the moment, only canny is available")
260
+ controlnet_conditioning_scale = gr.Slider(label="Controlnet conditioning Scale", minimum=0.1, maximum=0.9, step=0.01, value=0.5)
261
+ with gr.Group():
262
+ seed = gr.Slider(
263
+ label="Seed",
264
+ info = "-1 denotes a random seed",
265
+ minimum=-1,
266
+ maximum=423538377342,
267
+ step=1,
268
+ value=-1
269
+ )
270
+ last_used_seed = gr.Number(
271
+ label = "Last used seed",
272
+ info = "the seed used in the last generation",
273
+ )
274
+
275
  use_custom_model = gr.Checkbox(label="Use a public custom model ?(optional)", value=False, info="To use a private model, you'll prefer to duplicate the space with your own access token.")
276
+
277
+ with gr.Box():
278
+ with gr.Row():
279
+ with gr.Column():
280
+ if not is_shared_ui:
281
+ your_username = api.whoami()["name"]
282
+ my_models = api.list_models(author=your_username, filter=["diffusers", "stable-diffusion-xl", 'lora'])
283
+ model_names = [item.modelId for item in my_models]
284
+
285
+ if not is_shared_ui:
286
+ custom_model = gr.Dropdown(
287
+ label = "Your custom model ID",
288
+ info="You can pick one of your private models",
289
+ choices = model_names,
290
+ allow_custom_value = True
291
+ #placeholder = "username/model_id"
292
+ )
293
+ else:
294
+ custom_model = gr.Textbox(
295
+ label="Your custom model ID",
296
+ placeholder="your_username/your_trained_model_name",
297
+ info="Make sure your model is set to PUBLIC"
298
+ )
299
+
300
+ weight_name = gr.Dropdown(
301
+ label="Safetensors file",
302
+ #value="pytorch_lora_weights.safetensors",
303
+ info="specify which one if model has several .safetensors files",
304
+ allow_custom_value=True,
305
+ visible = False
306
+ )
307
+ with gr.Column():
308
+ with gr.Group():
309
+ load_model_btn = gr.Button("Load my model", elem_id="load_model_btn")
310
+ previous_model = gr.Textbox(
311
+ visible = False
312
+ )
313
+ model_status = gr.Textbox(
314
+ label = "model status",
315
+ show_label = False,
316
+ elem_id = "status_info"
317
+ )
318
+ trigger_word = gr.Textbox(label="Trigger word", interactive=False, visible=False)
319
+
320
+ custom_lora_weight = gr.Slider(label="Custom model weights", minimum=0.1, maximum=0.9, step=0.1, value=0.9)
321
+
322
  submit_btn = gr.Button("Submit")
323
+
324
  result = gr.Image(label="Result")
325
 
326
+ custom_model.blur(
327
+ fn=custom_model_changed,
328
+ inputs = [custom_model, previous_model],
329
+ outputs = [model_status],
330
+ queue = False
331
+ )
332
+ load_model_btn.click(
333
+ fn = load_model,
334
+ inputs=[custom_model],
335
+ outputs = [previous_model, model_status, weight_name, trigger_word],
336
+ queue = False
337
+ )
338
  submit_btn.click(
339
  fn = infer,
340
+ 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],
341
+ outputs = [result, last_used_seed]
342
  )
343
 
344
  demo.queue(max_size=12).launch()