Charbel Malo commited on
Commit
ea028b1
·
verified ·
1 Parent(s): 1543e66

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +235 -669
app.py CHANGED
@@ -4,6 +4,7 @@ import json
4
  import logging
5
  import torch
6
  from PIL import Image
 
7
  from diffusers import DiffusionPipeline, AutoencoderTiny, AutoencoderKL, AutoPipelineForImage2Image
8
  from live_preview_helpers import calculate_shift, retrieve_timesteps, flux_pipe_call_that_returns_an_iterable_of_images
9
  from diffusers.utils import load_image
@@ -13,7 +14,6 @@ import random
13
  import time
14
  import requests
15
  import pandas as pd
16
- import spaces
17
 
18
  # Load prompts for randomization
19
  df = pd.read_csv('prompts.csv', header=None)
@@ -81,472 +81,10 @@ def download_file(url, directory=None):
81
  file.write(response.content)
82
 
83
  return filepath
84
-
85
- def update_selection(evt: gr.SelectData, selected_indices, loras_state, width, height):
86
- selected_index = evt.index
87
- selected_indices = selected_indices or []
88
- if selected_index in selected_indices:
89
- selected_indices.remove(selected_index)
90
- else:
91
- if len(selected_indices) < 6:
92
- selected_indices.append(selected_index)
93
- else:
94
- gr.Warning("You can select up to 6 LoRAs, remove one to select a new one.")
95
- return gr.update(), "Select a LoRA 1", "Select a LoRA 2", "Select a LoRA 3", "Select a LoRA 4", "Select a LoRA 5", "Select a LoRA 6", selected_indices, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, width, height, None, None, None, None, None, None
96
-
97
- # Initialize defaults
98
- selected_info_1 = "Select a LoRA 1"
99
- selected_info_2 = "Select a LoRA 2"
100
- selected_info_3 = "Select a LoRA 3"
101
- selected_info_4 = "Select a LoRA 4"
102
- selected_info_5 = "Select a LoRA 5"
103
- selected_info_6 = "Select a LoRA 6"
104
- lora_scale_1 = 1.15
105
- lora_scale_2 = 1.15
106
- lora_scale_3 = 1.15
107
- lora_scale_4 = 1.15
108
- lora_scale_5 = 1.15
109
- lora_scale_6 = 1.15
110
- lora_image_1 = None
111
- lora_image_2 = None
112
- lora_image_3 = None
113
- lora_image_4 = None
114
- lora_image_5 = None
115
- lora_image_6 = None
116
-
117
- if len(selected_indices) >= 1:
118
- lora1 = loras_state[selected_indices[0]]
119
- selected_info_1 = f"### LoRA 1 Selected: [{lora1['title']}](https://huggingface.co/{lora1['repo']}) ✨"
120
- lora_image_1 = lora1['image']
121
- if len(selected_indices) >= 2:
122
- lora2 = loras_state[selected_indices[1]]
123
- selected_info_2 = f"### LoRA 2 Selected: [{lora2['title']}](https://huggingface.co/{lora2['repo']}) ✨"
124
- lora_image_2 = lora2['image']
125
- if len(selected_indices) >= 3:
126
- lora3 = loras_state[selected_indices[2]]
127
- selected_info_3 = f"### LoRA 3 Selected: [{lora3['title']}](https://huggingface.co/{lora3['repo']}) ✨"
128
- lora_image_3 = lora3['image']
129
- if len(selected_indices) >= 4:
130
- lora4 = loras_state[selected_indices[3]]
131
- selected_info_4 = f"### LoRA 4 Selected: [{lora4['title']}](https://huggingface.co/{lora4['repo']}) ✨"
132
- lora_image_4 = lora4['image']
133
- if len(selected_indices) >= 5:
134
- lora5 = loras_state[selected_indices[4]]
135
- selected_info_5 = f"### LoRA 5 Selected: [{lora5['title']}](https://huggingface.co/{lora5['repo']}) ✨"
136
- lora_image_5 = lora5['image']
137
- if len(selected_indices) >= 6:
138
- lora6 = loras_state[selected_indices[5]]
139
- selected_info_6 = f"### LoRA 6 Selected: [{lora6['title']}](https://huggingface.co/{lora6['repo']}) ✨"
140
- lora_image_6 = lora6['image']
141
-
142
- if selected_indices:
143
- last_selected_lora = loras_state[selected_indices[-1]]
144
- new_placeholder = f"Type a prompt for {last_selected_lora['title']}"
145
- else:
146
- new_placeholder = "Type a prompt after selecting a LoRA"
147
-
148
- return (
149
- gr.update(placeholder=new_placeholder),
150
- selected_info_1,
151
- selected_info_2,
152
- selected_info_3,
153
- selected_info_4,
154
- selected_info_5,
155
- selected_info_6,
156
- selected_indices,
157
- lora_scale_1,
158
- lora_scale_2,
159
- lora_scale_3,
160
- lora_scale_4,
161
- lora_scale_5,
162
- lora_scale_6,
163
- width,
164
- height,
165
- lora_image_1,
166
- lora_image_2,
167
- lora_image_3,
168
- lora_image_4,
169
- lora_image_5,
170
- lora_image_6
171
- )
172
-
173
- def remove_lora_1(selected_indices, loras_state):
174
- if len(selected_indices) >= 1:
175
- selected_indices.pop(0)
176
- return update_selection_after_removal(selected_indices, loras_state)
177
-
178
- def remove_lora_2(selected_indices, loras_state):
179
- if len(selected_indices) >= 2:
180
- selected_indices.pop(1)
181
- return update_selection_after_removal(selected_indices, loras_state)
182
-
183
- def remove_lora_3(selected_indices, loras_state):
184
- if len(selected_indices) >= 3:
185
- selected_indices.pop(2)
186
- return update_selection_after_removal(selected_indices, loras_state)
187
-
188
- def remove_lora_4(selected_indices, loras_state):
189
- if len(selected_indices) >= 4:
190
- selected_indices.pop(3)
191
- return update_selection_after_removal(selected_indices, loras_state)
192
-
193
- def remove_lora_5(selected_indices, loras_state):
194
- if len(selected_indices) >= 5:
195
- selected_indices.pop(4)
196
- return update_selection_after_removal(selected_indices, loras_state)
197
-
198
- def remove_lora_6(selected_indices, loras_state):
199
- if len(selected_indices) >= 6:
200
- selected_indices.pop(5)
201
- return update_selection_after_removal(selected_indices, loras_state)
202
-
203
- def update_selection_after_removal(selected_indices, loras_state):
204
- # Reinitialize defaults
205
- selected_info_1 = "Select a LoRA 1"
206
- selected_info_2 = "Select a LoRA 2"
207
- selected_info_3 = "Select a LoRA 3"
208
- selected_info_4 = "Select a LoRA 4"
209
- selected_info_5 = "Select a LoRA 5"
210
- selected_info_6 = "Select a LoRA 6"
211
- lora_scale_1 = 1.15
212
- lora_scale_2 = 1.15
213
- lora_scale_3 = 1.15
214
- lora_scale_4 = 1.15
215
- lora_scale_5 = 1.15
216
- lora_scale_6 = 1.15
217
- lora_image_1 = None
218
- lora_image_2 = None
219
- lora_image_3 = None
220
- lora_image_4 = None
221
- lora_image_5 = None
222
- lora_image_6 = None
223
-
224
- # Update selected LoRAs
225
- if len(selected_indices) >= 1:
226
- lora1 = loras_state[selected_indices[0]]
227
- selected_info_1 = f"### LoRA 1 Selected: [{lora1['title']}]({lora1['repo']}) ✨"
228
- lora_image_1 = lora1['image']
229
- if len(selected_indices) >= 2:
230
- lora2 = loras_state[selected_indices[1]]
231
- selected_info_2 = f"### LoRA 2 Selected: [{lora2['title']}]({lora2['repo']}) ✨"
232
- lora_image_2 = lora2['image']
233
- if len(selected_indices) >= 3:
234
- lora3 = loras_state[selected_indices[2]]
235
- selected_info_3 = f"### LoRA 3 Selected: [{lora3['title']}]({lora3['repo']}) ✨"
236
- lora_image_3 = lora3['image']
237
- if len(selected_indices) >= 4:
238
- lora4 = loras_state[selected_indices[3]]
239
- selected_info_4 = f"### LoRA 4 Selected: [{lora4['title']}]({lora4['repo']}) ✨"
240
- lora_image_4 = lora4['image']
241
- if len(selected_indices) >= 5:
242
- lora5 = loras_state[selected_indices[4]]
243
- selected_info_5 = f"### LoRA 5 Selected: [{lora5['title']}]({lora5['repo']}) ✨"
244
- lora_image_5 = lora5['image']
245
- if len(selected_indices) >= 6:
246
- lora6 = loras_state[selected_indices[5]]
247
- selected_info_6 = f"### LoRA 6 Selected: [{lora6['title']}]({lora6['repo']}) ✨"
248
- lora_image_6 = lora6['image']
249
-
250
- return (
251
- selected_info_1,
252
- selected_info_2,
253
- selected_info_3,
254
- selected_info_4,
255
- selected_info_5,
256
- selected_info_6,
257
- selected_indices,
258
- lora_scale_1,
259
- lora_scale_2,
260
- lora_scale_3,
261
- lora_scale_4,
262
- lora_scale_5,
263
- lora_scale_6,
264
- lora_image_1,
265
- lora_image_2,
266
- lora_image_3,
267
- lora_image_4,
268
- lora_image_5,
269
- lora_image_6
270
- )
271
-
272
- def randomize_loras(selected_indices, loras_state):
273
- num_loras = min(6, len(loras_state))
274
- selected_indices = random.sample(range(len(loras_state)), num_loras)
275
- selected_info_1 = "Select a LoRA 1"
276
- selected_info_2 = "Select a LoRA 2"
277
- selected_info_3 = "Select a LoRA 3"
278
- selected_info_4 = "Select a LoRA 4"
279
- selected_info_5 = "Select a LoRA 5"
280
- selected_info_6 = "Select a LoRA 6"
281
- lora_scale_1 = 1.15
282
- lora_scale_2 = 1.15
283
- lora_scale_3 = 1.15
284
- lora_scale_4 = 1.15
285
- lora_scale_5 = 1.15
286
- lora_scale_6 = 1.15
287
- lora_image_1 = None
288
- lora_image_2 = None
289
- lora_image_3 = None
290
- lora_image_4 = None
291
- lora_image_5 = None
292
- lora_image_6 = None
293
-
294
- for idx, sel_idx in enumerate(selected_indices):
295
- lora = loras_state[sel_idx]
296
- if idx == 0:
297
- selected_info_1 = f"### LoRA 1 Selected: [{lora['title']}](https://huggingface.co/{lora['repo']}) ✨"
298
- lora_image_1 = lora['image']
299
- elif idx == 1:
300
- selected_info_2 = f"### LoRA 2 Selected: [{lora['title']}](https://huggingface.co/{lora['repo']}) ✨"
301
- lora_image_2 = lora['image']
302
- elif idx == 2:
303
- selected_info_3 = f"### LoRA 3 Selected: [{lora['title']}](https://huggingface.co/{lora['repo']}) ✨"
304
- lora_image_3 = lora['image']
305
- elif idx == 3:
306
- selected_info_4 = f"### LoRA 4 Selected: [{lora['title']}](https://huggingface.co/{lora['repo']}) ✨"
307
- lora_image_4 = lora['image']
308
- elif idx == 4:
309
- selected_info_5 = f"### LoRA 5 Selected: [{lora['title']}](https://huggingface.co/{lora['repo']}) ✨"
310
- lora_image_5 = lora['image']
311
- elif idx == 5:
312
- selected_info_6 = f"### LoRA 6 Selected: [{lora['title']}](https://huggingface.co/{lora['repo']}) ✨"
313
- lora_image_6 = lora['image']
314
-
315
- random_prompt = random.choice(prompt_values)
316
- return (
317
- selected_info_1,
318
- selected_info_2,
319
- selected_info_3,
320
- selected_info_4,
321
- selected_info_5,
322
- selected_info_6,
323
- selected_indices,
324
- lora_scale_1,
325
- lora_scale_2,
326
- lora_scale_3,
327
- lora_scale_4,
328
- lora_scale_5,
329
- lora_scale_6,
330
- lora_image_1,
331
- lora_image_2,
332
- lora_image_3,
333
- lora_image_4,
334
- lora_image_5,
335
- lora_image_6,
336
- random_prompt
337
- )
338
-
339
- def add_custom_lora(custom_lora, selected_indices, current_loras, gallery):
340
- if custom_lora:
341
- try:
342
- title, repo, path, trigger_word, image = check_custom_model(custom_lora)
343
- print(f"Loaded custom LoRA: {repo}")
344
- existing_item_index = next((index for (index, item) in enumerate(current_loras) if item['repo'] == repo), None)
345
- if existing_item_index is None:
346
- if repo.endswith(".safetensors") and repo.startswith("http"):
347
- repo = download_file(repo)
348
- new_item = {
349
- "image": image if image else "/home/user/app/custom.png",
350
- "title": title,
351
- "repo": repo,
352
- "weights": path,
353
- "trigger_word": trigger_word
354
- }
355
- print(f"New LoRA: {new_item}")
356
- existing_item_index = len(current_loras)
357
- current_loras.append(new_item)
358
-
359
- # Update gallery
360
- gallery_items = [(item["image"], item["title"]) for item in current_loras]
361
- # Update selected_indices if there's room
362
- if len(selected_indices) < 6:
363
- selected_indices.append(existing_item_index)
364
- else:
365
- gr.Warning("You can select up to 6 LoRAs, remove one to select a new one.")
366
-
367
- # Update selected_info and images
368
- return update_selection_after_removal(selected_indices, current_loras)[:20] + (current_loras, gr.update(value=gallery_items))
369
-
370
- except Exception as e:
371
- print(e)
372
- gr.Warning(str(e))
373
- return current_loras, gr.update(), "Select a LoRA 1", "Select a LoRA 2", "Select a LoRA 3", "Select a LoRA 4", "Select a LoRA 5", "Select a LoRA 6", selected_indices, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, None, None, None, None, None, None
374
- else:
375
- return current_loras, gr.update(), "Select a LoRA 1", "Select a LoRA 2", "Select a LoRA 3", "Select a LoRA 4", "Select a LoRA 5", "Select a LoRA 6", selected_indices, 1.15, 1.15, 1.15, 1.15, 1.15, 1.15, None, None, None, None, None, None
376
-
377
- @spaces.GPU(duration=75)
378
- def generate_image(prompt_mash, steps, seed, cfg_scale, width, height, progress):
379
- print("Generating image...")
380
- pipe.to("cuda")
381
- generator = torch.Generator(device="cuda").manual_seed(seed)
382
- with calculateDuration("Generating image"):
383
- # Generate image
384
- for img in pipe.flux_pipe_call_that_returns_an_iterable_of_images(
385
- prompt=prompt_mash,
386
- num_inference_steps=steps,
387
- guidance_scale=cfg_scale,
388
- width=width,
389
- height=height,
390
- generator=generator,
391
- joint_attention_kwargs={"scale": 1.0},
392
- output_type="pil",
393
- good_vae=good_vae,
394
- ):
395
- yield img
396
-
397
- @spaces.GPU()
398
- def generate_image_to_image(prompt_mash, image_input_path, image_strength, steps, cfg_scale, width, height, seed):
399
- pipe_i2i.to("cuda")
400
- generator = torch.Generator(device="cuda").manual_seed(seed)
401
- image_input = load_image(image_input_path)
402
- final_image = pipe_i2i(
403
- prompt=prompt_mash,
404
- image=image_input,
405
- strength=image_strength,
406
- num_inference_steps=steps,
407
- guidance_scale=cfg_scale,
408
- width=width,
409
- height=height,
410
- generator=generator,
411
- joint_attention_kwargs={"scale": 1.0},
412
- output_type="pil",
413
- ).images[0]
414
- return final_image
415
-
416
-
417
- @spaces.GPU()
418
- def run_lora(prompt, image_input, image_strength, cfg_scale, steps, selected_indices, lora_scale_1, lora_scale_2, lora_scale_3, lora_scale_4, lora_scale_5, lora_scale_6, randomize_seed, seed, width, height, loras_state, progress=gr.Progress(track_tqdm=True)):
419
- if not selected_indices:
420
- raise gr.Error("You must select at least one LoRA before proceeding.")
421
-
422
- selected_loras = [loras_state[idx] for idx in selected_indices]
423
-
424
- # Build the prompt with trigger words
425
- prepends = []
426
- appends = []
427
- for lora in selected_loras:
428
- trigger_word = lora.get('trigger_word', '')
429
- if trigger_word:
430
- if lora.get("trigger_position") == "prepend":
431
- prepends.append(trigger_word)
432
- else:
433
- appends.append(trigger_word)
434
- prompt_mash = " ".join(prepends + [prompt] + appends)
435
- print("Prompt Mash: ", prompt_mash)
436
- # Unload previous LoRA weights
437
- with calculateDuration("Unloading LoRA"):
438
- pipe.unload_lora_weights()
439
- pipe_i2i.unload_lora_weights()
440
-
441
- print(pipe.get_active_adapters())
442
- # Load LoRA weights with respective scales
443
- lora_names = []
444
- lora_weights = []
445
- lora_scales = [
446
- lora_scale_1,
447
- lora_scale_2,
448
- lora_scale_3,
449
- lora_scale_4,
450
- lora_scale_5,
451
- lora_scale_6
452
- ]
453
- with calculateDuration("Loading LoRA weights"):
454
- for idx, lora in enumerate(selected_loras):
455
- if idx >= 6:
456
- break
457
- lora_name = f"lora_{idx}"
458
- lora_names.append(lora_name)
459
- print(f"Lora Name: {lora_name}")
460
- lora_weights.append(lora_scales[idx])
461
- lora_path = lora['repo']
462
- weight_name = lora.get("weights")
463
- print(f"Lora Path: {lora_path}")
464
- pipe_to_use = pipe_i2i if image_input is not None else pipe
465
- pipe_to_use.load_lora_weights(
466
- lora_path,
467
- weight_name=weight_name if weight_name else None,
468
- low_cpu_mem_usage=True,
469
- adapter_name=lora_name
470
- )
471
- print("Loaded LoRAs:", lora_names)
472
- print("Adapter weights:", lora_weights)
473
- if image_input is not None:
474
- pipe_i2i.set_adapters(lora_names, adapter_weights=lora_weights)
475
- else:
476
- pipe.set_adapters(lora_names, adapter_weights=lora_weights)
477
- print(pipe.get_active_adapters())
478
- # Set random seed for reproducibility
479
- with calculateDuration("Randomizing seed"):
480
- if randomize_seed:
481
- seed = random.randint(0, MAX_SEED)
482
-
483
- # Generate image
484
- if image_input is not None:
485
- final_image = generate_image_to_image(prompt_mash, image_input, image_strength, steps, cfg_scale, width, height, seed)
486
- yield final_image, seed, gr.update(visible=False)
487
- else:
488
- image_generator = generate_image(prompt_mash, steps, seed, cfg_scale, width, height, progress)
489
- # Consume the generator to get the final image
490
- final_image = None
491
- step_counter = 0
492
- for image in image_generator:
493
- step_counter += 1
494
- final_image = image
495
- progress_bar = f'<div class="progress-container"><div class="progress-bar" style="--current: {step_counter}; --total: {steps};"></div></div>'
496
- yield image, seed, gr.update(value=progress_bar, visible=True)
497
- yield final_image, seed, gr.update(value=progress_bar, visible=False)
498
-
499
-
500
- run_lora.zerogpu = True
501
- @spaces.GPU()
502
- def get_huggingface_safetensors(link):
503
- split_link = link.split("/")
504
- if len(split_link) == 2:
505
- model_card = ModelCard.load(link)
506
- base_model = model_card.data.get("base_model")
507
- print(f"Base model: {base_model}")
508
- if base_model not in ["black-forest-labs/FLUX.1-dev", "black-forest-labs/FLUX.1-schnell"]:
509
- raise Exception("Not a FLUX LoRA!")
510
- image_path = model_card.data.get("widget", [{}])[0].get("output", {}).get("url", None)
511
- trigger_word = model_card.data.get("instance_prompt", "")
512
- image_url = f"https://huggingface.co/{link}/resolve/main/{image_path}" if image_path else None
513
- fs = HfFileSystem()
514
- safetensors_name = None
515
- try:
516
- list_of_files = fs.ls(link, detail=False)
517
- for file in list_of_files:
518
- if file.endswith(".safetensors"):
519
- safetensors_name = file.split("/")[-1]
520
- if not image_url and file.lower().endswith((".jpg", ".jpeg", ".png", ".webp")):
521
- image_elements = file.split("/")
522
- image_url = f"https://huggingface.co/{link}/resolve/main/{image_elements[-1]}"
523
- except Exception as e:
524
- print(e)
525
- raise gr.Error("Invalid Hugging Face repository with a *.safetensors LoRA")
526
- if not safetensors_name:
527
- raise gr.Error("No *.safetensors file found in the repository")
528
- return split_link[1], link, safetensors_name, trigger_word, image_url
529
- else:
530
- raise gr.Error("Invalid Hugging Face repository link")
531
 
532
  def check_custom_model(link):
533
- if link.endswith(".safetensors"):
534
- # Treat as direct link to the LoRA weights
535
- title = os.path.basename(link)
536
- repo = link
537
- path = None # No specific weight name
538
- trigger_word = ""
539
- image_url = None
540
- return title, repo, path, trigger_word, image_url
541
- elif link.startswith("https://"):
542
- if "huggingface.co" in link:
543
- link_split = link.split("huggingface.co/")
544
- return get_huggingface_safetensors(link_split[1])
545
- else:
546
- raise Exception("Unsupported URL")
547
- else:
548
- # Assume it's a Hugging Face model path
549
- return get_huggingface_safetensors(link)
550
 
551
  def update_history(new_image, history):
552
  """Updates the history gallery with the new image."""
@@ -578,7 +116,7 @@ css = '''
578
  #component-11{align-self: stretch;}
579
  '''
580
 
581
- with gr.Blocks(css=css, delete_cache=(60, 60)) as app:
582
  title = gr.HTML(
583
  """<h1><img src="https://i.imgur.com/wMh2Oek.png" alt="LoRA"> LoRA Lab [beta]</h1><br><span style="
584
  margin-top: -25px !important;
@@ -589,222 +127,250 @@ with gr.Blocks(css=css, delete_cache=(60, 60)) as app:
589
  )
590
  loras_state = gr.State(loras)
591
  selected_indices = gr.State([])
 
 
592
  with gr.Row():
593
  with gr.Column(scale=3):
594
  prompt = gr.Textbox(label="Prompt", lines=1, placeholder="Type a prompt after selecting a LoRA")
595
  with gr.Column(scale=1):
596
  generate_button = gr.Button("Generate", variant="primary", elem_classes=["button_total"])
 
597
  with gr.Row(elem_id="loaded_loras"):
598
- with gr.Column(scale=1, min_width=25):
599
- randomize_button = gr.Button("🎲", variant="secondary", scale=1, elem_id="random_btn")
600
- # LoRA 1
601
- with gr.Column(scale=8):
602
- with gr.Row():
603
- with gr.Column(scale=0, min_width=50):
604
- lora_image_1 = gr.Image(label="LoRA 1 Image", interactive=False, min_width=50, width=50, show_label=False, show_share_button=False, show_download_button=False, show_fullscreen_button=False, height=50)
605
- with gr.Column(scale=3, min_width=100):
606
- selected_info_1 = gr.Markdown("Select a LoRA 1")
607
- with gr.Column(scale=5, min_width=50):
608
- lora_scale_1 = gr.Slider(label="LoRA 1 Scale", minimum=0, maximum=3, step=0.01, value=1.15)
609
- with gr.Row():
610
- remove_button_1 = gr.Button("Remove", size="sm",interactive=True)
611
- # LoRA 2
612
- with gr.Column(scale=8):
613
- with gr.Row():
614
- with gr.Column(scale=0, min_width=50):
615
- lora_image_2 = gr.Image(label="LoRA 2 Image", interactive=False, min_width=50, width=50, show_label=False, show_share_button=False, show_download_button=False, show_fullscreen_button=False, height=50)
616
- with gr.Column(scale=3, min_width=100):
617
- selected_info_2 = gr.Markdown("Select a LoRA 2")
618
- with gr.Column(scale=5, min_width=50):
619
- lora_scale_2 = gr.Slider(label="LoRA 2 Scale", minimum=0, maximum=3, step=0.01, value=1.15)
620
- with gr.Row():
621
- remove_button_2 = gr.Button("Remove", size="sm")
622
- # LoRA 3
623
- with gr.Column(scale=8):
624
- with gr.Row():
625
- with gr.Column(scale=0, min_width=50):
626
- lora_image_3 = gr.Image(label="LoRA 3 Image", interactive=False, min_width=50, width=50, show_label=False, show_share_button=False, show_download_button=False, show_fullscreen_button=False, height=50)
627
- with gr.Column(scale=3, min_width=100):
628
- selected_info_3 = gr.Markdown("Select a LoRA 3")
629
- with gr.Column(scale=5, min_width=50):
630
- lora_scale_3 = gr.Slider(label="LoRA 3 Scale", minimum=0, maximum=3, step=0.01, value=1.15)
631
- with gr.Row():
632
- remove_button_3 = gr.Button("Remove", size="sm")
633
- # LoRA 4
634
- with gr.Column(scale=8):
635
- with gr.Row():
636
- with gr.Column(scale=0, min_width=50):
637
- lora_image_4 = gr.Image(label="LoRA 4 Image", interactive=False, min_width=50, width=50, show_label=False, show_share_button=False, show_download_button=False, show_fullscreen_button=False, height=50)
638
- with gr.Column(scale=3, min_width=100):
639
- selected_info_4 = gr.Markdown("Select a LoRA 4")
640
- with gr.Column(scale=5, min_width=50):
641
- lora_scale_4 = gr.Slider(label="LoRA 4 Scale", minimum=0, maximum=3, step=0.01, value=1.15)
642
- with gr.Row():
643
- remove_button_4 = gr.Button("Remove", size="sm")
644
- # LoRA 5
645
- with gr.Column(scale=8):
646
- with gr.Row():
647
- with gr.Column(scale=0, min_width=50):
648
- lora_image_5 = gr.Image(label="LoRA 5 Image", interactive=False, min_width=50, width=50, show_label=False, show_share_button=False, show_download_button=False, show_fullscreen_button=False, height=50)
649
- with gr.Column(scale=3, min_width=100):
650
- selected_info_5 = gr.Markdown("Select a LoRA 5")
651
- with gr.Column(scale=5, min_width=50):
652
- lora_scale_5 = gr.Slider(label="LoRA 5 Scale", minimum=0, maximum=3, step=0.01, value=1.15)
653
- with gr.Row():
654
- remove_button_5 = gr.Button("Remove", size="sm")
655
- # LoRA 6
656
- with gr.Column(scale=8):
657
- with gr.Row():
658
- with gr.Column(scale=0, min_width=50):
659
- lora_image_6 = gr.Image(label="LoRA 6 Image", interactive=False, min_width=50, width=50, show_label=False, show_share_button=False, show_download_button=False, show_fullscreen_button=False, height=50)
660
- with gr.Column(scale=3, min_width=100):
661
- selected_info_6 = gr.Markdown("Select a LoRA 6")
662
- with gr.Column(scale=5, min_width=50):
663
- lora_scale_6 = gr.Slider(label="LoRA 6 Scale", minimum=0, maximum=3, step=0.01, value=1.15)
664
- with gr.Row():
665
- remove_button_6 = gr.Button("Remove", size="sm")
666
- with gr.Row():
667
- with gr.Column():
668
- with gr.Group():
669
- with gr.Row(elem_id="custom_lora_structure"):
670
- custom_lora = gr.Textbox(label="Custom LoRA", info="LoRA Hugging Face path or *.safetensors public URL", placeholder="multimodalart/vintage-ads-flux", scale=3, min_width=150)
671
- add_custom_lora_button = gr.Button("Add Custom LoRA", elem_id="custom_lora_btn", scale=2, min_width=150)
672
- remove_custom_lora_button = gr.Button("Remove Custom LoRA", visible=False)
673
- gr.Markdown("[Check the list of FLUX LoRAs](https://huggingface.co/models?other=base_model:adapter:black-forest-labs/FLUX.1-dev)", elem_id="lora_list")
674
- gallery = gr.Gallery(
675
- [(item["image"], item["title"]) for item in loras],
676
- label="Or pick from the LoRA Explorer gallery",
677
- allow_preview=False,
678
- columns=5,
679
- elem_id="gallery",
680
- show_share_button=False,
681
- interactive=False
682
- )
683
  with gr.Column():
684
- progress_bar = gr.Markdown(elem_id="progress", visible=False)
685
- result = gr.Image(label="Generated Image", interactive=False, show_share_button=False)
686
- with gr.Accordion("History", open=False):
687
- history_gallery = gr.Gallery(label="History", columns=6, object_fit="contain", interactive=False)
688
-
689
- with gr.Row():
690
- with gr.Accordion("Advanced Settings", open=False):
691
  with gr.Row():
692
- input_image = gr.Image(label="Input image", type="filepath", show_share_button=False)
693
- image_strength = gr.Slider(label="Denoise Strength", info="Lower means more image influence", minimum=0.1, maximum=1.0, step=0.01, value=0.75)
694
- with gr.Column():
695
- with gr.Row():
696
- cfg_scale = gr.Slider(label="CFG Scale", minimum=1, maximum=20, step=0.5, value=3.5)
697
- steps = gr.Slider(label="Steps", minimum=1, maximum=50, step=1, value=28)
698
 
699
- with gr.Row():
700
- width = gr.Slider(label="Width", minimum=256, maximum=1536, step=64, value=1024)
701
- height = gr.Slider(label="Height", minimum=256, maximum=1536, step=64, value=1024)
702
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
703
  with gr.Row():
704
- randomize_seed = gr.Checkbox(True, label="Randomize seed")
705
- seed = gr.Slider(label="Seed", minimum=0, maximum=MAX_SEED, step=1, value=0, randomize=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
706
 
707
- gallery.select(
708
- fn=update_selection,
709
- inputs=[selected_indices, loras_state, width, height],
710
- outputs=[
711
- prompt,
712
- selected_info_1, selected_info_2, selected_info_3, selected_info_4, selected_info_5, selected_info_6,
713
- selected_indices,
714
- lora_scale_1, lora_scale_2, lora_scale_3, lora_scale_4, lora_scale_5, lora_scale_6,
715
- width, height,
716
- lora_image_1, lora_image_2, lora_image_3, lora_image_4, lora_image_5, lora_image_6
717
- ])
718
- remove_lora_1event = remove_button_1.click(
719
- fn=remove_lora_1,
720
- inputs=[0, selected_indices, loras_state],
721
- outputs=[
722
- selected_info_1, selected_info_2, selected_info_3, selected_info_4, selected_info_5, selected_info_6,
723
- selected_indices,
724
- lora_scale_1, lora_scale_2, lora_scale_3, lora_scale_4, lora_scale_5, lora_scale_6,
725
- lora_image_1, lora_image_2, lora_image_3, lora_image_4, lora_image_5, lora_image_6
726
- ]
727
- )
728
- remove_button_2.click(
729
- remove_lora_2,
730
- inputs=[selected_indices, loras_state],
731
- outputs=[
732
- selected_info_1, selected_info_2, selected_info_3, selected_info_4, selected_info_5, selected_info_6,
733
- selected_indices,
734
- lora_scale_1, lora_scale_2, lora_scale_3, lora_scale_4, lora_scale_5, lora_scale_6,
735
- lora_image_1, lora_image_2, lora_image_3, lora_image_4, lora_image_5, lora_image_6
736
- ]
737
- )
738
- remove_button_3.click(
739
- remove_lora_3,
740
- inputs=[selected_indices, loras_state],
741
- outputs=[
742
- selected_info_1, selected_info_2, selected_info_3, selected_info_4, selected_info_5, selected_info_6,
743
- selected_indices,
744
- lora_scale_1, lora_scale_2, lora_scale_3, lora_scale_4, lora_scale_5, lora_scale_6,
745
- lora_image_1, lora_image_2, lora_image_3, lora_image_4, lora_image_5, lora_image_6
746
- ]
747
- )
748
- remove_button_4.click(
749
- remove_lora_4,
750
- inputs=[selected_indices, loras_state],
751
- outputs=[
752
- selected_info_1, selected_info_2, selected_info_3, selected_info_4, selected_info_5, selected_info_6,
753
- selected_indices,
754
- lora_scale_1, lora_scale_2, lora_scale_3, lora_scale_4, lora_scale_5, lora_scale_6,
755
- lora_image_1, lora_image_2, lora_image_3, lora_image_4, lora_image_5, lora_image_6
756
- ]
757
- )
758
- remove_button_5.click(
759
- remove_lora_5,
760
- inputs=[selected_indices, loras_state],
761
- outputs=[
762
- selected_info_1, selected_info_2, selected_info_3, selected_info_4, selected_info_5, selected_info_6,
763
- selected_indices,
764
- lora_scale_1, lora_scale_2, lora_scale_3, lora_scale_4, lora_scale_5, lora_scale_6,
765
- lora_image_1, lora_image_2, lora_image_3, lora_image_4, lora_image_5, lora_image_6
766
- ]
767
- )
768
- remove_button_6.click(
769
- remove_lora_6,
770
- inputs=[selected_indices, loras_state],
771
- outputs=[
772
- selected_info_1, selected_info_2, selected_info_3, selected_info_4, selected_info_5, selected_info_6,
773
- selected_indices,
774
- lora_scale_1, lora_scale_2, lora_scale_3, lora_scale_4, lora_scale_5, lora_scale_6,
775
- lora_image_1, lora_image_2, lora_image_3, lora_image_4, lora_image_5, lora_image_6
776
- ]
777
- )
778
- randomize_button.click(
779
- randomize_loras,
780
- inputs=[selected_indices, loras_state],
781
- outputs=[
782
- selected_info_1, selected_info_2, selected_info_3, selected_info_4, selected_info_5, selected_info_6,
783
- selected_indices,
784
- lora_scale_1, lora_scale_2, lora_scale_3, lora_scale_4, lora_scale_5, lora_scale_6,
785
- lora_image_1, lora_image_2, lora_image_3, lora_image_4, lora_image_5, lora_image_6,
786
- prompt
787
- ]
788
- )
789
- add_custom_lora_button.click(
790
- add_custom_lora,
791
- inputs=[custom_lora, selected_indices, loras_state, gallery],
792
- outputs=[
793
- loras_state,
794
- gallery,
795
- selected_info_1, selected_info_2, selected_info_3, selected_info_4, selected_info_5, selected_info_6,
796
- selected_indices,
797
- lora_scale_1, lora_scale_2, lora_scale_3, lora_scale_4, lora_scale_5, lora_scale_6,
798
- lora_image_1, lora_image_2, lora_image_3, lora_image_4, lora_image_5, lora_image_6
799
- ]
800
- )
801
- gr.on(
802
- triggers=[generate_button.click, prompt.submit],
803
- fn=run_lora,
804
  inputs=[
805
- prompt, input_image, image_strength, cfg_scale, steps, selected_indices,
806
- lora_scale_1, lora_scale_2, lora_scale_3, lora_scale_4, lora_scale_5, lora_scale_6,
807
- randomize_seed, seed, width, height, loras_state],
 
 
 
 
 
 
 
808
  outputs=[result, seed, progress_bar]
809
  ).then(
810
  fn=lambda x, history: update_history(x, history),
 
4
  import logging
5
  import torch
6
  from PIL import Image
7
+ import spaces
8
  from diffusers import DiffusionPipeline, AutoencoderTiny, AutoencoderKL, AutoPipelineForImage2Image
9
  from live_preview_helpers import calculate_shift, retrieve_timesteps, flux_pipe_call_that_returns_an_iterable_of_images
10
  from diffusers.utils import load_image
 
14
  import time
15
  import requests
16
  import pandas as pd
 
17
 
18
  # Load prompts for randomization
19
  df = pd.read_csv('prompts.csv', header=None)
 
81
  file.write(response.content)
82
 
83
  return filepath
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
 
85
  def check_custom_model(link):
86
+ # Your existing implementation of check_custom_model
87
+ # ...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
 
89
  def update_history(new_image, history):
90
  """Updates the history gallery with the new image."""
 
116
  #component-11{align-self: stretch;}
117
  '''
118
 
119
+ with gr.Blocks(css=css, theme=gr.themes.Default(), delete_cache=(60, 60)) as app:
120
  title = gr.HTML(
121
  """<h1><img src="https://i.imgur.com/wMh2Oek.png" alt="LoRA"> LoRA Lab [beta]</h1><br><span style="
122
  margin-top: -25px !important;
 
127
  )
128
  loras_state = gr.State(loras)
129
  selected_indices = gr.State([])
130
+
131
+ # Define UI components
132
  with gr.Row():
133
  with gr.Column(scale=3):
134
  prompt = gr.Textbox(label="Prompt", lines=1, placeholder="Type a prompt after selecting a LoRA")
135
  with gr.Column(scale=1):
136
  generate_button = gr.Button("Generate", variant="primary", elem_classes=["button_total"])
137
+
138
  with gr.Row(elem_id="loaded_loras"):
139
+ randomize_button = gr.Button("🎲", variant="secondary", scale=1, elem_id="random_btn")
140
+ # We'll dynamically render the LoRA selections below using @gr.render
141
+
142
+ with gr.Group():
143
+ with gr.Row(elem_id="custom_lora_structure"):
144
+ custom_lora = gr.Textbox(label="Custom LoRA", info="LoRA Hugging Face path or *.safetensors public URL", placeholder="multimodalart/vintage-ads-flux", scale=3, min_width=150)
145
+ add_custom_lora_button = gr.Button("Add Custom LoRA", elem_id="custom_lora_btn", scale=2, min_width=150)
146
+ remove_custom_lora_button = gr.Button("Remove Custom LoRA", visible=False)
147
+ gr.Markdown("[Check the list of FLUX LoRAs](https://huggingface.co/models?other=base_model:adapter:black-forest-labs/FLUX.1-dev)", elem_id="lora_list")
148
+ gallery = gr.Gallery(
149
+ [(item["image"], item["title"]) for item in loras],
150
+ label="Or pick from the LoRA Explorer gallery",
151
+ allow_preview=False,
152
+ columns=5,
153
+ elem_id="gallery",
154
+ show_share_button=False,
155
+ interactive=True # Set to True to allow selection
156
+ )
157
+ progress_bar = gr.Markdown(elem_id="progress", visible=False)
158
+ result = gr.Image(label="Generated Image", interactive=False, show_share_button=False)
159
+ with gr.Accordion("History", open=False):
160
+ history_gallery = gr.Gallery(label="History", columns=6, object_fit="contain", interactive=False)
161
+
162
+ with gr.Accordion("Advanced Settings", open=False):
163
+ with gr.Row():
164
+ input_image = gr.Image(label="Input image", type="filepath", show_share_button=False)
165
+ image_strength = gr.Slider(label="Denoise Strength", info="Lower means more image influence", minimum=0.1, maximum=1.0, step=0.01, value=0.75)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166
  with gr.Column():
 
 
 
 
 
 
 
167
  with gr.Row():
168
+ cfg_scale = gr.Slider(label="CFG Scale", minimum=1, maximum=20, step=0.5, value=3.5)
169
+ steps = gr.Slider(label="Steps", minimum=1, maximum=50, step=1, value=28)
 
 
 
 
170
 
171
+ with gr.Row():
172
+ width = gr.Slider(label="Width", minimum=256, maximum=1536, step=64, value=1024)
173
+ height = gr.Slider(label="Height", minimum=256, maximum=1536, step=64, value=1024)
174
 
175
+ with gr.Row():
176
+ randomize_seed = gr.Checkbox(True, label="Randomize seed")
177
+ seed = gr.Slider(label="Seed", minimum=0, maximum=MAX_SEED, step=1, value=0, randomize=True)
178
+
179
+ # Define states for LoRA selections
180
+ selected_loras_state = gr.State([]) # List of selected LoRA indices
181
+ lora_scales_state = gr.State([]) # List of corresponding scales
182
+
183
+ # Function to handle gallery selection
184
+ @gr.render(inputs=[gallery], outputs=[], triggers=[gallery.select])
185
+ def update_lora_selection(selected_gallery):
186
+ selected_index = selected_gallery.index
187
+ selected_indices = selected_loras_state.value.copy()
188
+ if selected_index in selected_indices:
189
+ selected_indices.remove(selected_index)
190
+ else:
191
+ if len(selected_indices) < 6:
192
+ selected_indices.append(selected_index)
193
+ else:
194
+ gr.Warning("You can select up to 6 LoRAs. Remove one to select a new one.")
195
+ selected_loras_state.value = selected_indices
196
+
197
+ # Function to render the LoRA selection components dynamically
198
+ @gr.render(inputs=[selected_loras_state], outputs=[], triggers=[selected_loras_state.change])
199
+ def render_lora_selections(selected_indices):
200
+ lora_scales = lora_scales_state.value
201
+ if len(lora_scales) != len(selected_indices):
202
+ lora_scales = [1.15] * len(selected_indices)
203
+ lora_scales_state.value = lora_scales
204
+
205
+ # Clear previous components
206
+ gr.Markdown("### Selected LoRAs")
207
+ if not selected_indices:
208
+ gr.Markdown("No LoRAs selected.")
209
+ else:
210
+ for idx, sel_idx in enumerate(selected_indices):
211
+ lora = loras_state.value[sel_idx]
212
  with gr.Row():
213
+ with gr.Column(scale=1, min_width=50):
214
+ gr.Image(value=lora['image'], interactive=False, show_label=False, height=50)
215
+ with gr.Column(scale=3):
216
+ gr.Markdown(f"### LoRA {idx+1}: [{lora['title']}](https://huggingface.co/{lora['repo']}) ✨")
217
+ with gr.Column(scale=2):
218
+ scale_slider = gr.Slider(label=f"Scale {idx+1}", minimum=0, maximum=3, step=0.01, value=lora_scales[idx])
219
+ scale_slider.change(lambda val, idx=idx: update_lora_scale(idx, val), inputs=[scale_slider], outputs=[])
220
+ with gr.Column(scale=1, min_width=50):
221
+ remove_btn = gr.Button("Remove", size="sm")
222
+ remove_btn.click(lambda idx=idx: remove_lora(idx), inputs=[], outputs=[])
223
+
224
+ # Helper function to update LoRA scales
225
+ def update_lora_scale(idx, value):
226
+ lora_scales = lora_scales_state.value
227
+ lora_scales[idx] = value
228
+ lora_scales_state.value = lora_scales
229
+
230
+ # Helper function to remove a LoRA
231
+ def remove_lora(idx):
232
+ selected_indices = selected_loras_state.value
233
+ lora_scales = lora_scales_state.value
234
+ if idx < len(selected_indices):
235
+ selected_indices.pop(idx)
236
+ lora_scales.pop(idx)
237
+ selected_loras_state.value = selected_indices
238
+ lora_scales_state.value = lora_scales
239
+
240
+ # Randomize LoRAs
241
+ def randomize_loras():
242
+ num_loras = min(6, len(loras_state.value))
243
+ selected_indices = random.sample(range(len(loras_state.value)), num_loras)
244
+ lora_scales = [1.15] * num_loras
245
+ selected_loras_state.value = selected_indices
246
+ lora_scales_state.value = lora_scales
247
+ random_prompt = random.choice(prompt_values)
248
+ prompt.value = random_prompt
249
+
250
+ randomize_button.click(randomize_loras, inputs=[], outputs=[])
251
+
252
+ # Add custom LoRA
253
+ def add_custom_lora_fn(custom_lora_input):
254
+ if custom_lora_input:
255
+ try:
256
+ title, repo, path, trigger_word, image = check_custom_model(custom_lora_input)
257
+ existing_item_index = next((index for (index, item) in enumerate(loras_state.value) if item['repo'] == repo), None)
258
+ if existing_item_index is None:
259
+ if repo.endswith(".safetensors") and repo.startswith("http"):
260
+ repo = download_file(repo)
261
+ new_item = {
262
+ "image": image if image else "/home/user/app/custom.png",
263
+ "title": title,
264
+ "repo": repo,
265
+ "weights": path,
266
+ "trigger_word": trigger_word
267
+ }
268
+ existing_item_index = len(loras_state.value)
269
+ loras_state.value.append(new_item)
270
+ # Update gallery
271
+ gallery.value = [(item["image"], item["title"]) for item in loras_state.value]
272
+ if len(selected_loras_state.value) < 6:
273
+ selected_loras_state.value.append(existing_item_index)
274
+ lora_scales_state.value.append(1.15)
275
+ else:
276
+ gr.Warning("You can select up to 6 LoRAs. Remove one to select a new one.")
277
+ except Exception as e:
278
+ gr.Warning(str(e))
279
+
280
+ add_custom_lora_button.click(add_custom_lora_fn, inputs=[custom_lora], outputs=[])
281
+
282
+ # Run the LoRA generation
283
+ @spaces.GPU(duration=75)
284
+ def run_lora(prompt_text, image_input_path, image_strength_value, cfg_scale_value, steps_value, randomize_seed_value, seed_value, width_value, height_value):
285
+ selected_indices = selected_loras_state.value
286
+ lora_scales = lora_scales_state.value
287
+
288
+ if not selected_indices:
289
+ raise gr.Error("You must select at least one LoRA before proceeding.")
290
+
291
+ selected_loras = [loras_state.value[idx] for idx in selected_indices]
292
+
293
+ # Build the prompt with trigger words
294
+ prepends = []
295
+ appends = []
296
+ for lora in selected_loras:
297
+ trigger_word = lora.get('trigger_word', '')
298
+ if trigger_word:
299
+ if lora.get("trigger_position") == "prepend":
300
+ prepends.append(trigger_word)
301
+ else:
302
+ appends.append(trigger_word)
303
+ prompt_mash = " ".join(prepends + [prompt_text] + appends)
304
+ print("Prompt Mash: ", prompt_mash)
305
+ # Unload previous LoRA weights
306
+ with calculateDuration("Unloading LoRA"):
307
+ pipe.unload_lora_weights()
308
+ pipe_i2i.unload_lora_weights()
309
+
310
+ print(pipe.get_active_adapters())
311
+ # Load LoRA weights with respective scales
312
+ lora_names = []
313
+ lora_weights = []
314
+ with calculateDuration("Loading LoRA weights"):
315
+ for idx, lora in enumerate(selected_loras):
316
+ lora_name = f"lora_{idx}"
317
+ lora_names.append(lora_name)
318
+ print(f"Lora Name: {lora_name}")
319
+ lora_weights.append(lora_scales[idx])
320
+ lora_path = lora['repo']
321
+ weight_name = lora.get("weights")
322
+ print(f"Lora Path: {lora_path}")
323
+ pipe_to_use = pipe_i2i if image_input_path is not None else pipe
324
+ pipe_to_use.load_lora_weights(
325
+ lora_path,
326
+ weight_name=weight_name if weight_name else None,
327
+ low_cpu_mem_usage=True,
328
+ adapter_name=lora_name
329
+ )
330
+ print("Loaded LoRAs:", lora_names)
331
+ print("Adapter weights:", lora_weights)
332
+ if image_input_path is not None:
333
+ pipe_i2i.set_adapters(lora_names, adapter_weights=lora_weights)
334
+ else:
335
+ pipe.set_adapters(lora_names, adapter_weights=lora_weights)
336
+ print(pipe.get_active_adapters())
337
+ # Set random seed for reproducibility
338
+ with calculateDuration("Randomizing seed"):
339
+ if randomize_seed_value:
340
+ seed_value = random.randint(0, MAX_SEED)
341
 
342
+ # Generate image
343
+ if image_input_path is not None:
344
+ final_image = generate_image_to_image(prompt_mash, image_input_path, image_strength_value, steps_value, cfg_scale_value, width_value, height_value, seed_value)
345
+ yield final_image, seed_value, gr.update(visible=False)
346
+ else:
347
+ image_generator = generate_image(prompt_mash, steps_value, seed_value, cfg_scale_value, width_value, height_value, progress=gr.Progress(track_tqdm=True))
348
+ # Consume the generator to get the final image
349
+ final_image = None
350
+ step_counter = 0
351
+ for image in image_generator:
352
+ step_counter += 1
353
+ final_image = image
354
+ progress_bar_html = f'<div class="progress-container"><div class="progress-bar" style="--current: {step_counter}; --total: {steps_value};"></div></div>'
355
+ yield image, seed_value, gr.update(value=progress_bar_html, visible=True)
356
+ yield final_image, seed_value, gr.update(value=progress_bar_html, visible=False)
357
+
358
+ run_lora.zerogpu = True
359
+
360
+ # Bind the generate button to run_lora function
361
+ generate_button.click(
362
+ run_lora,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
363
  inputs=[
364
+ prompt,
365
+ input_image,
366
+ image_strength,
367
+ cfg_scale,
368
+ steps,
369
+ randomize_seed,
370
+ seed,
371
+ width,
372
+ height
373
+ ],
374
  outputs=[result, seed, progress_bar]
375
  ).then(
376
  fn=lambda x, history: update_history(x, history),