Files changed (9) hide show
  1. .gitignore +0 -207
  2. README.md +1 -1
  3. app.py +89 -219
  4. constants.py +23 -49
  5. image_processor.py +2 -2
  6. packages.txt +1 -1
  7. pre-requirements.txt +0 -1
  8. requirements.txt +3 -11
  9. utils.py +104 -181
.gitignore DELETED
@@ -1,207 +0,0 @@
1
- # Byte-compiled / optimized / DLL files
2
- __pycache__/
3
- *.py[codz]
4
- *$py.class
5
-
6
- # C extensions
7
- *.so
8
-
9
- # Distribution / packaging
10
- .Python
11
- build/
12
- develop-eggs/
13
- dist/
14
- downloads/
15
- eggs/
16
- .eggs/
17
- lib/
18
- lib64/
19
- parts/
20
- sdist/
21
- var/
22
- wheels/
23
- share/python-wheels/
24
- *.egg-info/
25
- .installed.cfg
26
- *.egg
27
- MANIFEST
28
-
29
- # PyInstaller
30
- # Usually these files are written by a python script from a template
31
- # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
- *.manifest
33
- *.spec
34
-
35
- # Installer logs
36
- pip-log.txt
37
- pip-delete-this-directory.txt
38
-
39
- # Unit test / coverage reports
40
- htmlcov/
41
- .tox/
42
- .nox/
43
- .coverage
44
- .coverage.*
45
- .cache
46
- nosetests.xml
47
- coverage.xml
48
- *.cover
49
- *.py.cover
50
- .hypothesis/
51
- .pytest_cache/
52
- cover/
53
-
54
- # Translations
55
- *.mo
56
- *.pot
57
-
58
- # Django stuff:
59
- *.log
60
- local_settings.py
61
- db.sqlite3
62
- db.sqlite3-journal
63
-
64
- # Flask stuff:
65
- instance/
66
- .webassets-cache
67
-
68
- # Scrapy stuff:
69
- .scrapy
70
-
71
- # Sphinx documentation
72
- docs/_build/
73
-
74
- # PyBuilder
75
- .pybuilder/
76
- target/
77
-
78
- # Jupyter Notebook
79
- .ipynb_checkpoints
80
-
81
- # IPython
82
- profile_default/
83
- ipython_config.py
84
-
85
- # pyenv
86
- # For a library or package, you might want to ignore these files since the code is
87
- # intended to run in multiple environments; otherwise, check them in:
88
- # .python-version
89
-
90
- # pipenv
91
- # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
- # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
- # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
- # install all needed dependencies.
95
- #Pipfile.lock
96
-
97
- # UV
98
- # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
99
- # This is especially recommended for binary packages to ensure reproducibility, and is more
100
- # commonly ignored for libraries.
101
- #uv.lock
102
-
103
- # poetry
104
- # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105
- # This is especially recommended for binary packages to ensure reproducibility, and is more
106
- # commonly ignored for libraries.
107
- # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108
- #poetry.lock
109
- #poetry.toml
110
-
111
- # pdm
112
- # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
113
- # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
114
- # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
115
- #pdm.lock
116
- #pdm.toml
117
- .pdm-python
118
- .pdm-build/
119
-
120
- # pixi
121
- # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
122
- #pixi.lock
123
- # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
124
- # in the .venv directory. It is recommended not to include this directory in version control.
125
- .pixi
126
-
127
- # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
128
- __pypackages__/
129
-
130
- # Celery stuff
131
- celerybeat-schedule
132
- celerybeat.pid
133
-
134
- # SageMath parsed files
135
- *.sage.py
136
-
137
- # Environments
138
- .env
139
- .envrc
140
- .venv
141
- env/
142
- venv/
143
- ENV/
144
- env.bak/
145
- venv.bak/
146
-
147
- # Spyder project settings
148
- .spyderproject
149
- .spyproject
150
-
151
- # Rope project settings
152
- .ropeproject
153
-
154
- # mkdocs documentation
155
- /site
156
-
157
- # mypy
158
- .mypy_cache/
159
- .dmypy.json
160
- dmypy.json
161
-
162
- # Pyre type checker
163
- .pyre/
164
-
165
- # pytype static type analyzer
166
- .pytype/
167
-
168
- # Cython debug symbols
169
- cython_debug/
170
-
171
- # PyCharm
172
- # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
173
- # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
174
- # and can be added to the global gitignore or merged into this file. For a more nuclear
175
- # option (not recommended) you can uncomment the following to ignore the entire idea folder.
176
- #.idea/
177
-
178
- # Abstra
179
- # Abstra is an AI-powered process automation framework.
180
- # Ignore directories containing user credentials, local state, and settings.
181
- # Learn more at https://abstra.io/docs
182
- .abstra/
183
-
184
- # Visual Studio Code
185
- # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
186
- # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
187
- # and can be added to the global gitignore or merged into this file. However, if you prefer,
188
- # you could uncomment the following to ignore the entire vscode folder
189
- # .vscode/
190
-
191
- # Ruff stuff:
192
- .ruff_cache/
193
-
194
- # PyPI configuration file
195
- .pypirc
196
-
197
- # Cursor
198
- # Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
199
- # exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
200
- # refer to https://docs.cursor.com/context/ignore-files
201
- .cursorignore
202
- .cursorindexingignore
203
-
204
- # Marimo
205
- marimo/_static/
206
- marimo/_lsp/
207
- __marimo__/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
README.md CHANGED
@@ -4,7 +4,7 @@ emoji: 🧩🖼️
4
  colorFrom: red
5
  colorTo: pink
6
  sdk: gradio
7
- sdk_version: 5.44.1
8
  app_file: app.py
9
  pinned: true
10
  license: mit
 
4
  colorFrom: red
5
  colorTo: pink
6
  sdk: gradio
7
+ sdk_version: 4.31.3
8
  app_file: app.py
9
  pinned: true
10
  license: mit
app.py CHANGED
@@ -1,6 +1,5 @@
1
  import spaces
2
  import os
3
- from argparse import ArgumentParser
4
  from stablepy import (
5
  Model_Diffusers,
6
  SCHEDULE_TYPE_OPTIONS,
@@ -41,7 +40,6 @@ from constants import (
41
  DIFFUSERS_CONTROLNET_MODEL,
42
  IP_MODELS,
43
  MODE_IP_OPTIONS,
44
- CACHE_HF_ROOT,
45
  )
46
  from stablepy.diffusers_vanilla.style_prompt_config import STYLE_NAMES
47
  import torch
@@ -62,7 +60,6 @@ from utils import (
62
  progress_step_bar,
63
  html_template_message,
64
  escape_html,
65
- clear_hf_cache,
66
  )
67
  from image_processor import preprocessor_tab
68
  from datetime import datetime
@@ -75,17 +72,11 @@ from diffusers import FluxPipeline
75
  # import urllib.parse
76
  import subprocess
77
 
78
- IS_ZERO_GPU = bool(os.getenv("SPACES_ZERO_GPU"))
79
- if IS_ZERO_GPU:
80
- subprocess.run("rm -rf /data-nvme/zerogpu-offload/*", env={}, shell=True)
81
- IS_GPU_MODE = True if IS_ZERO_GPU else (True if torch.cuda.is_available() else False)
82
- img_path = "./images/"
83
- allowed_path = os.path.abspath(img_path)
84
- delete_cache_time = (9600, 9600) if IS_ZERO_GPU else (86400, 86400)
85
-
86
  ImageFile.LOAD_TRUNCATED_IMAGES = True
87
  torch.backends.cuda.matmul.allow_tf32 = True
88
  # os.environ["PYTORCH_NO_CUDA_MEMORY_CACHING"] = "1"
 
89
 
90
  directories = [DIRECTORY_MODELS, DIRECTORY_LORAS, DIRECTORY_VAES, DIRECTORY_EMBEDS, DIRECTORY_UPSCALERS]
91
  for directory in directories:
@@ -93,15 +84,19 @@ for directory in directories:
93
 
94
  # Download stuffs
95
  for url in [url.strip() for url in DOWNLOAD_MODEL.split(',')]:
96
- download_things(DIRECTORY_MODELS, url, HF_TOKEN, CIVITAI_API_KEY)
 
97
  for url in [url.strip() for url in DOWNLOAD_VAE.split(',')]:
98
- download_things(DIRECTORY_VAES, url, HF_TOKEN, CIVITAI_API_KEY)
 
99
  for url in [url.strip() for url in DOWNLOAD_LORA.split(',')]:
100
- download_things(DIRECTORY_LORAS, url, HF_TOKEN, CIVITAI_API_KEY)
 
101
 
102
  # Download Embeddings
103
  for url_embed in DOWNLOAD_EMBEDS:
104
- download_things(DIRECTORY_EMBEDS, url_embed, HF_TOKEN, CIVITAI_API_KEY)
 
105
 
106
  # Build list models
107
  embed_list = get_model_list(DIRECTORY_EMBEDS)
@@ -119,16 +114,15 @@ vae_model_list.insert(0, "None")
119
 
120
  print('\033[33m🏁 Download and listing of valid models completed.\033[0m')
121
 
122
- components = None
123
- if IS_ZERO_GPU:
124
- flux_repo = "camenduru/FLUX.1-dev-diffusers"
125
- flux_pipe = FluxPipeline.from_pretrained(
126
- flux_repo,
127
- transformer=None,
128
- torch_dtype=torch.bfloat16,
129
- ).to("cuda")
130
- components = flux_pipe.components
131
- delete_model(flux_repo)
132
 
133
  #######################
134
  # GUI
@@ -138,17 +132,7 @@ diffusers.utils.logging.set_verbosity(40)
138
  warnings.filterwarnings(action="ignore", category=FutureWarning, module="diffusers")
139
  warnings.filterwarnings(action="ignore", category=UserWarning, module="diffusers")
140
  warnings.filterwarnings(action="ignore", category=FutureWarning, module="transformers")
141
-
142
- parser = ArgumentParser(description='DiffuseCraft: Create images from text prompts.', add_help=True)
143
- parser.add_argument("--share", action="store_true", dest="share_enabled", default=False, help="Enable sharing")
144
- parser.add_argument('--theme', type=str, default="NoCrypt/miku", help='Set the theme (default: NoCrypt/miku)')
145
- parser.add_argument("--ssr", action="store_true", help="Enable SSR (Server-Side Rendering)")
146
- parser.add_argument("--log-level", type=str, default="INFO", choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"], help="Set logging level (default: INFO)")
147
- args = parser.parse_args()
148
-
149
- logger.setLevel(
150
- "INFO" if IS_ZERO_GPU else getattr(logging, args.log_level.upper())
151
- )
152
 
153
  CSS = """
154
  .contain { display: flex; flex-direction: column; }
@@ -158,12 +142,6 @@ CSS = """
158
  """
159
 
160
 
161
- def lora_chk(lora_):
162
- if isinstance(lora_, str) and lora_.strip() not in ["", "None"]:
163
- return lora_
164
- return None
165
-
166
-
167
  class GuiSD:
168
  def __init__(self, stream=True):
169
  self.model = None
@@ -179,15 +157,6 @@ class GuiSD:
179
  removal_candidate = self.inventory.pop(0)
180
  delete_model(removal_candidate)
181
 
182
- # Cleanup after 60 seconds of inactivity
183
- lowPrioCleanup = max((datetime.now() - self.last_load).total_seconds(), 0) > 60
184
- if lowPrioCleanup and not self.status_loading and get_used_storage_gb(CACHE_HF_ROOT) > (storage_floor_gb * 2):
185
- print("Cleaning up Hugging Face cache...")
186
- clear_hf_cache()
187
- self.inventory = [
188
- m for m in self.inventory if os.path.exists(m)
189
- ]
190
-
191
  def update_inventory(self, model_name):
192
  if model_name not in single_file_model_list:
193
  self.inventory = [
@@ -198,21 +167,14 @@ class GuiSD:
198
  def load_new_model(self, model_name, vae_model, task, controlnet_model, progress=gr.Progress(track_tqdm=True)):
199
 
200
  # download link model > model_name
201
- if model_name.startswith("http"):
202
- yield f"Downloading model: {model_name}"
203
- model_name = download_things(DIRECTORY_MODELS, model_name, HF_TOKEN, CIVITAI_API_KEY)
204
- if not model_name:
205
- raise ValueError("Error retrieving model information from URL")
206
 
207
- if IS_ZERO_GPU:
208
- self.update_storage_models()
209
 
210
  vae_model = vae_model if vae_model != "None" else None
211
  model_type = get_model_type(model_name)
212
  dtype_model = torch.bfloat16 if model_type == "FLUX" else torch.float16
213
 
214
  if not os.path.exists(model_name):
215
- logger.debug(f"model_name={model_name}, vae_model={vae_model}, task={task}, controlnet_model={controlnet_model}")
216
  _ = download_diffuser_repo(
217
  repo_name=model_name,
218
  model_type=model_type,
@@ -257,10 +219,10 @@ class GuiSD:
257
  type_model_precision=dtype_model,
258
  retain_task_model_in_cache=False,
259
  controlnet_model=controlnet_model,
260
- device="cpu" if IS_ZERO_GPU else None,
261
  env_components=components,
262
  )
263
- self.model.advanced_params(image_preprocessor_cuda_active=IS_GPU_MODE)
264
  else:
265
  if self.model.base_model_id != model_name:
266
  load_now_time = datetime.now()
@@ -270,8 +232,7 @@ class GuiSD:
270
  print("Waiting for the previous model's time ops...")
271
  time.sleep(9 - elapsed_time)
272
 
273
- if IS_ZERO_GPU:
274
- self.model.device = torch.device("cpu")
275
  self.model.load_pipe(
276
  model_name,
277
  task_name=TASK_STABLEPY[task],
@@ -425,7 +386,7 @@ class GuiSD:
425
  vae_msg = f"VAE: {vae_model}" if vae_model else ""
426
  msg_lora = ""
427
 
428
- logger.debug(f"Config model: {model_name}, {vae_model}, {loras_list}")
429
 
430
  task = TASK_STABLEPY[task]
431
 
@@ -523,19 +484,19 @@ class GuiSD:
523
  "distance_threshold": distance_threshold,
524
  "recolor_gamma_correction": float(recolor_gamma_correction),
525
  "tile_blur_sigma": int(tile_blur_sigma),
526
- "lora_A": lora_chk(lora1),
527
  "lora_scale_A": lora_scale1,
528
- "lora_B": lora_chk(lora2),
529
  "lora_scale_B": lora_scale2,
530
- "lora_C": lora_chk(lora3),
531
  "lora_scale_C": lora_scale3,
532
- "lora_D": lora_chk(lora4),
533
  "lora_scale_D": lora_scale4,
534
- "lora_E": lora_chk(lora5),
535
  "lora_scale_E": lora_scale5,
536
- "lora_F": lora_chk(lora6),
537
  "lora_scale_F": lora_scale6,
538
- "lora_G": lora_chk(lora7),
539
  "lora_scale_G": lora_scale7,
540
  "textual_inversion": embed_list if textual_inversion else [],
541
  "syntax_weights": syntax_weights, # "Classic"
@@ -593,11 +554,11 @@ class GuiSD:
593
  # kwargs for diffusers pipeline
594
  if guidance_rescale:
595
  pipe_params["guidance_rescale"] = guidance_rescale
596
- if IS_ZERO_GPU:
597
- self.model.device = torch.device("cuda:0")
598
- if hasattr(self.model.pipe, "transformer") and loras_list != ["None"] * self.model.num_loras:
599
- self.model.pipe.transformer.to(self.model.device)
600
- logger.debug("transformer to cuda")
601
 
602
  actual_progress = 0
603
  info_images = gr.update()
@@ -627,7 +588,7 @@ class GuiSD:
627
 
628
  download_links = "<br>".join(
629
  [
630
- f'<a href="{path.replace("/images/", f"/gradio_api/file={allowed_path}/")}" download="{os.path.basename(path)}">Download Image {i + 1}</a>'
631
  for i, path in enumerate(image_path)
632
  ]
633
  )
@@ -736,8 +697,7 @@ def sd_gen_generate_pipeline(*args):
736
 
737
  @spaces.GPU(duration=15)
738
  def process_upscale(image, upscaler_name, upscaler_size):
739
- if image is None:
740
- return None
741
 
742
  from stablepy.diffusers_vanilla.utils import save_pil_image_with_metadata
743
  from stablepy import load_upscaler_model
@@ -754,7 +714,7 @@ def process_upscale(image, upscaler_name, upscaler_size):
754
 
755
  name_upscaler = f"./{DIRECTORY_UPSCALERS}/{name_upscaler.split('/')[-1]}"
756
 
757
- scaler_beta = load_upscaler_model(model=name_upscaler, tile=(0 if IS_ZERO_GPU else 192), tile_overlap=8, device=("cuda" if IS_GPU_MODE else "cpu"), half=IS_GPU_MODE)
758
  image_up = scaler_beta.upscale(image, upscaler_size, True)
759
 
760
  image_path = save_pil_image_with_metadata(image_up, f'{os.getcwd()}/up_images', exif_image)
@@ -763,11 +723,11 @@ def process_upscale(image, upscaler_name, upscaler_size):
763
 
764
 
765
  # https://huggingface.co/spaces/BestWishYsh/ConsisID-preview-Space/discussions/1#674969a022b99c122af5d407
766
- # dynamic_gpu_duration.zerogpu = True
767
- # sd_gen_generate_pipeline.zerogpu = True
768
  sd_gen = GuiSD()
769
 
770
- with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as app:
771
  gr.Markdown("# 🧩 DiffuseCraft")
772
  gr.Markdown(SUBTITLE_GUI)
773
  with gr.Tab("Generation"):
@@ -816,7 +776,7 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
816
 
817
  actual_task_info = gr.HTML()
818
 
819
- with gr.Row(equal_height=False, variant="default", visible=IS_ZERO_GPU):
820
  gpu_duration_gui = gr.Number(minimum=5, maximum=240, value=59, show_label=False, container=False, info="GPU time duration (seconds)")
821
  with gr.Column():
822
  verbose_info_gui = gr.Checkbox(value=False, container=False, label="Status info")
@@ -852,22 +812,7 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
852
  "Schedule type": gr.update(value="Automatic"),
853
  "PAG": gr.update(value=.0),
854
  "FreeU": gr.update(value=False),
855
- "Hires upscaler": gr.update(),
856
- "Hires upscale": gr.update(),
857
- "Hires steps": gr.update(),
858
- "Hires denoising strength": gr.update(),
859
- "Hires CFG": gr.update(),
860
- "Hires sampler": gr.update(),
861
- "Hires schedule type": gr.update(),
862
- "Image resolution": gr.update(value=1024),
863
- "Strength": gr.update(),
864
  }
865
-
866
- # Generate up to 7 LoRAs
867
- for i in range(1, 8):
868
- valid_receptors[f"Lora_{i}"] = gr.update()
869
- valid_receptors[f"Lora_scale_{i}"] = gr.update()
870
-
871
  valid_keys = list(valid_receptors.keys())
872
 
873
  parameters = extract_parameters(base_prompt)
@@ -881,36 +826,6 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
881
  parameters["Sampler"] = value_sampler
882
  parameters["Schedule type"] = s_type
883
 
884
- params_lora = []
885
- if ">" in parameters["prompt"] and "<" in parameters["prompt"]:
886
- params_lora = re.findall(r'<lora:[^>]+>', parameters["prompt"])
887
- if "Loras" in parameters:
888
- params_lora += re.findall(r'<lora:[^>]+>', parameters["Loras"])
889
-
890
- if params_lora:
891
- parsed_params = []
892
- for tag_l in params_lora:
893
- try:
894
- inner = tag_l.strip("<>") # remove < >
895
- _, data_l = inner.split(":", 1) # remove the "lora:" part
896
- parts_l = data_l.split(":")
897
-
898
- name_l = parts_l[0]
899
- weight_l = float(parts_l[1]) if len(parts_l) > 1 else 1.0 # default weight = 1.0
900
-
901
- parsed_params.append((name_l, weight_l))
902
- except Exception as e:
903
- print(f"Error parsing LoRA tag {tag_l}: {e}")
904
-
905
- num_lora = 1
906
- for parsed_l, parsed_s in parsed_params:
907
- filtered_loras = [m for m in lora_model_list if parsed_l in m]
908
- if filtered_loras:
909
- parameters[f"Lora_{num_lora}"] = filtered_loras[0]
910
- parameters[f"Lora_scale_{num_lora}"] = parsed_s
911
- num_lora += 1
912
-
913
- # continue = discard new value
914
  for key, val in parameters.items():
915
  # print(val)
916
  if key in valid_keys:
@@ -918,12 +833,9 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
918
  if key == "Sampler":
919
  if val not in scheduler_names:
920
  continue
921
- if key in ["Schedule type", "Hires schedule type"]:
922
  if val not in SCHEDULE_TYPE_OPTIONS:
923
- continue
924
- if key == "Hires sampler":
925
- if val not in POST_PROCESSING_SAMPLER:
926
- continue
927
  elif key == "Clip skip":
928
  if "," in str(val):
929
  val = val.replace(",", "")
@@ -931,15 +843,15 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
931
  val = True
932
  if key == "prompt":
933
  if ">" in val and "<" in val:
934
- val = re.sub(r'<[^>]+>', '', val) # Delete html and loras
935
  print("Removed LoRA written in the prompt")
936
  if key in ["prompt", "neg_prompt"]:
937
  val = re.sub(r'\s+', ' ', re.sub(r',+', ',', val)).strip()
938
- if key in ["Steps", "width", "height", "Seed", "Hires steps", "Image resolution"]:
939
  val = int(val)
940
  if key == "FreeU":
941
  val = True
942
- if key in ["CFG scale", "PAG", "Hires upscale", "Hires denoising strength", "Hires CFG", "Strength"]:
943
  val = float(val)
944
  if key == "Model":
945
  filtered_models = [m for m in model_list if val in m]
@@ -947,12 +859,8 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
947
  val = filtered_models[0]
948
  else:
949
  val = name_model
950
- if key == "Hires upscaler":
951
- if val not in UPSCALER_KEYS:
952
- continue
953
  if key == "Seed":
954
  continue
955
-
956
  valid_receptors[key] = gr.update(value=val)
957
  # print(val, type(val))
958
  # print(valid_receptors)
@@ -960,6 +868,24 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
960
  print(str(e))
961
  return [value for value in valid_receptors.values()]
962
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
963
  def run_clear_prompt_gui():
964
  return gr.update(value=""), gr.update(value="")
965
  clear_prompt_gui.click(
@@ -972,7 +898,7 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
972
  run_set_random_seed, [], seed_gui
973
  )
974
 
975
- num_images_gui = gr.Slider(minimum=1, maximum=(5 if IS_ZERO_GPU else 20), step=1, value=1, label="Images")
976
  prompt_syntax_gui = gr.Dropdown(label="Prompt Syntax", choices=PROMPT_W_OPTIONS, value=PROMPT_W_OPTIONS[1][1])
977
  vae_model_gui = gr.Dropdown(label="VAE Model", choices=vae_model_list, value=vae_model_list[0])
978
 
@@ -980,7 +906,7 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
980
 
981
  upscaler_model_path_gui = gr.Dropdown(label="Upscaler", choices=UPSCALER_KEYS, value=UPSCALER_KEYS[0])
982
  upscaler_increases_size_gui = gr.Slider(minimum=1.1, maximum=4., step=0.1, value=1.2, label="Upscale by")
983
- upscaler_tile_size_gui = gr.Slider(minimum=0, maximum=512, step=16, value=(0 if IS_ZERO_GPU else 192), label="Upscaler Tile Size", info="0 = no tiling")
984
  upscaler_tile_overlap_gui = gr.Slider(minimum=0, maximum=48, step=1, value=8, label="Upscaler Tile Overlap")
985
  hires_steps_gui = gr.Slider(minimum=0, value=30, maximum=100, step=1, label="Hires Steps")
986
  hires_denoising_strength_gui = gr.Slider(minimum=0.1, maximum=1.0, step=0.01, value=0.55, label="Hires Denoising Strength")
@@ -997,8 +923,7 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
997
  return gr.Dropdown(label=label, choices=lora_model_list, value="None", allow_custom_value=True, visible=visible)
998
 
999
  def lora_scale_slider(label, visible=True):
1000
- val_lora = 2 if IS_ZERO_GPU else 8
1001
- return gr.Slider(minimum=-val_lora, maximum=val_lora, step=0.01, value=0.33, label=label, visible=visible)
1002
 
1003
  lora1_gui = lora_dropdown("Lora1")
1004
  lora_scale_1_gui = lora_scale_slider("Lora Scale 1")
@@ -1010,10 +935,10 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
1010
  lora_scale_4_gui = lora_scale_slider("Lora Scale 4")
1011
  lora5_gui = lora_dropdown("Lora5")
1012
  lora_scale_5_gui = lora_scale_slider("Lora Scale 5")
1013
- lora6_gui = lora_dropdown("Lora6", visible=(not IS_ZERO_GPU))
1014
- lora_scale_6_gui = lora_scale_slider("Lora Scale 6", visible=(not IS_ZERO_GPU))
1015
- lora7_gui = lora_dropdown("Lora7", visible=(not IS_ZERO_GPU))
1016
- lora_scale_7_gui = lora_scale_slider("Lora Scale 7", visible=(not IS_ZERO_GPU))
1017
 
1018
  with gr.Accordion("From URL", open=False, visible=True):
1019
  text_lora = gr.Textbox(
@@ -1022,7 +947,7 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
1022
  lines=1,
1023
  info="It has to be .safetensors files, and you can also download them from Hugging Face.",
1024
  )
1025
- romanize_text = gr.Checkbox(value=False, label="Transliterate name", visible=(not IS_ZERO_GPU))
1026
  button_lora = gr.Button("Get and Refresh the LoRA Lists")
1027
  new_lora_status = gr.HTML()
1028
  button_lora.click(
@@ -1087,8 +1012,8 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
1087
  preprocess_resolution_gui = gr.Slider(minimum=64, maximum=2048, step=64, value=512, label="Preprocessor Resolution")
1088
  low_threshold_gui = gr.Slider(minimum=1, maximum=255, step=1, value=100, label="'CANNY' low threshold")
1089
  high_threshold_gui = gr.Slider(minimum=1, maximum=255, step=1, value=200, label="'CANNY' high threshold")
1090
- value_threshold_gui = gr.Slider(minimum=0.0, maximum=2.0, step=0.01, value=0.1, label="'MLSD' Hough value threshold")
1091
- distance_threshold_gui = gr.Slider(minimum=0.0, maximum=20.0, step=0.01, value=0.1, label="'MLSD' Hough distance threshold")
1092
  recolor_gamma_correction_gui = gr.Number(minimum=0., maximum=25., value=1., step=0.001, label="'RECOLOR' gamma correction")
1093
  tile_blur_sigma_gui = gr.Number(minimum=0, maximum=100, value=9, step=1, label="'TILE' blur sigma")
1094
 
@@ -1123,7 +1048,7 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
1123
  gr.Info(f"{len(sd_gen.model.STYLE_NAMES)} styles loaded")
1124
  return gr.update(value=None, choices=sd_gen.model.STYLE_NAMES)
1125
 
1126
- style_button.click(load_json_style_file, [style_json_gui], [style_prompt_gui])
1127
 
1128
  with gr.Accordion("Textual inversion", open=False, visible=False):
1129
  active_textual_inversion_gui = gr.Checkbox(value=False, label="Active Textual Inversion in prompt")
@@ -1173,62 +1098,20 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
1173
  hires_before_adetailer_gui = gr.Checkbox(value=False, label="Hires Before Adetailer")
1174
  hires_after_adetailer_gui = gr.Checkbox(value=True, label="Hires After Adetailer")
1175
  generator_in_cpu_gui = gr.Checkbox(value=False, label="Generator in CPU")
1176
- with gr.Column(visible=(not IS_ZERO_GPU)):
1177
- image_storage_location_gui = gr.Textbox(value=img_path, label="Image Storage Location")
1178
- disable_progress_bar_gui = gr.Checkbox(value=False, label="Disable Progress Bar")
1179
- leave_progress_bar_gui = gr.Checkbox(value=True, label="Leave Progress Bar")
1180
 
1181
  with gr.Accordion("More settings", open=False, visible=False):
1182
  loop_generation_gui = gr.Slider(minimum=1, value=1, label="Loop Generation")
1183
  retain_task_cache_gui = gr.Checkbox(value=False, label="Retain task model in cache")
 
 
1184
  display_images_gui = gr.Checkbox(value=False, label="Display Images")
1185
  image_previews_gui = gr.Checkbox(value=True, label="Image Previews")
 
1186
  retain_compel_previous_load_gui = gr.Checkbox(value=False, label="Retain Compel Previous Load")
1187
  retain_detailfix_model_previous_load_gui = gr.Checkbox(value=False, label="Retain Detailfix Model Previous Load")
1188
  retain_hires_model_previous_load_gui = gr.Checkbox(value=False, label="Retain Hires Model Previous Load")
1189
  xformers_memory_efficient_attention_gui = gr.Checkbox(value=False, label="Xformers Memory Efficient Attention")
1190
 
1191
- set_params_gui.click(
1192
- run_set_params_gui, [prompt_gui, model_name_gui], [
1193
- prompt_gui,
1194
- neg_prompt_gui,
1195
- steps_gui,
1196
- img_width_gui,
1197
- img_height_gui,
1198
- seed_gui,
1199
- sampler_gui,
1200
- cfg_gui,
1201
- clip_skip_gui,
1202
- model_name_gui,
1203
- schedule_type_gui,
1204
- pag_scale_gui,
1205
- free_u_gui,
1206
- upscaler_model_path_gui,
1207
- upscaler_increases_size_gui,
1208
- hires_steps_gui,
1209
- hires_denoising_strength_gui,
1210
- hires_guidance_scale_gui,
1211
- hires_sampler_gui,
1212
- hires_schedule_type_gui,
1213
- image_resolution_gui,
1214
- strength_gui,
1215
- lora1_gui,
1216
- lora_scale_1_gui,
1217
- lora2_gui,
1218
- lora_scale_2_gui,
1219
- lora3_gui,
1220
- lora_scale_3_gui,
1221
- lora4_gui,
1222
- lora_scale_4_gui,
1223
- lora5_gui,
1224
- lora_scale_5_gui,
1225
- lora6_gui,
1226
- lora_scale_6_gui,
1227
- lora7_gui,
1228
- lora_scale_7_gui,
1229
- ],
1230
- )
1231
-
1232
  with gr.Accordion("Examples and help", open=False, visible=True):
1233
  gr.Markdown(HELP_GUI)
1234
  gr.Markdown(EXAMPLES_GUI_HELP)
@@ -1284,21 +1167,10 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
1284
  # "hsl(360, 120, 120)" # in fact any valid colorstring
1285
  ]
1286
  ),
1287
- eraser=gr.Eraser(default_size="16"),
1288
- render=True,
1289
- visible=False,
1290
- interactive=False,
1291
  )
1292
-
1293
- show_canvas = gr.Button("SHOW INPAINT CANVAS")
1294
-
1295
- def change_visibility_canvas():
1296
- return gr.update(visible=True, interactive=True), gr.update(visible=False)
1297
- show_canvas.click(change_visibility_canvas, [], [image_base, show_canvas])
1298
-
1299
  invert_mask = gr.Checkbox(value=False, label="Invert mask")
1300
  btn = gr.Button("Create mask")
1301
-
1302
  with gr.Column(scale=1):
1303
  img_source = gr.Image(interactive=False)
1304
  img_result = gr.Image(label="Mask image", show_label=True, interactive=False)
@@ -1490,12 +1362,10 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
1490
  show_progress="minimal",
1491
  )
1492
 
1493
- if __name__ == "__main__":
1494
- app.queue()
1495
- app.launch(
1496
- show_error=True,
1497
- share=args.share_enabled,
1498
- debug=True,
1499
- ssr_mode=args.ssr,
1500
- allowed_paths=[allowed_path],
1501
- )
 
1
  import spaces
2
  import os
 
3
  from stablepy import (
4
  Model_Diffusers,
5
  SCHEDULE_TYPE_OPTIONS,
 
40
  DIFFUSERS_CONTROLNET_MODEL,
41
  IP_MODELS,
42
  MODE_IP_OPTIONS,
 
43
  )
44
  from stablepy.diffusers_vanilla.style_prompt_config import STYLE_NAMES
45
  import torch
 
60
  progress_step_bar,
61
  html_template_message,
62
  escape_html,
 
63
  )
64
  from image_processor import preprocessor_tab
65
  from datetime import datetime
 
72
  # import urllib.parse
73
  import subprocess
74
 
75
+ subprocess.run("rm -rf /data-nvme/zerogpu-offload/*", env={}, shell=True)
 
 
 
 
 
 
 
76
  ImageFile.LOAD_TRUNCATED_IMAGES = True
77
  torch.backends.cuda.matmul.allow_tf32 = True
78
  # os.environ["PYTORCH_NO_CUDA_MEMORY_CACHING"] = "1"
79
+ print(os.getenv("SPACES_ZERO_GPU"))
80
 
81
  directories = [DIRECTORY_MODELS, DIRECTORY_LORAS, DIRECTORY_VAES, DIRECTORY_EMBEDS, DIRECTORY_UPSCALERS]
82
  for directory in directories:
 
84
 
85
  # Download stuffs
86
  for url in [url.strip() for url in DOWNLOAD_MODEL.split(',')]:
87
+ if not os.path.exists(f"./models/{url.split('/')[-1]}"):
88
+ download_things(DIRECTORY_MODELS, url, HF_TOKEN, CIVITAI_API_KEY)
89
  for url in [url.strip() for url in DOWNLOAD_VAE.split(',')]:
90
+ if not os.path.exists(f"./vaes/{url.split('/')[-1]}"):
91
+ download_things(DIRECTORY_VAES, url, HF_TOKEN, CIVITAI_API_KEY)
92
  for url in [url.strip() for url in DOWNLOAD_LORA.split(',')]:
93
+ if not os.path.exists(f"./loras/{url.split('/')[-1]}"):
94
+ download_things(DIRECTORY_LORAS, url, HF_TOKEN, CIVITAI_API_KEY)
95
 
96
  # Download Embeddings
97
  for url_embed in DOWNLOAD_EMBEDS:
98
+ if not os.path.exists(f"./embedings/{url_embed.split('/')[-1]}"):
99
+ download_things(DIRECTORY_EMBEDS, url_embed, HF_TOKEN, CIVITAI_API_KEY)
100
 
101
  # Build list models
102
  embed_list = get_model_list(DIRECTORY_EMBEDS)
 
114
 
115
  print('\033[33m🏁 Download and listing of valid models completed.\033[0m')
116
 
117
+ flux_repo = "camenduru/FLUX.1-dev-diffusers"
118
+ flux_pipe = FluxPipeline.from_pretrained(
119
+ flux_repo,
120
+ transformer=None,
121
+ torch_dtype=torch.bfloat16,
122
+ ).to("cuda")
123
+ components = flux_pipe.components
124
+ delete_model(flux_repo)
125
+ # components = None
 
126
 
127
  #######################
128
  # GUI
 
132
  warnings.filterwarnings(action="ignore", category=FutureWarning, module="diffusers")
133
  warnings.filterwarnings(action="ignore", category=UserWarning, module="diffusers")
134
  warnings.filterwarnings(action="ignore", category=FutureWarning, module="transformers")
135
+ logger.setLevel(logging.DEBUG)
 
 
 
 
 
 
 
 
 
 
136
 
137
  CSS = """
138
  .contain { display: flex; flex-direction: column; }
 
142
  """
143
 
144
 
 
 
 
 
 
 
145
  class GuiSD:
146
  def __init__(self, stream=True):
147
  self.model = None
 
157
  removal_candidate = self.inventory.pop(0)
158
  delete_model(removal_candidate)
159
 
 
 
 
 
 
 
 
 
 
160
  def update_inventory(self, model_name):
161
  if model_name not in single_file_model_list:
162
  self.inventory = [
 
167
  def load_new_model(self, model_name, vae_model, task, controlnet_model, progress=gr.Progress(track_tqdm=True)):
168
 
169
  # download link model > model_name
 
 
 
 
 
170
 
171
+ self.update_storage_models()
 
172
 
173
  vae_model = vae_model if vae_model != "None" else None
174
  model_type = get_model_type(model_name)
175
  dtype_model = torch.bfloat16 if model_type == "FLUX" else torch.float16
176
 
177
  if not os.path.exists(model_name):
 
178
  _ = download_diffuser_repo(
179
  repo_name=model_name,
180
  model_type=model_type,
 
219
  type_model_precision=dtype_model,
220
  retain_task_model_in_cache=False,
221
  controlnet_model=controlnet_model,
222
+ device="cpu",
223
  env_components=components,
224
  )
225
+ self.model.advanced_params(image_preprocessor_cuda_active=True)
226
  else:
227
  if self.model.base_model_id != model_name:
228
  load_now_time = datetime.now()
 
232
  print("Waiting for the previous model's time ops...")
233
  time.sleep(9 - elapsed_time)
234
 
235
+ self.model.device = torch.device("cpu")
 
236
  self.model.load_pipe(
237
  model_name,
238
  task_name=TASK_STABLEPY[task],
 
386
  vae_msg = f"VAE: {vae_model}" if vae_model else ""
387
  msg_lora = ""
388
 
389
+ print("Config model:", model_name, vae_model, loras_list)
390
 
391
  task = TASK_STABLEPY[task]
392
 
 
484
  "distance_threshold": distance_threshold,
485
  "recolor_gamma_correction": float(recolor_gamma_correction),
486
  "tile_blur_sigma": int(tile_blur_sigma),
487
+ "lora_A": lora1 if lora1 != "None" else None,
488
  "lora_scale_A": lora_scale1,
489
+ "lora_B": lora2 if lora2 != "None" else None,
490
  "lora_scale_B": lora_scale2,
491
+ "lora_C": lora3 if lora3 != "None" else None,
492
  "lora_scale_C": lora_scale3,
493
+ "lora_D": lora4 if lora4 != "None" else None,
494
  "lora_scale_D": lora_scale4,
495
+ "lora_E": lora5 if lora5 != "None" else None,
496
  "lora_scale_E": lora_scale5,
497
+ "lora_F": lora6 if lora6 != "None" else None,
498
  "lora_scale_F": lora_scale6,
499
+ "lora_G": lora7 if lora7 != "None" else None,
500
  "lora_scale_G": lora_scale7,
501
  "textual_inversion": embed_list if textual_inversion else [],
502
  "syntax_weights": syntax_weights, # "Classic"
 
554
  # kwargs for diffusers pipeline
555
  if guidance_rescale:
556
  pipe_params["guidance_rescale"] = guidance_rescale
557
+
558
+ self.model.device = torch.device("cuda:0")
559
+ if hasattr(self.model.pipe, "transformer") and loras_list != ["None"] * self.model.num_loras:
560
+ self.model.pipe.transformer.to(self.model.device)
561
+ print("transformer to cuda")
562
 
563
  actual_progress = 0
564
  info_images = gr.update()
 
588
 
589
  download_links = "<br>".join(
590
  [
591
+ f'<a href="{path.replace("/images/", "/file=/home/user/app/images/")}" download="{os.path.basename(path)}">Download Image {i + 1}</a>'
592
  for i, path in enumerate(image_path)
593
  ]
594
  )
 
697
 
698
  @spaces.GPU(duration=15)
699
  def process_upscale(image, upscaler_name, upscaler_size):
700
+ if image is None: return None
 
701
 
702
  from stablepy.diffusers_vanilla.utils import save_pil_image_with_metadata
703
  from stablepy import load_upscaler_model
 
714
 
715
  name_upscaler = f"./{DIRECTORY_UPSCALERS}/{name_upscaler.split('/')[-1]}"
716
 
717
+ scaler_beta = load_upscaler_model(model=name_upscaler, tile=0, tile_overlap=8, device="cuda", half=True)
718
  image_up = scaler_beta.upscale(image, upscaler_size, True)
719
 
720
  image_path = save_pil_image_with_metadata(image_up, f'{os.getcwd()}/up_images', exif_image)
 
723
 
724
 
725
  # https://huggingface.co/spaces/BestWishYsh/ConsisID-preview-Space/discussions/1#674969a022b99c122af5d407
726
+ dynamic_gpu_duration.zerogpu = True
727
+ sd_gen_generate_pipeline.zerogpu = True
728
  sd_gen = GuiSD()
729
 
730
+ with gr.Blocks(theme="NoCrypt/miku", css=CSS) as app:
731
  gr.Markdown("# 🧩 DiffuseCraft")
732
  gr.Markdown(SUBTITLE_GUI)
733
  with gr.Tab("Generation"):
 
776
 
777
  actual_task_info = gr.HTML()
778
 
779
+ with gr.Row(equal_height=False, variant="default"):
780
  gpu_duration_gui = gr.Number(minimum=5, maximum=240, value=59, show_label=False, container=False, info="GPU time duration (seconds)")
781
  with gr.Column():
782
  verbose_info_gui = gr.Checkbox(value=False, container=False, label="Status info")
 
812
  "Schedule type": gr.update(value="Automatic"),
813
  "PAG": gr.update(value=.0),
814
  "FreeU": gr.update(value=False),
 
 
 
 
 
 
 
 
 
815
  }
 
 
 
 
 
 
816
  valid_keys = list(valid_receptors.keys())
817
 
818
  parameters = extract_parameters(base_prompt)
 
826
  parameters["Sampler"] = value_sampler
827
  parameters["Schedule type"] = s_type
828
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
829
  for key, val in parameters.items():
830
  # print(val)
831
  if key in valid_keys:
 
833
  if key == "Sampler":
834
  if val not in scheduler_names:
835
  continue
836
+ if key == "Schedule type":
837
  if val not in SCHEDULE_TYPE_OPTIONS:
838
+ val = "Automatic"
 
 
 
839
  elif key == "Clip skip":
840
  if "," in str(val):
841
  val = val.replace(",", "")
 
843
  val = True
844
  if key == "prompt":
845
  if ">" in val and "<" in val:
846
+ val = re.sub(r'<[^>]+>', '', val)
847
  print("Removed LoRA written in the prompt")
848
  if key in ["prompt", "neg_prompt"]:
849
  val = re.sub(r'\s+', ' ', re.sub(r',+', ',', val)).strip()
850
+ if key in ["Steps", "width", "height", "Seed"]:
851
  val = int(val)
852
  if key == "FreeU":
853
  val = True
854
+ if key in ["CFG scale", "PAG"]:
855
  val = float(val)
856
  if key == "Model":
857
  filtered_models = [m for m in model_list if val in m]
 
859
  val = filtered_models[0]
860
  else:
861
  val = name_model
 
 
 
862
  if key == "Seed":
863
  continue
 
864
  valid_receptors[key] = gr.update(value=val)
865
  # print(val, type(val))
866
  # print(valid_receptors)
 
868
  print(str(e))
869
  return [value for value in valid_receptors.values()]
870
 
871
+ set_params_gui.click(
872
+ run_set_params_gui, [prompt_gui, model_name_gui], [
873
+ prompt_gui,
874
+ neg_prompt_gui,
875
+ steps_gui,
876
+ img_width_gui,
877
+ img_height_gui,
878
+ seed_gui,
879
+ sampler_gui,
880
+ cfg_gui,
881
+ clip_skip_gui,
882
+ model_name_gui,
883
+ schedule_type_gui,
884
+ pag_scale_gui,
885
+ free_u_gui,
886
+ ],
887
+ )
888
+
889
  def run_clear_prompt_gui():
890
  return gr.update(value=""), gr.update(value="")
891
  clear_prompt_gui.click(
 
898
  run_set_random_seed, [], seed_gui
899
  )
900
 
901
+ num_images_gui = gr.Slider(minimum=1, maximum=5, step=1, value=1, label="Images")
902
  prompt_syntax_gui = gr.Dropdown(label="Prompt Syntax", choices=PROMPT_W_OPTIONS, value=PROMPT_W_OPTIONS[1][1])
903
  vae_model_gui = gr.Dropdown(label="VAE Model", choices=vae_model_list, value=vae_model_list[0])
904
 
 
906
 
907
  upscaler_model_path_gui = gr.Dropdown(label="Upscaler", choices=UPSCALER_KEYS, value=UPSCALER_KEYS[0])
908
  upscaler_increases_size_gui = gr.Slider(minimum=1.1, maximum=4., step=0.1, value=1.2, label="Upscale by")
909
+ upscaler_tile_size_gui = gr.Slider(minimum=0, maximum=512, step=16, value=0, label="Upscaler Tile Size", info="0 = no tiling")
910
  upscaler_tile_overlap_gui = gr.Slider(minimum=0, maximum=48, step=1, value=8, label="Upscaler Tile Overlap")
911
  hires_steps_gui = gr.Slider(minimum=0, value=30, maximum=100, step=1, label="Hires Steps")
912
  hires_denoising_strength_gui = gr.Slider(minimum=0.1, maximum=1.0, step=0.01, value=0.55, label="Hires Denoising Strength")
 
923
  return gr.Dropdown(label=label, choices=lora_model_list, value="None", allow_custom_value=True, visible=visible)
924
 
925
  def lora_scale_slider(label, visible=True):
926
+ return gr.Slider(minimum=-2, maximum=2, step=0.01, value=0.33, label=label, visible=visible)
 
927
 
928
  lora1_gui = lora_dropdown("Lora1")
929
  lora_scale_1_gui = lora_scale_slider("Lora Scale 1")
 
935
  lora_scale_4_gui = lora_scale_slider("Lora Scale 4")
936
  lora5_gui = lora_dropdown("Lora5")
937
  lora_scale_5_gui = lora_scale_slider("Lora Scale 5")
938
+ lora6_gui = lora_dropdown("Lora6", visible=False)
939
+ lora_scale_6_gui = lora_scale_slider("Lora Scale 6", visible=False)
940
+ lora7_gui = lora_dropdown("Lora7", visible=False)
941
+ lora_scale_7_gui = lora_scale_slider("Lora Scale 7", visible=False)
942
 
943
  with gr.Accordion("From URL", open=False, visible=True):
944
  text_lora = gr.Textbox(
 
947
  lines=1,
948
  info="It has to be .safetensors files, and you can also download them from Hugging Face.",
949
  )
950
+ romanize_text = gr.Checkbox(value=False, label="Transliterate name", visible=False)
951
  button_lora = gr.Button("Get and Refresh the LoRA Lists")
952
  new_lora_status = gr.HTML()
953
  button_lora.click(
 
1012
  preprocess_resolution_gui = gr.Slider(minimum=64, maximum=2048, step=64, value=512, label="Preprocessor Resolution")
1013
  low_threshold_gui = gr.Slider(minimum=1, maximum=255, step=1, value=100, label="'CANNY' low threshold")
1014
  high_threshold_gui = gr.Slider(minimum=1, maximum=255, step=1, value=200, label="'CANNY' high threshold")
1015
+ value_threshold_gui = gr.Slider(minimum=1, maximum=2.0, step=0.01, value=0.1, label="'MLSD' Hough value threshold")
1016
+ distance_threshold_gui = gr.Slider(minimum=1, maximum=20.0, step=0.01, value=0.1, label="'MLSD' Hough distance threshold")
1017
  recolor_gamma_correction_gui = gr.Number(minimum=0., maximum=25., value=1., step=0.001, label="'RECOLOR' gamma correction")
1018
  tile_blur_sigma_gui = gr.Number(minimum=0, maximum=100, value=9, step=1, label="'TILE' blur sigma")
1019
 
 
1048
  gr.Info(f"{len(sd_gen.model.STYLE_NAMES)} styles loaded")
1049
  return gr.update(value=None, choices=sd_gen.model.STYLE_NAMES)
1050
 
1051
+ style_button.click(load_json_style_file, [style_json_gui], [style_prompt_gui])
1052
 
1053
  with gr.Accordion("Textual inversion", open=False, visible=False):
1054
  active_textual_inversion_gui = gr.Checkbox(value=False, label="Active Textual Inversion in prompt")
 
1098
  hires_before_adetailer_gui = gr.Checkbox(value=False, label="Hires Before Adetailer")
1099
  hires_after_adetailer_gui = gr.Checkbox(value=True, label="Hires After Adetailer")
1100
  generator_in_cpu_gui = gr.Checkbox(value=False, label="Generator in CPU")
 
 
 
 
1101
 
1102
  with gr.Accordion("More settings", open=False, visible=False):
1103
  loop_generation_gui = gr.Slider(minimum=1, value=1, label="Loop Generation")
1104
  retain_task_cache_gui = gr.Checkbox(value=False, label="Retain task model in cache")
1105
+ leave_progress_bar_gui = gr.Checkbox(value=True, label="Leave Progress Bar")
1106
+ disable_progress_bar_gui = gr.Checkbox(value=False, label="Disable Progress Bar")
1107
  display_images_gui = gr.Checkbox(value=False, label="Display Images")
1108
  image_previews_gui = gr.Checkbox(value=True, label="Image Previews")
1109
+ image_storage_location_gui = gr.Textbox(value="./images", label="Image Storage Location")
1110
  retain_compel_previous_load_gui = gr.Checkbox(value=False, label="Retain Compel Previous Load")
1111
  retain_detailfix_model_previous_load_gui = gr.Checkbox(value=False, label="Retain Detailfix Model Previous Load")
1112
  retain_hires_model_previous_load_gui = gr.Checkbox(value=False, label="Retain Hires Model Previous Load")
1113
  xformers_memory_efficient_attention_gui = gr.Checkbox(value=False, label="Xformers Memory Efficient Attention")
1114
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1115
  with gr.Accordion("Examples and help", open=False, visible=True):
1116
  gr.Markdown(HELP_GUI)
1117
  gr.Markdown(EXAMPLES_GUI_HELP)
 
1167
  # "hsl(360, 120, 120)" # in fact any valid colorstring
1168
  ]
1169
  ),
1170
+ eraser=gr.Eraser(default_size="16")
 
 
 
1171
  )
 
 
 
 
 
 
 
1172
  invert_mask = gr.Checkbox(value=False, label="Invert mask")
1173
  btn = gr.Button("Create mask")
 
1174
  with gr.Column(scale=1):
1175
  img_source = gr.Image(interactive=False)
1176
  img_result = gr.Image(label="Mask image", show_label=True, interactive=False)
 
1362
  show_progress="minimal",
1363
  )
1364
 
1365
+ app.queue()
1366
+
1367
+ app.launch(
1368
+ show_error=True,
1369
+ debug=True,
1370
+ allowed_paths=["./images/"],
1371
+ )
 
 
constants.py CHANGED
@@ -9,8 +9,6 @@ from stablepy import (
9
  IP_ADAPTERS_SDXL,
10
  )
11
 
12
- IS_ZERO_GPU = bool(os.getenv("SPACES_ZERO_GPU"))
13
-
14
  # - **Download Models**
15
  DOWNLOAD_MODEL = "https://huggingface.co/TechnoByte/MilkyWonderland/resolve/main/milkyWonderland_v40.safetensors"
16
 
@@ -25,12 +23,12 @@ LOAD_DIFFUSERS_FORMAT_MODEL = [
25
  'Laxhar/noobai-XL-1.1',
26
  'Laxhar/noobai-XL-Vpred-1.0',
27
  'black-forest-labs/FLUX.1-dev',
28
- 'black-forest-labs/FLUX.1-Krea-dev',
29
  'John6666/blue-pencil-flux1-v021-fp8-flux',
30
  'John6666/wai-ani-flux-v10forfp8-fp8-flux',
31
  'John6666/xe-anime-flux-v04-fp8-flux',
32
  'John6666/lyh-anime-flux-v2a1-fp8-flux',
33
  'John6666/carnival-unchained-v10-fp8-flux',
 
34
  'Freepik/flux.1-lite-8B-alpha',
35
  'shauray/FluxDev-HyperSD-merged',
36
  'mikeyandfriends/PixelWave_FLUX.1-dev_03',
@@ -39,19 +37,23 @@ LOAD_DIFFUSERS_FORMAT_MODEL = [
39
  # 'ostris/OpenFLUX.1',
40
  'shuttleai/shuttle-3-diffusion',
41
  'Laxhar/noobai-XL-1.0',
 
42
  'Laxhar/noobai-XL-0.77',
43
  'John6666/noobai-xl-nai-xl-epsilonpred075version-sdxl',
44
  'Laxhar/noobai-XL-0.6',
45
  'John6666/noobai-xl-nai-xl-epsilonpred05version-sdxl',
46
  'John6666/noobai-cyberfix-v10-sdxl',
47
  'John6666/noobaiiter-xl-vpred-v075-sdxl',
48
- 'John6666/ripplemix-noob-vpred10-illustrious01-v14-sdxl',
49
- 'John6666/sigmaih-15-sdxl',
 
 
50
  'John6666/ntr-mix-illustrious-xl-noob-xl-xi-sdxl',
51
  'John6666/ntr-mix-illustrious-xl-noob-xl-xii-sdxl',
52
  'John6666/ntr-mix-illustrious-xl-noob-xl-xiii-sdxl',
53
  'John6666/mistoon-anime-v10illustrious-sdxl',
54
- 'John6666/hassaku-xl-illustrious-v22-sdxl',
 
55
  'John6666/haruki-mix-illustrious-v10-sdxl',
56
  'John6666/noobreal-v10-sdxl',
57
  'John6666/complicated-noobai-merge-vprediction-sdxl',
@@ -62,7 +64,6 @@ LOAD_DIFFUSERS_FORMAT_MODEL = [
62
  'Laxhar/noobai-XL-Vpred-0.65',
63
  'Laxhar/noobai-XL-Vpred-0.6',
64
  'John6666/cat-tower-noobai-xl-checkpoint-v14vpred-sdxl',
65
- 'John6666/cat-tower-noobai-xl-checkpoint-v15vpred-sdxl',
66
  'John6666/noobai-xl-nai-xl-vpred05version-sdxl',
67
  'John6666/noobai-fusion2-vpred-itercomp-v1-sdxl',
68
  'John6666/noobai-xl-nai-xl-vpredtestversion-sdxl',
@@ -73,34 +74,19 @@ LOAD_DIFFUSERS_FORMAT_MODEL = [
73
  'John6666/obsession-illustriousxl-v21-sdxl',
74
  'John6666/obsession-illustriousxl-v30-sdxl',
75
  'John6666/obsession-illustriousxl-v31-sdxl',
76
- 'John6666/one-obsession-13-sdxl',
77
- 'John6666/one-obsession-14-24d-sdxl',
78
- 'John6666/one-obsession-15-noobai-sdxl',
79
- 'John6666/one-obsession-v16-noobai-sdxl',
80
- 'John6666/prefect-illustrious-xl-v3-sdxl',
81
  'John6666/wai-nsfw-illustrious-v70-sdxl',
82
- 'John6666/wai-nsfw-illustrious-sdxl-v140-sdxl',
83
  'John6666/illustrious-pony-mix-v3-sdxl',
84
- 'John6666/nova-anime-xl-il-v90-sdxl',
85
- 'John6666/nova-anime-xl-il-v110-sdxl',
86
- 'John6666/nova-orange-xl-re-v10-sdxl',
87
- 'John6666/nova-orange-xl-v110-sdxl',
88
- 'John6666/nova-orange-xl-re-v20-sdxl',
89
- 'John6666/nova-unreal-xl-v60-sdxl',
90
- 'John6666/nova-unreal-xl-v70-sdxl',
91
- 'John6666/nova-unreal-xl-v80-sdxl',
92
- 'John6666/nova-cartoon-xl-v40-sdxl',
93
  'John6666/silvermoon-mix03-illustrious-v10-sdxl',
94
  'eienmojiki/Anything-XL',
95
  'eienmojiki/Starry-XL-v5.2',
96
- 'votepurchase/plantMilkModelSuite_walnut',
97
  'John6666/meinaxl-v2-sdxl',
98
  'Eugeoter/artiwaifu-diffusion-2.0',
99
  'comin/IterComp',
100
- 'John6666/epicrealism-xl-v8kiss-sdxl',
101
- 'John6666/epicrealism-xl-v10kiss2-sdxl',
102
  'John6666/epicrealism-xl-vxiabeast-sdxl',
103
- 'John6666/epicrealism-xl-vxvii-crystal-clear-realism-sdxl',
 
104
  'misri/zavychromaxl_v80',
105
  'SG161222/RealVisXL_V4.0',
106
  'SG161222/RealVisXL_V5.0',
@@ -116,10 +102,8 @@ LOAD_DIFFUSERS_FORMAT_MODEL = [
116
  'John6666/ebara-mfcg-pony-mix-v12-sdxl',
117
  'John6666/t-ponynai3-v51-sdxl',
118
  'John6666/t-ponynai3-v65-sdxl',
119
- 'John6666/t-ponynai3-v7-sdxl',
120
  'John6666/prefect-pony-xl-v3-sdxl',
121
  'John6666/prefect-pony-xl-v4-sdxl',
122
- 'John6666/prefect-pony-xl-v50-sdxl',
123
  'John6666/mala-anime-mix-nsfw-pony-xl-v5-sdxl',
124
  'John6666/wai-ani-nsfw-ponyxl-v10-sdxl',
125
  'John6666/wai-real-mix-v11-sdxl',
@@ -127,14 +111,13 @@ LOAD_DIFFUSERS_FORMAT_MODEL = [
127
  'John6666/wai-c-v6-sdxl',
128
  'John6666/iniverse-mix-xl-sfwnsfw-pony-guofeng-v43-sdxl',
129
  'John6666/sifw-annihilation-xl-v2-sdxl',
130
- 'John6666/sifw-annihilation-xl-v305illustrious-beta-sdxl',
131
  'John6666/photo-realistic-pony-v5-sdxl',
132
  'John6666/pony-realism-v21main-sdxl',
133
  'John6666/pony-realism-v22main-sdxl',
134
- 'John6666/pony-realism-v23-ultra-sdxl',
 
135
  'John6666/cyberrealistic-pony-v65-sdxl',
136
  'John6666/cyberrealistic-pony-v7-sdxl',
137
- 'John6666/cyberrealistic-pony-v127-alternative-sdxl',
138
  'GraydientPlatformAPI/realcartoon-pony-diffusion',
139
  'John6666/nova-anime-xl-pony-v5-sdxl',
140
  'John6666/autismmix-sdxl-autismmix-pony-sdxl',
@@ -144,15 +127,13 @@ LOAD_DIFFUSERS_FORMAT_MODEL = [
144
  'John6666/duchaiten-pony-real-v11fix-sdxl',
145
  'John6666/duchaiten-pony-real-v20-sdxl',
146
  'John6666/duchaiten-pony-xl-no-score-v70-sdxl',
 
 
147
  'KBlueLeaf/Kohaku-XL-Zeta',
148
  'cagliostrolab/animagine-xl-3.1',
149
- 'cagliostrolab/animagine-xl-4.0',
150
  'yodayo-ai/kivotos-xl-2.0',
151
  'yodayo-ai/holodayo-xl-2.1',
152
  'yodayo-ai/clandestine-xl-1.0',
153
- 'https://huggingface.co/chemwolf/Karmix-XL-v0/resolve/main/Karmix-XL-v0.safetensors?download=true',
154
- 'https://civitai.com/api/download/models/128713?type=Model&format=SafeTensor&size=pruned&fp=fp16',
155
- 'https://civitai.com/models/30240?modelVersionId=125771',
156
  'digiplay/majicMIX_sombre_v2',
157
  'digiplay/majicMIX_realistic_v6',
158
  'digiplay/majicMIX_realistic_v7',
@@ -178,9 +159,9 @@ LOAD_DIFFUSERS_FORMAT_MODEL = [
178
  'GraydientPlatformAPI/realcartoon3d-17',
179
  'GraydientPlatformAPI/realcartoon-pixar11',
180
  'GraydientPlatformAPI/realcartoon-real17',
 
181
  ]
182
 
183
-
184
  DIFFUSERS_FORMAT_LORAS = [
185
  "nerijs/animation2k-flux",
186
  "XLabs-AI/flux-RealismLora",
@@ -202,11 +183,8 @@ DIRECTORY_VAES = 'vaes'
202
  DIRECTORY_EMBEDS = 'embedings'
203
  DIRECTORY_UPSCALERS = 'upscalers'
204
 
 
205
  STORAGE_ROOT = "/home/user/"
206
- CACHE_HF_ROOT = os.path.expanduser("~/.cache/huggingface")
207
- CACHE_HF = os.path.join(CACHE_HF_ROOT, "hub")
208
- if IS_ZERO_GPU:
209
- os.environ["HF_HOME"] = CACHE_HF
210
 
211
  TASK_STABLEPY = {
212
  'txt2img': 'txt2img',
@@ -248,7 +226,6 @@ UPSCALER_DICT_GUI = {
248
  # "realesr-general-x4v3": "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.5.0/realesr-general-x4v3.pth",
249
  # "realesr-general-wdn-x4v3": "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.5.0/realesr-general-wdn-x4v3.pth",
250
  "4x-UltraSharp": "https://huggingface.co/Shandypur/ESRGAN-4x-UltraSharp/resolve/main/4x-UltraSharp.pth",
251
- "Real-ESRGAN-Anime-finetuning": "https://huggingface.co/danhtran2mind/Real-ESRGAN-Anime-finetuning/resolve/main/Real-ESRGAN-Anime-finetuning.pth",
252
  "4x_foolhardy_Remacri": "https://huggingface.co/FacehugmanIII/4x_foolhardy_Remacri/resolve/main/4x_foolhardy_Remacri.pth",
253
  "Remacri4xExtraSmoother": "https://huggingface.co/hollowstrawberry/upscalers-backup/resolve/main/ESRGAN/Remacri%204x%20ExtraSmoother.pth",
254
  "AnimeSharp4x": "https://huggingface.co/hollowstrawberry/upscalers-backup/resolve/main/ESRGAN/AnimeSharp%204x.pth",
@@ -382,11 +359,9 @@ SUBTITLE_GUI = (
382
  " to perform different tasks in image generation."
383
  )
384
 
385
- msg_zero = "" if not IS_ZERO_GPU else "- The current space runs on a ZERO GPU which is assigned for approximately 60 seconds; Therefore, if you submit expensive tasks, the operation may be canceled upon reaching the maximum allowed time with 'GPU TASK ABORTED'."
386
-
387
  HELP_GUI = (
388
- f"""### Help:
389
- {msg_zero}
390
  - Distorted or strange images often result from high prompt weights, so it's best to use low weights and scales, and consider using Classic variants like 'Classic-original'.
391
  - For better results with Pony Diffusion, try using sampler DPM++ 1s or DPM2 with Compel or Classic prompt weights.
392
  """
@@ -510,7 +485,7 @@ EXAMPLES_GUI = [
510
  20,
511
  4.0,
512
  -1,
513
- ("loras/Coloring_book_-_LineArt.safetensors" if os.path.exists("loras/Coloring_book_-_LineArt.safetensors") else "None"),
514
  1.0,
515
  "DPM++ 2M SDE",
516
  1024,
@@ -605,7 +580,6 @@ EXAMPLES_GUI = [
605
  RESOURCES = (
606
  """### Resources
607
  - John6666's space has some great features you might find helpful [link](https://huggingface.co/spaces/John6666/DiffuseCraftMod).
608
- - Try the image generator in Colab’s free tier, which provides free GPU [link](https://github.com/R3gm/SD_diffusers_interactive).
609
- - `DiffuseCraft` in Colab:[link](https://github.com/R3gm/DiffuseCraft?tab=readme-ov-file#diffusecraft).
610
  """
611
- )
 
9
  IP_ADAPTERS_SDXL,
10
  )
11
 
 
 
12
  # - **Download Models**
13
  DOWNLOAD_MODEL = "https://huggingface.co/TechnoByte/MilkyWonderland/resolve/main/milkyWonderland_v40.safetensors"
14
 
 
23
  'Laxhar/noobai-XL-1.1',
24
  'Laxhar/noobai-XL-Vpred-1.0',
25
  'black-forest-labs/FLUX.1-dev',
 
26
  'John6666/blue-pencil-flux1-v021-fp8-flux',
27
  'John6666/wai-ani-flux-v10forfp8-fp8-flux',
28
  'John6666/xe-anime-flux-v04-fp8-flux',
29
  'John6666/lyh-anime-flux-v2a1-fp8-flux',
30
  'John6666/carnival-unchained-v10-fp8-flux',
31
+ 'John6666/iniverse-mix-xl-sfwnsfw-fluxdfp16nsfwv11-fp8-flux',
32
  'Freepik/flux.1-lite-8B-alpha',
33
  'shauray/FluxDev-HyperSD-merged',
34
  'mikeyandfriends/PixelWave_FLUX.1-dev_03',
 
37
  # 'ostris/OpenFLUX.1',
38
  'shuttleai/shuttle-3-diffusion',
39
  'Laxhar/noobai-XL-1.0',
40
+ 'John6666/noobai-xl-nai-xl-epsilonpred10version-sdxl',
41
  'Laxhar/noobai-XL-0.77',
42
  'John6666/noobai-xl-nai-xl-epsilonpred075version-sdxl',
43
  'Laxhar/noobai-XL-0.6',
44
  'John6666/noobai-xl-nai-xl-epsilonpred05version-sdxl',
45
  'John6666/noobai-cyberfix-v10-sdxl',
46
  'John6666/noobaiiter-xl-vpred-v075-sdxl',
47
+ 'John6666/ntr-mix-illustrious-xl-noob-xl-v40-sdxl',
48
+ 'John6666/ntr-mix-illustrious-xl-noob-xl-ntrmix35-sdxl',
49
+ 'John6666/ntr-mix-illustrious-xl-noob-xl-v777-sdxl',
50
+ 'John6666/ntr-mix-illustrious-xl-noob-xl-v777forlora-sdxl',
51
  'John6666/ntr-mix-illustrious-xl-noob-xl-xi-sdxl',
52
  'John6666/ntr-mix-illustrious-xl-noob-xl-xii-sdxl',
53
  'John6666/ntr-mix-illustrious-xl-noob-xl-xiii-sdxl',
54
  'John6666/mistoon-anime-v10illustrious-sdxl',
55
+ 'John6666/hassaku-xl-illustrious-v10-sdxl',
56
+ 'John6666/hassaku-xl-illustrious-v10style-sdxl',
57
  'John6666/haruki-mix-illustrious-v10-sdxl',
58
  'John6666/noobreal-v10-sdxl',
59
  'John6666/complicated-noobai-merge-vprediction-sdxl',
 
64
  'Laxhar/noobai-XL-Vpred-0.65',
65
  'Laxhar/noobai-XL-Vpred-0.6',
66
  'John6666/cat-tower-noobai-xl-checkpoint-v14vpred-sdxl',
 
67
  'John6666/noobai-xl-nai-xl-vpred05version-sdxl',
68
  'John6666/noobai-fusion2-vpred-itercomp-v1-sdxl',
69
  'John6666/noobai-xl-nai-xl-vpredtestversion-sdxl',
 
74
  'John6666/obsession-illustriousxl-v21-sdxl',
75
  'John6666/obsession-illustriousxl-v30-sdxl',
76
  'John6666/obsession-illustriousxl-v31-sdxl',
 
 
 
 
 
77
  'John6666/wai-nsfw-illustrious-v70-sdxl',
 
78
  'John6666/illustrious-pony-mix-v3-sdxl',
79
+ 'John6666/nova-anime-xl-illustriousv10-sdxl',
80
+ 'John6666/nova-orange-xl-v30-sdxl',
 
 
 
 
 
 
 
81
  'John6666/silvermoon-mix03-illustrious-v10-sdxl',
82
  'eienmojiki/Anything-XL',
83
  'eienmojiki/Starry-XL-v5.2',
 
84
  'John6666/meinaxl-v2-sdxl',
85
  'Eugeoter/artiwaifu-diffusion-2.0',
86
  'comin/IterComp',
 
 
87
  'John6666/epicrealism-xl-vxiabeast-sdxl',
88
+ 'John6666/epicrealism-xl-v10kiss2-sdxl',
89
+ 'John6666/epicrealism-xl-v8kiss-sdxl',
90
  'misri/zavychromaxl_v80',
91
  'SG161222/RealVisXL_V4.0',
92
  'SG161222/RealVisXL_V5.0',
 
102
  'John6666/ebara-mfcg-pony-mix-v12-sdxl',
103
  'John6666/t-ponynai3-v51-sdxl',
104
  'John6666/t-ponynai3-v65-sdxl',
 
105
  'John6666/prefect-pony-xl-v3-sdxl',
106
  'John6666/prefect-pony-xl-v4-sdxl',
 
107
  'John6666/mala-anime-mix-nsfw-pony-xl-v5-sdxl',
108
  'John6666/wai-ani-nsfw-ponyxl-v10-sdxl',
109
  'John6666/wai-real-mix-v11-sdxl',
 
111
  'John6666/wai-c-v6-sdxl',
112
  'John6666/iniverse-mix-xl-sfwnsfw-pony-guofeng-v43-sdxl',
113
  'John6666/sifw-annihilation-xl-v2-sdxl',
 
114
  'John6666/photo-realistic-pony-v5-sdxl',
115
  'John6666/pony-realism-v21main-sdxl',
116
  'John6666/pony-realism-v22main-sdxl',
117
+ 'John6666/cyberrealistic-pony-v63-sdxl',
118
+ 'John6666/cyberrealistic-pony-v64-sdxl',
119
  'John6666/cyberrealistic-pony-v65-sdxl',
120
  'John6666/cyberrealistic-pony-v7-sdxl',
 
121
  'GraydientPlatformAPI/realcartoon-pony-diffusion',
122
  'John6666/nova-anime-xl-pony-v5-sdxl',
123
  'John6666/autismmix-sdxl-autismmix-pony-sdxl',
 
127
  'John6666/duchaiten-pony-real-v11fix-sdxl',
128
  'John6666/duchaiten-pony-real-v20-sdxl',
129
  'John6666/duchaiten-pony-xl-no-score-v70-sdxl',
130
+ 'odyssey-labs/OdysseyXL-3.0',
131
+ 'odyssey-labs/OdysseyXL-4.0',
132
  'KBlueLeaf/Kohaku-XL-Zeta',
133
  'cagliostrolab/animagine-xl-3.1',
 
134
  'yodayo-ai/kivotos-xl-2.0',
135
  'yodayo-ai/holodayo-xl-2.1',
136
  'yodayo-ai/clandestine-xl-1.0',
 
 
 
137
  'digiplay/majicMIX_sombre_v2',
138
  'digiplay/majicMIX_realistic_v6',
139
  'digiplay/majicMIX_realistic_v7',
 
159
  'GraydientPlatformAPI/realcartoon3d-17',
160
  'GraydientPlatformAPI/realcartoon-pixar11',
161
  'GraydientPlatformAPI/realcartoon-real17',
162
+ 'nitrosocke/Ghibli-Diffusion',
163
  ]
164
 
 
165
  DIFFUSERS_FORMAT_LORAS = [
166
  "nerijs/animation2k-flux",
167
  "XLabs-AI/flux-RealismLora",
 
183
  DIRECTORY_EMBEDS = 'embedings'
184
  DIRECTORY_UPSCALERS = 'upscalers'
185
 
186
+ CACHE_HF = "/home/user/.cache/huggingface/hub/"
187
  STORAGE_ROOT = "/home/user/"
 
 
 
 
188
 
189
  TASK_STABLEPY = {
190
  'txt2img': 'txt2img',
 
226
  # "realesr-general-x4v3": "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.5.0/realesr-general-x4v3.pth",
227
  # "realesr-general-wdn-x4v3": "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.5.0/realesr-general-wdn-x4v3.pth",
228
  "4x-UltraSharp": "https://huggingface.co/Shandypur/ESRGAN-4x-UltraSharp/resolve/main/4x-UltraSharp.pth",
 
229
  "4x_foolhardy_Remacri": "https://huggingface.co/FacehugmanIII/4x_foolhardy_Remacri/resolve/main/4x_foolhardy_Remacri.pth",
230
  "Remacri4xExtraSmoother": "https://huggingface.co/hollowstrawberry/upscalers-backup/resolve/main/ESRGAN/Remacri%204x%20ExtraSmoother.pth",
231
  "AnimeSharp4x": "https://huggingface.co/hollowstrawberry/upscalers-backup/resolve/main/ESRGAN/AnimeSharp%204x.pth",
 
359
  " to perform different tasks in image generation."
360
  )
361
 
 
 
362
  HELP_GUI = (
363
+ """### Help:
364
+ - The current space runs on a ZERO GPU which is assigned for approximately 60 seconds; Therefore, if you submit expensive tasks, the operation may be canceled upon reaching the maximum allowed time with 'GPU TASK ABORTED'.
365
  - Distorted or strange images often result from high prompt weights, so it's best to use low weights and scales, and consider using Classic variants like 'Classic-original'.
366
  - For better results with Pony Diffusion, try using sampler DPM++ 1s or DPM2 with Compel or Classic prompt weights.
367
  """
 
485
  20,
486
  4.0,
487
  -1,
488
+ "loras/Coloring_book_-_LineArt.safetensors",
489
  1.0,
490
  "DPM++ 2M SDE",
491
  1024,
 
580
  RESOURCES = (
581
  """### Resources
582
  - John6666's space has some great features you might find helpful [link](https://huggingface.co/spaces/John6666/DiffuseCraftMod).
583
+ - You can also try the image generator in Colab’s free tier, which provides free GPU [link](https://github.com/R3gm/SD_diffusers_interactive).
 
584
  """
585
+ )
image_processor.py CHANGED
@@ -92,8 +92,8 @@ def preprocessor_tab():
92
  pre_processor_resolution = gr.Slider(minimum=64, maximum=2048, step=64, value=512, label="Preprocessor Resolution")
93
  pre_low_threshold = gr.Slider(minimum=1, maximum=255, step=1, value=100, label="'CANNY' low threshold")
94
  pre_high_threshold = gr.Slider(minimum=1, maximum=255, step=1, value=200, label="'CANNY' high threshold")
95
- pre_value_threshold = gr.Slider(minimum=0., maximum=2.0, step=0.01, value=0.1, label="'MLSD' Hough value threshold")
96
- pre_distance_threshold = gr.Slider(minimum=0., maximum=20.0, step=0.01, value=0.1, label="'MLSD' Hough distance threshold")
97
  pre_recolor_mode = gr.Dropdown(label="'RECOLOR' mode", choices=["luminance", "intensity"], value="luminance")
98
  pre_recolor_gamma_correction = gr.Number(minimum=0., maximum=25., value=1., step=0.001, label="'RECOLOR' gamma correction")
99
  pre_blur_k_size = gr.Number(minimum=0, maximum=100, value=9, step=1, label="'BLUR' sigma")
 
92
  pre_processor_resolution = gr.Slider(minimum=64, maximum=2048, step=64, value=512, label="Preprocessor Resolution")
93
  pre_low_threshold = gr.Slider(minimum=1, maximum=255, step=1, value=100, label="'CANNY' low threshold")
94
  pre_high_threshold = gr.Slider(minimum=1, maximum=255, step=1, value=200, label="'CANNY' high threshold")
95
+ pre_value_threshold = gr.Slider(minimum=1, maximum=2.0, step=0.01, value=0.1, label="'MLSD' Hough value threshold")
96
+ pre_distance_threshold = gr.Slider(minimum=1, maximum=20.0, step=0.01, value=0.1, label="'MLSD' Hough distance threshold")
97
  pre_recolor_mode = gr.Dropdown(label="'RECOLOR' mode", choices=["luminance", "intensity"], value="luminance")
98
  pre_recolor_gamma_correction = gr.Number(minimum=0., maximum=25., value=1., step=0.001, label="'RECOLOR' gamma correction")
99
  pre_blur_k_size = gr.Number(minimum=0, maximum=100, value=9, step=1, label="'BLUR' sigma")
packages.txt CHANGED
@@ -1,3 +1,3 @@
1
  git-lfs
2
- aria2
3
  ffmpeg
 
1
  git-lfs
2
+ aria2 -y
3
  ffmpeg
pre-requirements.txt DELETED
@@ -1 +0,0 @@
1
- pip>=23.0.0
 
 
requirements.txt CHANGED
@@ -1,13 +1,5 @@
1
- stablepy==0.6.2
2
- torch==2.5.1
3
- diffusers
4
  gdown
5
  opencv-python
6
- unidecode
7
- pydantic==2.10.6
8
- huggingface_hub
9
- hf_transfer
10
- hf_xet
11
- spaces
12
- gradio==5.44.1
13
- matplotlib-inline
 
1
+ stablepy==0.6.0
2
+ torch==2.2.0
 
3
  gdown
4
  opencv-python
5
+ unidecode
 
 
 
 
 
 
 
utils.py CHANGED
@@ -9,7 +9,6 @@ from constants import (
9
  DIRECTORY_LORAS,
10
  DIRECTORY_MODELS,
11
  DIFFUSECRAFT_CHECKPOINT_NAME,
12
- CACHE_HF_ROOT,
13
  CACHE_HF,
14
  STORAGE_ROOT,
15
  )
@@ -29,7 +28,6 @@ from urllib3.util import Retry
29
  import shutil
30
  import subprocess
31
 
32
- IS_ZERO_GPU = bool(os.getenv("SPACES_ZERO_GPU"))
33
  USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:127.0) Gecko/20100101 Firefox/127.0'
34
 
35
 
@@ -68,8 +66,7 @@ class ModelInformation:
68
  )
69
  self.filename_url = self.filename_url if self.filename_url else ""
70
  self.description = json_data.get("description", "")
71
- if self.description is None:
72
- self.description = ""
73
  self.model_name = json_data.get("model", {}).get("name", "")
74
  self.model_type = json_data.get("model", {}).get("type", "")
75
  self.nsfw = json_data.get("model", {}).get("nsfw", False)
@@ -79,175 +76,118 @@ class ModelInformation:
79
  self.original_json = copy.deepcopy(json_data)
80
 
81
 
82
- def get_civit_params(url):
83
- try:
84
- json_data = request_json_data(url)
85
- mdc = ModelInformation(json_data)
86
- if mdc.download_url and mdc.filename_url:
87
- return mdc.download_url, mdc.filename_url, mdc.model_url
88
- else:
89
- ValueError("Invalid Civitai model URL")
90
- except Exception as e:
91
- print(f"Error retrieving Civitai metadata: {e} — fallback to direct download")
92
- return url, None, None
93
-
94
-
95
- def civ_redirect_down(url, dir_, civitai_api_key, romanize, alternative_name):
96
- filename_base = filename = None
97
-
98
- if alternative_name:
99
- output_path = os.path.join(dir_, alternative_name)
100
- if os.path.exists(output_path):
101
- return output_path, alternative_name
102
-
103
- # Follow the redirect to get the actual download URL
104
- curl_command = (
105
- f'curl -L -sI --connect-timeout 5 --max-time 5 '
106
- f'-H "Content-Type: application/json" '
107
- f'-H "Authorization: Bearer {civitai_api_key}" "{url}"'
108
- )
109
-
110
- headers = os.popen(curl_command).read()
111
-
112
- # Look for the redirected "Location" URL
113
- location_match = re.search(r'location: (.+)', headers, re.IGNORECASE)
114
 
115
- if location_match:
116
- redirect_url = location_match.group(1).strip()
117
 
118
- # Extract the filename from the redirect URL's "Content-Disposition"
119
- filename_match = re.search(r'filename%3D%22(.+?)%22', redirect_url)
120
- if filename_match:
121
- encoded_filename = filename_match.group(1)
122
- # Decode the URL-encoded filename
123
- decoded_filename = urllib.parse.unquote(encoded_filename)
124
 
125
- filename = unidecode(decoded_filename) if romanize else decoded_filename
126
- # print(f"Filename redirect: {filename}")
 
 
 
 
 
 
 
 
 
127
 
128
- filename_base = alternative_name if alternative_name else filename
129
- if not filename_base:
130
- return None, None
131
- elif os.path.exists(os.path.join(dir_, filename_base)):
132
- return os.path.join(dir_, filename_base), filename_base
133
 
134
- aria2_command = (
135
- f'aria2c --console-log-level=error --summary-interval=10 -c -x 16 '
136
- f'-k 1M -s 16 -d "{dir_}" -o "{filename_base}" "{redirect_url}"'
137
- )
138
- r_code = os.system(aria2_command) # noqa
139
 
140
- # if r_code != 0:
141
- # raise RuntimeError(f"Failed to download file: {filename_base}. Error code: {r_code}")
142
 
143
- output_path = os.path.join(dir_, filename_base)
144
- if not os.path.exists(output_path):
145
- return None, filename_base
146
 
147
- return output_path, filename_base
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
 
 
 
149
 
150
- def civ_api_down(url, dir_, civitai_api_key, civ_filename):
151
- """
152
- This method is susceptible to being blocked because it generates a lot of temp redirect links with aria2c.
153
- If an API key limit is reached, generating a new API key and using it can fix the issue.
154
- """
155
- output_path = None
156
 
157
- url_dl = url + f"?token={civitai_api_key}"
158
- if not civ_filename:
159
- aria2_command = f'aria2c -c -x 1 -s 1 -d "{dir_}" "{url_dl}"'
 
160
  os.system(aria2_command)
161
- else:
162
- output_path = os.path.join(dir_, civ_filename)
163
- if not os.path.exists(output_path):
164
- aria2_command = (
165
- f'aria2c --console-log-level=error --summary-interval=10 -c -x 16 '
166
- f'-k 1M -s 16 -d "{dir_}" -o "{civ_filename}" "{url_dl}"'
167
- )
168
- os.system(aria2_command)
169
-
170
- return output_path
171
-
172
-
173
- def drive_down(url, dir_):
174
- import gdown
175
-
176
- output_path = None
177
 
178
- drive_id, _ = gdown.parse_url.parse_url(url, warning=False)
179
- dir_files = os.listdir(dir_)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
 
181
- for dfile in dir_files:
182
- if drive_id in dfile:
183
- output_path = os.path.join(dir_, dfile)
184
- break
185
-
186
- if not output_path:
187
- original_path = gdown.download(url, f"{dir_}/", fuzzy=True)
188
-
189
- dir_name, base_name = os.path.split(original_path)
190
- name, ext = base_name.rsplit(".", 1)
191
- new_name = f"{name}_{drive_id}.{ext}"
192
- output_path = os.path.join(dir_name, new_name)
193
-
194
- os.rename(original_path, output_path)
195
-
196
- return output_path
197
-
198
-
199
- def hf_down(url, dir_, hf_token, romanize):
200
- url = url.replace("?download=true", "")
201
- # url = urllib.parse.quote(url, safe=':/') # fix encoding
202
-
203
- filename = unidecode(url.split('/')[-1]) if romanize else url.split('/')[-1]
204
- output_path = os.path.join(dir_, filename)
205
-
206
- if os.path.exists(output_path):
207
- return output_path
208
-
209
- if "/blob/" in url:
210
- url = url.replace("/blob/", "/resolve/")
211
-
212
- if hf_token:
213
- user_header = f'"Authorization: Bearer {hf_token}"'
214
- os.system(f"aria2c --console-log-level=error --summary-interval=10 --header={user_header} -c -x 16 -k 1M -s 16 {url} -d {dir_} -o {filename}")
215
- else:
216
- os.system(f"aria2c --optimize-concurrent-downloads --console-log-level=error --summary-interval=10 -c -x 16 -k 1M -s 16 {url} -d {dir_} -o {filename}")
217
-
218
- return output_path
219
-
220
-
221
- def download_things(directory, url, hf_token="", civitai_api_key="", romanize=False):
222
- url = url.strip()
223
- downloaded_file_path = None
224
-
225
- if "drive.google.com" in url:
226
- downloaded_file_path = drive_down(url, directory)
227
- elif "huggingface.co" in url:
228
- downloaded_file_path = hf_down(url, directory, hf_token, romanize)
229
- elif "civitai.com" in url:
230
- if not civitai_api_key:
231
- msg = "You need an API key to download Civitai models."
232
- print(f"\033[91m{msg}\033[0m")
233
- gr.Warning(msg)
234
- return None
235
-
236
- url, civ_filename, civ_page = get_civit_params(url)
237
- if civ_page and not IS_ZERO_GPU:
238
- print(f"\033[92mCivitai model: {civ_filename} [page: {civ_page}]\033[0m")
239
-
240
- downloaded_file_path, civ_filename = civ_redirect_down(url, directory, civitai_api_key, romanize, civ_filename)
241
-
242
- if not downloaded_file_path:
243
- msg = (
244
- "Download failed.\n"
245
- "If this is due to an API limit, generating a new API key may resolve the issue.\n"
246
- "Attempting to download using the old method..."
247
- )
248
- print(msg)
249
- gr.Warning(msg)
250
- downloaded_file_path = civ_api_down(url, directory, civitai_api_key, civ_filename)
251
  else:
252
  os.system(f"aria2c --console-log-level=error --summary-interval=10 -c -x 16 -k 1M -s 16 -d {directory} {url}")
253
 
@@ -276,15 +216,14 @@ def extract_parameters(input_string):
276
  if "Steps:" in input_string:
277
  input_string = input_string.replace("Steps:", "Negative prompt: Steps:")
278
  else:
279
- msg = "Generation data is invalid."
280
- gr.Warning(msg)
281
- print(msg)
282
  parameters["prompt"] = input_string
283
  return parameters
284
 
285
  parm = input_string.split("Negative prompt:")
286
  parameters["prompt"] = parm[0].strip()
287
  if "Steps:" not in parm[1]:
 
288
  parameters["neg_prompt"] = parm[1].strip()
289
  return parameters
290
  parm = parm[1].split("Steps:")
@@ -367,8 +306,7 @@ def get_model_type(repo_id: str):
367
  model = api.model_info(repo_id=repo_id, timeout=5.0)
368
  tags = model.tags
369
  for tag in tags:
370
- if tag in MODEL_TYPE_CLASS.keys():
371
- return MODEL_TYPE_CLASS.get(tag, default)
372
 
373
  except Exception:
374
  return default
@@ -495,9 +433,9 @@ def get_folder_size_gb(folder_path):
495
  return total_size_gb
496
 
497
 
498
- def get_used_storage_gb(path_storage=STORAGE_ROOT):
499
  try:
500
- used_gb = get_folder_size_gb(path_storage)
501
  print(f"Used Storage: {used_gb:.2f} GB")
502
  except Exception as e:
503
  used_gb = 999
@@ -517,21 +455,6 @@ def delete_model(removal_candidate):
517
  shutil.rmtree(diffusers_model)
518
 
519
 
520
- def clear_hf_cache():
521
- """
522
- Clears the entire Hugging Face cache at ~/.cache/huggingface.
523
- Hugging Face will re-download models as needed later.
524
- """
525
- try:
526
- if os.path.exists(CACHE_HF_ROOT):
527
- shutil.rmtree(CACHE_HF_ROOT, ignore_errors=True)
528
- print(f"Hugging Face cache cleared: {CACHE_HF_ROOT}")
529
- else:
530
- print(f"No Hugging Face cache found at: {CACHE_HF_ROOT}")
531
- except Exception as e:
532
- print(f"Error clearing Hugging Face cache: {e}")
533
-
534
-
535
  def progress_step_bar(step, total):
536
  # Calculate the percentage for the progress bar width
537
  percentage = min(100, ((step / total) * 100))
 
9
  DIRECTORY_LORAS,
10
  DIRECTORY_MODELS,
11
  DIFFUSECRAFT_CHECKPOINT_NAME,
 
12
  CACHE_HF,
13
  STORAGE_ROOT,
14
  )
 
28
  import shutil
29
  import subprocess
30
 
 
31
  USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:127.0) Gecko/20100101 Firefox/127.0'
32
 
33
 
 
66
  )
67
  self.filename_url = self.filename_url if self.filename_url else ""
68
  self.description = json_data.get("description", "")
69
+ if self.description is None: self.description = ""
 
70
  self.model_name = json_data.get("model", {}).get("name", "")
71
  self.model_type = json_data.get("model", {}).get("type", "")
72
  self.nsfw = json_data.get("model", {}).get("nsfw", False)
 
76
  self.original_json = copy.deepcopy(json_data)
77
 
78
 
79
+ def retrieve_model_info(url):
80
+ json_data = request_json_data(url)
81
+ if not json_data:
82
+ return None
83
+ model_descriptor = ModelInformation(json_data)
84
+ return model_descriptor
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
 
 
 
86
 
87
+ def download_things(directory, url, hf_token="", civitai_api_key="", romanize=False):
88
+ url = url.strip()
89
+ downloaded_file_path = None
 
 
 
90
 
91
+ if "drive.google.com" in url:
92
+ original_dir = os.getcwd()
93
+ os.chdir(directory)
94
+ os.system(f"gdown --fuzzy {url}")
95
+ os.chdir(original_dir)
96
+ elif "huggingface.co" in url:
97
+ url = url.replace("?download=true", "")
98
+ # url = urllib.parse.quote(url, safe=':/') # fix encoding
99
+ if "/blob/" in url:
100
+ url = url.replace("/blob/", "/resolve/")
101
+ user_header = f'"Authorization: Bearer {hf_token}"'
102
 
103
+ filename = unidecode(url.split('/')[-1]) if romanize else url.split('/')[-1]
 
 
 
 
104
 
105
+ if hf_token:
106
+ 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 {filename}")
107
+ else:
108
+ 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 {filename}")
 
109
 
110
+ downloaded_file_path = os.path.join(directory, filename)
 
111
 
112
+ elif "civitai.com" in url:
 
 
113
 
114
+ if not civitai_api_key:
115
+ print("\033[91mYou need an API key to download Civitai models.\033[0m")
116
+
117
+ model_profile = retrieve_model_info(url)
118
+ if (
119
+ model_profile is not None
120
+ and model_profile.download_url
121
+ and model_profile.filename_url
122
+ ):
123
+ url = model_profile.download_url
124
+ filename = unidecode(model_profile.filename_url) if romanize else model_profile.filename_url
125
+ else:
126
+ if "?" in url:
127
+ url = url.split("?")[0]
128
+ filename = ""
129
 
130
+ url_dl = url + f"?token={civitai_api_key}"
131
+ print(f"Filename: {filename}")
132
 
133
+ param_filename = ""
134
+ if filename:
135
+ param_filename = f"-o '{filename}'"
 
 
 
136
 
137
+ aria2_command = (
138
+ f'aria2c --console-log-level=error --summary-interval=10 -c -x 16 '
139
+ f'-k 1M -s 16 -d "{directory}" {param_filename} "{url_dl}"'
140
+ )
141
  os.system(aria2_command)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
 
143
+ if param_filename and os.path.exists(os.path.join(directory, filename)):
144
+ downloaded_file_path = os.path.join(directory, filename)
145
+
146
+ # # PLAN B
147
+ # # Follow the redirect to get the actual download URL
148
+ # curl_command = (
149
+ # f'curl -L -sI --connect-timeout 5 --max-time 5 '
150
+ # f'-H "Content-Type: application/json" '
151
+ # f'-H "Authorization: Bearer {civitai_api_key}" "{url}"'
152
+ # )
153
+
154
+ # headers = os.popen(curl_command).read()
155
+
156
+ # # Look for the redirected "Location" URL
157
+ # location_match = re.search(r'location: (.+)', headers, re.IGNORECASE)
158
+
159
+ # if location_match:
160
+ # redirect_url = location_match.group(1).strip()
161
+
162
+ # # Extract the filename from the redirect URL's "Content-Disposition"
163
+ # filename_match = re.search(r'filename%3D%22(.+?)%22', redirect_url)
164
+ # if filename_match:
165
+ # encoded_filename = filename_match.group(1)
166
+ # # Decode the URL-encoded filename
167
+ # decoded_filename = urllib.parse.unquote(encoded_filename)
168
+
169
+ # filename = unidecode(decoded_filename) if romanize else decoded_filename
170
+ # print(f"Filename: {filename}")
171
+
172
+ # aria2_command = (
173
+ # f'aria2c --console-log-level=error --summary-interval=10 -c -x 16 '
174
+ # f'-k 1M -s 16 -d "{directory}" -o "{filename}" "{redirect_url}"'
175
+ # )
176
+ # return_code = os.system(aria2_command)
177
+
178
+ # # if return_code != 0:
179
+ # # raise RuntimeError(f"Failed to download file: {filename}. Error code: {return_code}")
180
+ # downloaded_file_path = os.path.join(directory, filename)
181
+ # if not os.path.exists(downloaded_file_path):
182
+ # downloaded_file_path = None
183
+
184
+ # if not downloaded_file_path:
185
+ # # Old method
186
+ # if "?" in url:
187
+ # url = url.split("?")[0]
188
+ # url = url + f"?token={civitai_api_key}"
189
+ # os.system(f"aria2c --console-log-level=error --summary-interval=10 -c -x 16 -k 1M -s 16 -d {directory} {url}")
190
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
  else:
192
  os.system(f"aria2c --console-log-level=error --summary-interval=10 -c -x 16 -k 1M -s 16 -d {directory} {url}")
193
 
 
216
  if "Steps:" in input_string:
217
  input_string = input_string.replace("Steps:", "Negative prompt: Steps:")
218
  else:
219
+ print("Invalid metadata")
 
 
220
  parameters["prompt"] = input_string
221
  return parameters
222
 
223
  parm = input_string.split("Negative prompt:")
224
  parameters["prompt"] = parm[0].strip()
225
  if "Steps:" not in parm[1]:
226
+ print("Steps not detected")
227
  parameters["neg_prompt"] = parm[1].strip()
228
  return parameters
229
  parm = parm[1].split("Steps:")
 
306
  model = api.model_info(repo_id=repo_id, timeout=5.0)
307
  tags = model.tags
308
  for tag in tags:
309
+ if tag in MODEL_TYPE_CLASS.keys(): return MODEL_TYPE_CLASS.get(tag, default)
 
310
 
311
  except Exception:
312
  return default
 
433
  return total_size_gb
434
 
435
 
436
+ def get_used_storage_gb():
437
  try:
438
+ used_gb = get_folder_size_gb(STORAGE_ROOT)
439
  print(f"Used Storage: {used_gb:.2f} GB")
440
  except Exception as e:
441
  used_gb = 999
 
455
  shutil.rmtree(diffusers_model)
456
 
457
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
458
  def progress_step_bar(step, total):
459
  # Calculate the percentage for the progress bar width
460
  percentage = min(100, ((step / total) * 100))