Files changed (9) hide show
  1. .gitignore +0 -207
  2. README.md +1 -3
  3. app.py +0 -1506
  4. constants.py +0 -611
  5. image_processor.py +0 -130
  6. packages.txt +1 -1
  7. pre-requirements.txt +0 -1
  8. requirements.txt +3 -12
  9. utils.py +0 -714
.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,13 +4,11 @@ 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
11
  short_description: Stunning images using stable diffusion.
12
- preload_from_hub:
13
- - madebyollin/sdxl-vae-fp16-fix config.json,diffusion_pytorch_model.safetensors
14
  ---
15
 
16
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
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
11
  short_description: Stunning images using stable diffusion.
 
 
12
  ---
13
 
14
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py DELETED
@@ -1,1506 +0,0 @@
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,
22
- LOAD_DIFFUSERS_FORMAT_MODEL,
23
- DIFFUSERS_FORMAT_LORAS,
24
- DOWNLOAD_EMBEDS,
25
- CIVITAI_API_KEY,
26
- HF_TOKEN,
27
- TASK_STABLEPY,
28
- TASK_MODEL_LIST,
29
- UPSCALER_DICT_GUI,
30
- UPSCALER_KEYS,
31
- PROMPT_W_OPTIONS,
32
- WARNING_MSG_VAE,
33
- SDXL_TASK,
34
- MODEL_TYPE_TASK,
35
- POST_PROCESSING_SAMPLER,
36
- SUBTITLE_GUI,
37
- HELP_GUI,
38
- EXAMPLES_GUI_HELP,
39
- EXAMPLES_GUI,
40
- RESOURCES,
41
- DIFFUSERS_CONTROLNET_MODEL,
42
- IP_MODELS,
43
- MODE_IP_OPTIONS,
44
- CACHE_HF_ROOT,
45
- CACHE_HF,
46
- )
47
- from stablepy.diffusers_vanilla.style_prompt_config import STYLE_NAMES
48
- import torch
49
- import re
50
- import time
51
- from PIL import ImageFile
52
- from utils import (
53
- download_things,
54
- get_model_list,
55
- extract_parameters,
56
- get_my_lora,
57
- get_model_type,
58
- extract_exif_data,
59
- create_mask_now,
60
- download_diffuser_repo,
61
- get_used_storage_gb,
62
- delete_model,
63
- progress_step_bar,
64
- html_template_message,
65
- escape_html,
66
- clear_hf_cache,
67
- )
68
- from image_processor import preprocessor_tab
69
- from datetime import datetime
70
- import gradio as gr
71
- import logging
72
- import diffusers
73
- import warnings
74
- from stablepy import logger
75
- from diffusers import FluxPipeline
76
- # import urllib.parse
77
- import subprocess
78
-
79
- IS_ZERO_GPU = bool(os.getenv("SPACES_ZERO_GPU"))
80
- HIDE_API = bool(os.getenv("HIDE_API"))
81
- if IS_ZERO_GPU:
82
- subprocess.run("rm -rf /data-nvme/zerogpu-offload/*", env={}, shell=True)
83
- IS_GPU_MODE = True if IS_ZERO_GPU else (True if torch.cuda.is_available() else False)
84
- img_path = "./images/"
85
- allowed_path = os.path.abspath(img_path)
86
- delete_cache_time = (9600, 9600) if IS_ZERO_GPU else (86400, 86400)
87
-
88
- ImageFile.LOAD_TRUNCATED_IMAGES = True
89
- torch.backends.cuda.matmul.allow_tf32 = True
90
- # os.environ["PYTORCH_NO_CUDA_MEMORY_CACHING"] = "1"
91
-
92
- directories = [DIRECTORY_MODELS, DIRECTORY_LORAS, DIRECTORY_VAES, DIRECTORY_EMBEDS, DIRECTORY_UPSCALERS]
93
- for directory in directories:
94
- os.makedirs(directory, exist_ok=True)
95
-
96
- # Download stuffs
97
- for url in [url.strip() for url in DOWNLOAD_MODEL.split(',')]:
98
- download_things(DIRECTORY_MODELS, url, HF_TOKEN, CIVITAI_API_KEY)
99
- for url in [url.strip() for url in DOWNLOAD_VAE.split(',')]:
100
- download_things(DIRECTORY_VAES, url, HF_TOKEN, CIVITAI_API_KEY)
101
- for url in [url.strip() for url in DOWNLOAD_LORA.split(',')]:
102
- download_things(DIRECTORY_LORAS, url, HF_TOKEN, CIVITAI_API_KEY)
103
-
104
- # Download Embeddings
105
- for url_embed in DOWNLOAD_EMBEDS:
106
- download_things(DIRECTORY_EMBEDS, url_embed, HF_TOKEN, CIVITAI_API_KEY)
107
-
108
- # Build list models
109
- embed_list = get_model_list(DIRECTORY_EMBEDS)
110
- embed_list = [
111
- (os.path.splitext(os.path.basename(emb))[0], emb) for emb in embed_list
112
- ]
113
- single_file_model_list = get_model_list(DIRECTORY_MODELS)
114
- model_list = LOAD_DIFFUSERS_FORMAT_MODEL + single_file_model_list
115
- lora_model_list = get_model_list(DIRECTORY_LORAS)
116
- lora_model_list.insert(0, "None")
117
- lora_model_list = lora_model_list + DIFFUSERS_FORMAT_LORAS
118
- vae_model_list = get_model_list(DIRECTORY_VAES)
119
- vae_model_list.insert(0, "BakedVAE")
120
- vae_model_list.insert(0, "None")
121
-
122
- print('\033[33m🏁 Download and listing of valid models completed.\033[0m')
123
-
124
- components = None
125
- if IS_ZERO_GPU:
126
- flux_repo = "camenduru/FLUX.1-dev-diffusers"
127
- flux_pipe = FluxPipeline.from_pretrained(
128
- flux_repo,
129
- transformer=None,
130
- torch_dtype=torch.bfloat16,
131
- ).to("cuda")
132
- components = flux_pipe.components
133
- delete_model(flux_repo)
134
-
135
- #######################
136
- # GUI
137
- #######################
138
- logging.getLogger("diffusers").setLevel(logging.ERROR)
139
- diffusers.utils.logging.set_verbosity(40)
140
- warnings.filterwarnings(action="ignore", category=FutureWarning, module="diffusers")
141
- warnings.filterwarnings(action="ignore", category=UserWarning, module="diffusers")
142
- warnings.filterwarnings(action="ignore", category=FutureWarning, module="transformers")
143
-
144
- parser = ArgumentParser(description='DiffuseCraft: Create images from text prompts.', add_help=True)
145
- parser.add_argument("--share", action="store_true", dest="share_enabled", default=False, help="Enable sharing")
146
- parser.add_argument('--theme', type=str, default="NoCrypt/miku", help='Set the theme (default: NoCrypt/miku)')
147
- parser.add_argument("--ssr", action="store_true", help="Enable SSR (Server-Side Rendering)")
148
- parser.add_argument("--log-level", type=str, default="INFO", choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"], help="Set logging level (default: INFO)")
149
- args = parser.parse_args()
150
-
151
- logger.setLevel(
152
- "INFO" if IS_ZERO_GPU else getattr(logging, args.log_level.upper())
153
- )
154
-
155
- CSS = """
156
- .contain { display: flex; flex-direction: column; }
157
- #component-0 { height: 100%; }
158
- #gallery { flex-grow: 1; }
159
- #load_model { height: 50px; }
160
- """
161
-
162
-
163
- def lora_chk(lora_):
164
- if isinstance(lora_, str) and lora_.strip() not in ["", "None"]:
165
- return lora_
166
- return None
167
-
168
-
169
- class GuiSD:
170
- def __init__(self, stream=True):
171
- self.model = None
172
- self.status_loading = False
173
- self.sleep_loading = 4
174
- self.last_load = datetime.now()
175
- self.inventory = []
176
-
177
- def update_storage_models(self, storage_floor_gb=30, required_inventory_for_purge=3):
178
- while get_used_storage_gb() > storage_floor_gb:
179
- if len(self.inventory) < required_inventory_for_purge:
180
- break
181
- removal_candidate = self.inventory.pop(0)
182
- delete_model(removal_candidate)
183
-
184
- # Cleanup after 60 seconds of inactivity
185
- lowPrioCleanup = max((datetime.now() - self.last_load).total_seconds(), 0) > 60
186
- if lowPrioCleanup and (len(self.inventory) >= required_inventory_for_purge - 1) and not self.status_loading and get_used_storage_gb(CACHE_HF_ROOT) > (storage_floor_gb * 2):
187
- print("Cleaning up Hugging Face cache...")
188
- clear_hf_cache()
189
- self.inventory = [
190
- m for m in self.inventory if os.path.exists(m)
191
- ]
192
-
193
- def update_inventory(self, model_name):
194
- if model_name not in single_file_model_list:
195
- self.inventory = [
196
- m for m in self.inventory if m != model_name
197
- ] + [model_name]
198
- print(self.inventory)
199
-
200
- def load_new_model(self, model_name, vae_model, task, controlnet_model, progress=gr.Progress(track_tqdm=True)):
201
-
202
- # download link model > model_name
203
- if model_name.startswith("http"):
204
- yield f"Downloading model: {model_name}"
205
- model_name = download_things(DIRECTORY_MODELS, model_name, HF_TOKEN, CIVITAI_API_KEY)
206
- if not model_name:
207
- raise ValueError("Error retrieving model information from URL")
208
-
209
- if IS_ZERO_GPU:
210
- self.update_storage_models()
211
-
212
- vae_model = vae_model if vae_model != "None" else None
213
- model_type = get_model_type(model_name)
214
- dtype_model = torch.bfloat16 if model_type == "FLUX" else torch.float16
215
-
216
- if not os.path.exists(model_name):
217
- logger.debug(f"model_name={model_name}, vae_model={vae_model}, task={task}, controlnet_model={controlnet_model}")
218
- _ = download_diffuser_repo(
219
- repo_name=model_name,
220
- model_type=model_type,
221
- revision="main",
222
- token=True,
223
- )
224
-
225
- self.update_inventory(model_name)
226
-
227
- for i in range(68):
228
- if not self.status_loading:
229
- self.status_loading = True
230
- if i > 0:
231
- time.sleep(self.sleep_loading)
232
- print("Previous model ops...")
233
- break
234
- time.sleep(0.5)
235
- print(f"Waiting queue {i}")
236
- yield "Waiting queue"
237
-
238
- self.status_loading = True
239
-
240
- yield f"Loading model: {model_name}"
241
-
242
- if vae_model == "BakedVAE":
243
- vae_model = model_name
244
- elif vae_model:
245
- vae_type = "SDXL" if "sdxl" in vae_model.lower() else "SD 1.5"
246
- if model_type != vae_type:
247
- gr.Warning(WARNING_MSG_VAE)
248
-
249
- print("Loading model...")
250
-
251
- try:
252
- start_time = time.time()
253
-
254
- if self.model is None:
255
- self.model = Model_Diffusers(
256
- base_model_id=model_name,
257
- task_name=TASK_STABLEPY[task],
258
- vae_model=vae_model,
259
- type_model_precision=dtype_model,
260
- retain_task_model_in_cache=False,
261
- controlnet_model=controlnet_model,
262
- device="cpu" if IS_ZERO_GPU else None,
263
- env_components=components,
264
- )
265
- self.model.advanced_params(image_preprocessor_cuda_active=IS_GPU_MODE)
266
- else:
267
- if self.model.base_model_id != model_name:
268
- load_now_time = datetime.now()
269
- elapsed_time = max((load_now_time - self.last_load).total_seconds(), 0)
270
-
271
- if elapsed_time <= 9:
272
- print("Waiting for the previous model's time ops...")
273
- time.sleep(9 - elapsed_time)
274
-
275
- if IS_ZERO_GPU:
276
- self.model.device = torch.device("cpu")
277
- self.model.load_pipe(
278
- model_name,
279
- task_name=TASK_STABLEPY[task],
280
- vae_model=vae_model,
281
- type_model_precision=dtype_model,
282
- retain_task_model_in_cache=False,
283
- controlnet_model=controlnet_model,
284
- )
285
-
286
- end_time = time.time()
287
- self.sleep_loading = max(min(int(end_time - start_time), 10), 4)
288
- except Exception as e:
289
- self.last_load = datetime.now()
290
- self.status_loading = False
291
- self.sleep_loading = 4
292
- raise e
293
-
294
- self.last_load = datetime.now()
295
- self.status_loading = False
296
-
297
- yield f"Model loaded: {model_name}"
298
-
299
- # @spaces.GPU(duration=59)
300
- @torch.inference_mode()
301
- def generate_pipeline(
302
- self,
303
- prompt,
304
- neg_prompt,
305
- num_images,
306
- steps,
307
- cfg,
308
- clip_skip,
309
- seed,
310
- lora1,
311
- lora_scale1,
312
- lora2,
313
- lora_scale2,
314
- lora3,
315
- lora_scale3,
316
- lora4,
317
- lora_scale4,
318
- lora5,
319
- lora_scale5,
320
- lora6,
321
- lora_scale6,
322
- lora7,
323
- lora_scale7,
324
- sampler,
325
- schedule_type,
326
- schedule_prediction_type,
327
- img_height,
328
- img_width,
329
- model_name,
330
- vae_model,
331
- task,
332
- image_control,
333
- preprocessor_name,
334
- preprocess_resolution,
335
- image_resolution,
336
- style_prompt, # list []
337
- style_json_file,
338
- image_mask,
339
- strength,
340
- low_threshold,
341
- high_threshold,
342
- value_threshold,
343
- distance_threshold,
344
- recolor_gamma_correction,
345
- tile_blur_sigma,
346
- controlnet_output_scaling_in_unet,
347
- controlnet_start_threshold,
348
- controlnet_stop_threshold,
349
- textual_inversion,
350
- syntax_weights,
351
- upscaler_model_path,
352
- upscaler_increases_size,
353
- upscaler_tile_size,
354
- upscaler_tile_overlap,
355
- hires_steps,
356
- hires_denoising_strength,
357
- hires_sampler,
358
- hires_prompt,
359
- hires_negative_prompt,
360
- hires_before_adetailer,
361
- hires_after_adetailer,
362
- hires_schedule_type,
363
- hires_guidance_scale,
364
- controlnet_model,
365
- loop_generation,
366
- leave_progress_bar,
367
- disable_progress_bar,
368
- image_previews,
369
- display_images,
370
- save_generated_images,
371
- filename_pattern,
372
- image_storage_location,
373
- retain_compel_previous_load,
374
- retain_detailfix_model_previous_load,
375
- retain_hires_model_previous_load,
376
- t2i_adapter_preprocessor,
377
- t2i_adapter_conditioning_scale,
378
- t2i_adapter_conditioning_factor,
379
- xformers_memory_efficient_attention,
380
- freeu,
381
- generator_in_cpu,
382
- adetailer_inpaint_only,
383
- adetailer_verbose,
384
- adetailer_sampler,
385
- adetailer_active_a,
386
- prompt_ad_a,
387
- negative_prompt_ad_a,
388
- strength_ad_a,
389
- face_detector_ad_a,
390
- person_detector_ad_a,
391
- hand_detector_ad_a,
392
- mask_dilation_a,
393
- mask_blur_a,
394
- mask_padding_a,
395
- adetailer_active_b,
396
- prompt_ad_b,
397
- negative_prompt_ad_b,
398
- strength_ad_b,
399
- face_detector_ad_b,
400
- person_detector_ad_b,
401
- hand_detector_ad_b,
402
- mask_dilation_b,
403
- mask_blur_b,
404
- mask_padding_b,
405
- retain_task_cache_gui,
406
- guidance_rescale,
407
- image_ip1,
408
- mask_ip1,
409
- model_ip1,
410
- mode_ip1,
411
- scale_ip1,
412
- image_ip2,
413
- mask_ip2,
414
- model_ip2,
415
- mode_ip2,
416
- scale_ip2,
417
- pag_scale,
418
- face_restoration_model,
419
- face_restoration_visibility,
420
- face_restoration_weight,
421
- ):
422
- info_state = html_template_message("Navigating latent space...")
423
- yield info_state, gr.update(), gr.update()
424
-
425
- vae_model = vae_model if vae_model != "None" else None
426
- loras_list = [lora1, lora2, lora3, lora4, lora5, lora6, lora7]
427
- vae_msg = f"VAE: {vae_model}" if vae_model else ""
428
- msg_lora = ""
429
-
430
- logger.debug(f"Config model: {model_name}, {vae_model}, {loras_list}")
431
-
432
- task = TASK_STABLEPY[task]
433
-
434
- params_ip_img = []
435
- params_ip_msk = []
436
- params_ip_model = []
437
- params_ip_mode = []
438
- params_ip_scale = []
439
-
440
- all_adapters = [
441
- (image_ip1, mask_ip1, model_ip1, mode_ip1, scale_ip1),
442
- (image_ip2, mask_ip2, model_ip2, mode_ip2, scale_ip2),
443
- ]
444
-
445
- if not hasattr(self.model.pipe, "transformer"):
446
- for imgip, mskip, modelip, modeip, scaleip in all_adapters:
447
- if imgip:
448
- params_ip_img.append(imgip)
449
- if mskip:
450
- params_ip_msk.append(mskip)
451
- params_ip_model.append(modelip)
452
- params_ip_mode.append(modeip)
453
- params_ip_scale.append(scaleip)
454
-
455
- concurrency = 5
456
- self.model.stream_config(concurrency=concurrency, latent_resize_by=1, vae_decoding=False)
457
-
458
- if task != "txt2img" and not image_control:
459
- raise ValueError("Reference image is required. Please upload one in 'Image ControlNet/Inpaint/Img2img'.")
460
-
461
- if task in ["inpaint", "repaint"] and not image_mask:
462
- raise ValueError("Mask image not found. Upload one in 'Image Mask' to proceed.")
463
-
464
- if "https://" not in str(UPSCALER_DICT_GUI[upscaler_model_path]):
465
- upscaler_model = upscaler_model_path
466
- else:
467
- url_upscaler = UPSCALER_DICT_GUI[upscaler_model_path]
468
-
469
- if not os.path.exists(f"./{DIRECTORY_UPSCALERS}/{url_upscaler.split('/')[-1]}"):
470
- download_things(DIRECTORY_UPSCALERS, url_upscaler, HF_TOKEN)
471
-
472
- upscaler_model = f"./{DIRECTORY_UPSCALERS}/{url_upscaler.split('/')[-1]}"
473
-
474
- logging.getLogger("ultralytics").setLevel(logging.INFO if adetailer_verbose else logging.ERROR)
475
-
476
- adetailer_params_A = {
477
- "face_detector_ad": face_detector_ad_a,
478
- "person_detector_ad": person_detector_ad_a,
479
- "hand_detector_ad": hand_detector_ad_a,
480
- "prompt": prompt_ad_a,
481
- "negative_prompt": negative_prompt_ad_a,
482
- "strength": strength_ad_a,
483
- # "image_list_task" : None,
484
- "mask_dilation": mask_dilation_a,
485
- "mask_blur": mask_blur_a,
486
- "mask_padding": mask_padding_a,
487
- "inpaint_only": adetailer_inpaint_only,
488
- "sampler": adetailer_sampler,
489
- }
490
-
491
- adetailer_params_B = {
492
- "face_detector_ad": face_detector_ad_b,
493
- "person_detector_ad": person_detector_ad_b,
494
- "hand_detector_ad": hand_detector_ad_b,
495
- "prompt": prompt_ad_b,
496
- "negative_prompt": negative_prompt_ad_b,
497
- "strength": strength_ad_b,
498
- # "image_list_task" : None,
499
- "mask_dilation": mask_dilation_b,
500
- "mask_blur": mask_blur_b,
501
- "mask_padding": mask_padding_b,
502
- }
503
- pipe_params = {
504
- "prompt": prompt,
505
- "negative_prompt": neg_prompt,
506
- "img_height": img_height,
507
- "img_width": img_width,
508
- "num_images": num_images,
509
- "num_steps": steps,
510
- "guidance_scale": cfg,
511
- "clip_skip": clip_skip,
512
- "pag_scale": float(pag_scale),
513
- "seed": seed,
514
- "image": image_control,
515
- "preprocessor_name": preprocessor_name,
516
- "preprocess_resolution": preprocess_resolution,
517
- "image_resolution": image_resolution,
518
- "style_prompt": style_prompt if style_prompt else "",
519
- "style_json_file": "",
520
- "image_mask": image_mask, # only for Inpaint
521
- "strength": strength, # only for Inpaint or ...
522
- "low_threshold": low_threshold,
523
- "high_threshold": high_threshold,
524
- "value_threshold": value_threshold,
525
- "distance_threshold": distance_threshold,
526
- "recolor_gamma_correction": float(recolor_gamma_correction),
527
- "tile_blur_sigma": int(tile_blur_sigma),
528
- "lora_A": lora_chk(lora1),
529
- "lora_scale_A": lora_scale1,
530
- "lora_B": lora_chk(lora2),
531
- "lora_scale_B": lora_scale2,
532
- "lora_C": lora_chk(lora3),
533
- "lora_scale_C": lora_scale3,
534
- "lora_D": lora_chk(lora4),
535
- "lora_scale_D": lora_scale4,
536
- "lora_E": lora_chk(lora5),
537
- "lora_scale_E": lora_scale5,
538
- "lora_F": lora_chk(lora6),
539
- "lora_scale_F": lora_scale6,
540
- "lora_G": lora_chk(lora7),
541
- "lora_scale_G": lora_scale7,
542
- "textual_inversion": embed_list if textual_inversion else [],
543
- "syntax_weights": syntax_weights, # "Classic"
544
- "sampler": sampler,
545
- "schedule_type": schedule_type,
546
- "schedule_prediction_type": schedule_prediction_type,
547
- "xformers_memory_efficient_attention": xformers_memory_efficient_attention,
548
- "gui_active": True,
549
- "loop_generation": loop_generation,
550
- "controlnet_conditioning_scale": float(controlnet_output_scaling_in_unet),
551
- "control_guidance_start": float(controlnet_start_threshold),
552
- "control_guidance_end": float(controlnet_stop_threshold),
553
- "generator_in_cpu": generator_in_cpu,
554
- "FreeU": freeu,
555
- "adetailer_A": adetailer_active_a,
556
- "adetailer_A_params": adetailer_params_A,
557
- "adetailer_B": adetailer_active_b,
558
- "adetailer_B_params": adetailer_params_B,
559
- "leave_progress_bar": leave_progress_bar,
560
- "disable_progress_bar": disable_progress_bar,
561
- "image_previews": image_previews,
562
- "display_images": display_images,
563
- "save_generated_images": save_generated_images,
564
- "filename_pattern": filename_pattern,
565
- "image_storage_location": image_storage_location,
566
- "retain_compel_previous_load": retain_compel_previous_load,
567
- "retain_detailfix_model_previous_load": retain_detailfix_model_previous_load,
568
- "retain_hires_model_previous_load": retain_hires_model_previous_load,
569
- "t2i_adapter_preprocessor": t2i_adapter_preprocessor,
570
- "t2i_adapter_conditioning_scale": float(t2i_adapter_conditioning_scale),
571
- "t2i_adapter_conditioning_factor": float(t2i_adapter_conditioning_factor),
572
- "upscaler_model_path": upscaler_model,
573
- "upscaler_increases_size": upscaler_increases_size,
574
- "upscaler_tile_size": upscaler_tile_size,
575
- "upscaler_tile_overlap": upscaler_tile_overlap,
576
- "hires_steps": hires_steps,
577
- "hires_denoising_strength": hires_denoising_strength,
578
- "hires_prompt": hires_prompt,
579
- "hires_negative_prompt": hires_negative_prompt,
580
- "hires_sampler": hires_sampler,
581
- "hires_before_adetailer": hires_before_adetailer,
582
- "hires_after_adetailer": hires_after_adetailer,
583
- "hires_schedule_type": hires_schedule_type,
584
- "hires_guidance_scale": hires_guidance_scale,
585
- "ip_adapter_image": params_ip_img,
586
- "ip_adapter_mask": params_ip_msk,
587
- "ip_adapter_model": params_ip_model,
588
- "ip_adapter_mode": params_ip_mode,
589
- "ip_adapter_scale": params_ip_scale,
590
- "face_restoration_model": face_restoration_model,
591
- "face_restoration_visibility": face_restoration_visibility,
592
- "face_restoration_weight": face_restoration_weight,
593
- }
594
-
595
- # kwargs for diffusers pipeline
596
- if guidance_rescale:
597
- pipe_params["guidance_rescale"] = guidance_rescale
598
- if IS_ZERO_GPU:
599
- self.model.device = torch.device("cuda:0")
600
- if hasattr(self.model.pipe, "transformer") and loras_list != ["None"] * self.model.num_loras:
601
- self.model.pipe.transformer.to(self.model.device)
602
- logger.debug("transformer to cuda")
603
-
604
- actual_progress = 0
605
- info_images = gr.update()
606
- for img, [seed, image_path, metadata] in self.model(**pipe_params):
607
- info_state = progress_step_bar(actual_progress, steps)
608
- actual_progress += concurrency
609
- if image_path:
610
- info_images = f"Seeds: {str(seed)}"
611
- if vae_msg:
612
- info_images = info_images + "<br>" + vae_msg
613
-
614
- if "Cannot copy out of meta tensor; no data!" in self.model.last_lora_error:
615
- msg_ram = "Unable to process the LoRAs due to high RAM usage; please try again later."
616
- print(msg_ram)
617
- msg_lora += f"<br>{msg_ram}"
618
-
619
- for status, lora in zip(self.model.lora_status, self.model.lora_memory):
620
- if status:
621
- msg_lora += f"<br>Loaded: {lora}"
622
- elif status is not None:
623
- msg_lora += f"<br>Error with: {lora}"
624
-
625
- if msg_lora:
626
- info_images += msg_lora
627
-
628
- info_images = info_images + "<br>" + "GENERATION DATA:<br>" + escape_html(metadata[-1]) + "<br>-------<br>"
629
-
630
- download_links = "<br>".join(
631
- [
632
- f'<a href="{path.replace("/images/", f"/gradio_api/file={allowed_path}/")}" download="{os.path.basename(path)}">Download Image {i + 1}</a>'
633
- for i, path in enumerate(image_path)
634
- ]
635
- )
636
- if save_generated_images:
637
- info_images += f"<br>{download_links}"
638
-
639
- info_state = "COMPLETE"
640
-
641
- yield info_state, img, info_images
642
-
643
-
644
- def dynamic_gpu_duration(func, duration, *args):
645
-
646
- # @torch.inference_mode()
647
- @spaces.GPU(duration=duration)
648
- def wrapped_func():
649
- yield from func(*args)
650
-
651
- return wrapped_func()
652
-
653
-
654
- @spaces.GPU
655
- def dummy_gpu():
656
- return None
657
-
658
-
659
- def sd_gen_generate_pipeline(*args):
660
- gpu_duration_arg = int(args[-1]) if args[-1] else 59
661
- verbose_arg = int(args[-2])
662
- load_lora_cpu = args[-3]
663
- generation_args = args[:-3]
664
- lora_list = [
665
- None if item == "None" else item
666
- for item in [args[7], args[9], args[11], args[13], args[15], args[17], args[19]]
667
- ]
668
- lora_status = [None] * sd_gen.model.num_loras
669
-
670
- msg_load_lora = "Updating LoRAs in GPU..."
671
- if load_lora_cpu:
672
- msg_load_lora = "Updating LoRAs in CPU..."
673
-
674
- if lora_list != sd_gen.model.lora_memory and lora_list != [None] * sd_gen.model.num_loras:
675
- yield msg_load_lora, gr.update(), gr.update()
676
-
677
- # Load lora in CPU
678
- if load_lora_cpu:
679
- lora_status = sd_gen.model.load_lora_on_the_fly(
680
- lora_A=lora_list[0], lora_scale_A=args[8],
681
- lora_B=lora_list[1], lora_scale_B=args[10],
682
- lora_C=lora_list[2], lora_scale_C=args[12],
683
- lora_D=lora_list[3], lora_scale_D=args[14],
684
- lora_E=lora_list[4], lora_scale_E=args[16],
685
- lora_F=lora_list[5], lora_scale_F=args[18],
686
- lora_G=lora_list[6], lora_scale_G=args[20],
687
- )
688
- print(lora_status)
689
-
690
- sampler_name = args[21]
691
- schedule_type_name = args[22]
692
- _, _, msg_sampler = check_scheduler_compatibility(
693
- sd_gen.model.class_name, sampler_name, schedule_type_name
694
- )
695
- if msg_sampler:
696
- gr.Warning(msg_sampler)
697
-
698
- if verbose_arg:
699
- for status, lora in zip(lora_status, lora_list):
700
- if status:
701
- gr.Info(f"LoRA loaded in CPU: {lora}")
702
- elif status is not None:
703
- gr.Warning(f"Failed to load LoRA: {lora}")
704
-
705
- if lora_status == [None] * sd_gen.model.num_loras and sd_gen.model.lora_memory != [None] * sd_gen.model.num_loras and load_lora_cpu:
706
- lora_cache_msg = ", ".join(
707
- str(x) for x in sd_gen.model.lora_memory if x is not None
708
- )
709
- gr.Info(f"LoRAs in cache: {lora_cache_msg}")
710
-
711
- msg_request = f"Requesting {gpu_duration_arg}s. of GPU time.\nModel: {sd_gen.model.base_model_id}"
712
- if verbose_arg:
713
- gr.Info(msg_request)
714
- print(msg_request)
715
- yield msg_request.replace("\n", "<br>"), gr.update(), gr.update()
716
-
717
- start_time = time.time()
718
-
719
- # yield from sd_gen.generate_pipeline(*generation_args)
720
- yield from dynamic_gpu_duration(
721
- sd_gen.generate_pipeline,
722
- gpu_duration_arg,
723
- *generation_args,
724
- )
725
-
726
- end_time = time.time()
727
- execution_time = end_time - start_time
728
- msg_task_complete = (
729
- f"GPU task complete in: {int(round(execution_time, 0) + 1)} seconds"
730
- )
731
-
732
- if verbose_arg:
733
- gr.Info(msg_task_complete)
734
- print(msg_task_complete)
735
-
736
- yield msg_task_complete, gr.update(), gr.update()
737
-
738
-
739
- @spaces.GPU(duration=15)
740
- def process_upscale(image, upscaler_name, upscaler_size):
741
- if image is None:
742
- return None
743
-
744
- from stablepy.diffusers_vanilla.utils import save_pil_image_with_metadata
745
- from stablepy import load_upscaler_model
746
-
747
- image = image.convert("RGB")
748
- exif_image = extract_exif_data(image)
749
-
750
- name_upscaler = UPSCALER_DICT_GUI[upscaler_name]
751
-
752
- if "https://" in str(name_upscaler):
753
-
754
- if not os.path.exists(f"./{DIRECTORY_UPSCALERS}/{name_upscaler.split('/')[-1]}"):
755
- download_things(DIRECTORY_UPSCALERS, name_upscaler, HF_TOKEN)
756
-
757
- name_upscaler = f"./{DIRECTORY_UPSCALERS}/{name_upscaler.split('/')[-1]}"
758
-
759
- 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)
760
- image_up = scaler_beta.upscale(image, upscaler_size, True)
761
-
762
- image_path = save_pil_image_with_metadata(image_up, f'{os.getcwd()}/up_images', exif_image)
763
-
764
- return image_path
765
-
766
-
767
- # https://huggingface.co/spaces/BestWishYsh/ConsisID-preview-Space/discussions/1#674969a022b99c122af5d407
768
- # dynamic_gpu_duration.zerogpu = True
769
- # sd_gen_generate_pipeline.zerogpu = True
770
- sd_gen = GuiSD()
771
-
772
- with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as app:
773
- gr.Markdown("# 🧩 DiffuseCraft")
774
- gr.Markdown(SUBTITLE_GUI)
775
- with gr.Tab("Generation"):
776
- with gr.Row():
777
-
778
- with gr.Column(scale=2):
779
-
780
- def update_task_options(model_name, task_name):
781
- new_choices = MODEL_TYPE_TASK[get_model_type(model_name)]
782
-
783
- if task_name not in new_choices:
784
- task_name = "txt2img"
785
-
786
- return gr.update(value=task_name, choices=new_choices)
787
-
788
- task_gui = gr.Dropdown(label="Task", choices=SDXL_TASK, value=TASK_MODEL_LIST[0])
789
- model_name_gui = gr.Dropdown(label="Model", choices=model_list, value=model_list[0], allow_custom_value=True)
790
- prompt_gui = gr.Textbox(lines=5, placeholder="Enter prompt", label="Prompt")
791
- neg_prompt_gui = gr.Textbox(lines=3, placeholder="Enter Neg prompt", label="Negative prompt", value="lowres, bad anatomy, bad hands, missing fingers, extra digit, fewer digits, worst quality, low quality, very displeasing, (bad)")
792
- with gr.Row(equal_height=False):
793
- set_params_gui = gr.Button(value="↙️", variant="secondary", size="sm")
794
- clear_prompt_gui = gr.Button(value="🗑️", variant="secondary", size="sm")
795
- set_random_seed = gr.Button(value="🎲", variant="secondary", size="sm")
796
- generate_button = gr.Button(value="GENERATE IMAGE", variant="primary")
797
-
798
- model_name_gui.change(
799
- update_task_options,
800
- [model_name_gui, task_gui],
801
- [task_gui],
802
- )
803
-
804
- load_model_gui = gr.HTML(elem_id="load_model", elem_classes="contain")
805
-
806
- result_images = gr.Gallery(
807
- label="Generated images",
808
- show_label=False,
809
- elem_id="gallery",
810
- columns=[2],
811
- rows=[2],
812
- object_fit="contain",
813
- # height="auto",
814
- interactive=False,
815
- preview=False,
816
- selected_index=50,
817
- )
818
-
819
- actual_task_info = gr.HTML()
820
-
821
- with gr.Row(equal_height=False, variant="default", visible=IS_ZERO_GPU):
822
- gpu_duration_gui = gr.Number(minimum=5, maximum=240, value=59, show_label=False, container=False, info="GPU time duration (seconds)")
823
- with gr.Column():
824
- verbose_info_gui = gr.Checkbox(value=False, container=False, label="Status info")
825
- load_lora_cpu_gui = gr.Checkbox(value=False, container=False, label="Load LoRAs on CPU")
826
-
827
- with gr.Column(scale=1):
828
- steps_gui = gr.Slider(minimum=1, maximum=100, step=1, value=28, label="Steps")
829
- cfg_gui = gr.Slider(minimum=0, maximum=30, step=0.5, value=7., label="CFG")
830
- sampler_gui = gr.Dropdown(label="Sampler", choices=scheduler_names, value="Euler")
831
- schedule_type_gui = gr.Dropdown(label="Schedule type", choices=SCHEDULE_TYPE_OPTIONS, value=SCHEDULE_TYPE_OPTIONS[0])
832
- img_width_gui = gr.Slider(minimum=64, maximum=4096, step=8, value=1024, label="Img Width")
833
- img_height_gui = gr.Slider(minimum=64, maximum=4096, step=8, value=1024, label="Img Height")
834
- seed_gui = gr.Number(minimum=-1, maximum=9999999999, value=-1, label="Seed")
835
- pag_scale_gui = gr.Slider(minimum=0.0, maximum=10.0, step=0.1, value=0.0, label="PAG Scale")
836
- with gr.Row():
837
- clip_skip_gui = gr.Checkbox(value=True, label="Layer 2 Clip Skip")
838
- free_u_gui = gr.Checkbox(value=False, label="FreeU")
839
-
840
- with gr.Row(equal_height=False):
841
-
842
- def run_set_params_gui(base_prompt, name_model):
843
- valid_receptors = { # default values
844
- "prompt": gr.update(value=base_prompt),
845
- "neg_prompt": gr.update(value=""),
846
- "Steps": gr.update(value=30),
847
- "width": gr.update(value=1024),
848
- "height": gr.update(value=1024),
849
- "Seed": gr.update(value=-1),
850
- "Sampler": gr.update(value="Euler"),
851
- "CFG scale": gr.update(value=7.), # cfg
852
- "Clip skip": gr.update(value=True),
853
- "Model": gr.update(value=name_model),
854
- "Schedule type": gr.update(value="Automatic"),
855
- "PAG": gr.update(value=.0),
856
- "FreeU": gr.update(value=False),
857
- "Hires upscaler": gr.update(),
858
- "Hires upscale": gr.update(),
859
- "Hires steps": gr.update(),
860
- "Hires denoising strength": gr.update(),
861
- "Hires CFG": gr.update(),
862
- "Hires sampler": gr.update(),
863
- "Hires schedule type": gr.update(),
864
- "Image resolution": gr.update(value=1024),
865
- "Strength": gr.update(),
866
- }
867
-
868
- # Generate up to 7 LoRAs
869
- for i in range(1, 8):
870
- valid_receptors[f"Lora_{i}"] = gr.update()
871
- valid_receptors[f"Lora_scale_{i}"] = gr.update()
872
-
873
- valid_keys = list(valid_receptors.keys())
874
-
875
- parameters = extract_parameters(base_prompt)
876
- # print(parameters)
877
-
878
- if "Sampler" in parameters:
879
- value_sampler = parameters["Sampler"]
880
- for s_type in SCHEDULE_TYPE_OPTIONS:
881
- if s_type in value_sampler:
882
- value_sampler = value_sampler.replace(s_type, "").strip()
883
- parameters["Sampler"] = value_sampler
884
- parameters["Schedule type"] = s_type
885
-
886
- params_lora = []
887
- if ">" in parameters["prompt"] and "<" in parameters["prompt"]:
888
- params_lora = re.findall(r'<lora:[^>]+>', parameters["prompt"])
889
- if "Loras" in parameters:
890
- params_lora += re.findall(r'<lora:[^>]+>', parameters["Loras"])
891
-
892
- if params_lora:
893
- parsed_params = []
894
- for tag_l in params_lora:
895
- try:
896
- inner = tag_l.strip("<>") # remove < >
897
- _, data_l = inner.split(":", 1) # remove the "lora:" part
898
- parts_l = data_l.split(":")
899
-
900
- name_l = parts_l[0]
901
- weight_l = float(parts_l[1]) if len(parts_l) > 1 else 1.0 # default weight = 1.0
902
-
903
- parsed_params.append((name_l, weight_l))
904
- except Exception as e:
905
- print(f"Error parsing LoRA tag {tag_l}: {e}")
906
-
907
- num_lora = 1
908
- for parsed_l, parsed_s in parsed_params:
909
- filtered_loras = [m for m in lora_model_list if parsed_l in m]
910
- if filtered_loras:
911
- parameters[f"Lora_{num_lora}"] = filtered_loras[0]
912
- parameters[f"Lora_scale_{num_lora}"] = parsed_s
913
- num_lora += 1
914
-
915
- # continue = discard new value
916
- for key, val in parameters.items():
917
- # print(val)
918
- if key in valid_keys:
919
- try:
920
- if key == "Sampler":
921
- if val not in scheduler_names:
922
- continue
923
- if key in ["Schedule type", "Hires schedule type"]:
924
- if val not in SCHEDULE_TYPE_OPTIONS:
925
- continue
926
- if key == "Hires sampler":
927
- if val not in POST_PROCESSING_SAMPLER:
928
- continue
929
- elif key == "Clip skip":
930
- if "," in str(val):
931
- val = val.replace(",", "")
932
- if int(val) >= 2:
933
- val = True
934
- if key == "prompt":
935
- if ">" in val and "<" in val:
936
- val = re.sub(r'<[^>]+>', '', val) # Delete html and loras
937
- print("Removed LoRA written in the prompt")
938
- if key in ["prompt", "neg_prompt"]:
939
- val = re.sub(r'\s+', ' ', re.sub(r',+', ',', val)).strip()
940
- if key in ["Steps", "width", "height", "Seed", "Hires steps", "Image resolution"]:
941
- val = int(val)
942
- if key == "FreeU":
943
- val = True
944
- if key in ["CFG scale", "PAG", "Hires upscale", "Hires denoising strength", "Hires CFG", "Strength"]:
945
- val = float(val)
946
- if key == "Model":
947
- filtered_models = [m for m in model_list if val in m]
948
- if filtered_models:
949
- val = filtered_models[0]
950
- else:
951
- val = name_model
952
- if key == "Hires upscaler":
953
- if val not in UPSCALER_KEYS:
954
- continue
955
- if key == "Seed":
956
- continue
957
-
958
- valid_receptors[key] = gr.update(value=val)
959
- # print(val, type(val))
960
- # print(valid_receptors)
961
- except Exception as e:
962
- print(str(e))
963
- return [value for value in valid_receptors.values()]
964
-
965
- def run_clear_prompt_gui():
966
- return gr.update(value=""), gr.update(value="")
967
- clear_prompt_gui.click(
968
- run_clear_prompt_gui, [], [prompt_gui, neg_prompt_gui]
969
- )
970
-
971
- def run_set_random_seed():
972
- return -1
973
- set_random_seed.click(
974
- run_set_random_seed, [], seed_gui
975
- )
976
-
977
- num_images_gui = gr.Slider(minimum=1, maximum=(8 if IS_ZERO_GPU else 20), step=1, value=1, label="Images")
978
- prompt_syntax_gui = gr.Dropdown(label="Prompt Syntax", choices=PROMPT_W_OPTIONS, value=PROMPT_W_OPTIONS[1][1])
979
- vae_model_gui = gr.Dropdown(label="VAE Model", choices=vae_model_list, value=vae_model_list[0])
980
-
981
- with gr.Accordion("Hires fix", open=False, visible=True):
982
-
983
- upscaler_model_path_gui = gr.Dropdown(label="Upscaler", choices=UPSCALER_KEYS, value=UPSCALER_KEYS[0])
984
- upscaler_increases_size_gui = gr.Slider(minimum=1.1, maximum=4., step=0.1, value=1.2, label="Upscale by")
985
- 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")
986
- upscaler_tile_overlap_gui = gr.Slider(minimum=0, maximum=48, step=1, value=8, label="Upscaler Tile Overlap")
987
- hires_steps_gui = gr.Slider(minimum=0, value=30, maximum=100, step=1, label="Hires Steps")
988
- hires_denoising_strength_gui = gr.Slider(minimum=0.1, maximum=1.0, step=0.01, value=0.55, label="Hires Denoising Strength")
989
- hires_sampler_gui = gr.Dropdown(label="Hires Sampler", choices=POST_PROCESSING_SAMPLER, value=POST_PROCESSING_SAMPLER[0])
990
- hires_schedule_list = ["Use same schedule type"] + SCHEDULE_TYPE_OPTIONS
991
- hires_schedule_type_gui = gr.Dropdown(label="Hires Schedule type", choices=hires_schedule_list, value=hires_schedule_list[0])
992
- hires_guidance_scale_gui = gr.Slider(minimum=-1., maximum=30., step=0.5, value=-1., label="Hires CFG", info="If the value is -1, the main CFG will be used")
993
- hires_prompt_gui = gr.Textbox(label="Hires Prompt", placeholder="Main prompt will be use", lines=3)
994
- hires_negative_prompt_gui = gr.Textbox(label="Hires Negative Prompt", placeholder="Main negative prompt will be use", lines=3)
995
-
996
- with gr.Accordion("LoRA", open=False, visible=True):
997
-
998
- def lora_dropdown(label, visible=True):
999
- return gr.Dropdown(label=label, choices=lora_model_list, value="None", allow_custom_value=True, visible=visible)
1000
-
1001
- def lora_scale_slider(label, visible=True):
1002
- val_lora = 8 if IS_ZERO_GPU else 10
1003
- return gr.Slider(minimum=-val_lora, maximum=val_lora, step=0.01, value=0.33, label=label, visible=visible)
1004
-
1005
- lora1_gui = lora_dropdown("Lora1")
1006
- lora_scale_1_gui = lora_scale_slider("Lora Scale 1")
1007
- lora2_gui = lora_dropdown("Lora2")
1008
- lora_scale_2_gui = lora_scale_slider("Lora Scale 2")
1009
- lora3_gui = lora_dropdown("Lora3")
1010
- lora_scale_3_gui = lora_scale_slider("Lora Scale 3")
1011
- lora4_gui = lora_dropdown("Lora4")
1012
- lora_scale_4_gui = lora_scale_slider("Lora Scale 4")
1013
- lora5_gui = lora_dropdown("Lora5")
1014
- lora_scale_5_gui = lora_scale_slider("Lora Scale 5")
1015
- lora6_gui = lora_dropdown("Lora6", visible=(not IS_ZERO_GPU))
1016
- lora_scale_6_gui = lora_scale_slider("Lora Scale 6", visible=(not IS_ZERO_GPU))
1017
- lora7_gui = lora_dropdown("Lora7", visible=(not IS_ZERO_GPU))
1018
- lora_scale_7_gui = lora_scale_slider("Lora Scale 7", visible=(not IS_ZERO_GPU))
1019
-
1020
- with gr.Accordion("From URL", open=False, visible=True):
1021
- text_lora = gr.Textbox(
1022
- label="LoRA's download URL",
1023
- placeholder="https://civitai.com/api/download/models/28907",
1024
- lines=1,
1025
- info="It has to be .safetensors files, and you can also download them from Hugging Face.",
1026
- )
1027
- romanize_text = gr.Checkbox(value=False, label="Transliterate name", visible=(not IS_ZERO_GPU))
1028
- button_lora = gr.Button("Get and Refresh the LoRA Lists")
1029
- new_lora_status = gr.HTML()
1030
- button_lora.click(
1031
- get_my_lora,
1032
- [text_lora, romanize_text],
1033
- [lora1_gui, lora2_gui, lora3_gui, lora4_gui, lora5_gui, lora6_gui, lora7_gui, new_lora_status]
1034
- )
1035
-
1036
- with gr.Accordion("Face restoration", open=False, visible=True):
1037
-
1038
- face_rest_options = [None] + FACE_RESTORATION_MODELS
1039
-
1040
- face_restoration_model_gui = gr.Dropdown(label="Face restoration model", choices=face_rest_options, value=face_rest_options[0])
1041
- face_restoration_visibility_gui = gr.Slider(minimum=0., maximum=1., step=0.001, value=1., label="Visibility")
1042
- face_restoration_weight_gui = gr.Slider(minimum=0., maximum=1., step=0.001, value=.5, label="Weight", info="(0 = maximum effect, 1 = minimum effect)")
1043
-
1044
- with gr.Accordion("IP-Adapter", open=False, visible=True):
1045
-
1046
- with gr.Accordion("IP-Adapter 1", open=False, visible=True):
1047
- image_ip1 = gr.Image(label="IP Image", type="filepath")
1048
- mask_ip1 = gr.Image(label="IP Mask", type="filepath")
1049
- model_ip1 = gr.Dropdown(value="plus_face", label="Model", choices=IP_MODELS)
1050
- mode_ip1 = gr.Dropdown(value="original", label="Mode", choices=MODE_IP_OPTIONS)
1051
- scale_ip1 = gr.Slider(minimum=0., maximum=2., step=0.01, value=0.7, label="Scale")
1052
- with gr.Accordion("IP-Adapter 2", open=False, visible=True):
1053
- image_ip2 = gr.Image(label="IP Image", type="filepath")
1054
- mask_ip2 = gr.Image(label="IP Mask (optional)", type="filepath")
1055
- model_ip2 = gr.Dropdown(value="base", label="Model", choices=IP_MODELS)
1056
- mode_ip2 = gr.Dropdown(value="style", label="Mode", choices=MODE_IP_OPTIONS)
1057
- scale_ip2 = gr.Slider(minimum=0., maximum=2., step=0.01, value=0.7, label="Scale")
1058
-
1059
- with gr.Accordion("ControlNet / Img2img / Inpaint", open=False, visible=True):
1060
- image_control = gr.Image(label="Image ControlNet/Inpaint/Img2img", type="filepath")
1061
- image_mask_gui = gr.Image(label="Image Mask", type="filepath")
1062
- strength_gui = gr.Slider(
1063
- minimum=0.01, maximum=1.0, step=0.01, value=0.55, label="Strength",
1064
- info="This option adjusts the level of changes for img2img, repaint and inpaint."
1065
- )
1066
- image_resolution_gui = gr.Slider(
1067
- minimum=64, maximum=2048, step=64, value=1024, label="Image Resolution",
1068
- info="The maximum proportional size of the generated image based on the uploaded image."
1069
- )
1070
- controlnet_model_gui = gr.Dropdown(label="ControlNet model", choices=DIFFUSERS_CONTROLNET_MODEL, value=DIFFUSERS_CONTROLNET_MODEL[0], allow_custom_value=True)
1071
- control_net_output_scaling_gui = gr.Slider(minimum=0, maximum=5.0, step=0.1, value=1, label="ControlNet Output Scaling in UNet")
1072
- control_net_start_threshold_gui = gr.Slider(minimum=0, maximum=1, step=0.01, value=0, label="ControlNet Start Threshold (%)")
1073
- control_net_stop_threshold_gui = gr.Slider(minimum=0, maximum=1, step=0.01, value=1, label="ControlNet Stop Threshold (%)")
1074
- preprocessor_name_gui = gr.Dropdown(label="Preprocessor Name", choices=TASK_AND_PREPROCESSORS["canny"])
1075
-
1076
- def change_preprocessor_choices(task):
1077
- task = TASK_STABLEPY[task]
1078
- if task in TASK_AND_PREPROCESSORS.keys():
1079
- choices_task = TASK_AND_PREPROCESSORS[task]
1080
- else:
1081
- choices_task = TASK_AND_PREPROCESSORS["canny"]
1082
- return gr.update(choices=choices_task, value=choices_task[0])
1083
- task_gui.change(
1084
- change_preprocessor_choices,
1085
- [task_gui],
1086
- [preprocessor_name_gui],
1087
- )
1088
-
1089
- preprocess_resolution_gui = gr.Slider(minimum=64, maximum=2048, step=64, value=512, label="Preprocessor Resolution")
1090
- low_threshold_gui = gr.Slider(minimum=1, maximum=255, step=1, value=100, label="'CANNY' low threshold")
1091
- high_threshold_gui = gr.Slider(minimum=1, maximum=255, step=1, value=200, label="'CANNY' high threshold")
1092
- value_threshold_gui = gr.Slider(minimum=0.0, maximum=2.0, step=0.01, value=0.1, label="'MLSD' Hough value threshold")
1093
- distance_threshold_gui = gr.Slider(minimum=0.0, maximum=20.0, step=0.01, value=0.1, label="'MLSD' Hough distance threshold")
1094
- recolor_gamma_correction_gui = gr.Number(minimum=0., maximum=25., value=1., step=0.001, label="'RECOLOR' gamma correction")
1095
- tile_blur_sigma_gui = gr.Number(minimum=0, maximum=100, value=9, step=1, label="'TILE' blur sigma")
1096
-
1097
- with gr.Accordion("T2I adapter", open=False, visible=False):
1098
- t2i_adapter_preprocessor_gui = gr.Checkbox(value=True, label="T2i Adapter Preprocessor")
1099
- adapter_conditioning_scale_gui = gr.Slider(minimum=0, maximum=5., step=0.1, value=1, label="Adapter Conditioning Scale")
1100
- adapter_conditioning_factor_gui = gr.Slider(minimum=0, maximum=1., step=0.01, value=0.55, label="Adapter Conditioning Factor (%)")
1101
-
1102
- with gr.Accordion("Styles", open=False, visible=True):
1103
-
1104
- try:
1105
- style_names_found = sd_gen.model.STYLE_NAMES
1106
- except Exception:
1107
- style_names_found = STYLE_NAMES
1108
-
1109
- style_prompt_gui = gr.Dropdown(
1110
- style_names_found,
1111
- multiselect=True,
1112
- value=None,
1113
- label="Style Prompt",
1114
- interactive=True,
1115
- )
1116
- style_json_gui = gr.File(label="Style JSON File")
1117
- style_button = gr.Button("Load styles")
1118
-
1119
- def load_json_style_file(json):
1120
- if not sd_gen.model:
1121
- gr.Info("First load the model")
1122
- return gr.update(value=None, choices=STYLE_NAMES)
1123
-
1124
- sd_gen.model.load_style_file(json)
1125
- gr.Info(f"{len(sd_gen.model.STYLE_NAMES)} styles loaded")
1126
- return gr.update(value=None, choices=sd_gen.model.STYLE_NAMES)
1127
-
1128
- style_button.click(load_json_style_file, [style_json_gui], [style_prompt_gui])
1129
-
1130
- with gr.Accordion("Textual inversion", open=False, visible=False):
1131
- active_textual_inversion_gui = gr.Checkbox(value=False, label="Active Textual Inversion in prompt")
1132
-
1133
- with gr.Accordion("Detailfix", open=False, visible=True):
1134
-
1135
- # Adetailer Inpaint Only
1136
- adetailer_inpaint_only_gui = gr.Checkbox(label="Inpaint only", value=True)
1137
-
1138
- # Adetailer Verbose
1139
- adetailer_verbose_gui = gr.Checkbox(label="Verbose", value=False)
1140
-
1141
- # Adetailer Sampler
1142
- adetailer_sampler_gui = gr.Dropdown(label="Adetailer sampler:", choices=POST_PROCESSING_SAMPLER, value=POST_PROCESSING_SAMPLER[0])
1143
-
1144
- with gr.Accordion("Detailfix A", open=False, visible=True):
1145
- # Adetailer A
1146
- adetailer_active_a_gui = gr.Checkbox(label="Enable Adetailer A", value=False)
1147
- prompt_ad_a_gui = gr.Textbox(label="Main prompt", placeholder="Main prompt will be use", lines=3)
1148
- negative_prompt_ad_a_gui = gr.Textbox(label="Negative prompt", placeholder="Main negative prompt will be use", lines=3)
1149
- strength_ad_a_gui = gr.Number(label="Strength:", value=0.35, step=0.01, minimum=0.01, maximum=1.0)
1150
- face_detector_ad_a_gui = gr.Checkbox(label="Face detector", value=True)
1151
- person_detector_ad_a_gui = gr.Checkbox(label="Person detector", value=False)
1152
- hand_detector_ad_a_gui = gr.Checkbox(label="Hand detector", value=False)
1153
- mask_dilation_a_gui = gr.Number(label="Mask dilation:", value=4, minimum=1)
1154
- mask_blur_a_gui = gr.Number(label="Mask blur:", value=4, minimum=1)
1155
- mask_padding_a_gui = gr.Number(label="Mask padding:", value=32, minimum=1)
1156
-
1157
- with gr.Accordion("Detailfix B", open=False, visible=True):
1158
- # Adetailer B
1159
- adetailer_active_b_gui = gr.Checkbox(label="Enable Adetailer B", value=False)
1160
- prompt_ad_b_gui = gr.Textbox(label="Main prompt", placeholder="Main prompt will be use", lines=3)
1161
- negative_prompt_ad_b_gui = gr.Textbox(label="Negative prompt", placeholder="Main negative prompt will be use", lines=3)
1162
- strength_ad_b_gui = gr.Number(label="Strength:", value=0.35, step=0.01, minimum=0.01, maximum=1.0)
1163
- face_detector_ad_b_gui = gr.Checkbox(label="Face detector", value=False)
1164
- person_detector_ad_b_gui = gr.Checkbox(label="Person detector", value=True)
1165
- hand_detector_ad_b_gui = gr.Checkbox(label="Hand detector", value=False)
1166
- mask_dilation_b_gui = gr.Number(label="Mask dilation:", value=4, minimum=1)
1167
- mask_blur_b_gui = gr.Number(label="Mask blur:", value=4, minimum=1)
1168
- mask_padding_b_gui = gr.Number(label="Mask padding:", value=32, minimum=1)
1169
-
1170
- with gr.Accordion("Other settings", open=False, visible=True):
1171
- schedule_prediction_type_gui = gr.Dropdown(label="Discrete Sampling Type", choices=SCHEDULE_PREDICTION_TYPE_OPTIONS, value=SCHEDULE_PREDICTION_TYPE_OPTIONS[0])
1172
- guidance_rescale_gui = gr.Number(label="CFG rescale:", value=0., step=0.01, minimum=0., maximum=1.5)
1173
- save_generated_images_gui = gr.Checkbox(value=True, label="Create a download link for the images")
1174
- filename_pattern_gui = gr.Textbox(label="Filename pattern", value="model,seed", placeholder="model,seed,sampler,schedule_type,img_width,img_height,guidance_scale,num_steps,vae,prompt_section,neg_prompt_section", lines=1)
1175
- hires_before_adetailer_gui = gr.Checkbox(value=False, label="Hires Before Adetailer")
1176
- hires_after_adetailer_gui = gr.Checkbox(value=True, label="Hires After Adetailer")
1177
- generator_in_cpu_gui = gr.Checkbox(value=False, label="Generator in CPU")
1178
- with gr.Column(visible=(not IS_ZERO_GPU)):
1179
- image_storage_location_gui = gr.Textbox(value=img_path, label="Image Storage Location")
1180
- disable_progress_bar_gui = gr.Checkbox(value=False, label="Disable Progress Bar")
1181
- leave_progress_bar_gui = gr.Checkbox(value=True, label="Leave Progress Bar")
1182
-
1183
- with gr.Accordion("More settings", open=False, visible=False):
1184
- loop_generation_gui = gr.Slider(minimum=1, value=1, label="Loop Generation")
1185
- retain_task_cache_gui = gr.Checkbox(value=False, label="Retain task model in cache")
1186
- display_images_gui = gr.Checkbox(value=False, label="Display Images")
1187
- image_previews_gui = gr.Checkbox(value=True, label="Image Previews")
1188
- retain_compel_previous_load_gui = gr.Checkbox(value=False, label="Retain Compel Previous Load")
1189
- retain_detailfix_model_previous_load_gui = gr.Checkbox(value=False, label="Retain Detailfix Model Previous Load")
1190
- retain_hires_model_previous_load_gui = gr.Checkbox(value=False, label="Retain Hires Model Previous Load")
1191
- xformers_memory_efficient_attention_gui = gr.Checkbox(value=False, label="Xformers Memory Efficient Attention")
1192
-
1193
- set_params_gui.click(
1194
- run_set_params_gui, [prompt_gui, model_name_gui], [
1195
- prompt_gui,
1196
- neg_prompt_gui,
1197
- steps_gui,
1198
- img_width_gui,
1199
- img_height_gui,
1200
- seed_gui,
1201
- sampler_gui,
1202
- cfg_gui,
1203
- clip_skip_gui,
1204
- model_name_gui,
1205
- schedule_type_gui,
1206
- pag_scale_gui,
1207
- free_u_gui,
1208
- upscaler_model_path_gui,
1209
- upscaler_increases_size_gui,
1210
- hires_steps_gui,
1211
- hires_denoising_strength_gui,
1212
- hires_guidance_scale_gui,
1213
- hires_sampler_gui,
1214
- hires_schedule_type_gui,
1215
- image_resolution_gui,
1216
- strength_gui,
1217
- lora1_gui,
1218
- lora_scale_1_gui,
1219
- lora2_gui,
1220
- lora_scale_2_gui,
1221
- lora3_gui,
1222
- lora_scale_3_gui,
1223
- lora4_gui,
1224
- lora_scale_4_gui,
1225
- lora5_gui,
1226
- lora_scale_5_gui,
1227
- lora6_gui,
1228
- lora_scale_6_gui,
1229
- lora7_gui,
1230
- lora_scale_7_gui,
1231
- ],
1232
- )
1233
-
1234
- with gr.Accordion("Examples and help", open=False, visible=True):
1235
- gr.Markdown(HELP_GUI)
1236
- gr.Markdown(EXAMPLES_GUI_HELP)
1237
- gr.Examples(
1238
- examples=EXAMPLES_GUI,
1239
- fn=sd_gen.generate_pipeline,
1240
- inputs=[
1241
- prompt_gui,
1242
- neg_prompt_gui,
1243
- steps_gui,
1244
- cfg_gui,
1245
- seed_gui,
1246
- lora1_gui,
1247
- lora_scale_1_gui,
1248
- sampler_gui,
1249
- img_height_gui,
1250
- img_width_gui,
1251
- model_name_gui,
1252
- task_gui,
1253
- image_control,
1254
- image_resolution_gui,
1255
- strength_gui,
1256
- control_net_output_scaling_gui,
1257
- control_net_start_threshold_gui,
1258
- control_net_stop_threshold_gui,
1259
- prompt_syntax_gui,
1260
- upscaler_model_path_gui,
1261
- gpu_duration_gui,
1262
- load_lora_cpu_gui,
1263
- ],
1264
- outputs=[load_model_gui, result_images, actual_task_info],
1265
- cache_examples=False,
1266
- )
1267
- gr.Markdown(RESOURCES)
1268
-
1269
- with gr.Tab("Inpaint mask maker", render=True):
1270
-
1271
- with gr.Row():
1272
- with gr.Column(scale=2):
1273
- image_base = gr.ImageEditor(
1274
- sources=["upload", "clipboard"],
1275
- # crop_size="1:1",
1276
- # enable crop (or disable it)
1277
- # transforms=["crop"],
1278
- brush=gr.Brush(
1279
- default_size="16", # or leave it as 'auto'
1280
- color_mode="fixed", # 'fixed' hides the user swatches and colorpicker, 'defaults' shows it
1281
- # default_color="black", # html names are supported
1282
- colors=[
1283
- "rgba(0, 0, 0, 1)", # rgb(a)
1284
- "rgba(0, 0, 0, 0.1)",
1285
- "rgba(255, 255, 255, 0.1)",
1286
- # "hsl(360, 120, 120)" # in fact any valid colorstring
1287
- ]
1288
- ),
1289
- eraser=gr.Eraser(default_size="16"),
1290
- render=True,
1291
- visible=False,
1292
- interactive=False,
1293
- )
1294
-
1295
- show_canvas = gr.Button("SHOW INPAINT CANVAS")
1296
-
1297
- def change_visibility_canvas():
1298
- return gr.update(visible=True, interactive=True), gr.update(visible=False)
1299
- show_canvas.click(change_visibility_canvas, [], [image_base, show_canvas])
1300
-
1301
- invert_mask = gr.Checkbox(value=False, label="Invert mask")
1302
- btn = gr.Button("Create mask")
1303
-
1304
- with gr.Column(scale=1):
1305
- img_source = gr.Image(interactive=False)
1306
- img_result = gr.Image(label="Mask image", show_label=True, interactive=False)
1307
- btn_send = gr.Button("Send to the first tab")
1308
-
1309
- btn.click(create_mask_now, [image_base, invert_mask], [img_source, img_result])
1310
-
1311
- def send_img(img_source, img_result):
1312
- return img_source, img_result
1313
- btn_send.click(send_img, [img_source, img_result], [image_control, image_mask_gui])
1314
-
1315
- with gr.Tab("PNG Info"):
1316
-
1317
- with gr.Row():
1318
- with gr.Column():
1319
- image_metadata = gr.Image(label="Image with metadata", type="pil", sources=["upload"])
1320
-
1321
- with gr.Column():
1322
- result_metadata = gr.Textbox(label="Metadata", show_label=True, show_copy_button=True, interactive=False, container=True, max_lines=99)
1323
-
1324
- image_metadata.change(
1325
- fn=extract_exif_data,
1326
- inputs=[image_metadata],
1327
- outputs=[result_metadata],
1328
- )
1329
-
1330
- with gr.Tab("Upscaler"):
1331
-
1332
- with gr.Row():
1333
- with gr.Column():
1334
-
1335
- USCALER_TAB_KEYS = [name for name in UPSCALER_KEYS[9:]]
1336
-
1337
- image_up_tab = gr.Image(label="Image", type="pil", sources=["upload"])
1338
- upscaler_tab = gr.Dropdown(label="Upscaler", choices=USCALER_TAB_KEYS, value=USCALER_TAB_KEYS[5])
1339
- upscaler_size_tab = gr.Slider(minimum=1., maximum=4., step=0.1, value=1.1, label="Upscale by")
1340
- generate_button_up_tab = gr.Button(value="START UPSCALE", variant="primary")
1341
-
1342
- with gr.Column():
1343
- result_up_tab = gr.Image(label="Result", type="pil", interactive=False, format="png")
1344
-
1345
- generate_button_up_tab.click(
1346
- fn=process_upscale,
1347
- inputs=[image_up_tab, upscaler_tab, upscaler_size_tab],
1348
- outputs=[result_up_tab],
1349
- )
1350
-
1351
- with gr.Tab("Preprocessor", render=True):
1352
- preprocessor_tab()
1353
-
1354
- generate_button.click(
1355
- fn=sd_gen.load_new_model,
1356
- inputs=[
1357
- model_name_gui,
1358
- vae_model_gui,
1359
- task_gui,
1360
- controlnet_model_gui,
1361
- ],
1362
- outputs=[load_model_gui],
1363
- queue=True,
1364
- show_progress="minimal",
1365
- api_name=(False if HIDE_API else None),
1366
- ).success(
1367
- fn=sd_gen_generate_pipeline, # fn=sd_gen.generate_pipeline,
1368
- inputs=[
1369
- prompt_gui,
1370
- neg_prompt_gui,
1371
- num_images_gui,
1372
- steps_gui,
1373
- cfg_gui,
1374
- clip_skip_gui,
1375
- seed_gui,
1376
- lora1_gui,
1377
- lora_scale_1_gui,
1378
- lora2_gui,
1379
- lora_scale_2_gui,
1380
- lora3_gui,
1381
- lora_scale_3_gui,
1382
- lora4_gui,
1383
- lora_scale_4_gui,
1384
- lora5_gui,
1385
- lora_scale_5_gui,
1386
- lora6_gui,
1387
- lora_scale_6_gui,
1388
- lora7_gui,
1389
- lora_scale_7_gui,
1390
- sampler_gui,
1391
- schedule_type_gui,
1392
- schedule_prediction_type_gui,
1393
- img_height_gui,
1394
- img_width_gui,
1395
- model_name_gui,
1396
- vae_model_gui,
1397
- task_gui,
1398
- image_control,
1399
- preprocessor_name_gui,
1400
- preprocess_resolution_gui,
1401
- image_resolution_gui,
1402
- style_prompt_gui,
1403
- style_json_gui,
1404
- image_mask_gui,
1405
- strength_gui,
1406
- low_threshold_gui,
1407
- high_threshold_gui,
1408
- value_threshold_gui,
1409
- distance_threshold_gui,
1410
- recolor_gamma_correction_gui,
1411
- tile_blur_sigma_gui,
1412
- control_net_output_scaling_gui,
1413
- control_net_start_threshold_gui,
1414
- control_net_stop_threshold_gui,
1415
- active_textual_inversion_gui,
1416
- prompt_syntax_gui,
1417
- upscaler_model_path_gui,
1418
- upscaler_increases_size_gui,
1419
- upscaler_tile_size_gui,
1420
- upscaler_tile_overlap_gui,
1421
- hires_steps_gui,
1422
- hires_denoising_strength_gui,
1423
- hires_sampler_gui,
1424
- hires_prompt_gui,
1425
- hires_negative_prompt_gui,
1426
- hires_before_adetailer_gui,
1427
- hires_after_adetailer_gui,
1428
- hires_schedule_type_gui,
1429
- hires_guidance_scale_gui,
1430
- controlnet_model_gui,
1431
- loop_generation_gui,
1432
- leave_progress_bar_gui,
1433
- disable_progress_bar_gui,
1434
- image_previews_gui,
1435
- display_images_gui,
1436
- save_generated_images_gui,
1437
- filename_pattern_gui,
1438
- image_storage_location_gui,
1439
- retain_compel_previous_load_gui,
1440
- retain_detailfix_model_previous_load_gui,
1441
- retain_hires_model_previous_load_gui,
1442
- t2i_adapter_preprocessor_gui,
1443
- adapter_conditioning_scale_gui,
1444
- adapter_conditioning_factor_gui,
1445
- xformers_memory_efficient_attention_gui,
1446
- free_u_gui,
1447
- generator_in_cpu_gui,
1448
- adetailer_inpaint_only_gui,
1449
- adetailer_verbose_gui,
1450
- adetailer_sampler_gui,
1451
- adetailer_active_a_gui,
1452
- prompt_ad_a_gui,
1453
- negative_prompt_ad_a_gui,
1454
- strength_ad_a_gui,
1455
- face_detector_ad_a_gui,
1456
- person_detector_ad_a_gui,
1457
- hand_detector_ad_a_gui,
1458
- mask_dilation_a_gui,
1459
- mask_blur_a_gui,
1460
- mask_padding_a_gui,
1461
- adetailer_active_b_gui,
1462
- prompt_ad_b_gui,
1463
- negative_prompt_ad_b_gui,
1464
- strength_ad_b_gui,
1465
- face_detector_ad_b_gui,
1466
- person_detector_ad_b_gui,
1467
- hand_detector_ad_b_gui,
1468
- mask_dilation_b_gui,
1469
- mask_blur_b_gui,
1470
- mask_padding_b_gui,
1471
- retain_task_cache_gui,
1472
- guidance_rescale_gui,
1473
- image_ip1,
1474
- mask_ip1,
1475
- model_ip1,
1476
- mode_ip1,
1477
- scale_ip1,
1478
- image_ip2,
1479
- mask_ip2,
1480
- model_ip2,
1481
- mode_ip2,
1482
- scale_ip2,
1483
- pag_scale_gui,
1484
- face_restoration_model_gui,
1485
- face_restoration_visibility_gui,
1486
- face_restoration_weight_gui,
1487
- load_lora_cpu_gui,
1488
- verbose_info_gui,
1489
- gpu_duration_gui,
1490
- ],
1491
- outputs=[load_model_gui, result_images, actual_task_info],
1492
- queue=True,
1493
- show_progress="minimal",
1494
- # api_name=(False if HIDE_API else None),
1495
- )
1496
-
1497
- if __name__ == "__main__":
1498
- app.queue()
1499
- app.launch(
1500
- show_error=True,
1501
- share=args.share_enabled,
1502
- debug=True,
1503
- ssr_mode=args.ssr,
1504
- allowed_paths=[allowed_path],
1505
- show_api=(not HIDE_API),
1506
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
constants.py DELETED
@@ -1,611 +0,0 @@
1
- import os
2
- from stablepy.diffusers_vanilla.constants import FLUX_CN_UNION_MODES
3
- 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
-
17
- # - **Download VAEs**
18
- DOWNLOAD_VAE = "https://huggingface.co/fp16-guy/anything_kl-f8-anime2_vae-ft-mse-840000-ema-pruned_blessed_clearvae_fp16_cleaned/resolve/main/vae-ft-mse-840000-ema-pruned_fp16.safetensors?download=true"
19
-
20
- # - **Download LoRAs**
21
- DOWNLOAD_LORA = "https://huggingface.co/Leopain/color/resolve/main/Coloring_book_-_LineArt.safetensors, https://civitai.com/api/download/models/135867, https://huggingface.co/Linaqruf/anime-detailer-xl-lora/resolve/main/anime-detailer-xl.safetensors?download=true, https://huggingface.co/Linaqruf/style-enhancer-xl-lora/resolve/main/style-enhancer-xl.safetensors?download=true, https://huggingface.co/ByteDance/Hyper-SD/resolve/main/Hyper-SD15-8steps-CFG-lora.safetensors?download=true, https://huggingface.co/ByteDance/Hyper-SD/resolve/main/Hyper-SDXL-8steps-CFG-lora.safetensors?download=true"
22
-
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',
69
- 'John6666/chadmix-noobai075-illustrious01-v10-sdxl',
70
- 'OnomaAIResearch/Illustrious-xl-early-release-v0',
71
- 'John6666/illustriousxl-mmmix-v50-sdxl',
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',
107
- 'misri/newrealityxlAllInOne_Newreality40',
108
- 'gsdf/CounterfeitXL',
109
- 'WhiteAiZ/autismmixSDXL_autismmixConfetti_diffusers',
110
- 'kitty7779/ponyDiffusionV6XL',
111
- 'GraydientPlatformAPI/aniverse-pony',
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',
126
- 'John6666/wai-shuffle-pdxl-v2-sdxl',
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',
159
- 'digiplay/DreamShaper_8',
160
- 'digiplay/BeautifulArt_v1',
161
- 'digiplay/DarkSushi2.5D_v1',
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',
171
- 'GraydientPlatformAPI/perfectworld6',
172
- 'emilianJR/epiCRealism',
173
- 'votepurchase/counterfeitV30_v30',
174
- 'votepurchase/ChilloutMix',
175
- 'Meina/MeinaMix_V11',
176
- 'Meina/MeinaUnreal_V5',
177
- 'Meina/MeinaPastel_V7',
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",
187
- "Shakker-Labs/FLUX.1-dev-LoRA-Logo-Design",
188
- ]
189
-
190
- DOWNLOAD_EMBEDS = [
191
- 'https://huggingface.co/datasets/Nerfgun3/bad_prompt/blob/main/bad_prompt_version2.pt',
192
- # 'https://huggingface.co/embed/negative/resolve/main/EasyNegativeV2.safetensors',
193
- # 'https://huggingface.co/embed/negative/resolve/main/bad-hands-5.pt',
194
- ]
195
-
196
- CIVITAI_API_KEY = os.environ.get("CIVITAI_API_KEY")
197
- HF_TOKEN = os.environ.get("HF_READ_TOKEN")
198
-
199
- 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',
213
- 'img2img': 'img2img',
214
- 'inpaint': 'inpaint',
215
- # 'canny T2I Adapter': 'sdxl_canny_t2i', # NO HAVE STEP CALLBACK PARAMETERS SO NOT WORKS WITH DIFFUSERS 0.29.0
216
- # 'sketch T2I Adapter': 'sdxl_sketch_t2i',
217
- # 'lineart T2I Adapter': 'sdxl_lineart_t2i',
218
- # 'depth-midas T2I Adapter': 'sdxl_depth-midas_t2i',
219
- # 'openpose T2I Adapter': 'sdxl_openpose_t2i',
220
- 'openpose ControlNet': 'openpose',
221
- 'canny ControlNet': 'canny',
222
- 'mlsd ControlNet': 'mlsd',
223
- 'scribble ControlNet': 'scribble',
224
- 'softedge ControlNet': 'softedge',
225
- 'segmentation ControlNet': 'segmentation',
226
- 'depth ControlNet': 'depth',
227
- 'normalbae ControlNet': 'normalbae',
228
- 'lineart ControlNet': 'lineart',
229
- 'lineart_anime ControlNet': 'lineart_anime',
230
- 'shuffle ControlNet': 'shuffle',
231
- 'ip2p ControlNet': 'ip2p',
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",
255
- "lollypop": "https://huggingface.co/hollowstrawberry/upscalers-backup/resolve/main/ESRGAN/lollypop.pth",
256
- "RealisticRescaler4x": "https://huggingface.co/hollowstrawberry/upscalers-backup/resolve/main/ESRGAN/RealisticRescaler%204x.pth",
257
- "NickelbackFS4x": "https://huggingface.co/hollowstrawberry/upscalers-backup/resolve/main/ESRGAN/NickelbackFS%204x.pth"
258
- }
259
-
260
- UPSCALER_KEYS = list(UPSCALER_DICT_GUI.keys())
261
-
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",
269
- "Eugeoter/noob-sdxl-controlnet-lineart_anime",
270
- "Eugeoter/noob-sdxl-controlnet-depth",
271
- "Eugeoter/noob-sdxl-controlnet-normal",
272
- "Eugeoter/noob-sdxl-controlnet-softedge_hed",
273
- "Eugeoter/noob-sdxl-controlnet-scribble_pidinet",
274
- "Eugeoter/noob-sdxl-controlnet-scribble_hed",
275
- "Eugeoter/noob-sdxl-controlnet-manga_line",
276
- "Eugeoter/noob-sdxl-controlnet-lineart_realistic",
277
- "Eugeoter/noob-sdxl-controlnet-depth_midas-v1-1",
278
- "dimitribarbot/controlnet-openpose-sdxl-1.0-safetensors",
279
- "r3gm/controlnet-openpose-sdxl-1.0-fp16",
280
- "r3gm/controlnet-canny-scribble-integrated-sdxl-v2-fp16",
281
- "r3gm/controlnet-union-sdxl-1.0-fp16",
282
- "r3gm/controlnet-lineart-anime-sdxl-fp16",
283
- "r3gm/control_v1p_sdxl_qrcode_monster_fp16",
284
- "r3gm/controlnet-tile-sdxl-1.0-fp16",
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",
291
- "briaai/BRIA-2.3-ControlNet-Canny",
292
-
293
- "lllyasviel/control_v11p_sd15_openpose",
294
- "lllyasviel/control_v11p_sd15_canny",
295
- "lllyasviel/control_v11p_sd15_mlsd",
296
- "lllyasviel/control_v11p_sd15_scribble",
297
- "lllyasviel/control_v11p_sd15_softedge",
298
- "lllyasviel/control_v11p_sd15_seg",
299
- "lllyasviel/control_v11f1p_sd15_depth",
300
- "lllyasviel/control_v11p_sd15_normalbae",
301
- "lllyasviel/control_v11p_sd15_lineart",
302
- "lllyasviel/control_v11p_sd15s2_lineart_anime",
303
- "lllyasviel/control_v11e_sd15_shuffle",
304
- "lllyasviel/control_v11e_sd15_ip2p",
305
- "lllyasviel/control_v11p_sd15_inpaint",
306
- "monster-labs/control_v1p_sd15_qrcode_monster",
307
- "lllyasviel/control_v11f1e_sd15_tile",
308
- "latentcat/control_v1p_sd15_brightness",
309
- "yuanqiuye/qrcode_controlnet_v3",
310
-
311
- "Shakker-Labs/FLUX.1-dev-ControlNet-Union-Pro",
312
- # "Shakker-Labs/FLUX.1-dev-ControlNet-Pose",
313
- # "Shakker-Labs/FLUX.1-dev-ControlNet-Depth",
314
- # "jasperai/Flux.1-dev-Controlnet-Upscaler",
315
- # "jasperai/Flux.1-dev-Controlnet-Depth",
316
- # "jasperai/Flux.1-dev-Controlnet-Surface-Normals",
317
- # "XLabs-AI/flux-controlnet-canny-diffusers",
318
- # "XLabs-AI/flux-controlnet-hed-diffusers",
319
- # "XLabs-AI/flux-controlnet-depth-diffusers",
320
- # "InstantX/FLUX.1-dev-Controlnet-Union",
321
- # "InstantX/FLUX.1-dev-Controlnet-Canny",
322
- ]
323
-
324
- PROMPT_W_OPTIONS = [
325
- ("Compel format: (word)weight", "Compel"),
326
- ("Classic format: (word:weight)", "Classic"),
327
- ("Classic-original format: (word:weight)", "Classic-original"),
328
- ("Classic-no_norm format: (word:weight)", "Classic-no_norm"),
329
- ("Classic-sd_embed format: (word:weight)", "Classic-sd_embed"),
330
- ("Classic-ignore", "Classic-ignore"),
331
- ("None", "None"),
332
- ]
333
-
334
- WARNING_MSG_VAE = (
335
- "Use the right VAE for your model to maintain image quality. The wrong"
336
- " VAE can lead to poor results, like blurriness in the generated images."
337
- )
338
-
339
- SDXL_TASK = [k for k, v in TASK_STABLEPY.items() if v in SDXL_TASKS]
340
- SD_TASK = [k for k, v in TASK_STABLEPY.items() if v in SD15_TASKS]
341
- FLUX_TASK = list(TASK_STABLEPY.keys())[:3] + [k for k, v in TASK_STABLEPY.items() if v in FLUX_CN_UNION_MODES.keys()]
342
-
343
- MODEL_TYPE_TASK = {
344
- "SD 1.5": SD_TASK,
345
- "SDXL": SDXL_TASK,
346
- "FLUX": FLUX_TASK,
347
- }
348
-
349
- MODEL_TYPE_CLASS = {
350
- "diffusers:StableDiffusionPipeline": "SD 1.5",
351
- "diffusers:StableDiffusionXLPipeline": "SDXL",
352
- "diffusers:FluxPipeline": "FLUX",
353
- }
354
-
355
- DIFFUSECRAFT_CHECKPOINT_NAME = {
356
- "sd1.5": "SD 1.5",
357
- "sdxl": "SDXL",
358
- "flux-dev": "FLUX",
359
- "flux-schnell": "FLUX",
360
- }
361
-
362
- 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
- """
393
- )
394
-
395
- EXAMPLES_GUI_HELP = (
396
- """### The following examples perform specific tasks:
397
- 1. Generation with SDXL and upscale
398
- 2. Generation with FLUX dev
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
- """
408
- )
409
-
410
- EXAMPLES_GUI = [
411
- [
412
- "splatter paint theme, 1girl, frame center, pretty face, face with artistic paint artwork, feminism, long hair, upper body view, futuristic expression illustrative painted background, origami, stripes, explosive paint splashes behind her, hand on cheek pose, strobe lighting, masterpiece photography creative artwork, golden morning light, highly detailed, masterpiece, best quality, very aesthetic, absurdres",
413
- "logo, artist name, (worst quality, normal quality), bad-artist, ((bad anatomy)), ((bad hands)), ((bad proportions)), ((duplicate limbs)), ((fused limbs)), ((interlocking fingers)), ((poorly drawn face)), high contrast., score_6, score_5, score_4, lowres, (bad), text, error, fewer, extra, missing, worst quality, jpeg artifacts, low quality, watermark, unfinished, displeasing, oldest, early, chromatic aberration, signature, extra digits, artistic error, username, scan, [abstract]",
414
- 28,
415
- 5.0,
416
- -1,
417
- "None",
418
- 0.33,
419
- "DPM++ 2M SDE",
420
- 1152,
421
- 896,
422
- "John6666/noobai-xl-nai-xl-epsilonpred10version-sdxl",
423
- "txt2img",
424
- "image.webp", # img conttol
425
- 1024, # img resolution
426
- 0.35, # strength
427
- 1.0, # cn scale
428
- 0.0, # cn start
429
- 1.0, # cn end
430
- "Classic-no_norm",
431
- "Nearest",
432
- 45,
433
- False,
434
- ],
435
- [
436
- "a digital illustration of a movie poster titled 'Finding Emo', finding nemo parody poster, featuring a depressed cartoon clownfish with black emo hair, eyeliner, and piercings, bored expression, swimming in a dark underwater scene, in the background, movie title in a dripping, grungy font, moody blue and purple color palette",
437
- "",
438
- 24,
439
- 3.5,
440
- -1,
441
- "None",
442
- 0.33,
443
- "FlowMatch Euler",
444
- 1152,
445
- 896,
446
- "black-forest-labs/FLUX.1-dev",
447
- "txt2img",
448
- None, # img conttol
449
- 1024, # img resolution
450
- 0.35, # strength
451
- 1.0, # cn scale
452
- 0.0, # cn start
453
- 1.0, # cn end
454
- "Classic",
455
- None,
456
- 70,
457
- True,
458
- ],
459
- [
460
- "((masterpiece)), best quality, blonde disco girl, detailed face, realistic face, realistic hair, dynamic pose, pink pvc, intergalactic disco background, pastel lights, dynamic contrast, airbrush, fine detail, 70s vibe, midriff",
461
- "(worst quality:1.2), (bad quality:1.2), (poor quality:1.2), (missing fingers:1.2), bad-artist-anime, bad-artist, bad-picture-chill-75v",
462
- 48,
463
- 3.5,
464
- -1,
465
- "None",
466
- 0.33,
467
- "DPM++ 2M SDE Ef",
468
- 1024,
469
- 1024,
470
- "John6666/epicrealism-xl-v10kiss2-sdxl",
471
- "canny ControlNet",
472
- "image.webp", # img conttol
473
- 1024, # img resolution
474
- 0.35, # strength
475
- 1.0, # cn scale
476
- 0.0, # cn start
477
- 1.0, # cn end
478
- "Classic",
479
- None,
480
- 44,
481
- False,
482
- ],
483
- [
484
- "cinematic scenery old city ruins",
485
- "(worst quality, low quality, illustration, 3d, 2d, painting, cartoons, sketch), (illustration, 3d, 2d, painting, cartoons, sketch, blurry, film grain, noise), (low quality, worst quality:1.2)",
486
- 50,
487
- 4.0,
488
- -1,
489
- "None",
490
- 0.33,
491
- "Euler a",
492
- 1024,
493
- 1024,
494
- "SG161222/RealVisXL_V5.0",
495
- "optical pattern ControlNet",
496
- "spiral_no_transparent.png", # img conttol
497
- 1024, # img resolution
498
- 0.35, # strength
499
- 1.0, # cn scale
500
- 0.05, # cn start
501
- 0.8, # cn end
502
- "Classic",
503
- None,
504
- 35,
505
- False,
506
- ],
507
- [
508
- "black and white, line art, coloring drawing, clean line art, black strokes, no background, white, black, free lines, black scribbles, on paper, A blend of comic book art and lineart full of black and white color, masterpiece, high-resolution, trending on Pixiv fan box, palette knife, brush strokes, two-dimensional, planar vector, T-shirt design, stickers, and T-shirt design, vector art, fantasy art, Adobe Illustrator, hand-painted, digital painting, low polygon, soft lighting, aerial view, isometric style, retro aesthetics, 8K resolution, black sketch lines, monochrome, invert color",
509
- "color, red, green, yellow, colored, duplicate, blurry, abstract, disfigured, deformed, animated, toy, figure, framed, 3d, bad art, poorly drawn, extra limbs, close up, b&w, weird colors, blurry, watermark, blur haze, 2 heads, long neck, watermark, elongated body, cropped image, out of frame, draft, deformed hands, twisted fingers, double image, malformed hands, multiple heads, extra limb, ugly, poorly drawn hands, missing limb, cut-off, over satured, grain, lowères, bad anatomy, poorly drawn face, mutation, mutated, floating limbs, disconnected limbs, out of focus, long body, disgusting, extra fingers, groos proportions, missing arms, mutated hands, cloned face, missing legs, ugly, tiling, poorly drawn hands, poorly drawn feet, poorly drawn face, out of frame, extra limbs, disfigured, deformed, body out of frame, blurry, bad anatomy, blurred, watermark, grainy, signature, cut off, draft, deformed, blurry, bad anatomy, disfigured, poorly drawn face, mutation, bluelish, blue",
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,
517
- 1024,
518
- "eienmojiki/Anything-XL",
519
- "lineart ControlNet",
520
- "color_image.png", # img conttol
521
- 896, # img resolution
522
- 0.35, # strength
523
- 1.0, # cn scale
524
- 0.0, # cn start
525
- 1.0, # cn end
526
- "Compel",
527
- None,
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,",
582
- 38,
583
- 5.0,
584
- -1,
585
- "None",
586
- 0.33,
587
- "DPM++ 2M SDE",
588
- 512,
589
- 512,
590
- "digiplay/majicMIX_realistic_v7",
591
- "openpose ControlNet",
592
- "image.webp", # img conttol
593
- 1024, # img resolution
594
- 0.35, # strength
595
- 1.0, # cn scale
596
- 0.0, # cn start
597
- 0.9, # cn end
598
- "Classic-original",
599
- "Latent (antialiased)",
600
- 46,
601
- False,
602
- ],
603
- ]
604
-
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
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
image_processor.py DELETED
@@ -1,130 +0,0 @@
1
- import spaces
2
- import gradio as gr
3
- from stablepy import Preprocessor
4
-
5
- PREPROCESSOR_TASKS_LIST = [
6
- "Canny",
7
- "Openpose",
8
- "DPT",
9
- "Midas",
10
- "ZoeDepth",
11
- "DepthAnything",
12
- "HED",
13
- "PidiNet",
14
- "TEED",
15
- "Lineart",
16
- "LineartAnime",
17
- "Anyline",
18
- "Lineart standard",
19
- "SegFormer",
20
- "UPerNet",
21
- "ContentShuffle",
22
- "Recolor",
23
- "Blur",
24
- "MLSD",
25
- "NormalBae",
26
- ]
27
-
28
- preprocessor = Preprocessor()
29
-
30
-
31
- def process_inputs(
32
- image,
33
- name,
34
- resolution,
35
- precessor_resolution,
36
- low_threshold,
37
- high_threshold,
38
- value_threshod,
39
- distance_threshold,
40
- recolor_mode,
41
- recolor_gamma_correction,
42
- blur_k_size,
43
- pre_openpose_extra,
44
- hed_scribble,
45
- pre_pidinet_safe,
46
- pre_lineart_coarse,
47
- use_cuda,
48
- ):
49
- if not image:
50
- raise ValueError("To use this, simply upload an image.")
51
-
52
- preprocessor.load(name, False)
53
-
54
- params = dict(
55
- image_resolution=resolution,
56
- detect_resolution=precessor_resolution,
57
- low_threshold=low_threshold,
58
- high_threshold=high_threshold,
59
- thr_v=value_threshod,
60
- thr_d=distance_threshold,
61
- mode=recolor_mode,
62
- gamma_correction=recolor_gamma_correction,
63
- blur_sigma=blur_k_size,
64
- hand_and_face=pre_openpose_extra,
65
- scribble=hed_scribble,
66
- safe=pre_pidinet_safe,
67
- coarse=pre_lineart_coarse,
68
- )
69
-
70
- if use_cuda:
71
- @spaces.GPU(duration=15)
72
- def wrapped_func():
73
- preprocessor.to("cuda")
74
- return preprocessor(image, **params)
75
- return wrapped_func()
76
-
77
- return preprocessor(image, **params)
78
-
79
-
80
- def preprocessor_tab():
81
- with gr.Row():
82
- with gr.Column():
83
- pre_image = gr.Image(label="Image", type="pil", sources=["upload"])
84
- pre_options = gr.Dropdown(label="Preprocessor", choices=PREPROCESSOR_TASKS_LIST, value=PREPROCESSOR_TASKS_LIST[0])
85
- pre_img_resolution = gr.Slider(
86
- minimum=64, maximum=4096, step=64, value=1024, label="Image Resolution",
87
- info="The maximum proportional size of the generated image based on the uploaded image."
88
- )
89
- pre_start = gr.Button(value="PROCESS IMAGE", variant="primary")
90
- with gr.Accordion("Advanced Settings", open=False):
91
- with gr.Column():
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")
100
- pre_openpose_extra = gr.Checkbox(value=True, label="'OPENPOSE' face and hand")
101
- pre_hed_scribble = gr.Checkbox(value=False, label="'HED' scribble")
102
- pre_pidinet_safe = gr.Checkbox(value=False, label="'PIDINET' safe")
103
- pre_lineart_coarse = gr.Checkbox(value=False, label="'LINEART' coarse")
104
- pre_use_cuda = gr.Checkbox(value=False, label="Use CUDA")
105
-
106
- with gr.Column():
107
- pre_result = gr.Image(label="Result", type="pil", interactive=False, format="png")
108
-
109
- pre_start.click(
110
- fn=process_inputs,
111
- inputs=[
112
- pre_image,
113
- pre_options,
114
- pre_img_resolution,
115
- pre_processor_resolution,
116
- pre_low_threshold,
117
- pre_high_threshold,
118
- pre_value_threshold,
119
- pre_distance_threshold,
120
- pre_recolor_mode,
121
- pre_recolor_gamma_correction,
122
- pre_blur_k_size,
123
- pre_openpose_extra,
124
- pre_hed_scribble,
125
- pre_pidinet_safe,
126
- pre_lineart_coarse,
127
- pre_use_cuda,
128
- ],
129
- outputs=[pre_result],
130
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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,4 @@
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@flux_beta
2
+ torch==2.2.0
 
3
  gdown
4
+ opencv-python
 
 
 
 
 
 
 
 
utils.py DELETED
@@ -1,714 +0,0 @@
1
- import os
2
- import re
3
- import gradio as gr
4
- from constants import (
5
- DIFFUSERS_FORMAT_LORAS,
6
- CIVITAI_API_KEY,
7
- HF_TOKEN,
8
- MODEL_TYPE_CLASS,
9
- DIRECTORY_LORAS,
10
- DIRECTORY_MODELS,
11
- DIFFUSECRAFT_CHECKPOINT_NAME,
12
- CACHE_HF_ROOT,
13
- CACHE_HF,
14
- STORAGE_ROOT,
15
- )
16
- from huggingface_hub import HfApi, get_hf_file_metadata, snapshot_download
17
- from diffusers import DiffusionPipeline
18
- from huggingface_hub import model_info as model_info_data
19
- from diffusers.pipelines.pipeline_loading_utils import variant_compatible_siblings
20
- from stablepy.diffusers_vanilla.utils import checkpoint_model_type
21
- from pathlib import PosixPath
22
- from unidecode import unidecode
23
- import urllib.parse
24
- import copy
25
- import requests
26
- from requests.adapters import HTTPAdapter
27
- from urllib3.util import Retry
28
- import shutil
29
- import subprocess
30
- import json
31
- import html as _html
32
-
33
- IS_ZERO_GPU = bool(os.getenv("SPACES_ZERO_GPU"))
34
- USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:127.0) Gecko/20100101 Firefox/127.0'
35
- MODEL_ARCH = {
36
- 'stable-diffusion-xl-v1-base/lora': "Stable Diffusion XL (Illustrious, Pony, NoobAI)",
37
- 'stable-diffusion-v1/lora': "Stable Diffusion 1.5",
38
- 'flux-1-dev/lora': "Flux",
39
- }
40
-
41
-
42
- def read_safetensors_header_from_url(url: str):
43
- """Read safetensors header from a remote Hugging Face file."""
44
- meta = get_hf_file_metadata(url)
45
-
46
- # Step 1: first 8 bytes → header length
47
- resp = requests.get(meta.location, headers={"Range": "bytes=0-7"})
48
- resp.raise_for_status()
49
- header_len = int.from_bytes(resp.content, "little")
50
-
51
- # Step 2: fetch full header JSON
52
- end = 8 + header_len - 1
53
- resp = requests.get(meta.location, headers={"Range": f"bytes=8-{end}"})
54
- resp.raise_for_status()
55
- header_json = resp.content.decode("utf-8")
56
-
57
- return json.loads(header_json)
58
-
59
-
60
- def read_safetensors_header_from_file(path: str):
61
- """Read safetensors header from a local file."""
62
- with open(path, "rb") as f:
63
- # Step 1: first 8 bytes → header length
64
- header_len = int.from_bytes(f.read(8), "little")
65
-
66
- # Step 2: read header JSON
67
- header_json = f.read(header_len).decode("utf-8")
68
-
69
- return json.loads(header_json)
70
-
71
-
72
- class LoraHeaderInformation:
73
- """
74
- Encapsulates parsed info from a LoRA JSON header and provides
75
- a compact HTML summary via .to_html().
76
- """
77
-
78
- def __init__(self, json_data):
79
- self.original_json = copy.deepcopy(json_data or {})
80
-
81
- # Check if text encoder was trained
82
- # guard for json_data being a mapping
83
- try:
84
- self.text_encoder_trained = any("text_model" in ln for ln in json_data)
85
- except Exception:
86
- self.text_encoder_trained = False
87
-
88
- # Metadata (may be None)
89
- metadata = (json_data or {}).get("__metadata__", None)
90
- self.metadata = metadata
91
-
92
- # Default values
93
- self.architecture = "undefined"
94
- self.prediction_type = "undefined"
95
- self.base_model = "undefined"
96
- self.author = "undefined"
97
- self.title = "undefined"
98
- self.common_tags_list = []
99
-
100
- if metadata:
101
- self.architecture = MODEL_ARCH.get(
102
- metadata.get('modelspec.architecture', None),
103
- "undefined"
104
- )
105
-
106
- self.prediction_type = metadata.get('modelspec.prediction_type', "undefined")
107
- self.base_model = metadata.get('ss_sd_model_name', "undefined")
108
- self.author = metadata.get('modelspec.author', "undefined")
109
- self.title = metadata.get('modelspec.title', "undefined")
110
-
111
- base_model_hash = metadata.get('ss_new_sd_model_hash', None) # SHA256
112
- # AUTOV1 ss_sd_model_hash
113
- # https://civitai.com/api/v1/model-versions/by-hash/{base_model_hash} # Info
114
- if base_model_hash:
115
- self.base_model += f" hash={base_model_hash}"
116
-
117
- # Extract tags
118
- try:
119
- tags = metadata.get('ss_tag_frequency') if "ss_tag_frequency" in metadata else metadata.get('ss_datasets', "")
120
- tags = json.loads(tags) if tags else ""
121
-
122
- if isinstance(tags, list):
123
- tags = tags[0].get("tag_frequency", {})
124
-
125
- if tags:
126
- self.common_tags_list = list(tags[list(tags.keys())[0]].keys())
127
- except Exception:
128
- self.common_tags_list = []
129
-
130
- def to_dict(self):
131
- """Return a plain dict summary of parsed fields."""
132
- return {
133
- "architecture": self.architecture,
134
- "prediction_type": self.prediction_type,
135
- "base_model": self.base_model,
136
- "author": self.author,
137
- "title": self.title,
138
- "text_encoder_trained": bool(self.text_encoder_trained),
139
- "common_tags": self.common_tags_list,
140
- }
141
-
142
- def to_html(self, limit_tags=20):
143
- """
144
- Return a compact HTML snippet (string) showing the parsed info
145
- in a small font. Values are HTML-escaped.
146
- """
147
- # helper to escape
148
- esc = _html.escape
149
-
150
- rows = [
151
- ("Title", esc(str(self.title))),
152
- ("Author", esc(str(self.author))),
153
- ("Architecture", esc(str(self.architecture))),
154
- ("Base model", esc(str(self.base_model))),
155
- ("Prediction type", esc(str(self.prediction_type))),
156
- ("Text encoder trained", esc(str(self.text_encoder_trained))),
157
- ("Reference tags", esc(str(", ".join(self.common_tags_list[:limit_tags])))),
158
- ]
159
-
160
- # small, compact table with inline styling (small font)
161
- html_rows = "".join(
162
- f"<tr><th style='text-align:left;padding:2px 6px;white-space:nowrap'>{k}</th>"
163
- f"<td style='padding:2px 6px'>{v}</td></tr>"
164
- for k, v in rows
165
- )
166
-
167
- html_snippet = (
168
- "<div style='font-family:system-ui, -apple-system, \"Segoe UI\", Roboto, "
169
- "Helvetica, Arial, \"Noto Sans\", sans-serif; font-size:12px; line-height:1.2; "
170
- "'>"
171
- f"<table style='border-collapse:collapse; font-size:12px;'>"
172
- f"{html_rows}"
173
- "</table>"
174
- "</div>"
175
- )
176
-
177
- return html_snippet
178
-
179
-
180
- def request_json_data(url):
181
- model_version_id = url.split('/')[-1]
182
- if "?modelVersionId=" in model_version_id:
183
- match = re.search(r'modelVersionId=(\d+)', url)
184
- model_version_id = match.group(1)
185
-
186
- endpoint_url = f"https://civitai.com/api/v1/model-versions/{model_version_id}"
187
-
188
- params = {}
189
- headers = {'User-Agent': USER_AGENT, 'content-type': 'application/json'}
190
- session = requests.Session()
191
- retries = Retry(total=5, backoff_factor=1, status_forcelist=[500, 502, 503, 504])
192
- session.mount("https://", HTTPAdapter(max_retries=retries))
193
-
194
- try:
195
- result = session.get(endpoint_url, params=params, headers=headers, stream=True, timeout=(3.0, 15))
196
- result.raise_for_status()
197
- json_data = result.json()
198
- return json_data if json_data else None
199
- except Exception as e:
200
- print(f"Error: {e}")
201
- return None
202
-
203
-
204
- class ModelInformation:
205
- def __init__(self, json_data):
206
- self.model_version_id = json_data.get("id", "")
207
- self.model_id = json_data.get("modelId", "")
208
- self.download_url = json_data.get("downloadUrl", "")
209
- self.model_url = f"https://civitai.com/models/{self.model_id}?modelVersionId={self.model_version_id}"
210
- self.filename_url = next(
211
- (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"), ""
212
- )
213
- self.filename_url = self.filename_url if self.filename_url else ""
214
- self.description = json_data.get("description", "")
215
- if self.description is None:
216
- self.description = ""
217
- self.model_name = json_data.get("model", {}).get("name", "")
218
- self.model_type = json_data.get("model", {}).get("type", "")
219
- self.nsfw = json_data.get("model", {}).get("nsfw", False)
220
- self.poi = json_data.get("model", {}).get("poi", False)
221
- self.images = [img.get("url", "") for img in json_data.get("images", [])]
222
- self.example_prompt = json_data.get("trainedWords", [""])[0] if json_data.get("trainedWords") else ""
223
- self.original_json = copy.deepcopy(json_data)
224
-
225
-
226
- def get_civit_params(url):
227
- try:
228
- json_data = request_json_data(url)
229
- mdc = ModelInformation(json_data)
230
- if mdc.download_url and mdc.filename_url:
231
- return mdc.download_url, mdc.filename_url, mdc.model_url
232
- else:
233
- ValueError("Invalid Civitai model URL")
234
- except Exception as e:
235
- print(f"Error retrieving Civitai metadata: {e} — fallback to direct download")
236
- return url, None, None
237
-
238
-
239
- def civ_redirect_down(url, dir_, civitai_api_key, romanize, alternative_name):
240
- filename_base = filename = None
241
-
242
- if alternative_name:
243
- output_path = os.path.join(dir_, alternative_name)
244
- if os.path.exists(output_path):
245
- return output_path, alternative_name
246
-
247
- # Follow the redirect to get the actual download URL
248
- curl_command = (
249
- f'curl -L -sI --connect-timeout 5 --max-time 5 '
250
- f'-H "Content-Type: application/json" '
251
- f'-H "Authorization: Bearer {civitai_api_key}" "{url}"'
252
- )
253
-
254
- headers = os.popen(curl_command).read()
255
-
256
- # Look for the redirected "Location" URL
257
- location_match = re.search(r'location: (.+)', headers, re.IGNORECASE)
258
-
259
- if location_match:
260
- redirect_url = location_match.group(1).strip()
261
-
262
- # Extract the filename from the redirect URL's "Content-Disposition"
263
- filename_match = re.search(r'filename%3D%22(.+?)%22', redirect_url)
264
- if filename_match:
265
- encoded_filename = filename_match.group(1)
266
- # Decode the URL-encoded filename
267
- decoded_filename = urllib.parse.unquote(encoded_filename)
268
-
269
- filename = unidecode(decoded_filename) if romanize else decoded_filename
270
- # print(f"Filename redirect: {filename}")
271
-
272
- filename_base = alternative_name if alternative_name else filename
273
- if not filename_base:
274
- return None, None
275
- elif os.path.exists(os.path.join(dir_, filename_base)):
276
- return os.path.join(dir_, filename_base), filename_base
277
-
278
- aria2_command = (
279
- f'aria2c --console-log-level=error --summary-interval=10 -c -x 16 '
280
- f'-k 1M -s 16 -d "{dir_}" -o "{filename_base}" "{redirect_url}"'
281
- )
282
- r_code = os.system(aria2_command) # noqa
283
-
284
- # if r_code != 0:
285
- # raise RuntimeError(f"Failed to download file: {filename_base}. Error code: {r_code}")
286
-
287
- output_path = os.path.join(dir_, filename_base)
288
- if not os.path.exists(output_path):
289
- return None, filename_base
290
-
291
- return output_path, filename_base
292
-
293
-
294
- def civ_api_down(url, dir_, civitai_api_key, civ_filename):
295
- """
296
- This method is susceptible to being blocked because it generates a lot of temp redirect links with aria2c.
297
- If an API key limit is reached, generating a new API key and using it can fix the issue.
298
- """
299
- output_path = None
300
-
301
- url_dl = url + f"?token={civitai_api_key}"
302
- if not civ_filename:
303
- aria2_command = f'aria2c -c -x 1 -s 1 -d "{dir_}" "{url_dl}"'
304
- os.system(aria2_command)
305
- else:
306
- output_path = os.path.join(dir_, civ_filename)
307
- if not os.path.exists(output_path):
308
- aria2_command = (
309
- f'aria2c --console-log-level=error --summary-interval=10 -c -x 16 '
310
- f'-k 1M -s 16 -d "{dir_}" -o "{civ_filename}" "{url_dl}"'
311
- )
312
- os.system(aria2_command)
313
-
314
- return output_path
315
-
316
-
317
- def drive_down(url, dir_):
318
- import gdown
319
-
320
- output_path = None
321
-
322
- drive_id, _ = gdown.parse_url.parse_url(url, warning=False)
323
- dir_files = os.listdir(dir_)
324
-
325
- for dfile in dir_files:
326
- if drive_id in dfile:
327
- output_path = os.path.join(dir_, dfile)
328
- break
329
-
330
- if not output_path:
331
- original_path = gdown.download(url, f"{dir_}/", fuzzy=True)
332
-
333
- dir_name, base_name = os.path.split(original_path)
334
- name, ext = base_name.rsplit(".", 1)
335
- new_name = f"{name}_{drive_id}.{ext}"
336
- output_path = os.path.join(dir_name, new_name)
337
-
338
- os.rename(original_path, output_path)
339
-
340
- return output_path
341
-
342
-
343
- def hf_down(url, dir_, hf_token, romanize):
344
- url = url.replace("?download=true", "")
345
- # url = urllib.parse.quote(url, safe=':/') # fix encoding
346
-
347
- filename = unidecode(url.split('/')[-1]) if romanize else url.split('/')[-1]
348
- output_path = os.path.join(dir_, filename)
349
-
350
- if os.path.exists(output_path):
351
- return output_path
352
-
353
- if "/blob/" in url:
354
- url = url.replace("/blob/", "/resolve/")
355
-
356
- if hf_token:
357
- user_header = f'"Authorization: Bearer {hf_token}"'
358
- 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}")
359
- else:
360
- 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}")
361
-
362
- return output_path
363
-
364
-
365
- def download_things(directory, url, hf_token="", civitai_api_key="", romanize=False):
366
- url = url.strip()
367
- downloaded_file_path = None
368
-
369
- if "drive.google.com" in url:
370
- downloaded_file_path = drive_down(url, directory)
371
- elif "huggingface.co" in url:
372
- downloaded_file_path = hf_down(url, directory, hf_token, romanize)
373
- elif "civitai.com" in url:
374
- if not civitai_api_key:
375
- msg = "You need an API key to download Civitai models."
376
- print(f"\033[91m{msg}\033[0m")
377
- gr.Warning(msg)
378
- return None
379
-
380
- url, civ_filename, civ_page = get_civit_params(url)
381
- if civ_page and not IS_ZERO_GPU:
382
- print(f"\033[92mCivitai model: {civ_filename} [page: {civ_page}]\033[0m")
383
-
384
- downloaded_file_path, civ_filename = civ_redirect_down(url, directory, civitai_api_key, romanize, civ_filename)
385
-
386
- if not downloaded_file_path:
387
- msg = (
388
- "Download failed.\n"
389
- "If this is due to an API limit, generating a new API key may resolve the issue.\n"
390
- "Attempting to download using the old method..."
391
- )
392
- print(msg)
393
- gr.Warning(msg)
394
- downloaded_file_path = civ_api_down(url, directory, civitai_api_key, civ_filename)
395
- else:
396
- os.system(f"aria2c --console-log-level=error --summary-interval=10 -c -x 16 -k 1M -s 16 -d {directory} {url}")
397
-
398
- return downloaded_file_path
399
-
400
-
401
- def get_model_list(directory_path):
402
- model_list = []
403
- valid_extensions = {'.ckpt', '.pt', '.pth', '.safetensors', '.bin'}
404
-
405
- for filename in os.listdir(directory_path):
406
- if os.path.splitext(filename)[1] in valid_extensions:
407
- # name_without_extension = os.path.splitext(filename)[0]
408
- file_path = os.path.join(directory_path, filename)
409
- # model_list.append((name_without_extension, file_path))
410
- model_list.append(file_path)
411
- print('\033[34mFILE: ' + file_path + '\033[0m')
412
- return model_list
413
-
414
-
415
- def extract_parameters(input_string):
416
- parameters = {}
417
- input_string = input_string.replace("\n", "")
418
-
419
- if "Negative prompt:" not in input_string:
420
- if "Steps:" in input_string:
421
- input_string = input_string.replace("Steps:", "Negative prompt: Steps:")
422
- else:
423
- msg = "Generation data is invalid."
424
- gr.Warning(msg)
425
- print(msg)
426
- parameters["prompt"] = input_string
427
- return parameters
428
-
429
- parm = input_string.split("Negative prompt:")
430
- parameters["prompt"] = parm[0].strip()
431
- if "Steps:" not in parm[1]:
432
- parameters["neg_prompt"] = parm[1].strip()
433
- return parameters
434
- parm = parm[1].split("Steps:")
435
- parameters["neg_prompt"] = parm[0].strip()
436
- input_string = "Steps:" + parm[1]
437
-
438
- # Extracting Steps
439
- steps_match = re.search(r'Steps: (\d+)', input_string)
440
- if steps_match:
441
- parameters['Steps'] = int(steps_match.group(1))
442
-
443
- # Extracting Size
444
- size_match = re.search(r'Size: (\d+x\d+)', input_string)
445
- if size_match:
446
- parameters['Size'] = size_match.group(1)
447
- width, height = map(int, parameters['Size'].split('x'))
448
- parameters['width'] = width
449
- parameters['height'] = height
450
-
451
- # Extracting other parameters
452
- other_parameters = re.findall(r'([^,:]+): (.*?)(?=, [^,:]+:|$)', input_string)
453
- for param in other_parameters:
454
- parameters[param[0].strip()] = param[1].strip('"')
455
-
456
- return parameters
457
-
458
-
459
- def get_my_lora(link_url, romanize):
460
- l_name = ""
461
- for url in [url.strip() for url in link_url.split(',')]:
462
- if not os.path.exists(f"./loras/{url.split('/')[-1]}"):
463
- l_name = download_things(DIRECTORY_LORAS, url, HF_TOKEN, CIVITAI_API_KEY, romanize)
464
- new_lora_model_list = get_model_list(DIRECTORY_LORAS)
465
- new_lora_model_list.insert(0, "None")
466
- new_lora_model_list = new_lora_model_list + DIFFUSERS_FORMAT_LORAS
467
- msg_lora = "Downloaded"
468
- if l_name:
469
- msg_lora += f": <b>{l_name}</b>"
470
- print(msg_lora)
471
-
472
- try:
473
- # Works with non-Civitai loras.
474
- json_data = read_safetensors_header_from_file(l_name)
475
- metadata_lora = LoraHeaderInformation(json_data)
476
- msg_lora += "<br>" + metadata_lora.to_html()
477
- except Exception:
478
- pass
479
-
480
- return gr.update(
481
- choices=new_lora_model_list
482
- ), gr.update(
483
- choices=new_lora_model_list
484
- ), gr.update(
485
- choices=new_lora_model_list
486
- ), gr.update(
487
- choices=new_lora_model_list
488
- ), gr.update(
489
- choices=new_lora_model_list
490
- ), gr.update(
491
- choices=new_lora_model_list
492
- ), gr.update(
493
- choices=new_lora_model_list
494
- ), gr.update(
495
- value=msg_lora
496
- )
497
-
498
-
499
- def info_html(json_data, title, subtitle):
500
- return f"""
501
- <div style='padding: 0; border-radius: 10px;'>
502
- <p style='margin: 0; font-weight: bold;'>{title}</p>
503
- <details>
504
- <summary>Details</summary>
505
- <p style='margin: 0; font-weight: bold;'>{subtitle}</p>
506
- </details>
507
- </div>
508
- """
509
-
510
-
511
- def get_model_type(repo_id: str):
512
- api = HfApi(token=os.environ.get("HF_TOKEN")) # if use private or gated model
513
- default = "SD 1.5"
514
- try:
515
- if os.path.exists(repo_id):
516
- tag, _, _, _ = checkpoint_model_type(repo_id)
517
- return DIFFUSECRAFT_CHECKPOINT_NAME[tag]
518
- else:
519
- model = api.model_info(repo_id=repo_id, timeout=5.0)
520
- tags = model.tags
521
- for tag in tags:
522
- if tag in MODEL_TYPE_CLASS.keys():
523
- return MODEL_TYPE_CLASS.get(tag, default)
524
-
525
- except Exception:
526
- return default
527
- return default
528
-
529
-
530
- def restart_space(repo_id: str, factory_reboot: bool):
531
- api = HfApi(token=os.environ.get("HF_TOKEN"))
532
- try:
533
- runtime = api.get_space_runtime(repo_id=repo_id)
534
- if runtime.stage == "RUNNING":
535
- api.restart_space(repo_id=repo_id, factory_reboot=factory_reboot)
536
- print(f"Restarting space: {repo_id}")
537
- else:
538
- print(f"Space {repo_id} is in stage: {runtime.stage}")
539
- except Exception as e:
540
- print(e)
541
-
542
-
543
- def extract_exif_data(image):
544
- if image is None:
545
- return ""
546
-
547
- try:
548
- metadata_keys = ['parameters', 'metadata', 'prompt', 'Comment']
549
-
550
- for key in metadata_keys:
551
- if key in image.info:
552
- return image.info[key]
553
-
554
- return str(image.info)
555
-
556
- except Exception as e:
557
- return f"Error extracting metadata: {str(e)}"
558
-
559
-
560
- def create_mask_now(img, invert):
561
- import numpy as np
562
- import time
563
-
564
- time.sleep(0.5)
565
-
566
- transparent_image = img["layers"][0]
567
-
568
- # Extract the alpha channel
569
- alpha_channel = np.array(transparent_image)[:, :, 3]
570
-
571
- # Create a binary mask by thresholding the alpha channel
572
- binary_mask = alpha_channel > 1
573
-
574
- if invert:
575
- print("Invert")
576
- # Invert the binary mask so that the drawn shape is white and the rest is black
577
- binary_mask = np.invert(binary_mask)
578
-
579
- # Convert the binary mask to a 3-channel RGB mask
580
- rgb_mask = np.stack((binary_mask,) * 3, axis=-1)
581
-
582
- # Convert the mask to uint8
583
- rgb_mask = rgb_mask.astype(np.uint8) * 255
584
-
585
- return img["background"], rgb_mask
586
-
587
-
588
- def download_diffuser_repo(repo_name: str, model_type: str, revision: str = "main", token=True):
589
-
590
- variant = None
591
- if token is True and not os.environ.get("HF_TOKEN"):
592
- token = None
593
-
594
- if model_type == "SDXL":
595
- info = model_info_data(
596
- repo_name,
597
- token=token,
598
- revision=revision,
599
- timeout=5.0,
600
- )
601
-
602
- filenames = {sibling.rfilename for sibling in info.siblings}
603
- model_filenames, variant_filenames = variant_compatible_siblings(
604
- filenames, variant="fp16"
605
- )
606
-
607
- if len(variant_filenames):
608
- variant = "fp16"
609
-
610
- if model_type == "FLUX":
611
- cached_folder = snapshot_download(
612
- repo_id=repo_name,
613
- allow_patterns="transformer/*"
614
- )
615
- else:
616
- cached_folder = DiffusionPipeline.download(
617
- pretrained_model_name=repo_name,
618
- force_download=False,
619
- token=token,
620
- revision=revision,
621
- # mirror="https://hf-mirror.com",
622
- variant=variant,
623
- use_safetensors=True,
624
- trust_remote_code=False,
625
- timeout=5.0,
626
- )
627
-
628
- if isinstance(cached_folder, PosixPath):
629
- cached_folder = cached_folder.as_posix()
630
-
631
- # Task model
632
- # from huggingface_hub import hf_hub_download
633
- # hf_hub_download(
634
- # task_model,
635
- # filename="diffusion_pytorch_model.safetensors", # fix fp16 variant
636
- # )
637
-
638
- return cached_folder
639
-
640
-
641
- def get_folder_size_gb(folder_path):
642
- result = subprocess.run(["du", "-s", folder_path], capture_output=True, text=True)
643
-
644
- total_size_kb = int(result.stdout.split()[0])
645
- total_size_gb = total_size_kb / (1024 ** 2)
646
-
647
- return total_size_gb
648
-
649
-
650
- def get_used_storage_gb(path_storage=STORAGE_ROOT):
651
- try:
652
- used_gb = get_folder_size_gb(path_storage)
653
- print(f"Used Storage: {used_gb:.2f} GB")
654
- except Exception as e:
655
- used_gb = 999
656
- print(f"Error while retrieving the used storage: {e}.")
657
-
658
- return used_gb
659
-
660
-
661
- def delete_model(removal_candidate):
662
- print(f"Removing: {removal_candidate}")
663
-
664
- if os.path.exists(removal_candidate):
665
- os.remove(removal_candidate)
666
- else:
667
- diffusers_model = f"{CACHE_HF}{DIRECTORY_MODELS}--{removal_candidate.replace('/', '--')}"
668
- if os.path.isdir(diffusers_model):
669
- shutil.rmtree(diffusers_model)
670
-
671
-
672
- def clear_hf_cache():
673
- """
674
- Clears the entire Hugging Face cache at ~/.cache/huggingface.
675
- Hugging Face will re-download models as needed later.
676
- """
677
- try:
678
- if os.path.exists(CACHE_HF):
679
- shutil.rmtree(CACHE_HF, ignore_errors=True)
680
- print(f"Hugging Face cache cleared: {CACHE_HF}")
681
- else:
682
- print(f"No Hugging Face cache found at: {CACHE_HF}")
683
- except Exception as e:
684
- print(f"Error clearing Hugging Face cache: {e}")
685
-
686
-
687
- def progress_step_bar(step, total):
688
- # Calculate the percentage for the progress bar width
689
- percentage = min(100, ((step / total) * 100))
690
-
691
- return f"""
692
- <div style="position: relative; width: 100%; background-color: gray; border-radius: 5px; overflow: hidden;">
693
- <div style="width: {percentage}%; height: 17px; background-color: #800080; transition: width 0.5s;"></div>
694
- <div style="position: absolute; width: 100%; text-align: center; color: white; top: 0; line-height: 19px; font-size: 13px;">
695
- {int(percentage)}%
696
- </div>
697
- </div>
698
- """
699
-
700
-
701
- def html_template_message(msg):
702
- return f"""
703
- <div style="position: relative; width: 100%; background-color: gray; border-radius: 5px; overflow: hidden;">
704
- <div style="width: 0%; height: 17px; background-color: #800080; transition: width 0.5s;"></div>
705
- <div style="position: absolute; width: 100%; text-align: center; color: white; top: 0; line-height: 19px; font-size: 14px; font-weight: bold; text-shadow: 1px 1px 2px black;">
706
- {msg}
707
- </div>
708
- </div>
709
- """
710
-
711
-
712
- def escape_html(text):
713
- """Escapes HTML special characters in the input text."""
714
- return text.replace("<", "&lt;").replace(">", "&gt;").replace("\n", "<br>")