Files changed (9) hide show
  1. .gitignore +0 -207
  2. README.md +1 -1
  3. app.py +130 -277
  4. constants.py +36 -146
  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 +106 -183
.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,21 +1,17 @@
1
  import spaces
2
  import os
3
- from argparse import ArgumentParser
4
  from stablepy import (
5
  Model_Diffusers,
6
  SCHEDULE_TYPE_OPTIONS,
7
  SCHEDULE_PREDICTION_TYPE_OPTIONS,
8
  check_scheduler_compatibility,
9
  TASK_AND_PREPROCESSORS,
10
- FACE_RESTORATION_MODELS,
11
- scheduler_names,
12
  )
13
  from constants import (
14
  DIRECTORY_MODELS,
15
  DIRECTORY_LORAS,
16
  DIRECTORY_VAES,
17
  DIRECTORY_EMBEDS,
18
- DIRECTORY_UPSCALERS,
19
  DOWNLOAD_MODEL,
20
  DOWNLOAD_VAE,
21
  DOWNLOAD_LORA,
@@ -39,13 +35,15 @@ from constants import (
39
  EXAMPLES_GUI,
40
  RESOURCES,
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
48
  import re
 
 
 
 
 
49
  import time
50
  from PIL import ImageFile
51
  from utils import (
@@ -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
@@ -73,35 +70,31 @@ import warnings
73
  from stablepy import logger
74
  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:
92
  os.makedirs(directory, exist_ok=True)
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 +112,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 +130,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 +140,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 +155,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 +165,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,
@@ -238,7 +198,10 @@ class GuiSD:
238
  yield f"Loading model: {model_name}"
239
 
240
  if vae_model == "BakedVAE":
241
- vae_model = model_name
 
 
 
242
  elif vae_model:
243
  vae_type = "SDXL" if "sdxl" in vae_model.lower() else "SD 1.5"
244
  if model_type != vae_type:
@@ -257,10 +220,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 +233,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],
@@ -348,8 +310,8 @@ class GuiSD:
348
  syntax_weights,
349
  upscaler_model_path,
350
  upscaler_increases_size,
351
- upscaler_tile_size,
352
- upscaler_tile_overlap,
353
  hires_steps,
354
  hires_denoising_strength,
355
  hires_sampler,
@@ -413,9 +375,6 @@ class GuiSD:
413
  mode_ip2,
414
  scale_ip2,
415
  pag_scale,
416
- face_restoration_model,
417
- face_restoration_visibility,
418
- face_restoration_weight,
419
  ):
420
  info_state = html_template_message("Navigating latent space...")
421
  yield info_state, gr.update(), gr.update()
@@ -425,7 +384,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
 
@@ -454,20 +413,23 @@ class GuiSD:
454
  self.model.stream_config(concurrency=concurrency, latent_resize_by=1, vae_decoding=False)
455
 
456
  if task != "txt2img" and not image_control:
457
- raise ValueError("Reference image is required. Please upload one in 'Image ControlNet/Inpaint/Img2img'.")
458
 
459
- if task in ["inpaint", "repaint"] and not image_mask:
460
- raise ValueError("Mask image not found. Upload one in 'Image Mask' to proceed.")
461
 
462
- if "https://" not in str(UPSCALER_DICT_GUI[upscaler_model_path]):
463
  upscaler_model = upscaler_model_path
464
  else:
 
 
 
465
  url_upscaler = UPSCALER_DICT_GUI[upscaler_model_path]
466
 
467
- if not os.path.exists(f"./{DIRECTORY_UPSCALERS}/{url_upscaler.split('/')[-1]}"):
468
- download_things(DIRECTORY_UPSCALERS, url_upscaler, HF_TOKEN)
469
 
470
- upscaler_model = f"./{DIRECTORY_UPSCALERS}/{url_upscaler.split('/')[-1]}"
471
 
472
  logging.getLogger("ultralytics").setLevel(logging.INFO if adetailer_verbose else logging.ERROR)
473
 
@@ -523,19 +485,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"
@@ -569,8 +531,8 @@ class GuiSD:
569
  "t2i_adapter_conditioning_factor": float(t2i_adapter_conditioning_factor),
570
  "upscaler_model_path": upscaler_model,
571
  "upscaler_increases_size": upscaler_increases_size,
572
- "upscaler_tile_size": upscaler_tile_size,
573
- "upscaler_tile_overlap": upscaler_tile_overlap,
574
  "hires_steps": hires_steps,
575
  "hires_denoising_strength": hires_denoising_strength,
576
  "hires_prompt": hires_prompt,
@@ -585,19 +547,16 @@ class GuiSD:
585
  "ip_adapter_model": params_ip_model,
586
  "ip_adapter_mode": params_ip_mode,
587
  "ip_adapter_scale": params_ip_scale,
588
- "face_restoration_model": face_restoration_model,
589
- "face_restoration_visibility": face_restoration_visibility,
590
- "face_restoration_weight": face_restoration_weight,
591
  }
592
 
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 +586,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
  )
@@ -735,27 +694,22 @@ def sd_gen_generate_pipeline(*args):
735
 
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
744
 
745
- image = image.convert("RGB")
746
  exif_image = extract_exif_data(image)
747
 
748
- name_upscaler = UPSCALER_DICT_GUI[upscaler_name]
749
-
750
- if "https://" in str(name_upscaler):
751
-
752
- if not os.path.exists(f"./{DIRECTORY_UPSCALERS}/{name_upscaler.split('/')[-1]}"):
753
- download_things(DIRECTORY_UPSCALERS, name_upscaler, HF_TOKEN)
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)
761
 
@@ -763,11 +717,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 +770,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 +806,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 +820,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 +827,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 +837,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 +853,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 +862,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 +892,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,8 +900,8 @@ 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")
987
  hires_sampler_gui = gr.Dropdown(label="Hires Sampler", choices=POST_PROCESSING_SAMPLER, value=POST_PROCESSING_SAMPLER[0])
@@ -997,8 +917,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 +929,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 +941,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(
@@ -1031,16 +950,11 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
1031
  [lora1_gui, lora2_gui, lora3_gui, lora4_gui, lora5_gui, lora6_gui, lora7_gui, new_lora_status]
1032
  )
1033
 
1034
- with gr.Accordion("Face restoration", open=False, visible=True):
1035
-
1036
- face_rest_options = [None] + FACE_RESTORATION_MODELS
1037
-
1038
- face_restoration_model_gui = gr.Dropdown(label="Face restoration model", choices=face_rest_options, value=face_rest_options[0])
1039
- face_restoration_visibility_gui = gr.Slider(minimum=0., maximum=1., step=0.001, value=1., label="Visibility")
1040
- face_restoration_weight_gui = gr.Slider(minimum=0., maximum=1., step=0.001, value=.5, label="Weight", info="(0 = maximum effect, 1 = minimum effect)")
1041
-
1042
  with gr.Accordion("IP-Adapter", open=False, visible=True):
1043
 
 
 
 
1044
  with gr.Accordion("IP-Adapter 1", open=False, visible=True):
1045
  image_ip1 = gr.Image(label="IP Image", type="filepath")
1046
  mask_ip1 = gr.Image(label="IP Mask", type="filepath")
@@ -1059,13 +973,13 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
1059
  image_mask_gui = gr.Image(label="Image Mask", type="filepath")
1060
  strength_gui = gr.Slider(
1061
  minimum=0.01, maximum=1.0, step=0.01, value=0.55, label="Strength",
1062
- info="This option adjusts the level of changes for img2img, repaint and inpaint."
1063
  )
1064
  image_resolution_gui = gr.Slider(
1065
  minimum=64, maximum=2048, step=64, value=1024, label="Image Resolution",
1066
  info="The maximum proportional size of the generated image based on the uploaded image."
1067
  )
1068
- controlnet_model_gui = gr.Dropdown(label="ControlNet model", choices=DIFFUSERS_CONTROLNET_MODEL, value=DIFFUSERS_CONTROLNET_MODEL[0], allow_custom_value=True)
1069
  control_net_output_scaling_gui = gr.Slider(minimum=0, maximum=5.0, step=0.1, value=1, label="ControlNet Output Scaling in UNet")
1070
  control_net_start_threshold_gui = gr.Slider(minimum=0, maximum=1, step=0.01, value=0, label="ControlNet Start Threshold (%)")
1071
  control_net_stop_threshold_gui = gr.Slider(minimum=0, maximum=1, step=0.01, value=1, label="ControlNet Stop Threshold (%)")
@@ -1087,8 +1001,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 +1037,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 +1087,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 +1156,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)
@@ -1329,11 +1190,8 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
1329
 
1330
  with gr.Row():
1331
  with gr.Column():
1332
-
1333
- USCALER_TAB_KEYS = [name for name in UPSCALER_KEYS[9:]]
1334
-
1335
  image_up_tab = gr.Image(label="Image", type="pil", sources=["upload"])
1336
- upscaler_tab = gr.Dropdown(label="Upscaler", choices=USCALER_TAB_KEYS, value=USCALER_TAB_KEYS[5])
1337
  upscaler_size_tab = gr.Slider(minimum=1., maximum=4., step=0.1, value=1.1, label="Upscale by")
1338
  generate_button_up_tab = gr.Button(value="START UPSCALE", variant="primary")
1339
 
@@ -1341,7 +1199,7 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
1341
  result_up_tab = gr.Image(label="Result", type="pil", interactive=False, format="png")
1342
 
1343
  generate_button_up_tab.click(
1344
- fn=process_upscale,
1345
  inputs=[image_up_tab, upscaler_tab, upscaler_size_tab],
1346
  outputs=[result_up_tab],
1347
  )
@@ -1413,8 +1271,8 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
1413
  prompt_syntax_gui,
1414
  upscaler_model_path_gui,
1415
  upscaler_increases_size_gui,
1416
- upscaler_tile_size_gui,
1417
- upscaler_tile_overlap_gui,
1418
  hires_steps_gui,
1419
  hires_denoising_strength_gui,
1420
  hires_sampler_gui,
@@ -1478,9 +1336,6 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
1478
  mode_ip2,
1479
  scale_ip2,
1480
  pag_scale_gui,
1481
- face_restoration_model_gui,
1482
- face_restoration_visibility_gui,
1483
- face_restoration_weight_gui,
1484
  load_lora_cpu_gui,
1485
  verbose_info_gui,
1486
  gpu_duration_gui,
@@ -1490,12 +1345,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,
6
  SCHEDULE_PREDICTION_TYPE_OPTIONS,
7
  check_scheduler_compatibility,
8
  TASK_AND_PREPROCESSORS,
 
 
9
  )
10
  from constants import (
11
  DIRECTORY_MODELS,
12
  DIRECTORY_LORAS,
13
  DIRECTORY_VAES,
14
  DIRECTORY_EMBEDS,
 
15
  DOWNLOAD_MODEL,
16
  DOWNLOAD_VAE,
17
  DOWNLOAD_LORA,
 
35
  EXAMPLES_GUI,
36
  RESOURCES,
37
  DIFFUSERS_CONTROLNET_MODEL,
 
 
 
38
  )
39
  from stablepy.diffusers_vanilla.style_prompt_config import STYLE_NAMES
40
  import torch
41
  import re
42
+ from stablepy import (
43
+ scheduler_names,
44
+ IP_ADAPTERS_SD,
45
+ IP_ADAPTERS_SDXL,
46
+ )
47
  import time
48
  from PIL import ImageFile
49
  from utils import (
 
60
  progress_step_bar,
61
  html_template_message,
62
  escape_html,
 
63
  )
64
  from image_processor import preprocessor_tab
65
  from datetime import datetime
 
70
  from stablepy import logger
71
  from diffusers import FluxPipeline
72
  # import urllib.parse
 
 
 
 
 
 
 
 
 
73
 
74
  ImageFile.LOAD_TRUNCATED_IMAGES = True
75
  torch.backends.cuda.matmul.allow_tf32 = True
76
  # os.environ["PYTORCH_NO_CUDA_MEMORY_CACHING"] = "1"
77
+ print(os.getenv("SPACES_ZERO_GPU"))
78
 
79
+ directories = [DIRECTORY_MODELS, DIRECTORY_LORAS, DIRECTORY_VAES, DIRECTORY_EMBEDS]
80
  for directory in directories:
81
  os.makedirs(directory, exist_ok=True)
82
 
83
  # Download stuffs
84
  for url in [url.strip() for url in DOWNLOAD_MODEL.split(',')]:
85
+ if not os.path.exists(f"./models/{url.split('/')[-1]}"):
86
+ download_things(DIRECTORY_MODELS, url, HF_TOKEN, CIVITAI_API_KEY)
87
  for url in [url.strip() for url in DOWNLOAD_VAE.split(',')]:
88
+ if not os.path.exists(f"./vaes/{url.split('/')[-1]}"):
89
+ download_things(DIRECTORY_VAES, url, HF_TOKEN, CIVITAI_API_KEY)
90
  for url in [url.strip() for url in DOWNLOAD_LORA.split(',')]:
91
+ if not os.path.exists(f"./loras/{url.split('/')[-1]}"):
92
+ download_things(DIRECTORY_LORAS, url, HF_TOKEN, CIVITAI_API_KEY)
93
 
94
  # Download Embeddings
95
  for url_embed in DOWNLOAD_EMBEDS:
96
+ if not os.path.exists(f"./embedings/{url_embed.split('/')[-1]}"):
97
+ download_things(DIRECTORY_EMBEDS, url_embed, HF_TOKEN, CIVITAI_API_KEY)
98
 
99
  # Build list models
100
  embed_list = get_model_list(DIRECTORY_EMBEDS)
 
112
 
113
  print('\033[33m🏁 Download and listing of valid models completed.\033[0m')
114
 
115
+ flux_repo = "camenduru/FLUX.1-dev-diffusers"
116
+ flux_pipe = FluxPipeline.from_pretrained(
117
+ flux_repo,
118
+ transformer=None,
119
+ torch_dtype=torch.bfloat16,
120
+ ).to("cuda")
121
+ components = flux_pipe.components
122
+ components.pop("transformer", None)
123
+ delete_model(flux_repo)
 
124
 
125
  #######################
126
  # GUI
 
130
  warnings.filterwarnings(action="ignore", category=FutureWarning, module="diffusers")
131
  warnings.filterwarnings(action="ignore", category=UserWarning, module="diffusers")
132
  warnings.filterwarnings(action="ignore", category=FutureWarning, module="transformers")
133
+ logger.setLevel(logging.DEBUG)
 
 
 
 
 
 
 
 
 
 
134
 
135
  CSS = """
136
  .contain { display: flex; flex-direction: column; }
 
140
  """
141
 
142
 
 
 
 
 
 
 
143
  class GuiSD:
144
  def __init__(self, stream=True):
145
  self.model = None
 
155
  removal_candidate = self.inventory.pop(0)
156
  delete_model(removal_candidate)
157
 
 
 
 
 
 
 
 
 
 
158
  def update_inventory(self, model_name):
159
  if model_name not in single_file_model_list:
160
  self.inventory = [
 
165
  def load_new_model(self, model_name, vae_model, task, controlnet_model, progress=gr.Progress(track_tqdm=True)):
166
 
167
  # download link model > model_name
 
 
 
 
 
168
 
169
+ self.update_storage_models()
 
170
 
171
  vae_model = vae_model if vae_model != "None" else None
172
  model_type = get_model_type(model_name)
173
  dtype_model = torch.bfloat16 if model_type == "FLUX" else torch.float16
174
 
175
  if not os.path.exists(model_name):
 
176
  _ = download_diffuser_repo(
177
  repo_name=model_name,
178
  model_type=model_type,
 
198
  yield f"Loading model: {model_name}"
199
 
200
  if vae_model == "BakedVAE":
201
+ if not os.path.exists(model_name):
202
+ vae_model = model_name
203
+ else:
204
+ vae_model = None
205
  elif vae_model:
206
  vae_type = "SDXL" if "sdxl" in vae_model.lower() else "SD 1.5"
207
  if model_type != vae_type:
 
220
  type_model_precision=dtype_model,
221
  retain_task_model_in_cache=False,
222
  controlnet_model=controlnet_model,
223
+ device="cpu",
224
  env_components=components,
225
  )
226
+ self.model.advanced_params(image_preprocessor_cuda_active=True)
227
  else:
228
  if self.model.base_model_id != model_name:
229
  load_now_time = datetime.now()
 
233
  print("Waiting for the previous model's time ops...")
234
  time.sleep(9 - elapsed_time)
235
 
236
+ self.model.device = torch.device("cpu")
 
237
  self.model.load_pipe(
238
  model_name,
239
  task_name=TASK_STABLEPY[task],
 
310
  syntax_weights,
311
  upscaler_model_path,
312
  upscaler_increases_size,
313
+ esrgan_tile,
314
+ esrgan_tile_overlap,
315
  hires_steps,
316
  hires_denoising_strength,
317
  hires_sampler,
 
375
  mode_ip2,
376
  scale_ip2,
377
  pag_scale,
 
 
 
378
  ):
379
  info_state = html_template_message("Navigating latent space...")
380
  yield info_state, gr.update(), gr.update()
 
384
  vae_msg = f"VAE: {vae_model}" if vae_model else ""
385
  msg_lora = ""
386
 
387
+ print("Config model:", model_name, vae_model, loras_list)
388
 
389
  task = TASK_STABLEPY[task]
390
 
 
413
  self.model.stream_config(concurrency=concurrency, latent_resize_by=1, vae_decoding=False)
414
 
415
  if task != "txt2img" and not image_control:
416
+ raise ValueError("No control image found: To use this function, you have to upload an image in 'Image ControlNet/Inpaint/Img2img'")
417
 
418
+ if task == "inpaint" and not image_mask:
419
+ raise ValueError("No mask image found: Specify one in 'Image Mask'")
420
 
421
+ if upscaler_model_path in UPSCALER_KEYS[:9]:
422
  upscaler_model = upscaler_model_path
423
  else:
424
+ directory_upscalers = 'upscalers'
425
+ os.makedirs(directory_upscalers, exist_ok=True)
426
+
427
  url_upscaler = UPSCALER_DICT_GUI[upscaler_model_path]
428
 
429
+ if not os.path.exists(f"./upscalers/{url_upscaler.split('/')[-1]}"):
430
+ download_things(directory_upscalers, url_upscaler, HF_TOKEN)
431
 
432
+ upscaler_model = f"./upscalers/{url_upscaler.split('/')[-1]}"
433
 
434
  logging.getLogger("ultralytics").setLevel(logging.INFO if adetailer_verbose else logging.ERROR)
435
 
 
485
  "distance_threshold": distance_threshold,
486
  "recolor_gamma_correction": float(recolor_gamma_correction),
487
  "tile_blur_sigma": int(tile_blur_sigma),
488
+ "lora_A": lora1 if lora1 != "None" else None,
489
  "lora_scale_A": lora_scale1,
490
+ "lora_B": lora2 if lora2 != "None" else None,
491
  "lora_scale_B": lora_scale2,
492
+ "lora_C": lora3 if lora3 != "None" else None,
493
  "lora_scale_C": lora_scale3,
494
+ "lora_D": lora4 if lora4 != "None" else None,
495
  "lora_scale_D": lora_scale4,
496
+ "lora_E": lora5 if lora5 != "None" else None,
497
  "lora_scale_E": lora_scale5,
498
+ "lora_F": lora6 if lora6 != "None" else None,
499
  "lora_scale_F": lora_scale6,
500
+ "lora_G": lora7 if lora7 != "None" else None,
501
  "lora_scale_G": lora_scale7,
502
  "textual_inversion": embed_list if textual_inversion else [],
503
  "syntax_weights": syntax_weights, # "Classic"
 
531
  "t2i_adapter_conditioning_factor": float(t2i_adapter_conditioning_factor),
532
  "upscaler_model_path": upscaler_model,
533
  "upscaler_increases_size": upscaler_increases_size,
534
+ "esrgan_tile": esrgan_tile,
535
+ "esrgan_tile_overlap": esrgan_tile_overlap,
536
  "hires_steps": hires_steps,
537
  "hires_denoising_strength": hires_denoising_strength,
538
  "hires_prompt": hires_prompt,
 
547
  "ip_adapter_model": params_ip_model,
548
  "ip_adapter_mode": params_ip_mode,
549
  "ip_adapter_scale": params_ip_scale,
 
 
 
550
  }
551
 
552
  # kwargs for diffusers pipeline
553
  if guidance_rescale:
554
  pipe_params["guidance_rescale"] = guidance_rescale
555
+
556
+ self.model.device = torch.device("cuda:0")
557
+ if hasattr(self.model.pipe, "transformer") and loras_list != ["None"] * self.model.num_loras:
558
+ self.model.pipe.transformer.to(self.model.device)
559
+ print("transformer to cuda")
560
 
561
  actual_progress = 0
562
  info_images = gr.update()
 
586
 
587
  download_links = "<br>".join(
588
  [
589
+ f'<a href="{path.replace("/images/", "/file=/home/user/app/images/")}" download="{os.path.basename(path)}">Download Image {i + 1}</a>'
590
  for i, path in enumerate(image_path)
591
  ]
592
  )
 
694
 
695
 
696
  @spaces.GPU(duration=15)
697
+ def esrgan_upscale(image, upscaler_name, upscaler_size):
698
+ if image is None: return None
 
699
 
700
  from stablepy.diffusers_vanilla.utils import save_pil_image_with_metadata
701
+ from stablepy import UpscalerESRGAN
702
 
 
703
  exif_image = extract_exif_data(image)
704
 
705
+ url_upscaler = UPSCALER_DICT_GUI[upscaler_name]
706
+ directory_upscalers = 'upscalers'
707
+ os.makedirs(directory_upscalers, exist_ok=True)
708
+ if not os.path.exists(f"./upscalers/{url_upscaler.split('/')[-1]}"):
709
+ download_things(directory_upscalers, url_upscaler, HF_TOKEN)
 
 
 
710
 
711
+ scaler_beta = UpscalerESRGAN(0, 0)
712
+ image_up = scaler_beta.upscale(image, upscaler_size, f"./upscalers/{url_upscaler.split('/')[-1]}")
713
 
714
  image_path = save_pil_image_with_metadata(image_up, f'{os.getcwd()}/up_images', exif_image)
715
 
 
717
 
718
 
719
  # https://huggingface.co/spaces/BestWishYsh/ConsisID-preview-Space/discussions/1#674969a022b99c122af5d407
720
+ dynamic_gpu_duration.zerogpu = True
721
+ sd_gen_generate_pipeline.zerogpu = True
722
  sd_gen = GuiSD()
723
 
724
+ with gr.Blocks(theme="NoCrypt/miku", css=CSS) as app:
725
  gr.Markdown("# 🧩 DiffuseCraft")
726
  gr.Markdown(SUBTITLE_GUI)
727
  with gr.Tab("Generation"):
 
770
 
771
  actual_task_info = gr.HTML()
772
 
773
+ with gr.Row(equal_height=False, variant="default"):
774
  gpu_duration_gui = gr.Number(minimum=5, maximum=240, value=59, show_label=False, container=False, info="GPU time duration (seconds)")
775
  with gr.Column():
776
  verbose_info_gui = gr.Checkbox(value=False, container=False, label="Status info")
 
806
  "Schedule type": gr.update(value="Automatic"),
807
  "PAG": gr.update(value=.0),
808
  "FreeU": gr.update(value=False),
 
 
 
 
 
 
 
 
 
809
  }
 
 
 
 
 
 
810
  valid_keys = list(valid_receptors.keys())
811
 
812
  parameters = extract_parameters(base_prompt)
 
820
  parameters["Sampler"] = value_sampler
821
  parameters["Schedule type"] = s_type
822
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
823
  for key, val in parameters.items():
824
  # print(val)
825
  if key in valid_keys:
 
827
  if key == "Sampler":
828
  if val not in scheduler_names:
829
  continue
830
+ if key == "Schedule type":
831
  if val not in SCHEDULE_TYPE_OPTIONS:
832
+ val = "Automatic"
 
 
 
833
  elif key == "Clip skip":
834
  if "," in str(val):
835
  val = val.replace(",", "")
 
837
  val = True
838
  if key == "prompt":
839
  if ">" in val and "<" in val:
840
+ val = re.sub(r'<[^>]+>', '', val)
841
  print("Removed LoRA written in the prompt")
842
  if key in ["prompt", "neg_prompt"]:
843
  val = re.sub(r'\s+', ' ', re.sub(r',+', ',', val)).strip()
844
+ if key in ["Steps", "width", "height", "Seed"]:
845
  val = int(val)
846
  if key == "FreeU":
847
  val = True
848
+ if key in ["CFG scale", "PAG"]:
849
  val = float(val)
850
  if key == "Model":
851
  filtered_models = [m for m in model_list if val in m]
 
853
  val = filtered_models[0]
854
  else:
855
  val = name_model
 
 
 
856
  if key == "Seed":
857
  continue
 
858
  valid_receptors[key] = gr.update(value=val)
859
  # print(val, type(val))
860
  # print(valid_receptors)
 
862
  print(str(e))
863
  return [value for value in valid_receptors.values()]
864
 
865
+ set_params_gui.click(
866
+ run_set_params_gui, [prompt_gui, model_name_gui], [
867
+ prompt_gui,
868
+ neg_prompt_gui,
869
+ steps_gui,
870
+ img_width_gui,
871
+ img_height_gui,
872
+ seed_gui,
873
+ sampler_gui,
874
+ cfg_gui,
875
+ clip_skip_gui,
876
+ model_name_gui,
877
+ schedule_type_gui,
878
+ pag_scale_gui,
879
+ free_u_gui,
880
+ ],
881
+ )
882
+
883
  def run_clear_prompt_gui():
884
  return gr.update(value=""), gr.update(value="")
885
  clear_prompt_gui.click(
 
892
  run_set_random_seed, [], seed_gui
893
  )
894
 
895
+ num_images_gui = gr.Slider(minimum=1, maximum=5, step=1, value=1, label="Images")
896
  prompt_syntax_gui = gr.Dropdown(label="Prompt Syntax", choices=PROMPT_W_OPTIONS, value=PROMPT_W_OPTIONS[1][1])
897
  vae_model_gui = gr.Dropdown(label="VAE Model", choices=vae_model_list, value=vae_model_list[0])
898
 
 
900
 
901
  upscaler_model_path_gui = gr.Dropdown(label="Upscaler", choices=UPSCALER_KEYS, value=UPSCALER_KEYS[0])
902
  upscaler_increases_size_gui = gr.Slider(minimum=1.1, maximum=4., step=0.1, value=1.2, label="Upscale by")
903
+ esrgan_tile_gui = gr.Slider(minimum=0, value=0, maximum=500, step=1, label="ESRGAN Tile")
904
+ esrgan_tile_overlap_gui = gr.Slider(minimum=1, maximum=200, step=1, value=8, label="ESRGAN Tile Overlap")
905
  hires_steps_gui = gr.Slider(minimum=0, value=30, maximum=100, step=1, label="Hires Steps")
906
  hires_denoising_strength_gui = gr.Slider(minimum=0.1, maximum=1.0, step=0.01, value=0.55, label="Hires Denoising Strength")
907
  hires_sampler_gui = gr.Dropdown(label="Hires Sampler", choices=POST_PROCESSING_SAMPLER, value=POST_PROCESSING_SAMPLER[0])
 
917
  return gr.Dropdown(label=label, choices=lora_model_list, value="None", allow_custom_value=True, visible=visible)
918
 
919
  def lora_scale_slider(label, visible=True):
920
+ return gr.Slider(minimum=-2, maximum=2, step=0.01, value=0.33, label=label, visible=visible)
 
921
 
922
  lora1_gui = lora_dropdown("Lora1")
923
  lora_scale_1_gui = lora_scale_slider("Lora Scale 1")
 
929
  lora_scale_4_gui = lora_scale_slider("Lora Scale 4")
930
  lora5_gui = lora_dropdown("Lora5")
931
  lora_scale_5_gui = lora_scale_slider("Lora Scale 5")
932
+ lora6_gui = lora_dropdown("Lora6", visible=False)
933
+ lora_scale_6_gui = lora_scale_slider("Lora Scale 6", visible=False)
934
+ lora7_gui = lora_dropdown("Lora7", visible=False)
935
+ lora_scale_7_gui = lora_scale_slider("Lora Scale 7", visible=False)
936
 
937
  with gr.Accordion("From URL", open=False, visible=True):
938
  text_lora = gr.Textbox(
 
941
  lines=1,
942
  info="It has to be .safetensors files, and you can also download them from Hugging Face.",
943
  )
944
+ romanize_text = gr.Checkbox(value=False, label="Transliterate name", visible=False)
945
  button_lora = gr.Button("Get and Refresh the LoRA Lists")
946
  new_lora_status = gr.HTML()
947
  button_lora.click(
 
950
  [lora1_gui, lora2_gui, lora3_gui, lora4_gui, lora5_gui, lora6_gui, lora7_gui, new_lora_status]
951
  )
952
 
 
 
 
 
 
 
 
 
953
  with gr.Accordion("IP-Adapter", open=False, visible=True):
954
 
955
+ IP_MODELS = sorted(list(set(IP_ADAPTERS_SD + IP_ADAPTERS_SDXL)))
956
+ MODE_IP_OPTIONS = ["original", "style", "layout", "style+layout"]
957
+
958
  with gr.Accordion("IP-Adapter 1", open=False, visible=True):
959
  image_ip1 = gr.Image(label="IP Image", type="filepath")
960
  mask_ip1 = gr.Image(label="IP Mask", type="filepath")
 
973
  image_mask_gui = gr.Image(label="Image Mask", type="filepath")
974
  strength_gui = gr.Slider(
975
  minimum=0.01, maximum=1.0, step=0.01, value=0.55, label="Strength",
976
+ info="This option adjusts the level of changes for img2img and inpainting."
977
  )
978
  image_resolution_gui = gr.Slider(
979
  minimum=64, maximum=2048, step=64, value=1024, label="Image Resolution",
980
  info="The maximum proportional size of the generated image based on the uploaded image."
981
  )
982
+ controlnet_model_gui = gr.Dropdown(label="ControlNet model", choices=DIFFUSERS_CONTROLNET_MODEL, value=DIFFUSERS_CONTROLNET_MODEL[0])
983
  control_net_output_scaling_gui = gr.Slider(minimum=0, maximum=5.0, step=0.1, value=1, label="ControlNet Output Scaling in UNet")
984
  control_net_start_threshold_gui = gr.Slider(minimum=0, maximum=1, step=0.01, value=0, label="ControlNet Start Threshold (%)")
985
  control_net_stop_threshold_gui = gr.Slider(minimum=0, maximum=1, step=0.01, value=1, label="ControlNet Stop Threshold (%)")
 
1001
  preprocess_resolution_gui = gr.Slider(minimum=64, maximum=2048, step=64, value=512, label="Preprocessor Resolution")
1002
  low_threshold_gui = gr.Slider(minimum=1, maximum=255, step=1, value=100, label="'CANNY' low threshold")
1003
  high_threshold_gui = gr.Slider(minimum=1, maximum=255, step=1, value=200, label="'CANNY' high threshold")
1004
+ value_threshold_gui = gr.Slider(minimum=1, maximum=2.0, step=0.01, value=0.1, label="'MLSD' Hough value threshold")
1005
+ distance_threshold_gui = gr.Slider(minimum=1, maximum=20.0, step=0.01, value=0.1, label="'MLSD' Hough distance threshold")
1006
  recolor_gamma_correction_gui = gr.Number(minimum=0., maximum=25., value=1., step=0.001, label="'RECOLOR' gamma correction")
1007
  tile_blur_sigma_gui = gr.Number(minimum=0, maximum=100, value=9, step=1, label="'TILE' blur sigma")
1008
 
 
1037
  gr.Info(f"{len(sd_gen.model.STYLE_NAMES)} styles loaded")
1038
  return gr.update(value=None, choices=sd_gen.model.STYLE_NAMES)
1039
 
1040
+ style_button.click(load_json_style_file, [style_json_gui], [style_prompt_gui])
1041
 
1042
  with gr.Accordion("Textual inversion", open=False, visible=False):
1043
  active_textual_inversion_gui = gr.Checkbox(value=False, label="Active Textual Inversion in prompt")
 
1087
  hires_before_adetailer_gui = gr.Checkbox(value=False, label="Hires Before Adetailer")
1088
  hires_after_adetailer_gui = gr.Checkbox(value=True, label="Hires After Adetailer")
1089
  generator_in_cpu_gui = gr.Checkbox(value=False, label="Generator in CPU")
 
 
 
 
1090
 
1091
  with gr.Accordion("More settings", open=False, visible=False):
1092
  loop_generation_gui = gr.Slider(minimum=1, value=1, label="Loop Generation")
1093
  retain_task_cache_gui = gr.Checkbox(value=False, label="Retain task model in cache")
1094
+ leave_progress_bar_gui = gr.Checkbox(value=True, label="Leave Progress Bar")
1095
+ disable_progress_bar_gui = gr.Checkbox(value=False, label="Disable Progress Bar")
1096
  display_images_gui = gr.Checkbox(value=False, label="Display Images")
1097
  image_previews_gui = gr.Checkbox(value=True, label="Image Previews")
1098
+ image_storage_location_gui = gr.Textbox(value="./images", label="Image Storage Location")
1099
  retain_compel_previous_load_gui = gr.Checkbox(value=False, label="Retain Compel Previous Load")
1100
  retain_detailfix_model_previous_load_gui = gr.Checkbox(value=False, label="Retain Detailfix Model Previous Load")
1101
  retain_hires_model_previous_load_gui = gr.Checkbox(value=False, label="Retain Hires Model Previous Load")
1102
  xformers_memory_efficient_attention_gui = gr.Checkbox(value=False, label="Xformers Memory Efficient Attention")
1103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1104
  with gr.Accordion("Examples and help", open=False, visible=True):
1105
  gr.Markdown(HELP_GUI)
1106
  gr.Markdown(EXAMPLES_GUI_HELP)
 
1156
  # "hsl(360, 120, 120)" # in fact any valid colorstring
1157
  ]
1158
  ),
1159
+ eraser=gr.Eraser(default_size="16")
 
 
 
1160
  )
 
 
 
 
 
 
 
1161
  invert_mask = gr.Checkbox(value=False, label="Invert mask")
1162
  btn = gr.Button("Create mask")
 
1163
  with gr.Column(scale=1):
1164
  img_source = gr.Image(interactive=False)
1165
  img_result = gr.Image(label="Mask image", show_label=True, interactive=False)
 
1190
 
1191
  with gr.Row():
1192
  with gr.Column():
 
 
 
1193
  image_up_tab = gr.Image(label="Image", type="pil", sources=["upload"])
1194
+ upscaler_tab = gr.Dropdown(label="Upscaler", choices=UPSCALER_KEYS[9:], value=UPSCALER_KEYS[11])
1195
  upscaler_size_tab = gr.Slider(minimum=1., maximum=4., step=0.1, value=1.1, label="Upscale by")
1196
  generate_button_up_tab = gr.Button(value="START UPSCALE", variant="primary")
1197
 
 
1199
  result_up_tab = gr.Image(label="Result", type="pil", interactive=False, format="png")
1200
 
1201
  generate_button_up_tab.click(
1202
+ fn=esrgan_upscale,
1203
  inputs=[image_up_tab, upscaler_tab, upscaler_size_tab],
1204
  outputs=[result_up_tab],
1205
  )
 
1271
  prompt_syntax_gui,
1272
  upscaler_model_path_gui,
1273
  upscaler_increases_size_gui,
1274
+ esrgan_tile_gui,
1275
+ esrgan_tile_overlap_gui,
1276
  hires_steps_gui,
1277
  hires_denoising_strength_gui,
1278
  hires_sampler_gui,
 
1336
  mode_ip2,
1337
  scale_ip2,
1338
  pag_scale_gui,
 
 
 
1339
  load_lora_cpu_gui,
1340
  verbose_info_gui,
1341
  gpu_duration_gui,
 
1345
  show_progress="minimal",
1346
  )
1347
 
1348
+ app.queue()
1349
+
1350
+ app.launch(
1351
+ show_error=True,
1352
+ debug=True,
1353
+ allowed_paths=["./images/"],
1354
+ )
 
 
constants.py CHANGED
@@ -4,13 +4,8 @@ from stablepy import (
4
  scheduler_names,
5
  SD15_TASKS,
6
  SDXL_TASKS,
7
- ALL_BUILTIN_UPSCALERS,
8
- IP_ADAPTERS_SD,
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
 
@@ -23,46 +18,37 @@ DOWNLOAD_LORA = "https://huggingface.co/Leopain/color/resolve/main/Coloring_book
23
  LOAD_DIFFUSERS_FORMAT_MODEL = [
24
  'stabilityai/stable-diffusion-xl-base-1.0',
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',
37
  'terminusresearch/FluxBooru-v0.3',
38
- 'black-forest-labs/FLUX.1-schnell',
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',
58
- 'Laxhar/noobai-XL-Vpred-0.9r',
59
- 'Laxhar/noobai-XL-Vpred-0.75s',
60
- 'Laxhar/noobai-XL-Vpred-0.75',
61
  'Laxhar/noobai-XL-Vpred-0.65s',
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',
@@ -72,35 +58,18 @@ LOAD_DIFFUSERS_FORMAT_MODEL = [
72
  'John6666/illustrious-pencil-xl-v200-sdxl',
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',
@@ -112,14 +81,11 @@ LOAD_DIFFUSERS_FORMAT_MODEL = [
112
  'John6666/ras-real-anime-screencap-v1-sdxl',
113
  'John6666/duchaiten-pony-xl-no-score-v60-sdxl',
114
  'John6666/mistoon-anime-ponyalpha-sdxl',
115
- 'John6666/mistoon-xl-copper-v20fast-sdxl',
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,32 +93,24 @@ 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',
141
  'John6666/aimz-dream-real-pony-mix-v3-sdxl',
142
- 'John6666/prefectious-xl-nsfw-v10-sdxl',
143
- 'GraydientPlatformAPI/iniverseponyRealGuofeng49',
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',
@@ -162,9 +120,7 @@ LOAD_DIFFUSERS_FORMAT_MODEL = [
162
  'digiplay/darkphoenix3D_v1.1',
163
  'digiplay/BeenYouLiteL11_diffusers',
164
  'GraydientPlatformAPI/rev-animated2',
165
- 'myxlmynx/cyberrealistic_classic40',
166
- 'GraydientPlatformAPI/cyberreal6',
167
- 'GraydientPlatformAPI/cyberreal5',
168
  'youknownothing/deliberate-v6',
169
  'GraydientPlatformAPI/deliberate-cyber3',
170
  'GraydientPlatformAPI/picx-real',
@@ -178,9 +134,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",
@@ -200,13 +156,9 @@ DIRECTORY_MODELS = 'models'
200
  DIRECTORY_LORAS = 'loras'
201
  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',
@@ -232,23 +184,28 @@ TASK_STABLEPY = {
232
  'optical pattern ControlNet': 'pattern',
233
  'recolor ControlNet': 'recolor',
234
  'tile ControlNet': 'tile',
235
- 'repaint ControlNet': 'repaint',
236
  }
237
 
238
  TASK_MODEL_LIST = list(TASK_STABLEPY.keys())
239
 
240
  UPSCALER_DICT_GUI = {
241
  None: None,
242
- **{bu: bu for bu in ALL_BUILTIN_UPSCALERS if bu not in ["HAT x4", "DAT x4", "DAT x3", "DAT x2", "SwinIR 4x"]},
243
- # "RealESRGAN_x4plus": "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.0/RealESRGAN_x4plus.pth",
 
 
 
 
 
 
 
244
  "RealESRNet_x4plus": "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.1/RealESRNet_x4plus.pth",
245
- # "RealESRGAN_x4plus_anime_6B": "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.2.4/RealESRGAN_x4plus_anime_6B.pth",
246
- # "RealESRGAN_x2plus": "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.1/RealESRGAN_x2plus.pth",
247
- # "realesr-animevideov3": "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.5.0/realesr-animevideov3.pth",
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",
@@ -262,7 +219,6 @@ UPSCALER_KEYS = list(UPSCALER_DICT_GUI.keys())
262
  DIFFUSERS_CONTROLNET_MODEL = [
263
  "Automatic",
264
 
265
- "brad-twinkl/controlnet-union-sdxl-1.0-promax",
266
  "xinsir/controlnet-union-sdxl-1.0",
267
  "xinsir/anime-painter",
268
  "Eugeoter/noob-sdxl-controlnet-canny",
@@ -285,6 +241,7 @@ DIFFUSERS_CONTROLNET_MODEL = [
285
  "r3gm/controlnet-recolor-sdxl-fp16",
286
  "r3gm/controlnet-openpose-twins-sdxl-1.0-fp16",
287
  "r3gm/controlnet-qr-pattern-sdxl-fp16",
 
288
  "Yakonrus/SDXL_Controlnet_Tile_Realistic_v2",
289
  "TheMistoAI/MistoLine",
290
  "briaai/BRIA-2.3-ControlNet-Recoloring",
@@ -363,30 +320,14 @@ POST_PROCESSING_SAMPLER = ["Use same sampler"] + [
363
  name_s for name_s in scheduler_names if "Auto-Loader" not in name_s
364
  ]
365
 
366
- IP_MODELS = []
367
- ALL_IPA = sorted(set(IP_ADAPTERS_SD + IP_ADAPTERS_SDXL))
368
-
369
- for origin_name in ALL_IPA:
370
- suffixes = []
371
- if origin_name in IP_ADAPTERS_SD:
372
- suffixes.append("sd1.5")
373
- if origin_name in IP_ADAPTERS_SDXL:
374
- suffixes.append("sdxl")
375
- ref_name = f"{origin_name} ({'/'.join(suffixes)})"
376
- IP_MODELS.append((ref_name, origin_name))
377
-
378
- MODE_IP_OPTIONS = ["original", "style", "layout", "style+layout"]
379
-
380
  SUBTITLE_GUI = (
381
  "### This demo uses [diffusers](https://github.com/huggingface/diffusers)"
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
  """
@@ -399,9 +340,7 @@ EXAMPLES_GUI_HELP = (
399
  3. ControlNet Canny SDXL
400
  4. Optical pattern (Optical illusion) SDXL
401
  5. Convert an image to a coloring drawing
402
- 6. V prediction model inference
403
- 7. V prediction model sd_embed variant inference
404
- 8. ControlNet OpenPose SD 1.5 and Latent upscale
405
 
406
  - Different tasks can be performed, such as img2img or using the IP adapter, to preserve a person's appearance or a specific style based on an image.
407
  """
@@ -510,7 +449,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,
@@ -528,54 +467,6 @@ EXAMPLES_GUI = [
528
  35,
529
  False,
530
  ],
531
- [
532
- "[mochizuki_shiina], [syuri22], newest, reimu, solo, outdoors, water, flower, lantern",
533
- "worst quality, normal quality, old, sketch,",
534
- 28,
535
- 7.0,
536
- -1,
537
- "None",
538
- 0.33,
539
- "DPM 3M Ef",
540
- 1600,
541
- 1024,
542
- "Laxhar/noobai-XL-Vpred-1.0",
543
- "txt2img",
544
- "color_image.png", # img conttol
545
- 1024, # img resolution
546
- 0.35, # strength
547
- 1.0, # cn scale
548
- 0.0, # cn start
549
- 1.0, # cn end
550
- "Classic",
551
- None,
552
- 30,
553
- False,
554
- ],
555
- [
556
- "[mochizuki_shiina], [syuri22], newest, multiple girls, 2girls, earrings, jewelry, gloves, purple eyes, black hair, looking at viewer, nail polish, hat, smile, open mouth, fingerless gloves, sleeveless, :d, upper body, blue eyes, closed mouth, black gloves, hands up, long hair, shirt, bare shoulders, white headwear, blush, black headwear, blue nails, upper teeth only, short hair, white gloves, white shirt, teeth, rabbit hat, star earrings, purple nails, pink hair, detached sleeves, fingernails, fake animal ears, animal hat, sleeves past wrists, black shirt, medium hair, fur trim, sleeveless shirt, turtleneck, long sleeves, rabbit ears, star \\(symbol\\)",
557
- "worst quality, normal quality, old, sketch,",
558
- 28,
559
- 7.0,
560
- -1,
561
- "None",
562
- 0.33,
563
- "DPM 3M Ef",
564
- 1600,
565
- 1024,
566
- "Laxhar/noobai-XL-Vpred-1.0",
567
- "txt2img",
568
- "color_image.png", # img conttol
569
- 1024, # img resolution
570
- 0.35, # strength
571
- 1.0, # cn scale
572
- 0.0, # cn start
573
- 1.0, # cn end
574
- "Classic-sd_embed",
575
- None,
576
- 30,
577
- False,
578
- ],
579
  [
580
  "1girl,face,curly hair,red hair,white background,",
581
  "(worst quality:2),(low quality:2),(normal quality:2),lowres,watermark,",
@@ -605,7 +496,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
- )
 
4
  scheduler_names,
5
  SD15_TASKS,
6
  SDXL_TASKS,
 
 
 
7
  )
8
 
 
 
9
  # - **Download Models**
10
  DOWNLOAD_MODEL = "https://huggingface.co/TechnoByte/MilkyWonderland/resolve/main/milkyWonderland_v40.safetensors"
11
 
 
18
  LOAD_DIFFUSERS_FORMAT_MODEL = [
19
  'stabilityai/stable-diffusion-xl-base-1.0',
20
  'Laxhar/noobai-XL-1.1',
 
21
  'black-forest-labs/FLUX.1-dev',
 
22
  'John6666/blue-pencil-flux1-v021-fp8-flux',
23
  'John6666/wai-ani-flux-v10forfp8-fp8-flux',
24
  'John6666/xe-anime-flux-v04-fp8-flux',
25
  'John6666/lyh-anime-flux-v2a1-fp8-flux',
26
  'John6666/carnival-unchained-v10-fp8-flux',
27
+ 'John6666/iniverse-mix-xl-sfwnsfw-fluxdfp16nsfwv11-fp8-flux',
28
  'Freepik/flux.1-lite-8B-alpha',
29
  'shauray/FluxDev-HyperSD-merged',
30
  'mikeyandfriends/PixelWave_FLUX.1-dev_03',
31
  'terminusresearch/FluxBooru-v0.3',
32
+ 'ostris/OpenFLUX.1',
 
33
  'shuttleai/shuttle-3-diffusion',
34
  'Laxhar/noobai-XL-1.0',
35
+ 'John6666/noobai-xl-nai-xl-epsilonpred10version-sdxl',
36
  'Laxhar/noobai-XL-0.77',
37
  'John6666/noobai-xl-nai-xl-epsilonpred075version-sdxl',
38
  'Laxhar/noobai-XL-0.6',
39
  'John6666/noobai-xl-nai-xl-epsilonpred05version-sdxl',
40
  'John6666/noobai-cyberfix-v10-sdxl',
41
  'John6666/noobaiiter-xl-vpred-v075-sdxl',
42
+ 'John6666/ntr-mix-illustrious-xl-noob-xl-v40-sdxl',
43
+ 'John6666/ntr-mix-illustrious-xl-noob-xl-ntrmix35-sdxl',
44
+ 'John6666/ntr-mix-illustrious-xl-noob-xl-v777-sdxl',
45
+ 'John6666/ntr-mix-illustrious-xl-noob-xl-v777forlora-sdxl',
 
 
 
46
  'John6666/haruki-mix-illustrious-v10-sdxl',
47
  'John6666/noobreal-v10-sdxl',
48
  'John6666/complicated-noobai-merge-vprediction-sdxl',
 
 
 
49
  'Laxhar/noobai-XL-Vpred-0.65s',
50
  'Laxhar/noobai-XL-Vpred-0.65',
51
  'Laxhar/noobai-XL-Vpred-0.6',
 
 
52
  'John6666/noobai-xl-nai-xl-vpred05version-sdxl',
53
  'John6666/noobai-fusion2-vpred-itercomp-v1-sdxl',
54
  'John6666/noobai-xl-nai-xl-vpredtestversion-sdxl',
 
58
  'John6666/illustrious-pencil-xl-v200-sdxl',
59
  'John6666/obsession-illustriousxl-v21-sdxl',
60
  'John6666/obsession-illustriousxl-v30-sdxl',
 
 
 
 
 
 
61
  'John6666/wai-nsfw-illustrious-v70-sdxl',
 
62
  'John6666/illustrious-pony-mix-v3-sdxl',
63
+ 'John6666/nova-anime-xl-illustriousv10-sdxl',
64
+ 'John6666/nova-orange-xl-v30-sdxl',
 
 
 
 
 
 
 
65
  'John6666/silvermoon-mix03-illustrious-v10-sdxl',
66
  'eienmojiki/Anything-XL',
67
  'eienmojiki/Starry-XL-v5.2',
 
68
  'John6666/meinaxl-v2-sdxl',
69
  'Eugeoter/artiwaifu-diffusion-2.0',
70
  'comin/IterComp',
 
71
  'John6666/epicrealism-xl-v10kiss2-sdxl',
72
+ 'John6666/epicrealism-xl-v8kiss-sdxl',
 
73
  'misri/zavychromaxl_v80',
74
  'SG161222/RealVisXL_V4.0',
75
  'SG161222/RealVisXL_V5.0',
 
81
  'John6666/ras-real-anime-screencap-v1-sdxl',
82
  'John6666/duchaiten-pony-xl-no-score-v60-sdxl',
83
  'John6666/mistoon-anime-ponyalpha-sdxl',
 
84
  'John6666/ebara-mfcg-pony-mix-v12-sdxl',
85
  'John6666/t-ponynai3-v51-sdxl',
86
  'John6666/t-ponynai3-v65-sdxl',
 
87
  'John6666/prefect-pony-xl-v3-sdxl',
88
  'John6666/prefect-pony-xl-v4-sdxl',
 
89
  'John6666/mala-anime-mix-nsfw-pony-xl-v5-sdxl',
90
  'John6666/wai-ani-nsfw-ponyxl-v10-sdxl',
91
  'John6666/wai-real-mix-v11-sdxl',
 
93
  'John6666/wai-c-v6-sdxl',
94
  'John6666/iniverse-mix-xl-sfwnsfw-pony-guofeng-v43-sdxl',
95
  'John6666/sifw-annihilation-xl-v2-sdxl',
 
96
  'John6666/photo-realistic-pony-v5-sdxl',
97
  'John6666/pony-realism-v21main-sdxl',
98
  'John6666/pony-realism-v22main-sdxl',
99
+ 'John6666/cyberrealistic-pony-v63-sdxl',
100
+ 'John6666/cyberrealistic-pony-v64-sdxl',
101
  'John6666/cyberrealistic-pony-v65-sdxl',
 
 
102
  'GraydientPlatformAPI/realcartoon-pony-diffusion',
103
  'John6666/nova-anime-xl-pony-v5-sdxl',
104
  'John6666/autismmix-sdxl-autismmix-pony-sdxl',
105
  'John6666/aimz-dream-real-pony-mix-v3-sdxl',
 
 
106
  'John6666/duchaiten-pony-real-v11fix-sdxl',
107
  'John6666/duchaiten-pony-real-v20-sdxl',
108
  'John6666/duchaiten-pony-xl-no-score-v70-sdxl',
109
  'KBlueLeaf/Kohaku-XL-Zeta',
110
  'cagliostrolab/animagine-xl-3.1',
 
111
  'yodayo-ai/kivotos-xl-2.0',
112
  'yodayo-ai/holodayo-xl-2.1',
113
  'yodayo-ai/clandestine-xl-1.0',
 
 
 
114
  'digiplay/majicMIX_sombre_v2',
115
  'digiplay/majicMIX_realistic_v6',
116
  'digiplay/majicMIX_realistic_v7',
 
120
  'digiplay/darkphoenix3D_v1.1',
121
  'digiplay/BeenYouLiteL11_diffusers',
122
  'GraydientPlatformAPI/rev-animated2',
123
+ 'youknownothing/cyberrealistic_v50',
 
 
124
  'youknownothing/deliberate-v6',
125
  'GraydientPlatformAPI/deliberate-cyber3',
126
  'GraydientPlatformAPI/picx-real',
 
134
  'GraydientPlatformAPI/realcartoon3d-17',
135
  'GraydientPlatformAPI/realcartoon-pixar11',
136
  'GraydientPlatformAPI/realcartoon-real17',
137
+ 'nitrosocke/Ghibli-Diffusion',
138
  ]
139
 
 
140
  DIFFUSERS_FORMAT_LORAS = [
141
  "nerijs/animation2k-flux",
142
  "XLabs-AI/flux-RealismLora",
 
156
  DIRECTORY_LORAS = 'loras'
157
  DIRECTORY_VAES = 'vaes'
158
  DIRECTORY_EMBEDS = 'embedings'
 
159
 
160
+ CACHE_HF = "/home/user/.cache/huggingface/hub/"
161
  STORAGE_ROOT = "/home/user/"
 
 
 
 
162
 
163
  TASK_STABLEPY = {
164
  'txt2img': 'txt2img',
 
184
  'optical pattern ControlNet': 'pattern',
185
  'recolor ControlNet': 'recolor',
186
  'tile ControlNet': 'tile',
 
187
  }
188
 
189
  TASK_MODEL_LIST = list(TASK_STABLEPY.keys())
190
 
191
  UPSCALER_DICT_GUI = {
192
  None: None,
193
+ "Lanczos": "Lanczos",
194
+ "Nearest": "Nearest",
195
+ 'Latent': 'Latent',
196
+ 'Latent (antialiased)': 'Latent (antialiased)',
197
+ 'Latent (bicubic)': 'Latent (bicubic)',
198
+ 'Latent (bicubic antialiased)': 'Latent (bicubic antialiased)',
199
+ 'Latent (nearest)': 'Latent (nearest)',
200
+ 'Latent (nearest-exact)': 'Latent (nearest-exact)',
201
+ "RealESRGAN_x4plus": "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.0/RealESRGAN_x4plus.pth",
202
  "RealESRNet_x4plus": "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.1/RealESRNet_x4plus.pth",
203
+ "RealESRGAN_x4plus_anime_6B": "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.2.4/RealESRGAN_x4plus_anime_6B.pth",
204
+ "RealESRGAN_x2plus": "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.1/RealESRGAN_x2plus.pth",
205
+ "realesr-animevideov3": "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.5.0/realesr-animevideov3.pth",
206
+ "realesr-general-x4v3": "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.5.0/realesr-general-x4v3.pth",
207
+ "realesr-general-wdn-x4v3": "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.5.0/realesr-general-wdn-x4v3.pth",
208
  "4x-UltraSharp": "https://huggingface.co/Shandypur/ESRGAN-4x-UltraSharp/resolve/main/4x-UltraSharp.pth",
 
209
  "4x_foolhardy_Remacri": "https://huggingface.co/FacehugmanIII/4x_foolhardy_Remacri/resolve/main/4x_foolhardy_Remacri.pth",
210
  "Remacri4xExtraSmoother": "https://huggingface.co/hollowstrawberry/upscalers-backup/resolve/main/ESRGAN/Remacri%204x%20ExtraSmoother.pth",
211
  "AnimeSharp4x": "https://huggingface.co/hollowstrawberry/upscalers-backup/resolve/main/ESRGAN/AnimeSharp%204x.pth",
 
219
  DIFFUSERS_CONTROLNET_MODEL = [
220
  "Automatic",
221
 
 
222
  "xinsir/controlnet-union-sdxl-1.0",
223
  "xinsir/anime-painter",
224
  "Eugeoter/noob-sdxl-controlnet-canny",
 
241
  "r3gm/controlnet-recolor-sdxl-fp16",
242
  "r3gm/controlnet-openpose-twins-sdxl-1.0-fp16",
243
  "r3gm/controlnet-qr-pattern-sdxl-fp16",
244
+ "brad-twinkl/controlnet-union-sdxl-1.0-promax",
245
  "Yakonrus/SDXL_Controlnet_Tile_Realistic_v2",
246
  "TheMistoAI/MistoLine",
247
  "briaai/BRIA-2.3-ControlNet-Recoloring",
 
320
  name_s for name_s in scheduler_names if "Auto-Loader" not in name_s
321
  ]
322
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
323
  SUBTITLE_GUI = (
324
  "### This demo uses [diffusers](https://github.com/huggingface/diffusers)"
325
  " to perform different tasks in image generation."
326
  )
327
 
 
 
328
  HELP_GUI = (
329
+ """### Help:
330
+ - 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'.
331
  - 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'.
332
  - For better results with Pony Diffusion, try using sampler DPM++ 1s or DPM2 with Compel or Classic prompt weights.
333
  """
 
340
  3. ControlNet Canny SDXL
341
  4. Optical pattern (Optical illusion) SDXL
342
  5. Convert an image to a coloring drawing
343
+ 6. ControlNet OpenPose SD 1.5 and Latent upscale
 
 
344
 
345
  - Different tasks can be performed, such as img2img or using the IP adapter, to preserve a person's appearance or a specific style based on an image.
346
  """
 
449
  20,
450
  4.0,
451
  -1,
452
+ "loras/Coloring_book_-_LineArt.safetensors",
453
  1.0,
454
  "DPM++ 2M SDE",
455
  1024,
 
467
  35,
468
  False,
469
  ],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
470
  [
471
  "1girl,face,curly hair,red hair,white background,",
472
  "(worst quality:2),(low quality:2),(normal quality:2),lowres,watermark,",
 
496
  RESOURCES = (
497
  """### Resources
498
  - John6666's space has some great features you might find helpful [link](https://huggingface.co/spaces/John6666/DiffuseCraftMod).
499
+ - You can also try the image generator in Colab’s free tier, which provides free GPU [link](https://github.com/R3gm/SD_diffusers_interactive).
 
500
  """
501
+ )
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
+ git+https://github.com/R3gm/stablepy.git@a9fe2dc # -b refactor_sampler_fix
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
 
@@ -64,12 +62,11 @@ class ModelInformation:
64
  self.download_url = json_data.get("downloadUrl", "")
65
  self.model_url = f"https://civitai.com/models/{self.model_id}?modelVersionId={self.model_version_id}"
66
  self.filename_url = next(
67
- (v.get("name", "") for v in json_data.get("files", []) if str(self.model_version_id) in v.get("downloadUrl", "") and v.get("type", "Model") == "Model"), ""
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:")
@@ -361,14 +300,13 @@ def get_model_type(repo_id: str):
361
  default = "SD 1.5"
362
  try:
363
  if os.path.exists(repo_id):
364
- tag, _, _, _ = checkpoint_model_type(repo_id)
365
  return DIFFUSECRAFT_CHECKPOINT_NAME[tag]
366
  else:
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
 
 
62
  self.download_url = json_data.get("downloadUrl", "")
63
  self.model_url = f"https://civitai.com/models/{self.model_id}?modelVersionId={self.model_version_id}"
64
  self.filename_url = next(
65
+ (v.get("name", "") for v in reversed(json_data.get("files", [])) if str(self.model_version_id) in v.get("downloadUrl", "")), ""
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:")
 
300
  default = "SD 1.5"
301
  try:
302
  if os.path.exists(repo_id):
303
+ tag = checkpoint_model_type(repo_id)
304
  return DIFFUSECRAFT_CHECKPOINT_NAME[tag]
305
  else:
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))