John6666 commited on
Commit
e2e3edb
·
verified ·
1 Parent(s): 0867260

Upload 4 files

Browse files
Files changed (3) hide show
  1. app.py +13 -13
  2. modutils.py +540 -156
  3. requirements.txt +2 -1
app.py CHANGED
@@ -163,7 +163,6 @@ def process_string(input_string):
163
  ## BEGIN MOD
164
  from modutils import (
165
  download_private_repo,
166
- get_private_lora_model_lists,
167
  get_local_model_list,
168
  get_model_id_list,
169
  escape_lora_basename,
@@ -172,6 +171,7 @@ from modutils import (
172
  get_tupled_embed_list,
173
  update_lora_dict,
174
  get_lora_model_list,
 
175
  )
176
  from env import (
177
  hf_token,
@@ -253,18 +253,19 @@ def get_my_lora(link_url):
253
  path.resolve().rename(new_path.resolve())
254
  update_lora_dict(str(new_path))
255
  new_lora_model_list = get_lora_model_list()
 
256
 
257
  return gr.update(
258
- choices=get_lora_tupled_list(new_lora_model_list), value=new_lora_model_list[-1]
259
  ), gr.update(
260
- choices=get_lora_tupled_list(new_lora_model_list)
261
  ), gr.update(
262
- choices=get_lora_tupled_list(new_lora_model_list)
263
  ), gr.update(
264
- choices=get_lora_tupled_list(new_lora_model_list)
265
  ), gr.update(
266
- choices=get_lora_tupled_list(new_lora_model_list)
267
- ),
268
  ## END MOD
269
 
270
  print('\033[33m🏁 Download and listing of valid models completed.\033[0m')
@@ -384,7 +385,6 @@ from modutils import (
384
  move_file_lora,
385
  set_lora_trigger,
386
  set_lora_prompt,
387
- get_lora_tupled_list,
388
  apply_lora_prompt,
389
  search_civitai_lora,
390
  select_civitai_lora,
@@ -1032,35 +1032,35 @@ with gr.Blocks(theme="NoCrypt/miku@>=1.2.2", elem_id="main", css=CSS) as app:
1032
  hires_negative_prompt_gui = gr.Textbox(label="Hires Negative Prompt", placeholder="Main negative prompt will be use", lines=3)
1033
 
1034
  with gr.Accordion("LoRA", open=False, visible=True) as menu_lora:
1035
- lora1_gui = gr.Dropdown(label="Lora1", choices=get_lora_tupled_list(lora_model_list), value="", allow_custom_value=True)
1036
  lora_scale_1_gui = gr.Slider(minimum=-2, maximum=2, step=0.01, value=1.00, label="Lora Scale 1")
1037
  with gr.Row():
1038
  with gr.Group():
1039
  lora1_trigger_gui = gr.Textbox(label="Lora1 prompts", info="Example of prompt:", value="None", show_copy_button=True, interactive=False, visible=False)
1040
  lora1_copy_button = gr.Button(value="Copy example to prompt", visible=False)
1041
  lora1_desc_gui = gr.Markdown(value="", visible=False)
1042
- lora2_gui = gr.Dropdown(label="Lora2", choices=get_lora_tupled_list(lora_model_list), value="", allow_custom_value=True)
1043
  lora_scale_2_gui = gr.Slider(minimum=-2, maximum=2, step=0.01, value=1.00, label="Lora Scale 2")
1044
  with gr.Row():
1045
  with gr.Group():
1046
  lora2_trigger_gui = gr.Textbox(label="Lora2 prompts", info="Example of prompt:", value="None", show_copy_button=True, interactive=False, visible=False)
1047
  lora2_copy_button = gr.Button(value="Copy example to prompt", visible=False)
1048
  lora2_desc_gui = gr.Markdown(value="", visible=False)
1049
- lora3_gui = gr.Dropdown(label="Lora3", choices=get_lora_tupled_list(lora_model_list), value="", allow_custom_value=True)
1050
  lora_scale_3_gui = gr.Slider(minimum=-2, maximum=2, step=0.01, value=1.00, label="Lora Scale 3")
1051
  with gr.Row():
1052
  with gr.Group():
1053
  lora3_trigger_gui = gr.Textbox(label="Lora3 prompts", info="Example of prompt:", value="None", show_copy_button=True, interactive=False, visible=False)
1054
  lora3_copy_button = gr.Button(value="Copy example to prompt", visible=False)
1055
  lora3_desc_gui = gr.Markdown(value="", visible=False)
1056
- lora4_gui = gr.Dropdown(label="Lora4", choices=get_lora_tupled_list(lora_model_list), value="", allow_custom_value=True)
1057
  lora_scale_4_gui = gr.Slider(minimum=-2, maximum=2, step=0.01, value=1.00, label="Lora Scale 4")
1058
  with gr.Row():
1059
  with gr.Group():
1060
  lora4_trigger_gui = gr.Textbox(label="Lora4 prompts", info="Example of prompt:", value="None", show_copy_button=True, interactive=False, visible=False)
1061
  lora4_copy_button = gr.Button(value="Copy example to prompt", visible=False)
1062
  lora4_desc_gui = gr.Markdown(value="", visible=False)
1063
- lora5_gui = gr.Dropdown(label="Lora5", choices=get_lora_tupled_list(lora_model_list), value="", allow_custom_value=True)
1064
  lora_scale_5_gui = gr.Slider(minimum=-2, maximum=2, step=0.01, value=1.00, label="Lora Scale 5")
1065
  with gr.Row():
1066
  with gr.Group():
 
163
  ## BEGIN MOD
164
  from modutils import (
165
  download_private_repo,
 
166
  get_local_model_list,
167
  get_model_id_list,
168
  escape_lora_basename,
 
171
  get_tupled_embed_list,
172
  update_lora_dict,
173
  get_lora_model_list,
174
+ get_all_lora_tupled_list,
175
  )
176
  from env import (
177
  hf_token,
 
253
  path.resolve().rename(new_path.resolve())
254
  update_lora_dict(str(new_path))
255
  new_lora_model_list = get_lora_model_list()
256
+ new_lora_tupled_list = get_all_lora_tupled_list()
257
 
258
  return gr.update(
259
+ choices=new_lora_tupled_list, value=new_lora_model_list[-1]
260
  ), gr.update(
261
+ choices=new_lora_tupled_list
262
  ), gr.update(
263
+ choices=new_lora_tupled_list
264
  ), gr.update(
265
+ choices=new_lora_tupled_list
266
  ), gr.update(
267
+ choices=new_lora_tupled_list
268
+ )
269
  ## END MOD
270
 
271
  print('\033[33m🏁 Download and listing of valid models completed.\033[0m')
 
385
  move_file_lora,
386
  set_lora_trigger,
387
  set_lora_prompt,
 
388
  apply_lora_prompt,
389
  search_civitai_lora,
390
  select_civitai_lora,
 
1032
  hires_negative_prompt_gui = gr.Textbox(label="Hires Negative Prompt", placeholder="Main negative prompt will be use", lines=3)
1033
 
1034
  with gr.Accordion("LoRA", open=False, visible=True) as menu_lora:
1035
+ lora1_gui = gr.Dropdown(label="Lora1", choices=get_all_lora_tupled_list(), value="", allow_custom_value=True)
1036
  lora_scale_1_gui = gr.Slider(minimum=-2, maximum=2, step=0.01, value=1.00, label="Lora Scale 1")
1037
  with gr.Row():
1038
  with gr.Group():
1039
  lora1_trigger_gui = gr.Textbox(label="Lora1 prompts", info="Example of prompt:", value="None", show_copy_button=True, interactive=False, visible=False)
1040
  lora1_copy_button = gr.Button(value="Copy example to prompt", visible=False)
1041
  lora1_desc_gui = gr.Markdown(value="", visible=False)
1042
+ lora2_gui = gr.Dropdown(label="Lora2", choices=get_all_lora_tupled_list(), value="", allow_custom_value=True)
1043
  lora_scale_2_gui = gr.Slider(minimum=-2, maximum=2, step=0.01, value=1.00, label="Lora Scale 2")
1044
  with gr.Row():
1045
  with gr.Group():
1046
  lora2_trigger_gui = gr.Textbox(label="Lora2 prompts", info="Example of prompt:", value="None", show_copy_button=True, interactive=False, visible=False)
1047
  lora2_copy_button = gr.Button(value="Copy example to prompt", visible=False)
1048
  lora2_desc_gui = gr.Markdown(value="", visible=False)
1049
+ lora3_gui = gr.Dropdown(label="Lora3", choices=get_all_lora_tupled_list(), value="", allow_custom_value=True)
1050
  lora_scale_3_gui = gr.Slider(minimum=-2, maximum=2, step=0.01, value=1.00, label="Lora Scale 3")
1051
  with gr.Row():
1052
  with gr.Group():
1053
  lora3_trigger_gui = gr.Textbox(label="Lora3 prompts", info="Example of prompt:", value="None", show_copy_button=True, interactive=False, visible=False)
1054
  lora3_copy_button = gr.Button(value="Copy example to prompt", visible=False)
1055
  lora3_desc_gui = gr.Markdown(value="", visible=False)
1056
+ lora4_gui = gr.Dropdown(label="Lora4", choices=get_all_lora_tupled_list(), value="", allow_custom_value=True)
1057
  lora_scale_4_gui = gr.Slider(minimum=-2, maximum=2, step=0.01, value=1.00, label="Lora Scale 4")
1058
  with gr.Row():
1059
  with gr.Group():
1060
  lora4_trigger_gui = gr.Textbox(label="Lora4 prompts", info="Example of prompt:", value="None", show_copy_button=True, interactive=False, visible=False)
1061
  lora4_copy_button = gr.Button(value="Copy example to prompt", visible=False)
1062
  lora4_desc_gui = gr.Markdown(value="", visible=False)
1063
+ lora5_gui = gr.Dropdown(label="Lora5", choices=get_all_lora_tupled_list(), value="", allow_custom_value=True)
1064
  lora_scale_5_gui = gr.Slider(minimum=-2, maximum=2, step=0.01, value=1.00, label="Lora Scale 5")
1065
  with gr.Row():
1066
  with gr.Group():
modutils.py CHANGED
@@ -1,6 +1,7 @@
1
  import json
2
  import gradio as gr
3
  from huggingface_hub import HfApi
 
4
  from pathlib import Path
5
 
6
  from env import (
@@ -10,29 +11,21 @@ from env import (
10
  HF_MODEL_USER_LIKES,
11
  directory_loras,
12
  hf_read_token,
 
 
13
  )
14
 
 
15
  def get_user_agent():
16
  return 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:127.0) Gecko/20100101 Firefox/127.0'
17
 
18
 
19
- def change_interface_mode(mode: str):
20
- if mode == "Fast":
21
- return gr.update(open=False), gr.update(visible=True), gr.update(open=False), gr.update(open=False),\
22
- gr.update(visible=True), gr.update(open=False), gr.update(visible=True), gr.update(open=False),\
23
- gr.update(visible=True), gr.update(value="Fast")
24
- elif mode == "Simple": # t2i mode
25
- return gr.update(open=True), gr.update(visible=True), gr.update(open=False), gr.update(open=False),\
26
- gr.update(visible=True), gr.update(open=False), gr.update(visible=False), gr.update(open=True),\
27
- gr.update(visible=False), gr.update(value="Standard")
28
- elif mode == "LoRA": # t2i LoRA mode
29
- return gr.update(open=True), gr.update(visible=True), gr.update(open=True), gr.update(open=False),\
30
- gr.update(visible=True), gr.update(open=True), gr.update(visible=True), gr.update(open=False),\
31
- gr.update(visible=False), gr.update(value="Standard")
32
- else: # Standard
33
- return gr.update(open=False), gr.update(visible=True), gr.update(open=False), gr.update(open=False),\
34
- gr.update(visible=True), gr.update(open=False), gr.update(visible=True), gr.update(open=False),\
35
- gr.update(visible=True), gr.update(value="Standard")
36
 
37
 
38
  def get_local_model_list(dir_path):
@@ -45,25 +38,83 @@ def get_local_model_list(dir_path):
45
  return model_list
46
 
47
 
48
- def list_uniq(l):
49
- return sorted(set(l), key=l.index)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
 
51
 
52
- def list_sub(a, b):
53
- return [e for e in a if e not in b]
54
 
55
 
56
- def normalize_prompt_list(tags):
57
- prompts = []
58
- for tag in tags:
59
- tag = str(tag).strip()
60
- if tag:
61
- prompts.append(tag)
62
- return prompts
63
 
64
 
65
- def escape_lora_basename(basename: str):
66
- return basename.replace(".", "_").replace(" ", "_").replace(",", "")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
 
68
 
69
  def download_private_repo(repo_id, dir_path, is_replace):
@@ -72,6 +123,7 @@ def download_private_repo(repo_id, dir_path, is_replace):
72
  try:
73
  snapshot_download(repo_id=repo_id, local_dir=dir_path, allow_patterns=['*.ckpt', '*.pt', '*.pth', '*.safetensors', '*.bin'], use_auth_token=hf_read_token)
74
  except Exception as e:
 
75
  return
76
  if is_replace:
77
  for file in Path(dir_path).glob("*"):
@@ -102,24 +154,6 @@ def get_private_model_list(repo_id, dir_path):
102
  return model_list
103
 
104
 
105
- private_lora_model_list = []
106
- def get_private_lora_model_lists():
107
- global private_lora_model_list
108
- if len(private_lora_model_list) != 0: return private_lora_model_list
109
- models1 = []
110
- models2 = []
111
- for repo in HF_LORA_PRIVATE_REPOS1:
112
- models1.extend(get_private_model_list(repo, directory_loras))
113
- for repo in HF_LORA_PRIVATE_REPOS2:
114
- models2.extend(get_private_model_list(repo, directory_loras))
115
- models = list_uniq(models1 + sorted(models2))
116
- private_lora_model_list = models
117
- return models
118
-
119
-
120
- private_lora_model_list = get_private_lora_model_lists()
121
-
122
-
123
  def download_private_file(repo_id, path, is_replace):
124
  from huggingface_hub import hf_hub_download
125
  file = Path(path)
@@ -142,7 +176,10 @@ def download_private_file_from_somewhere(path, is_replace):
142
  download_private_file(repo_id, path, is_replace)
143
 
144
 
 
145
  def get_model_id_list():
 
 
146
  api = HfApi()
147
  model_ids = []
148
  try:
@@ -153,6 +190,7 @@ def get_model_id_list():
153
  for author in HF_MODEL_USER_EX:
154
  models_ex = api.list_models(author=author, cardData=True, sort="last_modified")
155
  except Exception as e:
 
156
  return model_ids
157
  for model in models_likes:
158
  model_ids.append(model.id) if not model.private else ""
@@ -163,15 +201,20 @@ def get_model_id_list():
163
  anime_models.append(model.id) if 'anime' in model.tags else real_models.append(model.id)
164
  model_ids.extend(anime_models)
165
  model_ids.extend(real_models)
 
166
  return model_ids
167
 
168
 
 
 
 
169
  def get_t2i_model_info(repo_id: str):
170
  api = HfApi()
171
  try:
172
  if " " in repo_id or not api.repo_exists(repo_id): return ""
173
  model = api.model_info(repo_id=repo_id)
174
  except Exception as e:
 
175
  return ""
176
  if model.private or model.gated: return ""
177
  tags = model.tags
@@ -220,71 +263,37 @@ def get_tupled_model_list(model_list):
220
  return tupled_list
221
 
222
 
223
- def save_gallery_images(images, progress=gr.Progress(track_tqdm=True)):
224
- from datetime import datetime, timezone, timedelta
225
- progress(0, desc="Updating gallery...")
226
- dt_now = datetime.now(timezone(timedelta(hours=9)))
227
- basename = dt_now.strftime('%Y%m%d_%H%M%S_')
228
- i = 1
229
- if not images: return images
230
- output_images = []
231
- output_paths = []
232
- for image in images:
233
- filename = basename + str(i) + ".png"
234
- i += 1
235
- oldpath = Path(image[0])
236
- newpath = oldpath
237
- try:
238
- if oldpath.exists():
239
- newpath = oldpath.resolve().rename(Path(filename).resolve())
240
- except Exception:
241
- pass
242
- finally:
243
- output_paths.append(str(newpath))
244
- output_images.append((str(newpath), str(filename)))
245
- progress(1, desc="Gallery updated.")
246
- return gr.update(value=output_images), gr.update(value=output_paths), gr.update(visible=True)
247
-
248
 
249
- optimization_list = {
250
- "None": [28, 7., 'Euler a', False, 'None', 1.],
251
- "Default": [28, 7., 'Euler a', False, 'None', 1.],
252
- "SPO": [28, 7., 'Euler a', True, 'loras/spo_sdxl_10ep_4k-data_lora_diffusers.safetensors', 1.],
253
- "DPO": [28, 7., 'Euler a', True, 'loras/sdxl-DPO-LoRA.safetensors', 1.],
254
- "DPO Turbo": [8, 2.5, 'LCM', True, 'loras/sd_xl_dpo_turbo_lora_v1-128dim.safetensors', 1.],
255
- "SDXL Turbo": [8, 2.5, 'LCM', True, 'loras/sd_xl_turbo_lora_v1.safetensors', 1.],
256
- "Hyper-SDXL 12step": [12, 5., 'TCD', True, 'loras/Hyper-SDXL-12steps-CFG-lora.safetensors', 1.],
257
- "Hyper-SDXL 8step": [8, 5., 'TCD', True, 'loras/Hyper-SDXL-8steps-CFG-lora.safetensors', 1.],
258
- "Hyper-SDXL 4step": [4, 0, 'TCD', True, 'loras/Hyper-SDXL-4steps-lora.safetensors', 1.],
259
- "Hyper-SDXL 2step": [2, 0, 'TCD', True, 'loras/Hyper-SDXL-2steps-lora.safetensors', 1.],
260
- "Hyper-SDXL 1step": [1, 0, 'TCD', True, 'loras/Hyper-SDXL-1steps-lora.safetensors', 1.],
261
- "PCM 16step": [16, 4., 'Euler a trailing', True, 'loras/pcm_sdxl_normalcfg_16step_converted.safetensors', 1.],
262
- "PCM 8step": [8, 4., 'Euler a trailing', True, 'loras/pcm_sdxl_normalcfg_8step_converted.safetensors', 1.],
263
- "PCM 4step": [4, 2., 'Euler a trailing', True, 'loras/pcm_sdxl_smallcfg_4step_converted.safetensors', 1.],
264
- "PCM 2step": [2, 1., 'Euler a trailing', True, 'loras/pcm_sdxl_smallcfg_2step_converted.safetensors', 1.],
265
- }
266
 
 
 
 
 
 
 
 
 
 
 
 
 
 
267
 
268
- def set_optimization(opt, steps_gui, cfg_gui, sampler_gui, clip_skip_gui, lora_gui, lora_scale_gui):
269
- if not opt in list(optimization_list.keys()): opt = "None"
270
- def_steps_gui = 28
271
- def_cfg_gui = 7.
272
- steps = optimization_list.get(opt, "None")[0]
273
- cfg = optimization_list.get(opt, "None")[1]
274
- sampler = optimization_list.get(opt, "None")[2]
275
- clip_skip = optimization_list.get(opt, "None")[3]
276
- lora = optimization_list.get(opt, "None")[4]
277
- lora_scale = optimization_list.get(opt, "None")[5]
278
- if opt == "None":
279
- steps = max(steps_gui, def_steps_gui)
280
- cfg = max(cfg_gui, def_cfg_gui)
281
- clip_skip = clip_skip_gui
282
- elif opt == "SPO" or opt == "DPO":
283
- steps = max(steps_gui, def_steps_gui)
284
- cfg = max(cfg_gui, def_cfg_gui)
285
 
286
- return gr.update(value=steps), gr.update(value=cfg), gr.update(value=sampler),\
287
- gr.update(value=clip_skip), gr.update(value=lora), gr.update(value=lora_scale),
288
 
289
 
290
  def set_lora_prompt(prompt_gui, prompt_syntax_gui, lora1_gui, lora_scale_1_gui, lora2_gui, lora_scale_2_gui,\
@@ -318,19 +327,6 @@ def set_lora_prompt(prompt_gui, prompt_syntax_gui, lora1_gui, lora_scale_1_gui,
318
  return gr.update(value=prompt)
319
 
320
 
321
- lora_trigger_dict = {"None": ["", "", "", "", ""], "": ["", "", "", "", ""]}
322
- try:
323
- with open('lora_dict.json', encoding='utf-8') as f:
324
- temp_dict = json.load(f)
325
- for k, v in temp_dict.items():
326
- lora_trigger_dict[escape_lora_basename(k)] = v
327
- except Exception:
328
- pass
329
-
330
-
331
- civitai_not_exists_list = []
332
-
333
-
334
  def get_civitai_info(path):
335
  global civitai_not_exists_list
336
  import requests
@@ -368,15 +364,6 @@ def get_civitai_info(path):
368
  return items
369
 
370
 
371
- def update_lora_dict(path):
372
- global lora_trigger_dict
373
- key = escape_lora_basename(Path(path).stem)
374
- if key in lora_trigger_dict.keys(): return
375
- items = get_civitai_info(path)
376
- if items == None: return
377
- lora_trigger_dict[key] = items
378
-
379
-
380
  def get_lora_model_list():
381
  loras = list_uniq(get_private_lora_model_lists() + get_local_model_list(directory_loras))
382
  loras.insert(0, "None")
@@ -384,22 +371,29 @@ def get_lora_model_list():
384
  return loras
385
 
386
 
387
- def get_lora_tupled_list(lora_model_list):
388
- global lora_trigger_dict
389
- if not lora_model_list: return []
 
 
 
 
 
 
 
 
390
  tupled_list = []
391
- local_models = set(get_local_model_list(directory_loras))
392
- for model in lora_model_list:
393
- #if not model: continue
394
- basename = Path(model).stem if model else ""
395
- key = escape_lora_basename(basename)
396
  items = None
397
- if key in lora_trigger_dict.keys():
398
- items = lora_trigger_dict.get(key, None)
399
- elif model in local_models:
400
  items = get_civitai_info(model)
401
  if items != None:
402
- lora_trigger_dict[key] = items
403
  name = basename
404
  value = model
405
  if items and items[2] != "":
@@ -411,12 +405,312 @@ def get_lora_tupled_list(lora_model_list):
411
  return tupled_list
412
 
413
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
414
  def set_lora_trigger(lora_gui: str):
415
  if not lora_gui or lora_gui == "None": return gr.update(value="", visible=False), gr.update(visible=False),\
416
  gr.update(value="", visible=False), gr.update(value="")
417
  path = Path(lora_gui)
418
  new_path = Path(f'{path.parent.name}/{escape_lora_basename(path.stem)}{path.suffix}')
419
- if not new_path.stem in lora_trigger_dict.keys() and not str(path) in set(get_lora_model_list()):
420
  return gr.update(value="", visible=False), gr.update(visible=False),\
421
  gr.update(value="", visible=False), gr.update(value="")
422
  if not new_path.exists():
@@ -427,11 +721,11 @@ def set_lora_trigger(lora_gui: str):
427
  value = "None"
428
  md = "None"
429
  flag = False
430
- items = lora_trigger_dict.get(basename, None)
431
  if items == None:
432
  items = get_civitai_info(str(new_path))
433
  if items != None:
434
- lora_trigger_dict[basename] = items
435
  flag = True
436
  if items and items[2] != "":
437
  tag = items[0]
@@ -484,18 +778,19 @@ def move_file_lora(filepaths):
484
  update_lora_dict(str(newpath))
485
 
486
  new_lora_model_list = get_lora_model_list()
 
487
 
488
  return gr.update(
489
- choices=get_lora_tupled_list(new_lora_model_list), value=new_lora_model_list[-1]
490
  ), gr.update(
491
- choices=get_lora_tupled_list(new_lora_model_list)
492
  ), gr.update(
493
- choices=get_lora_tupled_list(new_lora_model_list)
494
  ), gr.update(
495
- choices=get_lora_tupled_list(new_lora_model_list)
496
  ), gr.update(
497
- choices=get_lora_tupled_list(new_lora_model_list)
498
- ),
499
 
500
 
501
  def search_lora_on_civitai(query: str, allow_model: list[str]):
@@ -563,6 +858,58 @@ def select_civitai_lora(search_result):
563
  return gr.update(value=search_result), gr.update(value=md, visible=True)
564
 
565
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
566
  quality_prompt_list = [
567
  {
568
  "name": "None",
@@ -661,6 +1008,47 @@ style_list = [
661
  ]
662
 
663
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
664
  # [sampler_gui, steps_gui, cfg_gui, clip_skip_gui, img_width_gui, img_height_gui, optimization_gui]
665
  preset_sampler_setting = {
666
  "None": ["Euler a", 28, 7., True, 1024, 1024, "None"],
@@ -832,14 +1220,12 @@ def set_textual_inversion_prompt(textual_inversion_gui, prompt_gui, neg_prompt_g
832
  tag = str(tag).strip()
833
  if tag and not tag in ti_tags:
834
  prompts.append(tag)
835
-
836
  ntags = neg_prompt_gui.split(",") if neg_prompt_gui else []
837
  neg_prompts = []
838
  for tag in ntags:
839
  tag = str(tag).strip()
840
  if tag and not tag in ti_tags:
841
  neg_prompts.append(tag)
842
-
843
  ti_prompts = []
844
  ti_neg_prompts = []
845
  for ti in textual_inversion_gui:
@@ -849,11 +1235,9 @@ def set_textual_inversion_prompt(textual_inversion_gui, prompt_gui, neg_prompt_g
849
  ti_prompts.append(tokens[0])
850
  else: # negative prompt (default)
851
  ti_neg_prompts.append(tokens[0])
852
-
853
  empty = [""]
854
  prompt = ", ".join(prompts + ti_prompts + empty)
855
  neg_prompt = ", ".join(neg_prompts + ti_neg_prompts + empty)
856
-
857
  return gr.update(value=prompt), gr.update(value=neg_prompt),
858
 
859
 
 
1
  import json
2
  import gradio as gr
3
  from huggingface_hub import HfApi
4
+ import os
5
  from pathlib import Path
6
 
7
  from env import (
 
11
  HF_MODEL_USER_LIKES,
12
  directory_loras,
13
  hf_read_token,
14
+ hf_token,
15
+ CIVITAI_API_KEY,
16
  )
17
 
18
+
19
  def get_user_agent():
20
  return 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:127.0) Gecko/20100101 Firefox/127.0'
21
 
22
 
23
+ def list_uniq(l):
24
+ return sorted(set(l), key=l.index)
25
+
26
+
27
+ def list_sub(a, b):
28
+ return [e for e in a if e not in b]
 
 
 
 
 
 
 
 
 
 
 
29
 
30
 
31
  def get_local_model_list(dir_path):
 
38
  return model_list
39
 
40
 
41
+ def download_things(directory, url, hf_token="", civitai_api_key=""):
42
+ url = url.strip()
43
+
44
+ if "drive.google.com" in url:
45
+ original_dir = os.getcwd()
46
+ os.chdir(directory)
47
+ os.system(f"gdown --fuzzy {url}")
48
+ os.chdir(original_dir)
49
+ elif "huggingface.co" in url:
50
+ url = url.replace("?download=true", "")
51
+ # url = urllib.parse.quote(url, safe=':/') # fix encoding
52
+ if "/blob/" in url:
53
+ url = url.replace("/blob/", "/resolve/")
54
+ user_header = f'"Authorization: Bearer {hf_token}"'
55
+ if hf_token:
56
+ os.system(f"aria2c --console-log-level=error --summary-interval=10 --header={user_header} -c -x 16 -k 1M -s 16 {url} -d {directory} -o {url.split('/')[-1]}")
57
+ else:
58
+ os.system (f"aria2c --optimize-concurrent-downloads --console-log-level=error --summary-interval=10 -c -x 16 -k 1M -s 16 {url} -d {directory} -o {url.split('/')[-1]}")
59
+ elif "civitai.com" in url:
60
+ if "?" in url:
61
+ url = url.split("?")[0]
62
+ if civitai_api_key:
63
+ url = url + f"?token={civitai_api_key}"
64
+ os.system(f"aria2c --console-log-level=error --summary-interval=10 -c -x 16 -k 1M -s 16 -d {directory} {url}")
65
+ else:
66
+ print("\033[91mYou need an API key to download Civitai models.\033[0m")
67
+ else:
68
+ os.system(f"aria2c --console-log-level=error --summary-interval=10 -c -x 16 -k 1M -s 16 -d {directory} {url}")
69
 
70
 
71
+ def escape_lora_basename(basename: str):
72
+ return basename.replace(".", "_").replace(" ", "_").replace(",", "")
73
 
74
 
75
+ def to_lora_key(path: str):
76
+ return escape_lora_basename(Path(path).stem)
 
 
 
 
 
77
 
78
 
79
+ def to_lora_path(key: str):
80
+ if Path(key).is_file(): return key
81
+ path = Path(f"{directory_loras}/{escape_lora_basename(key)}.safetensors")
82
+ return str(path)
83
+
84
+
85
+ def safe_float(input):
86
+ output = 1.0
87
+ try:
88
+ output = float(input)
89
+ except Exception:
90
+ output = 1.0
91
+ return output
92
+
93
+
94
+ def save_gallery_images(images, progress=gr.Progress(track_tqdm=True)):
95
+ from datetime import datetime, timezone, timedelta
96
+ progress(0, desc="Updating gallery...")
97
+ dt_now = datetime.now(timezone(timedelta(hours=9)))
98
+ basename = dt_now.strftime('%Y%m%d_%H%M%S_')
99
+ i = 1
100
+ if not images: return images
101
+ output_images = []
102
+ output_paths = []
103
+ for image in images:
104
+ filename = basename + str(i) + ".png"
105
+ i += 1
106
+ oldpath = Path(image[0])
107
+ newpath = oldpath
108
+ try:
109
+ if oldpath.exists():
110
+ newpath = oldpath.resolve().rename(Path(filename).resolve())
111
+ except Exception:
112
+ pass
113
+ finally:
114
+ output_paths.append(str(newpath))
115
+ output_images.append((str(newpath), str(filename)))
116
+ progress(1, desc="Gallery updated.")
117
+ return gr.update(value=output_images), gr.update(value=output_paths), gr.update(visible=True)
118
 
119
 
120
  def download_private_repo(repo_id, dir_path, is_replace):
 
123
  try:
124
  snapshot_download(repo_id=repo_id, local_dir=dir_path, allow_patterns=['*.ckpt', '*.pt', '*.pth', '*.safetensors', '*.bin'], use_auth_token=hf_read_token)
125
  except Exception as e:
126
+ print(f"Error: Failed to download {repo_id}. ")
127
  return
128
  if is_replace:
129
  for file in Path(dir_path).glob("*"):
 
154
  return model_list
155
 
156
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
  def download_private_file(repo_id, path, is_replace):
158
  from huggingface_hub import hf_hub_download
159
  file = Path(path)
 
176
  download_private_file(repo_id, path, is_replace)
177
 
178
 
179
+ model_id_list = []
180
  def get_model_id_list():
181
+ global model_id_list
182
+ if len(model_id_list) != 0: return model_id_list
183
  api = HfApi()
184
  model_ids = []
185
  try:
 
190
  for author in HF_MODEL_USER_EX:
191
  models_ex = api.list_models(author=author, cardData=True, sort="last_modified")
192
  except Exception as e:
193
+ print(f"Error: Failed to list {author}'s models. ")
194
  return model_ids
195
  for model in models_likes:
196
  model_ids.append(model.id) if not model.private else ""
 
201
  anime_models.append(model.id) if 'anime' in model.tags else real_models.append(model.id)
202
  model_ids.extend(anime_models)
203
  model_ids.extend(real_models)
204
+ model_id_list = model_ids.copy()
205
  return model_ids
206
 
207
 
208
+ model_id_list = get_model_id_list()
209
+
210
+
211
  def get_t2i_model_info(repo_id: str):
212
  api = HfApi()
213
  try:
214
  if " " in repo_id or not api.repo_exists(repo_id): return ""
215
  model = api.model_info(repo_id=repo_id)
216
  except Exception as e:
217
+ print(f"Error: Failed to get {repo_id}'s info. ")
218
  return ""
219
  if model.private or model.gated: return ""
220
  tags = model.tags
 
263
  return tupled_list
264
 
265
 
266
+ private_lora_dict = {}
267
+ try:
268
+ with open('lora_dict.json', encoding='utf-8') as f:
269
+ d = json.load(f)
270
+ for k, v in d.items():
271
+ private_lora_dict[escape_lora_basename(k)] = v
272
+ except Exception:
273
+ pass
274
+ loras_dict = {"None": ["", "", "", "", ""], "": ["", "", "", "", ""]} | private_lora_dict.copy()
275
+ civitai_not_exists_list = []
276
+ loras_url_to_path_dict = {} # {"URL to download": "local filepath", ...}
277
+ civitai_lora_last_results = {} # {"URL to download": {search results}, ...}
278
+ all_lora_list = []
 
 
 
 
 
 
 
 
 
 
 
 
279
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
280
 
281
+ private_lora_model_list = []
282
+ def get_private_lora_model_lists():
283
+ global private_lora_model_list
284
+ if len(private_lora_model_list) != 0: return private_lora_model_list
285
+ models1 = []
286
+ models2 = []
287
+ for repo in HF_LORA_PRIVATE_REPOS1:
288
+ models1.extend(get_private_model_list(repo, directory_loras))
289
+ for repo in HF_LORA_PRIVATE_REPOS2:
290
+ models2.extend(get_private_model_list(repo, directory_loras))
291
+ models = list_uniq(models1 + sorted(models2))
292
+ private_lora_model_list = models.copy()
293
+ return models
294
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
295
 
296
+ private_lora_model_list = get_private_lora_model_lists()
 
297
 
298
 
299
  def set_lora_prompt(prompt_gui, prompt_syntax_gui, lora1_gui, lora_scale_1_gui, lora2_gui, lora_scale_2_gui,\
 
327
  return gr.update(value=prompt)
328
 
329
 
 
 
 
 
 
 
 
 
 
 
 
 
 
330
  def get_civitai_info(path):
331
  global civitai_not_exists_list
332
  import requests
 
364
  return items
365
 
366
 
 
 
 
 
 
 
 
 
 
367
  def get_lora_model_list():
368
  loras = list_uniq(get_private_lora_model_lists() + get_local_model_list(directory_loras))
369
  loras.insert(0, "None")
 
371
  return loras
372
 
373
 
374
+ def get_all_lora_list():
375
+ global all_lora_list
376
+ loras = get_lora_model_list()
377
+ all_lora_list = loras.copy()
378
+ return loras
379
+
380
+
381
+ def get_all_lora_tupled_list():
382
+ global loras_dict
383
+ models = get_all_lora_list()
384
+ if not models: return []
385
  tupled_list = []
386
+ for model in models:
387
+ #if not model: continue # to avoid GUI-related bug
388
+ basename = Path(model).stem
389
+ key = to_lora_key(model)
 
390
  items = None
391
+ if key in loras_dict.keys():
392
+ items = loras_dict.get(key, None)
393
+ else:
394
  items = get_civitai_info(model)
395
  if items != None:
396
+ loras_dict[key] = items
397
  name = basename
398
  value = model
399
  if items and items[2] != "":
 
405
  return tupled_list
406
 
407
 
408
+ def update_lora_dict(path):
409
+ global loras_dict
410
+ key = escape_lora_basename(Path(path).stem)
411
+ if key in loras_dict.keys(): return
412
+ items = get_civitai_info(path)
413
+ if items == None: return
414
+ loras_dict[key] = items
415
+
416
+
417
+ def download_lora(dl_urls: str):
418
+ global loras_url_to_path_dict
419
+ dl_path = ""
420
+ before = get_local_model_list(directory_loras)
421
+ urls = []
422
+ for url in [url.strip() for url in dl_urls.split(',')]:
423
+ local_path = f"{directory_loras}/{url.split('/')[-1]}"
424
+ if not Path(local_path).exists():
425
+ download_things(directory_loras, url, hf_token, CIVITAI_API_KEY)
426
+ urls.append(url)
427
+ after = get_local_model_list(directory_loras)
428
+ new_files = list_sub(after, before)
429
+ i = 0
430
+ for file in new_files:
431
+ path = Path(file)
432
+ if path.exists():
433
+ new_path = Path(f'{path.parent.name}/{escape_lora_basename(path.stem)}{path.suffix}')
434
+ path.resolve().rename(new_path.resolve())
435
+ loras_url_to_path_dict[urls[i]] = str(new_path)
436
+ update_lora_dict(str(new_path))
437
+ dl_path = str(new_path)
438
+ i += 1
439
+ return dl_path
440
+
441
+
442
+ def copy_lora(path: str, new_path: str):
443
+ import shutil
444
+ if path == new_path: return new_path
445
+ cpath = Path(path)
446
+ npath = Path(new_path)
447
+ if cpath.exists():
448
+ try:
449
+ shutil.copy(str(cpath.resolve()), str(npath.resolve()))
450
+ except Exception:
451
+ return None
452
+ update_lora_dict(str(npath))
453
+ return new_path
454
+ else:
455
+ return None
456
+
457
+
458
+ def download_my_lora(dl_urls: str, lora1: str, lora2: str, lora3: str, lora4: str, lora5: str):
459
+ path = download_lora(dl_urls)
460
+ if path:
461
+ if not lora1 or lora1 == "None":
462
+ lora1 = path
463
+ elif not lora2 or lora2 == "None":
464
+ lora2 = path
465
+ elif not lora3 or lora3 == "None":
466
+ lora3 = path
467
+ elif not lora4 or lora4 == "None":
468
+ lora4 = path
469
+ elif not lora5 or lora5 == "None":
470
+ lora5 = path
471
+ choices = get_all_lora_tupled_list()
472
+ return gr.update(value=lora1, choices=choices), gr.update(value=lora2, choices=choices), gr.update(value=lora3, choices=choices),\
473
+ gr.update(value=lora4, choices=choices), gr.update(value=lora5, choices=choices)
474
+
475
+
476
+ def get_valid_lora_name(query: str):
477
+ path = "None"
478
+ if not query or query == "None": return "None"
479
+ if to_lora_key(query) in loras_dict.keys(): return query
480
+ if query in loras_url_to_path_dict.keys():
481
+ path = loras_url_to_path_dict[query]
482
+ else:
483
+ path = to_lora_path(query.strip().split('/')[-1])
484
+ if Path(path).exists():
485
+ return path
486
+ elif "http" in query:
487
+ dl_file = download_lora(query)
488
+ if dl_file and Path(dl_file).exists(): return dl_file
489
+ else:
490
+ dl_file = find_similar_lora(query)
491
+ if dl_file and Path(dl_file).exists(): return dl_file
492
+ return "None"
493
+
494
+
495
+ def get_valid_lora_path(query: str):
496
+ path = None
497
+ if not query or query == "None": return None
498
+ if to_lora_key(query) in loras_dict.keys(): return query
499
+ if Path(path).exists():
500
+ return path
501
+ else:
502
+ return None
503
+
504
+
505
+ def get_valid_lora_wt(prompt: str, lora_path: str, lora_wt: float):
506
+ import re
507
+ wt = lora_wt
508
+ result = re.findall(f'<lora:{to_lora_key(lora_path)}:(.+?)>', prompt)
509
+ if not result: return wt
510
+ wt = safe_float(result[0][0])
511
+ return wt
512
+
513
+
514
+ def set_prompt_loras(prompt, lora1, lora1_wt, lora2, lora2_wt, lora3, lora3_wt, lora4, lora4_wt, lora5, lora5_wt):
515
+ import re
516
+ lora1 = get_valid_lora_name(lora1)
517
+ lora2 = get_valid_lora_name(lora2)
518
+ lora3 = get_valid_lora_name(lora3)
519
+ lora4 = get_valid_lora_name(lora4)
520
+ lora5 = get_valid_lora_name(lora5)
521
+ if not "<lora" in prompt: return lora1, lora1_wt, lora2, lora2_wt, lora3, lora3_wt, lora4, lora4_wt, lora5, lora5_wt
522
+ lora1_wt = get_valid_lora_wt(prompt, lora1, lora1_wt)
523
+ lora2_wt = get_valid_lora_wt(prompt, lora2, lora2_wt)
524
+ lora3_wt = get_valid_lora_wt(prompt, lora3, lora3_wt)
525
+ lora4_wt = get_valid_lora_wt(prompt, lora4, lora4_wt)
526
+ lora5_wt = get_valid_lora_wt(prompt, lora5, lora5_wt)
527
+ on1, label1, tag1, md1 = get_lora_info(lora1)
528
+ on2, label2, tag2, md2 = get_lora_info(lora2)
529
+ on3, label3, tag3, md3 = get_lora_info(lora3)
530
+ on4, label4, tag4, md4 = get_lora_info(lora4)
531
+ on5, label5, tag5, md5 = get_lora_info(lora5)
532
+ lora_paths = [lora1, lora2, lora3, lora4, lora5]
533
+
534
+ prompts = prompt.split(",") if prompt else []
535
+ for p in prompts:
536
+ p = str(p).strip()
537
+ if "<lora" in p:
538
+ result = re.findall(r'<lora:(.+?):(.+?)>', p)
539
+ if not result: continue
540
+ key = result[0][0]
541
+ wt = result[0][1]
542
+ path = to_lora_path(key)
543
+ if not key in loras_dict.keys() or not path:
544
+ path = get_valid_lora_name(path)
545
+ if not path or path == "None": continue
546
+ if path in lora_paths:
547
+ continue
548
+ elif not on1:
549
+ lora1 = path
550
+ lora_paths = [lora1, lora2, lora3, lora4, lora5]
551
+ lora1_wt = safe_float(wt)
552
+ on1 = True
553
+ elif not on2:
554
+ lora2 = path
555
+ lora_paths = [lora1, lora2, lora3, lora4, lora5]
556
+ lora2_wt = safe_float(wt)
557
+ on2 = True
558
+ elif not on3:
559
+ lora3 = path
560
+ lora_paths = [lora1, lora2, lora3, lora4, lora5]
561
+ lora3_wt = safe_float(wt)
562
+ on3 = True
563
+ elif not on4:
564
+ lora4 = path
565
+ lora_paths = [lora1, lora2, lora3, lora4, lora5]
566
+ lora4_wt = safe_float(wt)
567
+ on4, label4, tag4, md4 = get_lora_info(lora4)
568
+ elif not on5:
569
+ lora5 = path
570
+ lora_paths = [lora1, lora2, lora3, lora4, lora5]
571
+ lora5_wt = safe_float(wt)
572
+ on5 = True
573
+
574
+ return lora1, lora1_wt, lora2, lora2_wt, lora3, lora3_wt, lora4, lora4_wt, lora5, lora5_wt
575
+
576
+
577
+ def get_lora_info(lora_path: str):
578
+ is_valid = False
579
+ tag = ""
580
+ label = ""
581
+ md = "None"
582
+ if not lora_path or lora_path == "None": return is_valid, label, tag, md
583
+ path = Path(lora_path)
584
+ new_path = Path(f'{path.parent.name}/{escape_lora_basename(path.stem)}{path.suffix}')
585
+ if not to_lora_key(str(new_path)) in loras_dict.keys() and not str(path) in set(all_lora_list):
586
+ return tag, label, md
587
+ if not new_path.exists():
588
+ download_private_file_from_somewhere(str(path), True)
589
+ basename = new_path.stem
590
+ label = f'Name: {basename}'
591
+ items = loras_dict.get(basename, None)
592
+ if items == None:
593
+ items = get_civitai_info(str(new_path))
594
+ if items != None:
595
+ loras_dict[basename] = items
596
+ if items and items[2] != "":
597
+ tag = items[0]
598
+ label = f'Name: {basename}'
599
+ if items[1] == "Pony":
600
+ label = f'Name: {basename} (for Pony🐴)'
601
+ if items[4]:
602
+ md = f'<img src="{items[4]}" alt="thumbnail" width="150" height="240"><br>[LoRA Model URL]({items[3]})'
603
+ elif items[3]:
604
+ md = f'[LoRA Model URL]({items[3]})'
605
+ is_valid = True
606
+ return is_valid, label, tag, md
607
+
608
+
609
+ def normalize_prompt_list(tags: list[str]):
610
+ prompts = []
611
+ for tag in tags:
612
+ tag = str(tag).strip()
613
+ if tag:
614
+ prompts.append(tag)
615
+ return prompts
616
+
617
+ '''
618
+ def apply_lora_prompt(prompt: str, lora_info: str):
619
+ if lora_info == "None": return gr.update(value=prompt)
620
+ tags = prompt.split(",") if prompt else []
621
+ prompts = normalize_prompt_list(tags)
622
+
623
+ lora_tag = lora_info.replace("/",",")
624
+ lora_tags = lora_tag.split(",") if str(lora_info) != "None" else []
625
+ lora_prompts = normalize_prompt_list(lora_tags)
626
+
627
+ empty = [""]
628
+ prompt = ", ".join(list_uniq(prompts + lora_prompts) + empty)
629
+ return gr.update(value=prompt)
630
+ '''
631
+
632
+ def update_loras(prompt, lora1, lora1_wt, lora2, lora2_wt, lora3, lora3_wt, lora4, lora4_wt, lora5, lora5_wt):
633
+ import re
634
+ on1, label1, tag1, md1 = get_lora_info(lora1)
635
+ on2, label2, tag2, md2 = get_lora_info(lora2)
636
+ on3, label3, tag3, md3 = get_lora_info(lora3)
637
+ on4, label4, tag4, md4 = get_lora_info(lora4)
638
+ on5, label5, tag5, md5 = get_lora_info(lora5)
639
+ lora_paths = [lora1, lora2, lora3, lora4, lora5]
640
+
641
+ prompts = prompt.split(",") if prompt else []
642
+ output_prompts = []
643
+ for p in prompts:
644
+ p = str(p).strip()
645
+ if "<lora" in p:
646
+ result = re.findall(r'<lora:(.+?):(.+?)>', p)
647
+ if not result: continue
648
+ key = result[0][0]
649
+ wt = result[0][1]
650
+ path = to_lora_path(key)
651
+ if not key in loras_dict.keys() or not path: continue
652
+ if path in lora_paths:
653
+ output_prompts.append(f"<lora:{to_lora_key(path)}:{safe_float(wt):.2f}>")
654
+ elif not on1:
655
+ lora1 = path
656
+ lora_paths = [lora1, lora2, lora3, lora4, lora5]
657
+ lora1_wt = safe_float(wt)
658
+ on1, label1, tag1, md1 = get_lora_info(lora1)
659
+ output_prompts.append(f"<lora:{to_lora_key(lora1)}:{lora1_wt:.2f}>")
660
+ elif not on2:
661
+ lora2 = path
662
+ lora_paths = [lora1, lora2, lora3, lora4, lora5]
663
+ lora2_wt = safe_float(wt)
664
+ on2, label2, tag2, md2 = get_lora_info(lora2)
665
+ output_prompts.append(f"<lora:{to_lora_key(lora2)}:{lora2_wt:.2f}>")
666
+ elif not on3:
667
+ lora3 = path
668
+ lora_paths = [lora1, lora2, lora3, lora4, lora5]
669
+ lora3_wt = safe_float(wt)
670
+ on3, label3, tag3, md3 = get_lora_info(lora3)
671
+ output_prompts.append(f"<lora:{to_lora_key(lora3)}:{lora3_wt:.2f}>")
672
+ elif not on4:
673
+ lora4 = path
674
+ lora_paths = [lora1, lora2, lora3, lora4, lora5]
675
+ lora4_wt = safe_float(wt)
676
+ on4, label4, tag4, md4 = get_lora_info(lora4)
677
+ output_prompts.append(f"<lora:{to_lora_key(lora4)}:{lora4_wt:.2f}>")
678
+ elif not on5:
679
+ lora5 = path
680
+ lora_paths = [lora1, lora2, lora3, lora4, lora5]
681
+ lora5_wt = safe_float(wt)
682
+ on5, label5, tag5, md5 = get_lora_info(lora5)
683
+ output_prompts.append(f"<lora:{to_lora_key(lora5)}:{lora5_wt:.2f}>")
684
+ elif p:
685
+ output_prompts.append(p)
686
+ lora_prompts = []
687
+ if on1: lora_prompts.append(f"<lora:{to_lora_key(lora1)}:{lora1_wt:.2f}>")
688
+ if on2: lora_prompts.append(f"<lora:{to_lora_key(lora2)}:{lora2_wt:.2f}>")
689
+ if on3: lora_prompts.append(f"<lora:{to_lora_key(lora3)}:{lora3_wt:.2f}>")
690
+ if on4: lora_prompts.append(f"<lora:{to_lora_key(lora4)}:{lora4_wt:.2f}>")
691
+ if on5: lora_prompts.append(f"<lora:{to_lora_key(lora5)}:{lora5_wt:.2f}>")
692
+ output_prompt = ", ".join(list_uniq(output_prompts + lora_prompts + [""]))
693
+
694
+ choices = get_all_lora_tupled_list()
695
+
696
+ return gr.update(value=output_prompt), gr.update(value=lora1, choices=choices), gr.update(value=lora1_wt),\
697
+ gr.update(value=tag1, label=label1, visible=on1), gr.update(visible=on1), gr.update(value=md1, visible=on1),\
698
+ gr.update(value=lora2, choices=choices), gr.update(value=lora2_wt),\
699
+ gr.update(value=tag2, label=label2, visible=on2), gr.update(visible=on2), gr.update(value=md2, visible=on2),\
700
+ gr.update(value=lora3, choices=choices), gr.update(value=lora3_wt),\
701
+ gr.update(value=tag3, label=label3, visible=on3), gr.update(visible=on3), gr.update(value=md3, visible=on3),\
702
+ gr.update(value=lora4, choices=choices), gr.update(value=lora4_wt),\
703
+ gr.update(value=tag4, label=label4, visible=on4), gr.update(visible=on4), gr.update(value=md4, visible=on4),\
704
+ gr.update(value=lora5, choices=choices), gr.update(value=lora5_wt),\
705
+ gr.update(value=tag5, label=label5, visible=on5), gr.update(visible=on5), gr.update(value=md5, visible=on5)
706
+
707
+
708
  def set_lora_trigger(lora_gui: str):
709
  if not lora_gui or lora_gui == "None": return gr.update(value="", visible=False), gr.update(visible=False),\
710
  gr.update(value="", visible=False), gr.update(value="")
711
  path = Path(lora_gui)
712
  new_path = Path(f'{path.parent.name}/{escape_lora_basename(path.stem)}{path.suffix}')
713
+ if not new_path.stem in loras_dict.keys() and not str(path) in set(get_lora_model_list()):
714
  return gr.update(value="", visible=False), gr.update(visible=False),\
715
  gr.update(value="", visible=False), gr.update(value="")
716
  if not new_path.exists():
 
721
  value = "None"
722
  md = "None"
723
  flag = False
724
+ items = loras_dict.get(basename, None)
725
  if items == None:
726
  items = get_civitai_info(str(new_path))
727
  if items != None:
728
+ loras_dict[basename] = items
729
  flag = True
730
  if items and items[2] != "":
731
  tag = items[0]
 
778
  update_lora_dict(str(newpath))
779
 
780
  new_lora_model_list = get_lora_model_list()
781
+ new_lora_tupled_list = get_all_lora_tupled_list()
782
 
783
  return gr.update(
784
+ choices=new_lora_tupled_list, value=new_lora_model_list[-1]
785
  ), gr.update(
786
+ choices=new_lora_tupled_list
787
  ), gr.update(
788
+ choices=new_lora_tupled_list
789
  ), gr.update(
790
+ choices=new_lora_tupled_list
791
  ), gr.update(
792
+ choices=new_lora_tupled_list
793
+ )
794
 
795
 
796
  def search_lora_on_civitai(query: str, allow_model: list[str]):
 
858
  return gr.update(value=search_result), gr.update(value=md, visible=True)
859
 
860
 
861
+ def find_similar_lora(q: str):
862
+ from rapidfuzz.process import extractOne
863
+ from rapidfuzz.utils import default_process
864
+ query = to_lora_key(q)
865
+ print(f"Finding <lora:{query}:...>...")
866
+ keys = list(private_lora_dict.keys())
867
+ values = [x[2] for x in list(private_lora_dict.values())]
868
+ s = default_process(query)
869
+ e1 = extractOne(s, keys + values, processor=default_process, score_cutoff=80.0)
870
+ key = ""
871
+ if e1:
872
+ e = e1[0]
873
+ if e in set(keys): key = e
874
+ elif e in set(values): key = keys[values.index(e)]
875
+ if key:
876
+ path = to_lora_path(key)
877
+ new_path = to_lora_path(query)
878
+ if not Path(path).exists():
879
+ if not Path(new_path).exists(): download_private_file_from_somewhere(path, True)
880
+ if Path(path).exists() and copy_lora(path, new_path): return new_path
881
+ print(f"Finding <lora:{query}:...> on Civitai...")
882
+ civitai_query = Path(query).stem if Path(query).is_file() else query
883
+ civitai_query = civitai_query.replace("_", " ").replace("-", " ")
884
+ base_model = ["Pony", "SDXL 1.0"]
885
+ items = search_lora_on_civitai(civitai_query, base_model, 1)
886
+ if items:
887
+ item = items[0]
888
+ path = download_lora(item['dl_url'])
889
+ new_path = query if Path(query).is_file() else to_lora_path(query)
890
+ if path and copy_lora(path, new_path): return new_path
891
+ return None
892
+
893
+
894
+ def change_interface_mode(mode: str):
895
+ if mode == "Fast":
896
+ return gr.update(open=False), gr.update(visible=True), gr.update(open=False), gr.update(open=False),\
897
+ gr.update(visible=True), gr.update(open=False), gr.update(visible=True), gr.update(open=False),\
898
+ gr.update(visible=True), gr.update(value="Fast")
899
+ elif mode == "Simple": # t2i mode
900
+ return gr.update(open=True), gr.update(visible=True), gr.update(open=False), gr.update(open=False),\
901
+ gr.update(visible=True), gr.update(open=False), gr.update(visible=False), gr.update(open=True),\
902
+ gr.update(visible=False), gr.update(value="Standard")
903
+ elif mode == "LoRA": # t2i LoRA mode
904
+ return gr.update(open=True), gr.update(visible=True), gr.update(open=True), gr.update(open=False),\
905
+ gr.update(visible=True), gr.update(open=True), gr.update(visible=True), gr.update(open=False),\
906
+ gr.update(visible=False), gr.update(value="Standard")
907
+ else: # Standard
908
+ return gr.update(open=False), gr.update(visible=True), gr.update(open=False), gr.update(open=False),\
909
+ gr.update(visible=True), gr.update(open=False), gr.update(visible=True), gr.update(open=False),\
910
+ gr.update(visible=True), gr.update(value="Standard")
911
+
912
+
913
  quality_prompt_list = [
914
  {
915
  "name": "None",
 
1008
  ]
1009
 
1010
 
1011
+ optimization_list = {
1012
+ "None": [28, 7., 'Euler a', False, 'None', 1.],
1013
+ "Default": [28, 7., 'Euler a', False, 'None', 1.],
1014
+ "SPO": [28, 7., 'Euler a', True, 'loras/spo_sdxl_10ep_4k-data_lora_diffusers.safetensors', 1.],
1015
+ "DPO": [28, 7., 'Euler a', True, 'loras/sdxl-DPO-LoRA.safetensors', 1.],
1016
+ "DPO Turbo": [8, 2.5, 'LCM', True, 'loras/sd_xl_dpo_turbo_lora_v1-128dim.safetensors', 1.],
1017
+ "SDXL Turbo": [8, 2.5, 'LCM', True, 'loras/sd_xl_turbo_lora_v1.safetensors', 1.],
1018
+ "Hyper-SDXL 12step": [12, 5., 'TCD', True, 'loras/Hyper-SDXL-12steps-CFG-lora.safetensors', 1.],
1019
+ "Hyper-SDXL 8step": [8, 5., 'TCD', True, 'loras/Hyper-SDXL-8steps-CFG-lora.safetensors', 1.],
1020
+ "Hyper-SDXL 4step": [4, 0, 'TCD', True, 'loras/Hyper-SDXL-4steps-lora.safetensors', 1.],
1021
+ "Hyper-SDXL 2step": [2, 0, 'TCD', True, 'loras/Hyper-SDXL-2steps-lora.safetensors', 1.],
1022
+ "Hyper-SDXL 1step": [1, 0, 'TCD', True, 'loras/Hyper-SDXL-1steps-lora.safetensors', 1.],
1023
+ "PCM 16step": [16, 4., 'Euler a trailing', True, 'loras/pcm_sdxl_normalcfg_16step_converted.safetensors', 1.],
1024
+ "PCM 8step": [8, 4., 'Euler a trailing', True, 'loras/pcm_sdxl_normalcfg_8step_converted.safetensors', 1.],
1025
+ "PCM 4step": [4, 2., 'Euler a trailing', True, 'loras/pcm_sdxl_smallcfg_4step_converted.safetensors', 1.],
1026
+ "PCM 2step": [2, 1., 'Euler a trailing', True, 'loras/pcm_sdxl_smallcfg_2step_converted.safetensors', 1.],
1027
+ }
1028
+
1029
+
1030
+ def set_optimization(opt, steps_gui, cfg_gui, sampler_gui, clip_skip_gui, lora_gui, lora_scale_gui):
1031
+ if not opt in list(optimization_list.keys()): opt = "None"
1032
+ def_steps_gui = 28
1033
+ def_cfg_gui = 7.
1034
+ steps = optimization_list.get(opt, "None")[0]
1035
+ cfg = optimization_list.get(opt, "None")[1]
1036
+ sampler = optimization_list.get(opt, "None")[2]
1037
+ clip_skip = optimization_list.get(opt, "None")[3]
1038
+ lora = optimization_list.get(opt, "None")[4]
1039
+ lora_scale = optimization_list.get(opt, "None")[5]
1040
+ if opt == "None":
1041
+ steps = max(steps_gui, def_steps_gui)
1042
+ cfg = max(cfg_gui, def_cfg_gui)
1043
+ clip_skip = clip_skip_gui
1044
+ elif opt == "SPO" or opt == "DPO":
1045
+ steps = max(steps_gui, def_steps_gui)
1046
+ cfg = max(cfg_gui, def_cfg_gui)
1047
+
1048
+ return gr.update(value=steps), gr.update(value=cfg), gr.update(value=sampler),\
1049
+ gr.update(value=clip_skip), gr.update(value=lora), gr.update(value=lora_scale),
1050
+
1051
+
1052
  # [sampler_gui, steps_gui, cfg_gui, clip_skip_gui, img_width_gui, img_height_gui, optimization_gui]
1053
  preset_sampler_setting = {
1054
  "None": ["Euler a", 28, 7., True, 1024, 1024, "None"],
 
1220
  tag = str(tag).strip()
1221
  if tag and not tag in ti_tags:
1222
  prompts.append(tag)
 
1223
  ntags = neg_prompt_gui.split(",") if neg_prompt_gui else []
1224
  neg_prompts = []
1225
  for tag in ntags:
1226
  tag = str(tag).strip()
1227
  if tag and not tag in ti_tags:
1228
  neg_prompts.append(tag)
 
1229
  ti_prompts = []
1230
  ti_neg_prompts = []
1231
  for ti in textual_inversion_gui:
 
1235
  ti_prompts.append(tokens[0])
1236
  else: # negative prompt (default)
1237
  ti_neg_prompts.append(tokens[0])
 
1238
  empty = [""]
1239
  prompt = ", ".join(prompts + ti_prompts + empty)
1240
  neg_prompt = ", ".join(neg_prompts + ti_neg_prompts + empty)
 
1241
  return gr.update(value=prompt), gr.update(value=neg_prompt),
1242
 
1243
 
requirements.txt CHANGED
@@ -13,4 +13,5 @@ huggingface_hub
13
  httpx==0.13.3
14
  httpcore
15
  googletrans==4.0.0rc1
16
- timm
 
 
13
  httpx==0.13.3
14
  httpcore
15
  googletrans==4.0.0rc1
16
+ timm
17
+ rapidfuzz