Spaces:
Running
on
Zero
Running
on
Zero
Update utils.py
#11
by
John6666
- opened
- .gitignore +0 -207
- README.md +1 -1
- app.py +130 -277
- constants.py +36 -146
- image_processor.py +2 -2
- packages.txt +1 -1
- pre-requirements.txt +0 -1
- requirements.txt +3 -11
- utils.py +106 -183
.gitignore
DELETED
@@ -1,207 +0,0 @@
|
|
1 |
-
# Byte-compiled / optimized / DLL files
|
2 |
-
__pycache__/
|
3 |
-
*.py[codz]
|
4 |
-
*$py.class
|
5 |
-
|
6 |
-
# C extensions
|
7 |
-
*.so
|
8 |
-
|
9 |
-
# Distribution / packaging
|
10 |
-
.Python
|
11 |
-
build/
|
12 |
-
develop-eggs/
|
13 |
-
dist/
|
14 |
-
downloads/
|
15 |
-
eggs/
|
16 |
-
.eggs/
|
17 |
-
lib/
|
18 |
-
lib64/
|
19 |
-
parts/
|
20 |
-
sdist/
|
21 |
-
var/
|
22 |
-
wheels/
|
23 |
-
share/python-wheels/
|
24 |
-
*.egg-info/
|
25 |
-
.installed.cfg
|
26 |
-
*.egg
|
27 |
-
MANIFEST
|
28 |
-
|
29 |
-
# PyInstaller
|
30 |
-
# Usually these files are written by a python script from a template
|
31 |
-
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
32 |
-
*.manifest
|
33 |
-
*.spec
|
34 |
-
|
35 |
-
# Installer logs
|
36 |
-
pip-log.txt
|
37 |
-
pip-delete-this-directory.txt
|
38 |
-
|
39 |
-
# Unit test / coverage reports
|
40 |
-
htmlcov/
|
41 |
-
.tox/
|
42 |
-
.nox/
|
43 |
-
.coverage
|
44 |
-
.coverage.*
|
45 |
-
.cache
|
46 |
-
nosetests.xml
|
47 |
-
coverage.xml
|
48 |
-
*.cover
|
49 |
-
*.py.cover
|
50 |
-
.hypothesis/
|
51 |
-
.pytest_cache/
|
52 |
-
cover/
|
53 |
-
|
54 |
-
# Translations
|
55 |
-
*.mo
|
56 |
-
*.pot
|
57 |
-
|
58 |
-
# Django stuff:
|
59 |
-
*.log
|
60 |
-
local_settings.py
|
61 |
-
db.sqlite3
|
62 |
-
db.sqlite3-journal
|
63 |
-
|
64 |
-
# Flask stuff:
|
65 |
-
instance/
|
66 |
-
.webassets-cache
|
67 |
-
|
68 |
-
# Scrapy stuff:
|
69 |
-
.scrapy
|
70 |
-
|
71 |
-
# Sphinx documentation
|
72 |
-
docs/_build/
|
73 |
-
|
74 |
-
# PyBuilder
|
75 |
-
.pybuilder/
|
76 |
-
target/
|
77 |
-
|
78 |
-
# Jupyter Notebook
|
79 |
-
.ipynb_checkpoints
|
80 |
-
|
81 |
-
# IPython
|
82 |
-
profile_default/
|
83 |
-
ipython_config.py
|
84 |
-
|
85 |
-
# pyenv
|
86 |
-
# For a library or package, you might want to ignore these files since the code is
|
87 |
-
# intended to run in multiple environments; otherwise, check them in:
|
88 |
-
# .python-version
|
89 |
-
|
90 |
-
# pipenv
|
91 |
-
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
92 |
-
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
93 |
-
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
94 |
-
# install all needed dependencies.
|
95 |
-
#Pipfile.lock
|
96 |
-
|
97 |
-
# UV
|
98 |
-
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
99 |
-
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
100 |
-
# commonly ignored for libraries.
|
101 |
-
#uv.lock
|
102 |
-
|
103 |
-
# poetry
|
104 |
-
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
105 |
-
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
106 |
-
# commonly ignored for libraries.
|
107 |
-
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
108 |
-
#poetry.lock
|
109 |
-
#poetry.toml
|
110 |
-
|
111 |
-
# pdm
|
112 |
-
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
113 |
-
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
114 |
-
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
115 |
-
#pdm.lock
|
116 |
-
#pdm.toml
|
117 |
-
.pdm-python
|
118 |
-
.pdm-build/
|
119 |
-
|
120 |
-
# pixi
|
121 |
-
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
122 |
-
#pixi.lock
|
123 |
-
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
124 |
-
# in the .venv directory. It is recommended not to include this directory in version control.
|
125 |
-
.pixi
|
126 |
-
|
127 |
-
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
128 |
-
__pypackages__/
|
129 |
-
|
130 |
-
# Celery stuff
|
131 |
-
celerybeat-schedule
|
132 |
-
celerybeat.pid
|
133 |
-
|
134 |
-
# SageMath parsed files
|
135 |
-
*.sage.py
|
136 |
-
|
137 |
-
# Environments
|
138 |
-
.env
|
139 |
-
.envrc
|
140 |
-
.venv
|
141 |
-
env/
|
142 |
-
venv/
|
143 |
-
ENV/
|
144 |
-
env.bak/
|
145 |
-
venv.bak/
|
146 |
-
|
147 |
-
# Spyder project settings
|
148 |
-
.spyderproject
|
149 |
-
.spyproject
|
150 |
-
|
151 |
-
# Rope project settings
|
152 |
-
.ropeproject
|
153 |
-
|
154 |
-
# mkdocs documentation
|
155 |
-
/site
|
156 |
-
|
157 |
-
# mypy
|
158 |
-
.mypy_cache/
|
159 |
-
.dmypy.json
|
160 |
-
dmypy.json
|
161 |
-
|
162 |
-
# Pyre type checker
|
163 |
-
.pyre/
|
164 |
-
|
165 |
-
# pytype static type analyzer
|
166 |
-
.pytype/
|
167 |
-
|
168 |
-
# Cython debug symbols
|
169 |
-
cython_debug/
|
170 |
-
|
171 |
-
# PyCharm
|
172 |
-
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
173 |
-
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
174 |
-
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
175 |
-
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
176 |
-
#.idea/
|
177 |
-
|
178 |
-
# Abstra
|
179 |
-
# Abstra is an AI-powered process automation framework.
|
180 |
-
# Ignore directories containing user credentials, local state, and settings.
|
181 |
-
# Learn more at https://abstra.io/docs
|
182 |
-
.abstra/
|
183 |
-
|
184 |
-
# Visual Studio Code
|
185 |
-
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
|
186 |
-
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
187 |
-
# and can be added to the global gitignore or merged into this file. However, if you prefer,
|
188 |
-
# you could uncomment the following to ignore the entire vscode folder
|
189 |
-
# .vscode/
|
190 |
-
|
191 |
-
# Ruff stuff:
|
192 |
-
.ruff_cache/
|
193 |
-
|
194 |
-
# PyPI configuration file
|
195 |
-
.pypirc
|
196 |
-
|
197 |
-
# Cursor
|
198 |
-
# Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
|
199 |
-
# exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
|
200 |
-
# refer to https://docs.cursor.com/context/ignore-files
|
201 |
-
.cursorignore
|
202 |
-
.cursorindexingignore
|
203 |
-
|
204 |
-
# Marimo
|
205 |
-
marimo/_static/
|
206 |
-
marimo/_lsp/
|
207 |
-
__marimo__/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
README.md
CHANGED
@@ -4,7 +4,7 @@ emoji: 🧩🖼️
|
|
4 |
colorFrom: red
|
5 |
colorTo: pink
|
6 |
sdk: gradio
|
7 |
-
sdk_version:
|
8 |
app_file: app.py
|
9 |
pinned: true
|
10 |
license: mit
|
|
|
4 |
colorFrom: red
|
5 |
colorTo: pink
|
6 |
sdk: gradio
|
7 |
+
sdk_version: 4.31.3
|
8 |
app_file: app.py
|
9 |
pinned: true
|
10 |
license: mit
|
app.py
CHANGED
@@ -1,21 +1,17 @@
|
|
1 |
import spaces
|
2 |
import os
|
3 |
-
from argparse import ArgumentParser
|
4 |
from stablepy import (
|
5 |
Model_Diffusers,
|
6 |
SCHEDULE_TYPE_OPTIONS,
|
7 |
SCHEDULE_PREDICTION_TYPE_OPTIONS,
|
8 |
check_scheduler_compatibility,
|
9 |
TASK_AND_PREPROCESSORS,
|
10 |
-
FACE_RESTORATION_MODELS,
|
11 |
-
scheduler_names,
|
12 |
)
|
13 |
from constants import (
|
14 |
DIRECTORY_MODELS,
|
15 |
DIRECTORY_LORAS,
|
16 |
DIRECTORY_VAES,
|
17 |
DIRECTORY_EMBEDS,
|
18 |
-
DIRECTORY_UPSCALERS,
|
19 |
DOWNLOAD_MODEL,
|
20 |
DOWNLOAD_VAE,
|
21 |
DOWNLOAD_LORA,
|
@@ -39,13 +35,15 @@ from constants import (
|
|
39 |
EXAMPLES_GUI,
|
40 |
RESOURCES,
|
41 |
DIFFUSERS_CONTROLNET_MODEL,
|
42 |
-
IP_MODELS,
|
43 |
-
MODE_IP_OPTIONS,
|
44 |
-
CACHE_HF_ROOT,
|
45 |
)
|
46 |
from stablepy.diffusers_vanilla.style_prompt_config import STYLE_NAMES
|
47 |
import torch
|
48 |
import re
|
|
|
|
|
|
|
|
|
|
|
49 |
import time
|
50 |
from PIL import ImageFile
|
51 |
from utils import (
|
@@ -62,7 +60,6 @@ from utils import (
|
|
62 |
progress_step_bar,
|
63 |
html_template_message,
|
64 |
escape_html,
|
65 |
-
clear_hf_cache,
|
66 |
)
|
67 |
from image_processor import preprocessor_tab
|
68 |
from datetime import datetime
|
@@ -73,35 +70,31 @@ import warnings
|
|
73 |
from stablepy import logger
|
74 |
from diffusers import FluxPipeline
|
75 |
# import urllib.parse
|
76 |
-
import subprocess
|
77 |
-
|
78 |
-
IS_ZERO_GPU = bool(os.getenv("SPACES_ZERO_GPU"))
|
79 |
-
if IS_ZERO_GPU:
|
80 |
-
subprocess.run("rm -rf /data-nvme/zerogpu-offload/*", env={}, shell=True)
|
81 |
-
IS_GPU_MODE = True if IS_ZERO_GPU else (True if torch.cuda.is_available() else False)
|
82 |
-
img_path = "./images/"
|
83 |
-
allowed_path = os.path.abspath(img_path)
|
84 |
-
delete_cache_time = (9600, 9600) if IS_ZERO_GPU else (86400, 86400)
|
85 |
|
86 |
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
87 |
torch.backends.cuda.matmul.allow_tf32 = True
|
88 |
# os.environ["PYTORCH_NO_CUDA_MEMORY_CACHING"] = "1"
|
|
|
89 |
|
90 |
-
directories = [DIRECTORY_MODELS, DIRECTORY_LORAS, DIRECTORY_VAES, DIRECTORY_EMBEDS
|
91 |
for directory in directories:
|
92 |
os.makedirs(directory, exist_ok=True)
|
93 |
|
94 |
# Download stuffs
|
95 |
for url in [url.strip() for url in DOWNLOAD_MODEL.split(',')]:
|
96 |
-
|
|
|
97 |
for url in [url.strip() for url in DOWNLOAD_VAE.split(',')]:
|
98 |
-
|
|
|
99 |
for url in [url.strip() for url in DOWNLOAD_LORA.split(',')]:
|
100 |
-
|
|
|
101 |
|
102 |
# Download Embeddings
|
103 |
for url_embed in DOWNLOAD_EMBEDS:
|
104 |
-
|
|
|
105 |
|
106 |
# Build list models
|
107 |
embed_list = get_model_list(DIRECTORY_EMBEDS)
|
@@ -119,16 +112,15 @@ vae_model_list.insert(0, "None")
|
|
119 |
|
120 |
print('\033[33m🏁 Download and listing of valid models completed.\033[0m')
|
121 |
|
122 |
-
|
123 |
-
|
124 |
-
flux_repo
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
delete_model(flux_repo)
|
132 |
|
133 |
#######################
|
134 |
# GUI
|
@@ -138,17 +130,7 @@ diffusers.utils.logging.set_verbosity(40)
|
|
138 |
warnings.filterwarnings(action="ignore", category=FutureWarning, module="diffusers")
|
139 |
warnings.filterwarnings(action="ignore", category=UserWarning, module="diffusers")
|
140 |
warnings.filterwarnings(action="ignore", category=FutureWarning, module="transformers")
|
141 |
-
|
142 |
-
parser = ArgumentParser(description='DiffuseCraft: Create images from text prompts.', add_help=True)
|
143 |
-
parser.add_argument("--share", action="store_true", dest="share_enabled", default=False, help="Enable sharing")
|
144 |
-
parser.add_argument('--theme', type=str, default="NoCrypt/miku", help='Set the theme (default: NoCrypt/miku)')
|
145 |
-
parser.add_argument("--ssr", action="store_true", help="Enable SSR (Server-Side Rendering)")
|
146 |
-
parser.add_argument("--log-level", type=str, default="INFO", choices=["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"], help="Set logging level (default: INFO)")
|
147 |
-
args = parser.parse_args()
|
148 |
-
|
149 |
-
logger.setLevel(
|
150 |
-
"INFO" if IS_ZERO_GPU else getattr(logging, args.log_level.upper())
|
151 |
-
)
|
152 |
|
153 |
CSS = """
|
154 |
.contain { display: flex; flex-direction: column; }
|
@@ -158,12 +140,6 @@ CSS = """
|
|
158 |
"""
|
159 |
|
160 |
|
161 |
-
def lora_chk(lora_):
|
162 |
-
if isinstance(lora_, str) and lora_.strip() not in ["", "None"]:
|
163 |
-
return lora_
|
164 |
-
return None
|
165 |
-
|
166 |
-
|
167 |
class GuiSD:
|
168 |
def __init__(self, stream=True):
|
169 |
self.model = None
|
@@ -179,15 +155,6 @@ class GuiSD:
|
|
179 |
removal_candidate = self.inventory.pop(0)
|
180 |
delete_model(removal_candidate)
|
181 |
|
182 |
-
# Cleanup after 60 seconds of inactivity
|
183 |
-
lowPrioCleanup = max((datetime.now() - self.last_load).total_seconds(), 0) > 60
|
184 |
-
if lowPrioCleanup and not self.status_loading and get_used_storage_gb(CACHE_HF_ROOT) > (storage_floor_gb * 2):
|
185 |
-
print("Cleaning up Hugging Face cache...")
|
186 |
-
clear_hf_cache()
|
187 |
-
self.inventory = [
|
188 |
-
m for m in self.inventory if os.path.exists(m)
|
189 |
-
]
|
190 |
-
|
191 |
def update_inventory(self, model_name):
|
192 |
if model_name not in single_file_model_list:
|
193 |
self.inventory = [
|
@@ -198,21 +165,14 @@ class GuiSD:
|
|
198 |
def load_new_model(self, model_name, vae_model, task, controlnet_model, progress=gr.Progress(track_tqdm=True)):
|
199 |
|
200 |
# download link model > model_name
|
201 |
-
if model_name.startswith("http"):
|
202 |
-
yield f"Downloading model: {model_name}"
|
203 |
-
model_name = download_things(DIRECTORY_MODELS, model_name, HF_TOKEN, CIVITAI_API_KEY)
|
204 |
-
if not model_name:
|
205 |
-
raise ValueError("Error retrieving model information from URL")
|
206 |
|
207 |
-
|
208 |
-
self.update_storage_models()
|
209 |
|
210 |
vae_model = vae_model if vae_model != "None" else None
|
211 |
model_type = get_model_type(model_name)
|
212 |
dtype_model = torch.bfloat16 if model_type == "FLUX" else torch.float16
|
213 |
|
214 |
if not os.path.exists(model_name):
|
215 |
-
logger.debug(f"model_name={model_name}, vae_model={vae_model}, task={task}, controlnet_model={controlnet_model}")
|
216 |
_ = download_diffuser_repo(
|
217 |
repo_name=model_name,
|
218 |
model_type=model_type,
|
@@ -238,7 +198,10 @@ class GuiSD:
|
|
238 |
yield f"Loading model: {model_name}"
|
239 |
|
240 |
if vae_model == "BakedVAE":
|
241 |
-
|
|
|
|
|
|
|
242 |
elif vae_model:
|
243 |
vae_type = "SDXL" if "sdxl" in vae_model.lower() else "SD 1.5"
|
244 |
if model_type != vae_type:
|
@@ -257,10 +220,10 @@ class GuiSD:
|
|
257 |
type_model_precision=dtype_model,
|
258 |
retain_task_model_in_cache=False,
|
259 |
controlnet_model=controlnet_model,
|
260 |
-
device="cpu"
|
261 |
env_components=components,
|
262 |
)
|
263 |
-
self.model.advanced_params(image_preprocessor_cuda_active=
|
264 |
else:
|
265 |
if self.model.base_model_id != model_name:
|
266 |
load_now_time = datetime.now()
|
@@ -270,8 +233,7 @@ class GuiSD:
|
|
270 |
print("Waiting for the previous model's time ops...")
|
271 |
time.sleep(9 - elapsed_time)
|
272 |
|
273 |
-
|
274 |
-
self.model.device = torch.device("cpu")
|
275 |
self.model.load_pipe(
|
276 |
model_name,
|
277 |
task_name=TASK_STABLEPY[task],
|
@@ -348,8 +310,8 @@ class GuiSD:
|
|
348 |
syntax_weights,
|
349 |
upscaler_model_path,
|
350 |
upscaler_increases_size,
|
351 |
-
|
352 |
-
|
353 |
hires_steps,
|
354 |
hires_denoising_strength,
|
355 |
hires_sampler,
|
@@ -413,9 +375,6 @@ class GuiSD:
|
|
413 |
mode_ip2,
|
414 |
scale_ip2,
|
415 |
pag_scale,
|
416 |
-
face_restoration_model,
|
417 |
-
face_restoration_visibility,
|
418 |
-
face_restoration_weight,
|
419 |
):
|
420 |
info_state = html_template_message("Navigating latent space...")
|
421 |
yield info_state, gr.update(), gr.update()
|
@@ -425,7 +384,7 @@ class GuiSD:
|
|
425 |
vae_msg = f"VAE: {vae_model}" if vae_model else ""
|
426 |
msg_lora = ""
|
427 |
|
428 |
-
|
429 |
|
430 |
task = TASK_STABLEPY[task]
|
431 |
|
@@ -454,20 +413,23 @@ class GuiSD:
|
|
454 |
self.model.stream_config(concurrency=concurrency, latent_resize_by=1, vae_decoding=False)
|
455 |
|
456 |
if task != "txt2img" and not image_control:
|
457 |
-
raise ValueError("
|
458 |
|
459 |
-
if task
|
460 |
-
raise ValueError("
|
461 |
|
462 |
-
if
|
463 |
upscaler_model = upscaler_model_path
|
464 |
else:
|
|
|
|
|
|
|
465 |
url_upscaler = UPSCALER_DICT_GUI[upscaler_model_path]
|
466 |
|
467 |
-
if not os.path.exists(f"./
|
468 |
-
download_things(
|
469 |
|
470 |
-
upscaler_model = f"./
|
471 |
|
472 |
logging.getLogger("ultralytics").setLevel(logging.INFO if adetailer_verbose else logging.ERROR)
|
473 |
|
@@ -523,19 +485,19 @@ class GuiSD:
|
|
523 |
"distance_threshold": distance_threshold,
|
524 |
"recolor_gamma_correction": float(recolor_gamma_correction),
|
525 |
"tile_blur_sigma": int(tile_blur_sigma),
|
526 |
-
"lora_A":
|
527 |
"lora_scale_A": lora_scale1,
|
528 |
-
"lora_B":
|
529 |
"lora_scale_B": lora_scale2,
|
530 |
-
"lora_C":
|
531 |
"lora_scale_C": lora_scale3,
|
532 |
-
"lora_D":
|
533 |
"lora_scale_D": lora_scale4,
|
534 |
-
"lora_E":
|
535 |
"lora_scale_E": lora_scale5,
|
536 |
-
"lora_F":
|
537 |
"lora_scale_F": lora_scale6,
|
538 |
-
"lora_G":
|
539 |
"lora_scale_G": lora_scale7,
|
540 |
"textual_inversion": embed_list if textual_inversion else [],
|
541 |
"syntax_weights": syntax_weights, # "Classic"
|
@@ -569,8 +531,8 @@ class GuiSD:
|
|
569 |
"t2i_adapter_conditioning_factor": float(t2i_adapter_conditioning_factor),
|
570 |
"upscaler_model_path": upscaler_model,
|
571 |
"upscaler_increases_size": upscaler_increases_size,
|
572 |
-
"
|
573 |
-
"
|
574 |
"hires_steps": hires_steps,
|
575 |
"hires_denoising_strength": hires_denoising_strength,
|
576 |
"hires_prompt": hires_prompt,
|
@@ -585,19 +547,16 @@ class GuiSD:
|
|
585 |
"ip_adapter_model": params_ip_model,
|
586 |
"ip_adapter_mode": params_ip_mode,
|
587 |
"ip_adapter_scale": params_ip_scale,
|
588 |
-
"face_restoration_model": face_restoration_model,
|
589 |
-
"face_restoration_visibility": face_restoration_visibility,
|
590 |
-
"face_restoration_weight": face_restoration_weight,
|
591 |
}
|
592 |
|
593 |
# kwargs for diffusers pipeline
|
594 |
if guidance_rescale:
|
595 |
pipe_params["guidance_rescale"] = guidance_rescale
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
|
602 |
actual_progress = 0
|
603 |
info_images = gr.update()
|
@@ -627,7 +586,7 @@ class GuiSD:
|
|
627 |
|
628 |
download_links = "<br>".join(
|
629 |
[
|
630 |
-
f'<a href="{path.replace("/images/",
|
631 |
for i, path in enumerate(image_path)
|
632 |
]
|
633 |
)
|
@@ -735,27 +694,22 @@ def sd_gen_generate_pipeline(*args):
|
|
735 |
|
736 |
|
737 |
@spaces.GPU(duration=15)
|
738 |
-
def
|
739 |
-
if image is None:
|
740 |
-
return None
|
741 |
|
742 |
from stablepy.diffusers_vanilla.utils import save_pil_image_with_metadata
|
743 |
-
from stablepy import
|
744 |
|
745 |
-
image = image.convert("RGB")
|
746 |
exif_image = extract_exif_data(image)
|
747 |
|
748 |
-
|
749 |
-
|
750 |
-
|
751 |
-
|
752 |
-
|
753 |
-
download_things(DIRECTORY_UPSCALERS, name_upscaler, HF_TOKEN)
|
754 |
-
|
755 |
-
name_upscaler = f"./{DIRECTORY_UPSCALERS}/{name_upscaler.split('/')[-1]}"
|
756 |
|
757 |
-
scaler_beta =
|
758 |
-
image_up = scaler_beta.upscale(image, upscaler_size,
|
759 |
|
760 |
image_path = save_pil_image_with_metadata(image_up, f'{os.getcwd()}/up_images', exif_image)
|
761 |
|
@@ -763,11 +717,11 @@ def process_upscale(image, upscaler_name, upscaler_size):
|
|
763 |
|
764 |
|
765 |
# https://huggingface.co/spaces/BestWishYsh/ConsisID-preview-Space/discussions/1#674969a022b99c122af5d407
|
766 |
-
|
767 |
-
|
768 |
sd_gen = GuiSD()
|
769 |
|
770 |
-
with gr.Blocks(theme=
|
771 |
gr.Markdown("# 🧩 DiffuseCraft")
|
772 |
gr.Markdown(SUBTITLE_GUI)
|
773 |
with gr.Tab("Generation"):
|
@@ -816,7 +770,7 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
|
|
816 |
|
817 |
actual_task_info = gr.HTML()
|
818 |
|
819 |
-
with gr.Row(equal_height=False, variant="default"
|
820 |
gpu_duration_gui = gr.Number(minimum=5, maximum=240, value=59, show_label=False, container=False, info="GPU time duration (seconds)")
|
821 |
with gr.Column():
|
822 |
verbose_info_gui = gr.Checkbox(value=False, container=False, label="Status info")
|
@@ -852,22 +806,7 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
|
|
852 |
"Schedule type": gr.update(value="Automatic"),
|
853 |
"PAG": gr.update(value=.0),
|
854 |
"FreeU": gr.update(value=False),
|
855 |
-
"Hires upscaler": gr.update(),
|
856 |
-
"Hires upscale": gr.update(),
|
857 |
-
"Hires steps": gr.update(),
|
858 |
-
"Hires denoising strength": gr.update(),
|
859 |
-
"Hires CFG": gr.update(),
|
860 |
-
"Hires sampler": gr.update(),
|
861 |
-
"Hires schedule type": gr.update(),
|
862 |
-
"Image resolution": gr.update(value=1024),
|
863 |
-
"Strength": gr.update(),
|
864 |
}
|
865 |
-
|
866 |
-
# Generate up to 7 LoRAs
|
867 |
-
for i in range(1, 8):
|
868 |
-
valid_receptors[f"Lora_{i}"] = gr.update()
|
869 |
-
valid_receptors[f"Lora_scale_{i}"] = gr.update()
|
870 |
-
|
871 |
valid_keys = list(valid_receptors.keys())
|
872 |
|
873 |
parameters = extract_parameters(base_prompt)
|
@@ -881,36 +820,6 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
|
|
881 |
parameters["Sampler"] = value_sampler
|
882 |
parameters["Schedule type"] = s_type
|
883 |
|
884 |
-
params_lora = []
|
885 |
-
if ">" in parameters["prompt"] and "<" in parameters["prompt"]:
|
886 |
-
params_lora = re.findall(r'<lora:[^>]+>', parameters["prompt"])
|
887 |
-
if "Loras" in parameters:
|
888 |
-
params_lora += re.findall(r'<lora:[^>]+>', parameters["Loras"])
|
889 |
-
|
890 |
-
if params_lora:
|
891 |
-
parsed_params = []
|
892 |
-
for tag_l in params_lora:
|
893 |
-
try:
|
894 |
-
inner = tag_l.strip("<>") # remove < >
|
895 |
-
_, data_l = inner.split(":", 1) # remove the "lora:" part
|
896 |
-
parts_l = data_l.split(":")
|
897 |
-
|
898 |
-
name_l = parts_l[0]
|
899 |
-
weight_l = float(parts_l[1]) if len(parts_l) > 1 else 1.0 # default weight = 1.0
|
900 |
-
|
901 |
-
parsed_params.append((name_l, weight_l))
|
902 |
-
except Exception as e:
|
903 |
-
print(f"Error parsing LoRA tag {tag_l}: {e}")
|
904 |
-
|
905 |
-
num_lora = 1
|
906 |
-
for parsed_l, parsed_s in parsed_params:
|
907 |
-
filtered_loras = [m for m in lora_model_list if parsed_l in m]
|
908 |
-
if filtered_loras:
|
909 |
-
parameters[f"Lora_{num_lora}"] = filtered_loras[0]
|
910 |
-
parameters[f"Lora_scale_{num_lora}"] = parsed_s
|
911 |
-
num_lora += 1
|
912 |
-
|
913 |
-
# continue = discard new value
|
914 |
for key, val in parameters.items():
|
915 |
# print(val)
|
916 |
if key in valid_keys:
|
@@ -918,12 +827,9 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
|
|
918 |
if key == "Sampler":
|
919 |
if val not in scheduler_names:
|
920 |
continue
|
921 |
-
if key
|
922 |
if val not in SCHEDULE_TYPE_OPTIONS:
|
923 |
-
|
924 |
-
if key == "Hires sampler":
|
925 |
-
if val not in POST_PROCESSING_SAMPLER:
|
926 |
-
continue
|
927 |
elif key == "Clip skip":
|
928 |
if "," in str(val):
|
929 |
val = val.replace(",", "")
|
@@ -931,15 +837,15 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
|
|
931 |
val = True
|
932 |
if key == "prompt":
|
933 |
if ">" in val and "<" in val:
|
934 |
-
val = re.sub(r'<[^>]+>', '', val)
|
935 |
print("Removed LoRA written in the prompt")
|
936 |
if key in ["prompt", "neg_prompt"]:
|
937 |
val = re.sub(r'\s+', ' ', re.sub(r',+', ',', val)).strip()
|
938 |
-
if key in ["Steps", "width", "height", "Seed"
|
939 |
val = int(val)
|
940 |
if key == "FreeU":
|
941 |
val = True
|
942 |
-
if key in ["CFG scale", "PAG"
|
943 |
val = float(val)
|
944 |
if key == "Model":
|
945 |
filtered_models = [m for m in model_list if val in m]
|
@@ -947,12 +853,8 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
|
|
947 |
val = filtered_models[0]
|
948 |
else:
|
949 |
val = name_model
|
950 |
-
if key == "Hires upscaler":
|
951 |
-
if val not in UPSCALER_KEYS:
|
952 |
-
continue
|
953 |
if key == "Seed":
|
954 |
continue
|
955 |
-
|
956 |
valid_receptors[key] = gr.update(value=val)
|
957 |
# print(val, type(val))
|
958 |
# print(valid_receptors)
|
@@ -960,6 +862,24 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
|
|
960 |
print(str(e))
|
961 |
return [value for value in valid_receptors.values()]
|
962 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
963 |
def run_clear_prompt_gui():
|
964 |
return gr.update(value=""), gr.update(value="")
|
965 |
clear_prompt_gui.click(
|
@@ -972,7 +892,7 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
|
|
972 |
run_set_random_seed, [], seed_gui
|
973 |
)
|
974 |
|
975 |
-
num_images_gui = gr.Slider(minimum=1, maximum=
|
976 |
prompt_syntax_gui = gr.Dropdown(label="Prompt Syntax", choices=PROMPT_W_OPTIONS, value=PROMPT_W_OPTIONS[1][1])
|
977 |
vae_model_gui = gr.Dropdown(label="VAE Model", choices=vae_model_list, value=vae_model_list[0])
|
978 |
|
@@ -980,8 +900,8 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
|
|
980 |
|
981 |
upscaler_model_path_gui = gr.Dropdown(label="Upscaler", choices=UPSCALER_KEYS, value=UPSCALER_KEYS[0])
|
982 |
upscaler_increases_size_gui = gr.Slider(minimum=1.1, maximum=4., step=0.1, value=1.2, label="Upscale by")
|
983 |
-
|
984 |
-
|
985 |
hires_steps_gui = gr.Slider(minimum=0, value=30, maximum=100, step=1, label="Hires Steps")
|
986 |
hires_denoising_strength_gui = gr.Slider(minimum=0.1, maximum=1.0, step=0.01, value=0.55, label="Hires Denoising Strength")
|
987 |
hires_sampler_gui = gr.Dropdown(label="Hires Sampler", choices=POST_PROCESSING_SAMPLER, value=POST_PROCESSING_SAMPLER[0])
|
@@ -997,8 +917,7 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
|
|
997 |
return gr.Dropdown(label=label, choices=lora_model_list, value="None", allow_custom_value=True, visible=visible)
|
998 |
|
999 |
def lora_scale_slider(label, visible=True):
|
1000 |
-
|
1001 |
-
return gr.Slider(minimum=-val_lora, maximum=val_lora, step=0.01, value=0.33, label=label, visible=visible)
|
1002 |
|
1003 |
lora1_gui = lora_dropdown("Lora1")
|
1004 |
lora_scale_1_gui = lora_scale_slider("Lora Scale 1")
|
@@ -1010,10 +929,10 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
|
|
1010 |
lora_scale_4_gui = lora_scale_slider("Lora Scale 4")
|
1011 |
lora5_gui = lora_dropdown("Lora5")
|
1012 |
lora_scale_5_gui = lora_scale_slider("Lora Scale 5")
|
1013 |
-
lora6_gui = lora_dropdown("Lora6", visible=
|
1014 |
-
lora_scale_6_gui = lora_scale_slider("Lora Scale 6", visible=
|
1015 |
-
lora7_gui = lora_dropdown("Lora7", visible=
|
1016 |
-
lora_scale_7_gui = lora_scale_slider("Lora Scale 7", visible=
|
1017 |
|
1018 |
with gr.Accordion("From URL", open=False, visible=True):
|
1019 |
text_lora = gr.Textbox(
|
@@ -1022,7 +941,7 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
|
|
1022 |
lines=1,
|
1023 |
info="It has to be .safetensors files, and you can also download them from Hugging Face.",
|
1024 |
)
|
1025 |
-
romanize_text = gr.Checkbox(value=False, label="Transliterate name", visible=
|
1026 |
button_lora = gr.Button("Get and Refresh the LoRA Lists")
|
1027 |
new_lora_status = gr.HTML()
|
1028 |
button_lora.click(
|
@@ -1031,16 +950,11 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
|
|
1031 |
[lora1_gui, lora2_gui, lora3_gui, lora4_gui, lora5_gui, lora6_gui, lora7_gui, new_lora_status]
|
1032 |
)
|
1033 |
|
1034 |
-
with gr.Accordion("Face restoration", open=False, visible=True):
|
1035 |
-
|
1036 |
-
face_rest_options = [None] + FACE_RESTORATION_MODELS
|
1037 |
-
|
1038 |
-
face_restoration_model_gui = gr.Dropdown(label="Face restoration model", choices=face_rest_options, value=face_rest_options[0])
|
1039 |
-
face_restoration_visibility_gui = gr.Slider(minimum=0., maximum=1., step=0.001, value=1., label="Visibility")
|
1040 |
-
face_restoration_weight_gui = gr.Slider(minimum=0., maximum=1., step=0.001, value=.5, label="Weight", info="(0 = maximum effect, 1 = minimum effect)")
|
1041 |
-
|
1042 |
with gr.Accordion("IP-Adapter", open=False, visible=True):
|
1043 |
|
|
|
|
|
|
|
1044 |
with gr.Accordion("IP-Adapter 1", open=False, visible=True):
|
1045 |
image_ip1 = gr.Image(label="IP Image", type="filepath")
|
1046 |
mask_ip1 = gr.Image(label="IP Mask", type="filepath")
|
@@ -1059,13 +973,13 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
|
|
1059 |
image_mask_gui = gr.Image(label="Image Mask", type="filepath")
|
1060 |
strength_gui = gr.Slider(
|
1061 |
minimum=0.01, maximum=1.0, step=0.01, value=0.55, label="Strength",
|
1062 |
-
info="This option adjusts the level of changes for img2img
|
1063 |
)
|
1064 |
image_resolution_gui = gr.Slider(
|
1065 |
minimum=64, maximum=2048, step=64, value=1024, label="Image Resolution",
|
1066 |
info="The maximum proportional size of the generated image based on the uploaded image."
|
1067 |
)
|
1068 |
-
controlnet_model_gui = gr.Dropdown(label="ControlNet model", choices=DIFFUSERS_CONTROLNET_MODEL, value=DIFFUSERS_CONTROLNET_MODEL[0]
|
1069 |
control_net_output_scaling_gui = gr.Slider(minimum=0, maximum=5.0, step=0.1, value=1, label="ControlNet Output Scaling in UNet")
|
1070 |
control_net_start_threshold_gui = gr.Slider(minimum=0, maximum=1, step=0.01, value=0, label="ControlNet Start Threshold (%)")
|
1071 |
control_net_stop_threshold_gui = gr.Slider(minimum=0, maximum=1, step=0.01, value=1, label="ControlNet Stop Threshold (%)")
|
@@ -1087,8 +1001,8 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
|
|
1087 |
preprocess_resolution_gui = gr.Slider(minimum=64, maximum=2048, step=64, value=512, label="Preprocessor Resolution")
|
1088 |
low_threshold_gui = gr.Slider(minimum=1, maximum=255, step=1, value=100, label="'CANNY' low threshold")
|
1089 |
high_threshold_gui = gr.Slider(minimum=1, maximum=255, step=1, value=200, label="'CANNY' high threshold")
|
1090 |
-
value_threshold_gui = gr.Slider(minimum=
|
1091 |
-
distance_threshold_gui = gr.Slider(minimum=
|
1092 |
recolor_gamma_correction_gui = gr.Number(minimum=0., maximum=25., value=1., step=0.001, label="'RECOLOR' gamma correction")
|
1093 |
tile_blur_sigma_gui = gr.Number(minimum=0, maximum=100, value=9, step=1, label="'TILE' blur sigma")
|
1094 |
|
@@ -1123,7 +1037,7 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
|
|
1123 |
gr.Info(f"{len(sd_gen.model.STYLE_NAMES)} styles loaded")
|
1124 |
return gr.update(value=None, choices=sd_gen.model.STYLE_NAMES)
|
1125 |
|
1126 |
-
style_button.click(load_json_style_file, [style_json_gui], [style_prompt_gui])
|
1127 |
|
1128 |
with gr.Accordion("Textual inversion", open=False, visible=False):
|
1129 |
active_textual_inversion_gui = gr.Checkbox(value=False, label="Active Textual Inversion in prompt")
|
@@ -1173,62 +1087,20 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
|
|
1173 |
hires_before_adetailer_gui = gr.Checkbox(value=False, label="Hires Before Adetailer")
|
1174 |
hires_after_adetailer_gui = gr.Checkbox(value=True, label="Hires After Adetailer")
|
1175 |
generator_in_cpu_gui = gr.Checkbox(value=False, label="Generator in CPU")
|
1176 |
-
with gr.Column(visible=(not IS_ZERO_GPU)):
|
1177 |
-
image_storage_location_gui = gr.Textbox(value=img_path, label="Image Storage Location")
|
1178 |
-
disable_progress_bar_gui = gr.Checkbox(value=False, label="Disable Progress Bar")
|
1179 |
-
leave_progress_bar_gui = gr.Checkbox(value=True, label="Leave Progress Bar")
|
1180 |
|
1181 |
with gr.Accordion("More settings", open=False, visible=False):
|
1182 |
loop_generation_gui = gr.Slider(minimum=1, value=1, label="Loop Generation")
|
1183 |
retain_task_cache_gui = gr.Checkbox(value=False, label="Retain task model in cache")
|
|
|
|
|
1184 |
display_images_gui = gr.Checkbox(value=False, label="Display Images")
|
1185 |
image_previews_gui = gr.Checkbox(value=True, label="Image Previews")
|
|
|
1186 |
retain_compel_previous_load_gui = gr.Checkbox(value=False, label="Retain Compel Previous Load")
|
1187 |
retain_detailfix_model_previous_load_gui = gr.Checkbox(value=False, label="Retain Detailfix Model Previous Load")
|
1188 |
retain_hires_model_previous_load_gui = gr.Checkbox(value=False, label="Retain Hires Model Previous Load")
|
1189 |
xformers_memory_efficient_attention_gui = gr.Checkbox(value=False, label="Xformers Memory Efficient Attention")
|
1190 |
|
1191 |
-
set_params_gui.click(
|
1192 |
-
run_set_params_gui, [prompt_gui, model_name_gui], [
|
1193 |
-
prompt_gui,
|
1194 |
-
neg_prompt_gui,
|
1195 |
-
steps_gui,
|
1196 |
-
img_width_gui,
|
1197 |
-
img_height_gui,
|
1198 |
-
seed_gui,
|
1199 |
-
sampler_gui,
|
1200 |
-
cfg_gui,
|
1201 |
-
clip_skip_gui,
|
1202 |
-
model_name_gui,
|
1203 |
-
schedule_type_gui,
|
1204 |
-
pag_scale_gui,
|
1205 |
-
free_u_gui,
|
1206 |
-
upscaler_model_path_gui,
|
1207 |
-
upscaler_increases_size_gui,
|
1208 |
-
hires_steps_gui,
|
1209 |
-
hires_denoising_strength_gui,
|
1210 |
-
hires_guidance_scale_gui,
|
1211 |
-
hires_sampler_gui,
|
1212 |
-
hires_schedule_type_gui,
|
1213 |
-
image_resolution_gui,
|
1214 |
-
strength_gui,
|
1215 |
-
lora1_gui,
|
1216 |
-
lora_scale_1_gui,
|
1217 |
-
lora2_gui,
|
1218 |
-
lora_scale_2_gui,
|
1219 |
-
lora3_gui,
|
1220 |
-
lora_scale_3_gui,
|
1221 |
-
lora4_gui,
|
1222 |
-
lora_scale_4_gui,
|
1223 |
-
lora5_gui,
|
1224 |
-
lora_scale_5_gui,
|
1225 |
-
lora6_gui,
|
1226 |
-
lora_scale_6_gui,
|
1227 |
-
lora7_gui,
|
1228 |
-
lora_scale_7_gui,
|
1229 |
-
],
|
1230 |
-
)
|
1231 |
-
|
1232 |
with gr.Accordion("Examples and help", open=False, visible=True):
|
1233 |
gr.Markdown(HELP_GUI)
|
1234 |
gr.Markdown(EXAMPLES_GUI_HELP)
|
@@ -1284,21 +1156,10 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
|
|
1284 |
# "hsl(360, 120, 120)" # in fact any valid colorstring
|
1285 |
]
|
1286 |
),
|
1287 |
-
eraser=gr.Eraser(default_size="16")
|
1288 |
-
render=True,
|
1289 |
-
visible=False,
|
1290 |
-
interactive=False,
|
1291 |
)
|
1292 |
-
|
1293 |
-
show_canvas = gr.Button("SHOW INPAINT CANVAS")
|
1294 |
-
|
1295 |
-
def change_visibility_canvas():
|
1296 |
-
return gr.update(visible=True, interactive=True), gr.update(visible=False)
|
1297 |
-
show_canvas.click(change_visibility_canvas, [], [image_base, show_canvas])
|
1298 |
-
|
1299 |
invert_mask = gr.Checkbox(value=False, label="Invert mask")
|
1300 |
btn = gr.Button("Create mask")
|
1301 |
-
|
1302 |
with gr.Column(scale=1):
|
1303 |
img_source = gr.Image(interactive=False)
|
1304 |
img_result = gr.Image(label="Mask image", show_label=True, interactive=False)
|
@@ -1329,11 +1190,8 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
|
|
1329 |
|
1330 |
with gr.Row():
|
1331 |
with gr.Column():
|
1332 |
-
|
1333 |
-
USCALER_TAB_KEYS = [name for name in UPSCALER_KEYS[9:]]
|
1334 |
-
|
1335 |
image_up_tab = gr.Image(label="Image", type="pil", sources=["upload"])
|
1336 |
-
upscaler_tab = gr.Dropdown(label="Upscaler", choices=
|
1337 |
upscaler_size_tab = gr.Slider(minimum=1., maximum=4., step=0.1, value=1.1, label="Upscale by")
|
1338 |
generate_button_up_tab = gr.Button(value="START UPSCALE", variant="primary")
|
1339 |
|
@@ -1341,7 +1199,7 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
|
|
1341 |
result_up_tab = gr.Image(label="Result", type="pil", interactive=False, format="png")
|
1342 |
|
1343 |
generate_button_up_tab.click(
|
1344 |
-
fn=
|
1345 |
inputs=[image_up_tab, upscaler_tab, upscaler_size_tab],
|
1346 |
outputs=[result_up_tab],
|
1347 |
)
|
@@ -1413,8 +1271,8 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
|
|
1413 |
prompt_syntax_gui,
|
1414 |
upscaler_model_path_gui,
|
1415 |
upscaler_increases_size_gui,
|
1416 |
-
|
1417 |
-
|
1418 |
hires_steps_gui,
|
1419 |
hires_denoising_strength_gui,
|
1420 |
hires_sampler_gui,
|
@@ -1478,9 +1336,6 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
|
|
1478 |
mode_ip2,
|
1479 |
scale_ip2,
|
1480 |
pag_scale_gui,
|
1481 |
-
face_restoration_model_gui,
|
1482 |
-
face_restoration_visibility_gui,
|
1483 |
-
face_restoration_weight_gui,
|
1484 |
load_lora_cpu_gui,
|
1485 |
verbose_info_gui,
|
1486 |
gpu_duration_gui,
|
@@ -1490,12 +1345,10 @@ with gr.Blocks(theme=args.theme, css=CSS, fill_width=True, fill_height=False) as
|
|
1490 |
show_progress="minimal",
|
1491 |
)
|
1492 |
|
1493 |
-
|
1494 |
-
|
1495 |
-
|
1496 |
-
|
1497 |
-
|
1498 |
-
|
1499 |
-
|
1500 |
-
allowed_paths=[allowed_path],
|
1501 |
-
)
|
|
|
1 |
import spaces
|
2 |
import os
|
|
|
3 |
from stablepy import (
|
4 |
Model_Diffusers,
|
5 |
SCHEDULE_TYPE_OPTIONS,
|
6 |
SCHEDULE_PREDICTION_TYPE_OPTIONS,
|
7 |
check_scheduler_compatibility,
|
8 |
TASK_AND_PREPROCESSORS,
|
|
|
|
|
9 |
)
|
10 |
from constants import (
|
11 |
DIRECTORY_MODELS,
|
12 |
DIRECTORY_LORAS,
|
13 |
DIRECTORY_VAES,
|
14 |
DIRECTORY_EMBEDS,
|
|
|
15 |
DOWNLOAD_MODEL,
|
16 |
DOWNLOAD_VAE,
|
17 |
DOWNLOAD_LORA,
|
|
|
35 |
EXAMPLES_GUI,
|
36 |
RESOURCES,
|
37 |
DIFFUSERS_CONTROLNET_MODEL,
|
|
|
|
|
|
|
38 |
)
|
39 |
from stablepy.diffusers_vanilla.style_prompt_config import STYLE_NAMES
|
40 |
import torch
|
41 |
import re
|
42 |
+
from stablepy import (
|
43 |
+
scheduler_names,
|
44 |
+
IP_ADAPTERS_SD,
|
45 |
+
IP_ADAPTERS_SDXL,
|
46 |
+
)
|
47 |
import time
|
48 |
from PIL import ImageFile
|
49 |
from utils import (
|
|
|
60 |
progress_step_bar,
|
61 |
html_template_message,
|
62 |
escape_html,
|
|
|
63 |
)
|
64 |
from image_processor import preprocessor_tab
|
65 |
from datetime import datetime
|
|
|
70 |
from stablepy import logger
|
71 |
from diffusers import FluxPipeline
|
72 |
# import urllib.parse
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
|
74 |
ImageFile.LOAD_TRUNCATED_IMAGES = True
|
75 |
torch.backends.cuda.matmul.allow_tf32 = True
|
76 |
# os.environ["PYTORCH_NO_CUDA_MEMORY_CACHING"] = "1"
|
77 |
+
print(os.getenv("SPACES_ZERO_GPU"))
|
78 |
|
79 |
+
directories = [DIRECTORY_MODELS, DIRECTORY_LORAS, DIRECTORY_VAES, DIRECTORY_EMBEDS]
|
80 |
for directory in directories:
|
81 |
os.makedirs(directory, exist_ok=True)
|
82 |
|
83 |
# Download stuffs
|
84 |
for url in [url.strip() for url in DOWNLOAD_MODEL.split(',')]:
|
85 |
+
if not os.path.exists(f"./models/{url.split('/')[-1]}"):
|
86 |
+
download_things(DIRECTORY_MODELS, url, HF_TOKEN, CIVITAI_API_KEY)
|
87 |
for url in [url.strip() for url in DOWNLOAD_VAE.split(',')]:
|
88 |
+
if not os.path.exists(f"./vaes/{url.split('/')[-1]}"):
|
89 |
+
download_things(DIRECTORY_VAES, url, HF_TOKEN, CIVITAI_API_KEY)
|
90 |
for url in [url.strip() for url in DOWNLOAD_LORA.split(',')]:
|
91 |
+
if not os.path.exists(f"./loras/{url.split('/')[-1]}"):
|
92 |
+
download_things(DIRECTORY_LORAS, url, HF_TOKEN, CIVITAI_API_KEY)
|
93 |
|
94 |
# Download Embeddings
|
95 |
for url_embed in DOWNLOAD_EMBEDS:
|
96 |
+
if not os.path.exists(f"./embedings/{url_embed.split('/')[-1]}"):
|
97 |
+
download_things(DIRECTORY_EMBEDS, url_embed, HF_TOKEN, CIVITAI_API_KEY)
|
98 |
|
99 |
# Build list models
|
100 |
embed_list = get_model_list(DIRECTORY_EMBEDS)
|
|
|
112 |
|
113 |
print('\033[33m🏁 Download and listing of valid models completed.\033[0m')
|
114 |
|
115 |
+
flux_repo = "camenduru/FLUX.1-dev-diffusers"
|
116 |
+
flux_pipe = FluxPipeline.from_pretrained(
|
117 |
+
flux_repo,
|
118 |
+
transformer=None,
|
119 |
+
torch_dtype=torch.bfloat16,
|
120 |
+
).to("cuda")
|
121 |
+
components = flux_pipe.components
|
122 |
+
components.pop("transformer", None)
|
123 |
+
delete_model(flux_repo)
|
|
|
124 |
|
125 |
#######################
|
126 |
# GUI
|
|
|
130 |
warnings.filterwarnings(action="ignore", category=FutureWarning, module="diffusers")
|
131 |
warnings.filterwarnings(action="ignore", category=UserWarning, module="diffusers")
|
132 |
warnings.filterwarnings(action="ignore", category=FutureWarning, module="transformers")
|
133 |
+
logger.setLevel(logging.DEBUG)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
|
135 |
CSS = """
|
136 |
.contain { display: flex; flex-direction: column; }
|
|
|
140 |
"""
|
141 |
|
142 |
|
|
|
|
|
|
|
|
|
|
|
|
|
143 |
class GuiSD:
|
144 |
def __init__(self, stream=True):
|
145 |
self.model = None
|
|
|
155 |
removal_candidate = self.inventory.pop(0)
|
156 |
delete_model(removal_candidate)
|
157 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
158 |
def update_inventory(self, model_name):
|
159 |
if model_name not in single_file_model_list:
|
160 |
self.inventory = [
|
|
|
165 |
def load_new_model(self, model_name, vae_model, task, controlnet_model, progress=gr.Progress(track_tqdm=True)):
|
166 |
|
167 |
# download link model > model_name
|
|
|
|
|
|
|
|
|
|
|
168 |
|
169 |
+
self.update_storage_models()
|
|
|
170 |
|
171 |
vae_model = vae_model if vae_model != "None" else None
|
172 |
model_type = get_model_type(model_name)
|
173 |
dtype_model = torch.bfloat16 if model_type == "FLUX" else torch.float16
|
174 |
|
175 |
if not os.path.exists(model_name):
|
|
|
176 |
_ = download_diffuser_repo(
|
177 |
repo_name=model_name,
|
178 |
model_type=model_type,
|
|
|
198 |
yield f"Loading model: {model_name}"
|
199 |
|
200 |
if vae_model == "BakedVAE":
|
201 |
+
if not os.path.exists(model_name):
|
202 |
+
vae_model = model_name
|
203 |
+
else:
|
204 |
+
vae_model = None
|
205 |
elif vae_model:
|
206 |
vae_type = "SDXL" if "sdxl" in vae_model.lower() else "SD 1.5"
|
207 |
if model_type != vae_type:
|
|
|
220 |
type_model_precision=dtype_model,
|
221 |
retain_task_model_in_cache=False,
|
222 |
controlnet_model=controlnet_model,
|
223 |
+
device="cpu",
|
224 |
env_components=components,
|
225 |
)
|
226 |
+
self.model.advanced_params(image_preprocessor_cuda_active=True)
|
227 |
else:
|
228 |
if self.model.base_model_id != model_name:
|
229 |
load_now_time = datetime.now()
|
|
|
233 |
print("Waiting for the previous model's time ops...")
|
234 |
time.sleep(9 - elapsed_time)
|
235 |
|
236 |
+
self.model.device = torch.device("cpu")
|
|
|
237 |
self.model.load_pipe(
|
238 |
model_name,
|
239 |
task_name=TASK_STABLEPY[task],
|
|
|
310 |
syntax_weights,
|
311 |
upscaler_model_path,
|
312 |
upscaler_increases_size,
|
313 |
+
esrgan_tile,
|
314 |
+
esrgan_tile_overlap,
|
315 |
hires_steps,
|
316 |
hires_denoising_strength,
|
317 |
hires_sampler,
|
|
|
375 |
mode_ip2,
|
376 |
scale_ip2,
|
377 |
pag_scale,
|
|
|
|
|
|
|
378 |
):
|
379 |
info_state = html_template_message("Navigating latent space...")
|
380 |
yield info_state, gr.update(), gr.update()
|
|
|
384 |
vae_msg = f"VAE: {vae_model}" if vae_model else ""
|
385 |
msg_lora = ""
|
386 |
|
387 |
+
print("Config model:", model_name, vae_model, loras_list)
|
388 |
|
389 |
task = TASK_STABLEPY[task]
|
390 |
|
|
|
413 |
self.model.stream_config(concurrency=concurrency, latent_resize_by=1, vae_decoding=False)
|
414 |
|
415 |
if task != "txt2img" and not image_control:
|
416 |
+
raise ValueError("No control image found: To use this function, you have to upload an image in 'Image ControlNet/Inpaint/Img2img'")
|
417 |
|
418 |
+
if task == "inpaint" and not image_mask:
|
419 |
+
raise ValueError("No mask image found: Specify one in 'Image Mask'")
|
420 |
|
421 |
+
if upscaler_model_path in UPSCALER_KEYS[:9]:
|
422 |
upscaler_model = upscaler_model_path
|
423 |
else:
|
424 |
+
directory_upscalers = 'upscalers'
|
425 |
+
os.makedirs(directory_upscalers, exist_ok=True)
|
426 |
+
|
427 |
url_upscaler = UPSCALER_DICT_GUI[upscaler_model_path]
|
428 |
|
429 |
+
if not os.path.exists(f"./upscalers/{url_upscaler.split('/')[-1]}"):
|
430 |
+
download_things(directory_upscalers, url_upscaler, HF_TOKEN)
|
431 |
|
432 |
+
upscaler_model = f"./upscalers/{url_upscaler.split('/')[-1]}"
|
433 |
|
434 |
logging.getLogger("ultralytics").setLevel(logging.INFO if adetailer_verbose else logging.ERROR)
|
435 |
|
|
|
485 |
"distance_threshold": distance_threshold,
|
486 |
"recolor_gamma_correction": float(recolor_gamma_correction),
|
487 |
"tile_blur_sigma": int(tile_blur_sigma),
|
488 |
+
"lora_A": lora1 if lora1 != "None" else None,
|
489 |
"lora_scale_A": lora_scale1,
|
490 |
+
"lora_B": lora2 if lora2 != "None" else None,
|
491 |
"lora_scale_B": lora_scale2,
|
492 |
+
"lora_C": lora3 if lora3 != "None" else None,
|
493 |
"lora_scale_C": lora_scale3,
|
494 |
+
"lora_D": lora4 if lora4 != "None" else None,
|
495 |
"lora_scale_D": lora_scale4,
|
496 |
+
"lora_E": lora5 if lora5 != "None" else None,
|
497 |
"lora_scale_E": lora_scale5,
|
498 |
+
"lora_F": lora6 if lora6 != "None" else None,
|
499 |
"lora_scale_F": lora_scale6,
|
500 |
+
"lora_G": lora7 if lora7 != "None" else None,
|
501 |
"lora_scale_G": lora_scale7,
|
502 |
"textual_inversion": embed_list if textual_inversion else [],
|
503 |
"syntax_weights": syntax_weights, # "Classic"
|
|
|
531 |
"t2i_adapter_conditioning_factor": float(t2i_adapter_conditioning_factor),
|
532 |
"upscaler_model_path": upscaler_model,
|
533 |
"upscaler_increases_size": upscaler_increases_size,
|
534 |
+
"esrgan_tile": esrgan_tile,
|
535 |
+
"esrgan_tile_overlap": esrgan_tile_overlap,
|
536 |
"hires_steps": hires_steps,
|
537 |
"hires_denoising_strength": hires_denoising_strength,
|
538 |
"hires_prompt": hires_prompt,
|
|
|
547 |
"ip_adapter_model": params_ip_model,
|
548 |
"ip_adapter_mode": params_ip_mode,
|
549 |
"ip_adapter_scale": params_ip_scale,
|
|
|
|
|
|
|
550 |
}
|
551 |
|
552 |
# kwargs for diffusers pipeline
|
553 |
if guidance_rescale:
|
554 |
pipe_params["guidance_rescale"] = guidance_rescale
|
555 |
+
|
556 |
+
self.model.device = torch.device("cuda:0")
|
557 |
+
if hasattr(self.model.pipe, "transformer") and loras_list != ["None"] * self.model.num_loras:
|
558 |
+
self.model.pipe.transformer.to(self.model.device)
|
559 |
+
print("transformer to cuda")
|
560 |
|
561 |
actual_progress = 0
|
562 |
info_images = gr.update()
|
|
|
586 |
|
587 |
download_links = "<br>".join(
|
588 |
[
|
589 |
+
f'<a href="{path.replace("/images/", "/file=/home/user/app/images/")}" download="{os.path.basename(path)}">Download Image {i + 1}</a>'
|
590 |
for i, path in enumerate(image_path)
|
591 |
]
|
592 |
)
|
|
|
694 |
|
695 |
|
696 |
@spaces.GPU(duration=15)
|
697 |
+
def esrgan_upscale(image, upscaler_name, upscaler_size):
|
698 |
+
if image is None: return None
|
|
|
699 |
|
700 |
from stablepy.diffusers_vanilla.utils import save_pil_image_with_metadata
|
701 |
+
from stablepy import UpscalerESRGAN
|
702 |
|
|
|
703 |
exif_image = extract_exif_data(image)
|
704 |
|
705 |
+
url_upscaler = UPSCALER_DICT_GUI[upscaler_name]
|
706 |
+
directory_upscalers = 'upscalers'
|
707 |
+
os.makedirs(directory_upscalers, exist_ok=True)
|
708 |
+
if not os.path.exists(f"./upscalers/{url_upscaler.split('/')[-1]}"):
|
709 |
+
download_things(directory_upscalers, url_upscaler, HF_TOKEN)
|
|
|
|
|
|
|
710 |
|
711 |
+
scaler_beta = UpscalerESRGAN(0, 0)
|
712 |
+
image_up = scaler_beta.upscale(image, upscaler_size, f"./upscalers/{url_upscaler.split('/')[-1]}")
|
713 |
|
714 |
image_path = save_pil_image_with_metadata(image_up, f'{os.getcwd()}/up_images', exif_image)
|
715 |
|
|
|
717 |
|
718 |
|
719 |
# https://huggingface.co/spaces/BestWishYsh/ConsisID-preview-Space/discussions/1#674969a022b99c122af5d407
|
720 |
+
dynamic_gpu_duration.zerogpu = True
|
721 |
+
sd_gen_generate_pipeline.zerogpu = True
|
722 |
sd_gen = GuiSD()
|
723 |
|
724 |
+
with gr.Blocks(theme="NoCrypt/miku", css=CSS) as app:
|
725 |
gr.Markdown("# 🧩 DiffuseCraft")
|
726 |
gr.Markdown(SUBTITLE_GUI)
|
727 |
with gr.Tab("Generation"):
|
|
|
770 |
|
771 |
actual_task_info = gr.HTML()
|
772 |
|
773 |
+
with gr.Row(equal_height=False, variant="default"):
|
774 |
gpu_duration_gui = gr.Number(minimum=5, maximum=240, value=59, show_label=False, container=False, info="GPU time duration (seconds)")
|
775 |
with gr.Column():
|
776 |
verbose_info_gui = gr.Checkbox(value=False, container=False, label="Status info")
|
|
|
806 |
"Schedule type": gr.update(value="Automatic"),
|
807 |
"PAG": gr.update(value=.0),
|
808 |
"FreeU": gr.update(value=False),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
809 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
810 |
valid_keys = list(valid_receptors.keys())
|
811 |
|
812 |
parameters = extract_parameters(base_prompt)
|
|
|
820 |
parameters["Sampler"] = value_sampler
|
821 |
parameters["Schedule type"] = s_type
|
822 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
823 |
for key, val in parameters.items():
|
824 |
# print(val)
|
825 |
if key in valid_keys:
|
|
|
827 |
if key == "Sampler":
|
828 |
if val not in scheduler_names:
|
829 |
continue
|
830 |
+
if key == "Schedule type":
|
831 |
if val not in SCHEDULE_TYPE_OPTIONS:
|
832 |
+
val = "Automatic"
|
|
|
|
|
|
|
833 |
elif key == "Clip skip":
|
834 |
if "," in str(val):
|
835 |
val = val.replace(",", "")
|
|
|
837 |
val = True
|
838 |
if key == "prompt":
|
839 |
if ">" in val and "<" in val:
|
840 |
+
val = re.sub(r'<[^>]+>', '', val)
|
841 |
print("Removed LoRA written in the prompt")
|
842 |
if key in ["prompt", "neg_prompt"]:
|
843 |
val = re.sub(r'\s+', ' ', re.sub(r',+', ',', val)).strip()
|
844 |
+
if key in ["Steps", "width", "height", "Seed"]:
|
845 |
val = int(val)
|
846 |
if key == "FreeU":
|
847 |
val = True
|
848 |
+
if key in ["CFG scale", "PAG"]:
|
849 |
val = float(val)
|
850 |
if key == "Model":
|
851 |
filtered_models = [m for m in model_list if val in m]
|
|
|
853 |
val = filtered_models[0]
|
854 |
else:
|
855 |
val = name_model
|
|
|
|
|
|
|
856 |
if key == "Seed":
|
857 |
continue
|
|
|
858 |
valid_receptors[key] = gr.update(value=val)
|
859 |
# print(val, type(val))
|
860 |
# print(valid_receptors)
|
|
|
862 |
print(str(e))
|
863 |
return [value for value in valid_receptors.values()]
|
864 |
|
865 |
+
set_params_gui.click(
|
866 |
+
run_set_params_gui, [prompt_gui, model_name_gui], [
|
867 |
+
prompt_gui,
|
868 |
+
neg_prompt_gui,
|
869 |
+
steps_gui,
|
870 |
+
img_width_gui,
|
871 |
+
img_height_gui,
|
872 |
+
seed_gui,
|
873 |
+
sampler_gui,
|
874 |
+
cfg_gui,
|
875 |
+
clip_skip_gui,
|
876 |
+
model_name_gui,
|
877 |
+
schedule_type_gui,
|
878 |
+
pag_scale_gui,
|
879 |
+
free_u_gui,
|
880 |
+
],
|
881 |
+
)
|
882 |
+
|
883 |
def run_clear_prompt_gui():
|
884 |
return gr.update(value=""), gr.update(value="")
|
885 |
clear_prompt_gui.click(
|
|
|
892 |
run_set_random_seed, [], seed_gui
|
893 |
)
|
894 |
|
895 |
+
num_images_gui = gr.Slider(minimum=1, maximum=5, step=1, value=1, label="Images")
|
896 |
prompt_syntax_gui = gr.Dropdown(label="Prompt Syntax", choices=PROMPT_W_OPTIONS, value=PROMPT_W_OPTIONS[1][1])
|
897 |
vae_model_gui = gr.Dropdown(label="VAE Model", choices=vae_model_list, value=vae_model_list[0])
|
898 |
|
|
|
900 |
|
901 |
upscaler_model_path_gui = gr.Dropdown(label="Upscaler", choices=UPSCALER_KEYS, value=UPSCALER_KEYS[0])
|
902 |
upscaler_increases_size_gui = gr.Slider(minimum=1.1, maximum=4., step=0.1, value=1.2, label="Upscale by")
|
903 |
+
esrgan_tile_gui = gr.Slider(minimum=0, value=0, maximum=500, step=1, label="ESRGAN Tile")
|
904 |
+
esrgan_tile_overlap_gui = gr.Slider(minimum=1, maximum=200, step=1, value=8, label="ESRGAN Tile Overlap")
|
905 |
hires_steps_gui = gr.Slider(minimum=0, value=30, maximum=100, step=1, label="Hires Steps")
|
906 |
hires_denoising_strength_gui = gr.Slider(minimum=0.1, maximum=1.0, step=0.01, value=0.55, label="Hires Denoising Strength")
|
907 |
hires_sampler_gui = gr.Dropdown(label="Hires Sampler", choices=POST_PROCESSING_SAMPLER, value=POST_PROCESSING_SAMPLER[0])
|
|
|
917 |
return gr.Dropdown(label=label, choices=lora_model_list, value="None", allow_custom_value=True, visible=visible)
|
918 |
|
919 |
def lora_scale_slider(label, visible=True):
|
920 |
+
return gr.Slider(minimum=-2, maximum=2, step=0.01, value=0.33, label=label, visible=visible)
|
|
|
921 |
|
922 |
lora1_gui = lora_dropdown("Lora1")
|
923 |
lora_scale_1_gui = lora_scale_slider("Lora Scale 1")
|
|
|
929 |
lora_scale_4_gui = lora_scale_slider("Lora Scale 4")
|
930 |
lora5_gui = lora_dropdown("Lora5")
|
931 |
lora_scale_5_gui = lora_scale_slider("Lora Scale 5")
|
932 |
+
lora6_gui = lora_dropdown("Lora6", visible=False)
|
933 |
+
lora_scale_6_gui = lora_scale_slider("Lora Scale 6", visible=False)
|
934 |
+
lora7_gui = lora_dropdown("Lora7", visible=False)
|
935 |
+
lora_scale_7_gui = lora_scale_slider("Lora Scale 7", visible=False)
|
936 |
|
937 |
with gr.Accordion("From URL", open=False, visible=True):
|
938 |
text_lora = gr.Textbox(
|
|
|
941 |
lines=1,
|
942 |
info="It has to be .safetensors files, and you can also download them from Hugging Face.",
|
943 |
)
|
944 |
+
romanize_text = gr.Checkbox(value=False, label="Transliterate name", visible=False)
|
945 |
button_lora = gr.Button("Get and Refresh the LoRA Lists")
|
946 |
new_lora_status = gr.HTML()
|
947 |
button_lora.click(
|
|
|
950 |
[lora1_gui, lora2_gui, lora3_gui, lora4_gui, lora5_gui, lora6_gui, lora7_gui, new_lora_status]
|
951 |
)
|
952 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
953 |
with gr.Accordion("IP-Adapter", open=False, visible=True):
|
954 |
|
955 |
+
IP_MODELS = sorted(list(set(IP_ADAPTERS_SD + IP_ADAPTERS_SDXL)))
|
956 |
+
MODE_IP_OPTIONS = ["original", "style", "layout", "style+layout"]
|
957 |
+
|
958 |
with gr.Accordion("IP-Adapter 1", open=False, visible=True):
|
959 |
image_ip1 = gr.Image(label="IP Image", type="filepath")
|
960 |
mask_ip1 = gr.Image(label="IP Mask", type="filepath")
|
|
|
973 |
image_mask_gui = gr.Image(label="Image Mask", type="filepath")
|
974 |
strength_gui = gr.Slider(
|
975 |
minimum=0.01, maximum=1.0, step=0.01, value=0.55, label="Strength",
|
976 |
+
info="This option adjusts the level of changes for img2img and inpainting."
|
977 |
)
|
978 |
image_resolution_gui = gr.Slider(
|
979 |
minimum=64, maximum=2048, step=64, value=1024, label="Image Resolution",
|
980 |
info="The maximum proportional size of the generated image based on the uploaded image."
|
981 |
)
|
982 |
+
controlnet_model_gui = gr.Dropdown(label="ControlNet model", choices=DIFFUSERS_CONTROLNET_MODEL, value=DIFFUSERS_CONTROLNET_MODEL[0])
|
983 |
control_net_output_scaling_gui = gr.Slider(minimum=0, maximum=5.0, step=0.1, value=1, label="ControlNet Output Scaling in UNet")
|
984 |
control_net_start_threshold_gui = gr.Slider(minimum=0, maximum=1, step=0.01, value=0, label="ControlNet Start Threshold (%)")
|
985 |
control_net_stop_threshold_gui = gr.Slider(minimum=0, maximum=1, step=0.01, value=1, label="ControlNet Stop Threshold (%)")
|
|
|
1001 |
preprocess_resolution_gui = gr.Slider(minimum=64, maximum=2048, step=64, value=512, label="Preprocessor Resolution")
|
1002 |
low_threshold_gui = gr.Slider(minimum=1, maximum=255, step=1, value=100, label="'CANNY' low threshold")
|
1003 |
high_threshold_gui = gr.Slider(minimum=1, maximum=255, step=1, value=200, label="'CANNY' high threshold")
|
1004 |
+
value_threshold_gui = gr.Slider(minimum=1, maximum=2.0, step=0.01, value=0.1, label="'MLSD' Hough value threshold")
|
1005 |
+
distance_threshold_gui = gr.Slider(minimum=1, maximum=20.0, step=0.01, value=0.1, label="'MLSD' Hough distance threshold")
|
1006 |
recolor_gamma_correction_gui = gr.Number(minimum=0., maximum=25., value=1., step=0.001, label="'RECOLOR' gamma correction")
|
1007 |
tile_blur_sigma_gui = gr.Number(minimum=0, maximum=100, value=9, step=1, label="'TILE' blur sigma")
|
1008 |
|
|
|
1037 |
gr.Info(f"{len(sd_gen.model.STYLE_NAMES)} styles loaded")
|
1038 |
return gr.update(value=None, choices=sd_gen.model.STYLE_NAMES)
|
1039 |
|
1040 |
+
style_button.click(load_json_style_file, [style_json_gui], [style_prompt_gui])
|
1041 |
|
1042 |
with gr.Accordion("Textual inversion", open=False, visible=False):
|
1043 |
active_textual_inversion_gui = gr.Checkbox(value=False, label="Active Textual Inversion in prompt")
|
|
|
1087 |
hires_before_adetailer_gui = gr.Checkbox(value=False, label="Hires Before Adetailer")
|
1088 |
hires_after_adetailer_gui = gr.Checkbox(value=True, label="Hires After Adetailer")
|
1089 |
generator_in_cpu_gui = gr.Checkbox(value=False, label="Generator in CPU")
|
|
|
|
|
|
|
|
|
1090 |
|
1091 |
with gr.Accordion("More settings", open=False, visible=False):
|
1092 |
loop_generation_gui = gr.Slider(minimum=1, value=1, label="Loop Generation")
|
1093 |
retain_task_cache_gui = gr.Checkbox(value=False, label="Retain task model in cache")
|
1094 |
+
leave_progress_bar_gui = gr.Checkbox(value=True, label="Leave Progress Bar")
|
1095 |
+
disable_progress_bar_gui = gr.Checkbox(value=False, label="Disable Progress Bar")
|
1096 |
display_images_gui = gr.Checkbox(value=False, label="Display Images")
|
1097 |
image_previews_gui = gr.Checkbox(value=True, label="Image Previews")
|
1098 |
+
image_storage_location_gui = gr.Textbox(value="./images", label="Image Storage Location")
|
1099 |
retain_compel_previous_load_gui = gr.Checkbox(value=False, label="Retain Compel Previous Load")
|
1100 |
retain_detailfix_model_previous_load_gui = gr.Checkbox(value=False, label="Retain Detailfix Model Previous Load")
|
1101 |
retain_hires_model_previous_load_gui = gr.Checkbox(value=False, label="Retain Hires Model Previous Load")
|
1102 |
xformers_memory_efficient_attention_gui = gr.Checkbox(value=False, label="Xformers Memory Efficient Attention")
|
1103 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1104 |
with gr.Accordion("Examples and help", open=False, visible=True):
|
1105 |
gr.Markdown(HELP_GUI)
|
1106 |
gr.Markdown(EXAMPLES_GUI_HELP)
|
|
|
1156 |
# "hsl(360, 120, 120)" # in fact any valid colorstring
|
1157 |
]
|
1158 |
),
|
1159 |
+
eraser=gr.Eraser(default_size="16")
|
|
|
|
|
|
|
1160 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1161 |
invert_mask = gr.Checkbox(value=False, label="Invert mask")
|
1162 |
btn = gr.Button("Create mask")
|
|
|
1163 |
with gr.Column(scale=1):
|
1164 |
img_source = gr.Image(interactive=False)
|
1165 |
img_result = gr.Image(label="Mask image", show_label=True, interactive=False)
|
|
|
1190 |
|
1191 |
with gr.Row():
|
1192 |
with gr.Column():
|
|
|
|
|
|
|
1193 |
image_up_tab = gr.Image(label="Image", type="pil", sources=["upload"])
|
1194 |
+
upscaler_tab = gr.Dropdown(label="Upscaler", choices=UPSCALER_KEYS[9:], value=UPSCALER_KEYS[11])
|
1195 |
upscaler_size_tab = gr.Slider(minimum=1., maximum=4., step=0.1, value=1.1, label="Upscale by")
|
1196 |
generate_button_up_tab = gr.Button(value="START UPSCALE", variant="primary")
|
1197 |
|
|
|
1199 |
result_up_tab = gr.Image(label="Result", type="pil", interactive=False, format="png")
|
1200 |
|
1201 |
generate_button_up_tab.click(
|
1202 |
+
fn=esrgan_upscale,
|
1203 |
inputs=[image_up_tab, upscaler_tab, upscaler_size_tab],
|
1204 |
outputs=[result_up_tab],
|
1205 |
)
|
|
|
1271 |
prompt_syntax_gui,
|
1272 |
upscaler_model_path_gui,
|
1273 |
upscaler_increases_size_gui,
|
1274 |
+
esrgan_tile_gui,
|
1275 |
+
esrgan_tile_overlap_gui,
|
1276 |
hires_steps_gui,
|
1277 |
hires_denoising_strength_gui,
|
1278 |
hires_sampler_gui,
|
|
|
1336 |
mode_ip2,
|
1337 |
scale_ip2,
|
1338 |
pag_scale_gui,
|
|
|
|
|
|
|
1339 |
load_lora_cpu_gui,
|
1340 |
verbose_info_gui,
|
1341 |
gpu_duration_gui,
|
|
|
1345 |
show_progress="minimal",
|
1346 |
)
|
1347 |
|
1348 |
+
app.queue()
|
1349 |
+
|
1350 |
+
app.launch(
|
1351 |
+
show_error=True,
|
1352 |
+
debug=True,
|
1353 |
+
allowed_paths=["./images/"],
|
1354 |
+
)
|
|
|
|
constants.py
CHANGED
@@ -4,13 +4,8 @@ from stablepy import (
|
|
4 |
scheduler_names,
|
5 |
SD15_TASKS,
|
6 |
SDXL_TASKS,
|
7 |
-
ALL_BUILTIN_UPSCALERS,
|
8 |
-
IP_ADAPTERS_SD,
|
9 |
-
IP_ADAPTERS_SDXL,
|
10 |
)
|
11 |
|
12 |
-
IS_ZERO_GPU = bool(os.getenv("SPACES_ZERO_GPU"))
|
13 |
-
|
14 |
# - **Download Models**
|
15 |
DOWNLOAD_MODEL = "https://huggingface.co/TechnoByte/MilkyWonderland/resolve/main/milkyWonderland_v40.safetensors"
|
16 |
|
@@ -23,46 +18,37 @@ DOWNLOAD_LORA = "https://huggingface.co/Leopain/color/resolve/main/Coloring_book
|
|
23 |
LOAD_DIFFUSERS_FORMAT_MODEL = [
|
24 |
'stabilityai/stable-diffusion-xl-base-1.0',
|
25 |
'Laxhar/noobai-XL-1.1',
|
26 |
-
'Laxhar/noobai-XL-Vpred-1.0',
|
27 |
'black-forest-labs/FLUX.1-dev',
|
28 |
-
'black-forest-labs/FLUX.1-Krea-dev',
|
29 |
'John6666/blue-pencil-flux1-v021-fp8-flux',
|
30 |
'John6666/wai-ani-flux-v10forfp8-fp8-flux',
|
31 |
'John6666/xe-anime-flux-v04-fp8-flux',
|
32 |
'John6666/lyh-anime-flux-v2a1-fp8-flux',
|
33 |
'John6666/carnival-unchained-v10-fp8-flux',
|
|
|
34 |
'Freepik/flux.1-lite-8B-alpha',
|
35 |
'shauray/FluxDev-HyperSD-merged',
|
36 |
'mikeyandfriends/PixelWave_FLUX.1-dev_03',
|
37 |
'terminusresearch/FluxBooru-v0.3',
|
38 |
-
'
|
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/
|
49 |
-
'John6666/
|
50 |
-
'John6666/ntr-mix-illustrious-xl-noob-xl-
|
51 |
-
'John6666/ntr-mix-illustrious-xl-noob-xl-
|
52 |
-
'John6666/ntr-mix-illustrious-xl-noob-xl-xiii-sdxl',
|
53 |
-
'John6666/mistoon-anime-v10illustrious-sdxl',
|
54 |
-
'John6666/hassaku-xl-illustrious-v22-sdxl',
|
55 |
'John6666/haruki-mix-illustrious-v10-sdxl',
|
56 |
'John6666/noobreal-v10-sdxl',
|
57 |
'John6666/complicated-noobai-merge-vprediction-sdxl',
|
58 |
-
'Laxhar/noobai-XL-Vpred-0.9r',
|
59 |
-
'Laxhar/noobai-XL-Vpred-0.75s',
|
60 |
-
'Laxhar/noobai-XL-Vpred-0.75',
|
61 |
'Laxhar/noobai-XL-Vpred-0.65s',
|
62 |
'Laxhar/noobai-XL-Vpred-0.65',
|
63 |
'Laxhar/noobai-XL-Vpred-0.6',
|
64 |
-
'John6666/cat-tower-noobai-xl-checkpoint-v14vpred-sdxl',
|
65 |
-
'John6666/cat-tower-noobai-xl-checkpoint-v15vpred-sdxl',
|
66 |
'John6666/noobai-xl-nai-xl-vpred05version-sdxl',
|
67 |
'John6666/noobai-fusion2-vpred-itercomp-v1-sdxl',
|
68 |
'John6666/noobai-xl-nai-xl-vpredtestversion-sdxl',
|
@@ -72,35 +58,18 @@ LOAD_DIFFUSERS_FORMAT_MODEL = [
|
|
72 |
'John6666/illustrious-pencil-xl-v200-sdxl',
|
73 |
'John6666/obsession-illustriousxl-v21-sdxl',
|
74 |
'John6666/obsession-illustriousxl-v30-sdxl',
|
75 |
-
'John6666/obsession-illustriousxl-v31-sdxl',
|
76 |
-
'John6666/one-obsession-13-sdxl',
|
77 |
-
'John6666/one-obsession-14-24d-sdxl',
|
78 |
-
'John6666/one-obsession-15-noobai-sdxl',
|
79 |
-
'John6666/one-obsession-v16-noobai-sdxl',
|
80 |
-
'John6666/prefect-illustrious-xl-v3-sdxl',
|
81 |
'John6666/wai-nsfw-illustrious-v70-sdxl',
|
82 |
-
'John6666/wai-nsfw-illustrious-sdxl-v140-sdxl',
|
83 |
'John6666/illustrious-pony-mix-v3-sdxl',
|
84 |
-
'John6666/nova-anime-xl-
|
85 |
-
'John6666/nova-
|
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-
|
103 |
-
'John6666/epicrealism-xl-vxvii-crystal-clear-realism-sdxl',
|
104 |
'misri/zavychromaxl_v80',
|
105 |
'SG161222/RealVisXL_V4.0',
|
106 |
'SG161222/RealVisXL_V5.0',
|
@@ -112,14 +81,11 @@ LOAD_DIFFUSERS_FORMAT_MODEL = [
|
|
112 |
'John6666/ras-real-anime-screencap-v1-sdxl',
|
113 |
'John6666/duchaiten-pony-xl-no-score-v60-sdxl',
|
114 |
'John6666/mistoon-anime-ponyalpha-sdxl',
|
115 |
-
'John6666/mistoon-xl-copper-v20fast-sdxl',
|
116 |
'John6666/ebara-mfcg-pony-mix-v12-sdxl',
|
117 |
'John6666/t-ponynai3-v51-sdxl',
|
118 |
'John6666/t-ponynai3-v65-sdxl',
|
119 |
-
'John6666/t-ponynai3-v7-sdxl',
|
120 |
'John6666/prefect-pony-xl-v3-sdxl',
|
121 |
'John6666/prefect-pony-xl-v4-sdxl',
|
122 |
-
'John6666/prefect-pony-xl-v50-sdxl',
|
123 |
'John6666/mala-anime-mix-nsfw-pony-xl-v5-sdxl',
|
124 |
'John6666/wai-ani-nsfw-ponyxl-v10-sdxl',
|
125 |
'John6666/wai-real-mix-v11-sdxl',
|
@@ -127,32 +93,24 @@ LOAD_DIFFUSERS_FORMAT_MODEL = [
|
|
127 |
'John6666/wai-c-v6-sdxl',
|
128 |
'John6666/iniverse-mix-xl-sfwnsfw-pony-guofeng-v43-sdxl',
|
129 |
'John6666/sifw-annihilation-xl-v2-sdxl',
|
130 |
-
'John6666/sifw-annihilation-xl-v305illustrious-beta-sdxl',
|
131 |
'John6666/photo-realistic-pony-v5-sdxl',
|
132 |
'John6666/pony-realism-v21main-sdxl',
|
133 |
'John6666/pony-realism-v22main-sdxl',
|
134 |
-
'John6666/pony-
|
|
|
135 |
'John6666/cyberrealistic-pony-v65-sdxl',
|
136 |
-
'John6666/cyberrealistic-pony-v7-sdxl',
|
137 |
-
'John6666/cyberrealistic-pony-v127-alternative-sdxl',
|
138 |
'GraydientPlatformAPI/realcartoon-pony-diffusion',
|
139 |
'John6666/nova-anime-xl-pony-v5-sdxl',
|
140 |
'John6666/autismmix-sdxl-autismmix-pony-sdxl',
|
141 |
'John6666/aimz-dream-real-pony-mix-v3-sdxl',
|
142 |
-
'John6666/prefectious-xl-nsfw-v10-sdxl',
|
143 |
-
'GraydientPlatformAPI/iniverseponyRealGuofeng49',
|
144 |
'John6666/duchaiten-pony-real-v11fix-sdxl',
|
145 |
'John6666/duchaiten-pony-real-v20-sdxl',
|
146 |
'John6666/duchaiten-pony-xl-no-score-v70-sdxl',
|
147 |
'KBlueLeaf/Kohaku-XL-Zeta',
|
148 |
'cagliostrolab/animagine-xl-3.1',
|
149 |
-
'cagliostrolab/animagine-xl-4.0',
|
150 |
'yodayo-ai/kivotos-xl-2.0',
|
151 |
'yodayo-ai/holodayo-xl-2.1',
|
152 |
'yodayo-ai/clandestine-xl-1.0',
|
153 |
-
'https://huggingface.co/chemwolf/Karmix-XL-v0/resolve/main/Karmix-XL-v0.safetensors?download=true',
|
154 |
-
'https://civitai.com/api/download/models/128713?type=Model&format=SafeTensor&size=pruned&fp=fp16',
|
155 |
-
'https://civitai.com/models/30240?modelVersionId=125771',
|
156 |
'digiplay/majicMIX_sombre_v2',
|
157 |
'digiplay/majicMIX_realistic_v6',
|
158 |
'digiplay/majicMIX_realistic_v7',
|
@@ -162,9 +120,7 @@ LOAD_DIFFUSERS_FORMAT_MODEL = [
|
|
162 |
'digiplay/darkphoenix3D_v1.1',
|
163 |
'digiplay/BeenYouLiteL11_diffusers',
|
164 |
'GraydientPlatformAPI/rev-animated2',
|
165 |
-
'
|
166 |
-
'GraydientPlatformAPI/cyberreal6',
|
167 |
-
'GraydientPlatformAPI/cyberreal5',
|
168 |
'youknownothing/deliberate-v6',
|
169 |
'GraydientPlatformAPI/deliberate-cyber3',
|
170 |
'GraydientPlatformAPI/picx-real',
|
@@ -178,9 +134,9 @@ LOAD_DIFFUSERS_FORMAT_MODEL = [
|
|
178 |
'GraydientPlatformAPI/realcartoon3d-17',
|
179 |
'GraydientPlatformAPI/realcartoon-pixar11',
|
180 |
'GraydientPlatformAPI/realcartoon-real17',
|
|
|
181 |
]
|
182 |
|
183 |
-
|
184 |
DIFFUSERS_FORMAT_LORAS = [
|
185 |
"nerijs/animation2k-flux",
|
186 |
"XLabs-AI/flux-RealismLora",
|
@@ -200,13 +156,9 @@ DIRECTORY_MODELS = 'models'
|
|
200 |
DIRECTORY_LORAS = 'loras'
|
201 |
DIRECTORY_VAES = 'vaes'
|
202 |
DIRECTORY_EMBEDS = 'embedings'
|
203 |
-
DIRECTORY_UPSCALERS = 'upscalers'
|
204 |
|
|
|
205 |
STORAGE_ROOT = "/home/user/"
|
206 |
-
CACHE_HF_ROOT = os.path.expanduser("~/.cache/huggingface")
|
207 |
-
CACHE_HF = os.path.join(CACHE_HF_ROOT, "hub")
|
208 |
-
if IS_ZERO_GPU:
|
209 |
-
os.environ["HF_HOME"] = CACHE_HF
|
210 |
|
211 |
TASK_STABLEPY = {
|
212 |
'txt2img': 'txt2img',
|
@@ -232,23 +184,28 @@ TASK_STABLEPY = {
|
|
232 |
'optical pattern ControlNet': 'pattern',
|
233 |
'recolor ControlNet': 'recolor',
|
234 |
'tile ControlNet': 'tile',
|
235 |
-
'repaint ControlNet': 'repaint',
|
236 |
}
|
237 |
|
238 |
TASK_MODEL_LIST = list(TASK_STABLEPY.keys())
|
239 |
|
240 |
UPSCALER_DICT_GUI = {
|
241 |
None: None,
|
242 |
-
|
243 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
244 |
"RealESRNet_x4plus": "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.1/RealESRNet_x4plus.pth",
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
"4x-UltraSharp": "https://huggingface.co/Shandypur/ESRGAN-4x-UltraSharp/resolve/main/4x-UltraSharp.pth",
|
251 |
-
"Real-ESRGAN-Anime-finetuning": "https://huggingface.co/danhtran2mind/Real-ESRGAN-Anime-finetuning/resolve/main/Real-ESRGAN-Anime-finetuning.pth",
|
252 |
"4x_foolhardy_Remacri": "https://huggingface.co/FacehugmanIII/4x_foolhardy_Remacri/resolve/main/4x_foolhardy_Remacri.pth",
|
253 |
"Remacri4xExtraSmoother": "https://huggingface.co/hollowstrawberry/upscalers-backup/resolve/main/ESRGAN/Remacri%204x%20ExtraSmoother.pth",
|
254 |
"AnimeSharp4x": "https://huggingface.co/hollowstrawberry/upscalers-backup/resolve/main/ESRGAN/AnimeSharp%204x.pth",
|
@@ -262,7 +219,6 @@ UPSCALER_KEYS = list(UPSCALER_DICT_GUI.keys())
|
|
262 |
DIFFUSERS_CONTROLNET_MODEL = [
|
263 |
"Automatic",
|
264 |
|
265 |
-
"brad-twinkl/controlnet-union-sdxl-1.0-promax",
|
266 |
"xinsir/controlnet-union-sdxl-1.0",
|
267 |
"xinsir/anime-painter",
|
268 |
"Eugeoter/noob-sdxl-controlnet-canny",
|
@@ -285,6 +241,7 @@ DIFFUSERS_CONTROLNET_MODEL = [
|
|
285 |
"r3gm/controlnet-recolor-sdxl-fp16",
|
286 |
"r3gm/controlnet-openpose-twins-sdxl-1.0-fp16",
|
287 |
"r3gm/controlnet-qr-pattern-sdxl-fp16",
|
|
|
288 |
"Yakonrus/SDXL_Controlnet_Tile_Realistic_v2",
|
289 |
"TheMistoAI/MistoLine",
|
290 |
"briaai/BRIA-2.3-ControlNet-Recoloring",
|
@@ -363,30 +320,14 @@ POST_PROCESSING_SAMPLER = ["Use same sampler"] + [
|
|
363 |
name_s for name_s in scheduler_names if "Auto-Loader" not in name_s
|
364 |
]
|
365 |
|
366 |
-
IP_MODELS = []
|
367 |
-
ALL_IPA = sorted(set(IP_ADAPTERS_SD + IP_ADAPTERS_SDXL))
|
368 |
-
|
369 |
-
for origin_name in ALL_IPA:
|
370 |
-
suffixes = []
|
371 |
-
if origin_name in IP_ADAPTERS_SD:
|
372 |
-
suffixes.append("sd1.5")
|
373 |
-
if origin_name in IP_ADAPTERS_SDXL:
|
374 |
-
suffixes.append("sdxl")
|
375 |
-
ref_name = f"{origin_name} ({'/'.join(suffixes)})"
|
376 |
-
IP_MODELS.append((ref_name, origin_name))
|
377 |
-
|
378 |
-
MODE_IP_OPTIONS = ["original", "style", "layout", "style+layout"]
|
379 |
-
|
380 |
SUBTITLE_GUI = (
|
381 |
"### This demo uses [diffusers](https://github.com/huggingface/diffusers)"
|
382 |
" to perform different tasks in image generation."
|
383 |
)
|
384 |
|
385 |
-
msg_zero = "" if not IS_ZERO_GPU else "- The current space runs on a ZERO GPU which is assigned for approximately 60 seconds; Therefore, if you submit expensive tasks, the operation may be canceled upon reaching the maximum allowed time with 'GPU TASK ABORTED'."
|
386 |
-
|
387 |
HELP_GUI = (
|
388 |
-
|
389 |
-
|
390 |
- Distorted or strange images often result from high prompt weights, so it's best to use low weights and scales, and consider using Classic variants like 'Classic-original'.
|
391 |
- For better results with Pony Diffusion, try using sampler DPM++ 1s or DPM2 with Compel or Classic prompt weights.
|
392 |
"""
|
@@ -399,9 +340,7 @@ EXAMPLES_GUI_HELP = (
|
|
399 |
3. ControlNet Canny SDXL
|
400 |
4. Optical pattern (Optical illusion) SDXL
|
401 |
5. Convert an image to a coloring drawing
|
402 |
-
6.
|
403 |
-
7. V prediction model sd_embed variant inference
|
404 |
-
8. ControlNet OpenPose SD 1.5 and Latent upscale
|
405 |
|
406 |
- Different tasks can be performed, such as img2img or using the IP adapter, to preserve a person's appearance or a specific style based on an image.
|
407 |
"""
|
@@ -510,7 +449,7 @@ EXAMPLES_GUI = [
|
|
510 |
20,
|
511 |
4.0,
|
512 |
-1,
|
513 |
-
|
514 |
1.0,
|
515 |
"DPM++ 2M SDE",
|
516 |
1024,
|
@@ -528,54 +467,6 @@ EXAMPLES_GUI = [
|
|
528 |
35,
|
529 |
False,
|
530 |
],
|
531 |
-
[
|
532 |
-
"[mochizuki_shiina], [syuri22], newest, reimu, solo, outdoors, water, flower, lantern",
|
533 |
-
"worst quality, normal quality, old, sketch,",
|
534 |
-
28,
|
535 |
-
7.0,
|
536 |
-
-1,
|
537 |
-
"None",
|
538 |
-
0.33,
|
539 |
-
"DPM 3M Ef",
|
540 |
-
1600,
|
541 |
-
1024,
|
542 |
-
"Laxhar/noobai-XL-Vpred-1.0",
|
543 |
-
"txt2img",
|
544 |
-
"color_image.png", # img conttol
|
545 |
-
1024, # img resolution
|
546 |
-
0.35, # strength
|
547 |
-
1.0, # cn scale
|
548 |
-
0.0, # cn start
|
549 |
-
1.0, # cn end
|
550 |
-
"Classic",
|
551 |
-
None,
|
552 |
-
30,
|
553 |
-
False,
|
554 |
-
],
|
555 |
-
[
|
556 |
-
"[mochizuki_shiina], [syuri22], newest, multiple girls, 2girls, earrings, jewelry, gloves, purple eyes, black hair, looking at viewer, nail polish, hat, smile, open mouth, fingerless gloves, sleeveless, :d, upper body, blue eyes, closed mouth, black gloves, hands up, long hair, shirt, bare shoulders, white headwear, blush, black headwear, blue nails, upper teeth only, short hair, white gloves, white shirt, teeth, rabbit hat, star earrings, purple nails, pink hair, detached sleeves, fingernails, fake animal ears, animal hat, sleeves past wrists, black shirt, medium hair, fur trim, sleeveless shirt, turtleneck, long sleeves, rabbit ears, star \\(symbol\\)",
|
557 |
-
"worst quality, normal quality, old, sketch,",
|
558 |
-
28,
|
559 |
-
7.0,
|
560 |
-
-1,
|
561 |
-
"None",
|
562 |
-
0.33,
|
563 |
-
"DPM 3M Ef",
|
564 |
-
1600,
|
565 |
-
1024,
|
566 |
-
"Laxhar/noobai-XL-Vpred-1.0",
|
567 |
-
"txt2img",
|
568 |
-
"color_image.png", # img conttol
|
569 |
-
1024, # img resolution
|
570 |
-
0.35, # strength
|
571 |
-
1.0, # cn scale
|
572 |
-
0.0, # cn start
|
573 |
-
1.0, # cn end
|
574 |
-
"Classic-sd_embed",
|
575 |
-
None,
|
576 |
-
30,
|
577 |
-
False,
|
578 |
-
],
|
579 |
[
|
580 |
"1girl,face,curly hair,red hair,white background,",
|
581 |
"(worst quality:2),(low quality:2),(normal quality:2),lowres,watermark,",
|
@@ -605,7 +496,6 @@ EXAMPLES_GUI = [
|
|
605 |
RESOURCES = (
|
606 |
"""### Resources
|
607 |
- John6666's space has some great features you might find helpful [link](https://huggingface.co/spaces/John6666/DiffuseCraftMod).
|
608 |
-
-
|
609 |
-
- `DiffuseCraft` in Colab:[link](https://github.com/R3gm/DiffuseCraft?tab=readme-ov-file#diffusecraft).
|
610 |
"""
|
611 |
-
)
|
|
|
4 |
scheduler_names,
|
5 |
SD15_TASKS,
|
6 |
SDXL_TASKS,
|
|
|
|
|
|
|
7 |
)
|
8 |
|
|
|
|
|
9 |
# - **Download Models**
|
10 |
DOWNLOAD_MODEL = "https://huggingface.co/TechnoByte/MilkyWonderland/resolve/main/milkyWonderland_v40.safetensors"
|
11 |
|
|
|
18 |
LOAD_DIFFUSERS_FORMAT_MODEL = [
|
19 |
'stabilityai/stable-diffusion-xl-base-1.0',
|
20 |
'Laxhar/noobai-XL-1.1',
|
|
|
21 |
'black-forest-labs/FLUX.1-dev',
|
|
|
22 |
'John6666/blue-pencil-flux1-v021-fp8-flux',
|
23 |
'John6666/wai-ani-flux-v10forfp8-fp8-flux',
|
24 |
'John6666/xe-anime-flux-v04-fp8-flux',
|
25 |
'John6666/lyh-anime-flux-v2a1-fp8-flux',
|
26 |
'John6666/carnival-unchained-v10-fp8-flux',
|
27 |
+
'John6666/iniverse-mix-xl-sfwnsfw-fluxdfp16nsfwv11-fp8-flux',
|
28 |
'Freepik/flux.1-lite-8B-alpha',
|
29 |
'shauray/FluxDev-HyperSD-merged',
|
30 |
'mikeyandfriends/PixelWave_FLUX.1-dev_03',
|
31 |
'terminusresearch/FluxBooru-v0.3',
|
32 |
+
'ostris/OpenFLUX.1',
|
|
|
33 |
'shuttleai/shuttle-3-diffusion',
|
34 |
'Laxhar/noobai-XL-1.0',
|
35 |
+
'John6666/noobai-xl-nai-xl-epsilonpred10version-sdxl',
|
36 |
'Laxhar/noobai-XL-0.77',
|
37 |
'John6666/noobai-xl-nai-xl-epsilonpred075version-sdxl',
|
38 |
'Laxhar/noobai-XL-0.6',
|
39 |
'John6666/noobai-xl-nai-xl-epsilonpred05version-sdxl',
|
40 |
'John6666/noobai-cyberfix-v10-sdxl',
|
41 |
'John6666/noobaiiter-xl-vpred-v075-sdxl',
|
42 |
+
'John6666/ntr-mix-illustrious-xl-noob-xl-v40-sdxl',
|
43 |
+
'John6666/ntr-mix-illustrious-xl-noob-xl-ntrmix35-sdxl',
|
44 |
+
'John6666/ntr-mix-illustrious-xl-noob-xl-v777-sdxl',
|
45 |
+
'John6666/ntr-mix-illustrious-xl-noob-xl-v777forlora-sdxl',
|
|
|
|
|
|
|
46 |
'John6666/haruki-mix-illustrious-v10-sdxl',
|
47 |
'John6666/noobreal-v10-sdxl',
|
48 |
'John6666/complicated-noobai-merge-vprediction-sdxl',
|
|
|
|
|
|
|
49 |
'Laxhar/noobai-XL-Vpred-0.65s',
|
50 |
'Laxhar/noobai-XL-Vpred-0.65',
|
51 |
'Laxhar/noobai-XL-Vpred-0.6',
|
|
|
|
|
52 |
'John6666/noobai-xl-nai-xl-vpred05version-sdxl',
|
53 |
'John6666/noobai-fusion2-vpred-itercomp-v1-sdxl',
|
54 |
'John6666/noobai-xl-nai-xl-vpredtestversion-sdxl',
|
|
|
58 |
'John6666/illustrious-pencil-xl-v200-sdxl',
|
59 |
'John6666/obsession-illustriousxl-v21-sdxl',
|
60 |
'John6666/obsession-illustriousxl-v30-sdxl',
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
'John6666/wai-nsfw-illustrious-v70-sdxl',
|
|
|
62 |
'John6666/illustrious-pony-mix-v3-sdxl',
|
63 |
+
'John6666/nova-anime-xl-illustriousv10-sdxl',
|
64 |
+
'John6666/nova-orange-xl-v30-sdxl',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
'John6666/silvermoon-mix03-illustrious-v10-sdxl',
|
66 |
'eienmojiki/Anything-XL',
|
67 |
'eienmojiki/Starry-XL-v5.2',
|
|
|
68 |
'John6666/meinaxl-v2-sdxl',
|
69 |
'Eugeoter/artiwaifu-diffusion-2.0',
|
70 |
'comin/IterComp',
|
|
|
71 |
'John6666/epicrealism-xl-v10kiss2-sdxl',
|
72 |
+
'John6666/epicrealism-xl-v8kiss-sdxl',
|
|
|
73 |
'misri/zavychromaxl_v80',
|
74 |
'SG161222/RealVisXL_V4.0',
|
75 |
'SG161222/RealVisXL_V5.0',
|
|
|
81 |
'John6666/ras-real-anime-screencap-v1-sdxl',
|
82 |
'John6666/duchaiten-pony-xl-no-score-v60-sdxl',
|
83 |
'John6666/mistoon-anime-ponyalpha-sdxl',
|
|
|
84 |
'John6666/ebara-mfcg-pony-mix-v12-sdxl',
|
85 |
'John6666/t-ponynai3-v51-sdxl',
|
86 |
'John6666/t-ponynai3-v65-sdxl',
|
|
|
87 |
'John6666/prefect-pony-xl-v3-sdxl',
|
88 |
'John6666/prefect-pony-xl-v4-sdxl',
|
|
|
89 |
'John6666/mala-anime-mix-nsfw-pony-xl-v5-sdxl',
|
90 |
'John6666/wai-ani-nsfw-ponyxl-v10-sdxl',
|
91 |
'John6666/wai-real-mix-v11-sdxl',
|
|
|
93 |
'John6666/wai-c-v6-sdxl',
|
94 |
'John6666/iniverse-mix-xl-sfwnsfw-pony-guofeng-v43-sdxl',
|
95 |
'John6666/sifw-annihilation-xl-v2-sdxl',
|
|
|
96 |
'John6666/photo-realistic-pony-v5-sdxl',
|
97 |
'John6666/pony-realism-v21main-sdxl',
|
98 |
'John6666/pony-realism-v22main-sdxl',
|
99 |
+
'John6666/cyberrealistic-pony-v63-sdxl',
|
100 |
+
'John6666/cyberrealistic-pony-v64-sdxl',
|
101 |
'John6666/cyberrealistic-pony-v65-sdxl',
|
|
|
|
|
102 |
'GraydientPlatformAPI/realcartoon-pony-diffusion',
|
103 |
'John6666/nova-anime-xl-pony-v5-sdxl',
|
104 |
'John6666/autismmix-sdxl-autismmix-pony-sdxl',
|
105 |
'John6666/aimz-dream-real-pony-mix-v3-sdxl',
|
|
|
|
|
106 |
'John6666/duchaiten-pony-real-v11fix-sdxl',
|
107 |
'John6666/duchaiten-pony-real-v20-sdxl',
|
108 |
'John6666/duchaiten-pony-xl-no-score-v70-sdxl',
|
109 |
'KBlueLeaf/Kohaku-XL-Zeta',
|
110 |
'cagliostrolab/animagine-xl-3.1',
|
|
|
111 |
'yodayo-ai/kivotos-xl-2.0',
|
112 |
'yodayo-ai/holodayo-xl-2.1',
|
113 |
'yodayo-ai/clandestine-xl-1.0',
|
|
|
|
|
|
|
114 |
'digiplay/majicMIX_sombre_v2',
|
115 |
'digiplay/majicMIX_realistic_v6',
|
116 |
'digiplay/majicMIX_realistic_v7',
|
|
|
120 |
'digiplay/darkphoenix3D_v1.1',
|
121 |
'digiplay/BeenYouLiteL11_diffusers',
|
122 |
'GraydientPlatformAPI/rev-animated2',
|
123 |
+
'youknownothing/cyberrealistic_v50',
|
|
|
|
|
124 |
'youknownothing/deliberate-v6',
|
125 |
'GraydientPlatformAPI/deliberate-cyber3',
|
126 |
'GraydientPlatformAPI/picx-real',
|
|
|
134 |
'GraydientPlatformAPI/realcartoon3d-17',
|
135 |
'GraydientPlatformAPI/realcartoon-pixar11',
|
136 |
'GraydientPlatformAPI/realcartoon-real17',
|
137 |
+
'nitrosocke/Ghibli-Diffusion',
|
138 |
]
|
139 |
|
|
|
140 |
DIFFUSERS_FORMAT_LORAS = [
|
141 |
"nerijs/animation2k-flux",
|
142 |
"XLabs-AI/flux-RealismLora",
|
|
|
156 |
DIRECTORY_LORAS = 'loras'
|
157 |
DIRECTORY_VAES = 'vaes'
|
158 |
DIRECTORY_EMBEDS = 'embedings'
|
|
|
159 |
|
160 |
+
CACHE_HF = "/home/user/.cache/huggingface/hub/"
|
161 |
STORAGE_ROOT = "/home/user/"
|
|
|
|
|
|
|
|
|
162 |
|
163 |
TASK_STABLEPY = {
|
164 |
'txt2img': 'txt2img',
|
|
|
184 |
'optical pattern ControlNet': 'pattern',
|
185 |
'recolor ControlNet': 'recolor',
|
186 |
'tile ControlNet': 'tile',
|
|
|
187 |
}
|
188 |
|
189 |
TASK_MODEL_LIST = list(TASK_STABLEPY.keys())
|
190 |
|
191 |
UPSCALER_DICT_GUI = {
|
192 |
None: None,
|
193 |
+
"Lanczos": "Lanczos",
|
194 |
+
"Nearest": "Nearest",
|
195 |
+
'Latent': 'Latent',
|
196 |
+
'Latent (antialiased)': 'Latent (antialiased)',
|
197 |
+
'Latent (bicubic)': 'Latent (bicubic)',
|
198 |
+
'Latent (bicubic antialiased)': 'Latent (bicubic antialiased)',
|
199 |
+
'Latent (nearest)': 'Latent (nearest)',
|
200 |
+
'Latent (nearest-exact)': 'Latent (nearest-exact)',
|
201 |
+
"RealESRGAN_x4plus": "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.0/RealESRGAN_x4plus.pth",
|
202 |
"RealESRNet_x4plus": "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.1/RealESRNet_x4plus.pth",
|
203 |
+
"RealESRGAN_x4plus_anime_6B": "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.2.4/RealESRGAN_x4plus_anime_6B.pth",
|
204 |
+
"RealESRGAN_x2plus": "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.1/RealESRGAN_x2plus.pth",
|
205 |
+
"realesr-animevideov3": "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.5.0/realesr-animevideov3.pth",
|
206 |
+
"realesr-general-x4v3": "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.5.0/realesr-general-x4v3.pth",
|
207 |
+
"realesr-general-wdn-x4v3": "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.5.0/realesr-general-wdn-x4v3.pth",
|
208 |
"4x-UltraSharp": "https://huggingface.co/Shandypur/ESRGAN-4x-UltraSharp/resolve/main/4x-UltraSharp.pth",
|
|
|
209 |
"4x_foolhardy_Remacri": "https://huggingface.co/FacehugmanIII/4x_foolhardy_Remacri/resolve/main/4x_foolhardy_Remacri.pth",
|
210 |
"Remacri4xExtraSmoother": "https://huggingface.co/hollowstrawberry/upscalers-backup/resolve/main/ESRGAN/Remacri%204x%20ExtraSmoother.pth",
|
211 |
"AnimeSharp4x": "https://huggingface.co/hollowstrawberry/upscalers-backup/resolve/main/ESRGAN/AnimeSharp%204x.pth",
|
|
|
219 |
DIFFUSERS_CONTROLNET_MODEL = [
|
220 |
"Automatic",
|
221 |
|
|
|
222 |
"xinsir/controlnet-union-sdxl-1.0",
|
223 |
"xinsir/anime-painter",
|
224 |
"Eugeoter/noob-sdxl-controlnet-canny",
|
|
|
241 |
"r3gm/controlnet-recolor-sdxl-fp16",
|
242 |
"r3gm/controlnet-openpose-twins-sdxl-1.0-fp16",
|
243 |
"r3gm/controlnet-qr-pattern-sdxl-fp16",
|
244 |
+
"brad-twinkl/controlnet-union-sdxl-1.0-promax",
|
245 |
"Yakonrus/SDXL_Controlnet_Tile_Realistic_v2",
|
246 |
"TheMistoAI/MistoLine",
|
247 |
"briaai/BRIA-2.3-ControlNet-Recoloring",
|
|
|
320 |
name_s for name_s in scheduler_names if "Auto-Loader" not in name_s
|
321 |
]
|
322 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
323 |
SUBTITLE_GUI = (
|
324 |
"### This demo uses [diffusers](https://github.com/huggingface/diffusers)"
|
325 |
" to perform different tasks in image generation."
|
326 |
)
|
327 |
|
|
|
|
|
328 |
HELP_GUI = (
|
329 |
+
"""### Help:
|
330 |
+
- The current space runs on a ZERO GPU which is assigned for approximately 60 seconds; Therefore, if you submit expensive tasks, the operation may be canceled upon reaching the maximum allowed time with 'GPU TASK ABORTED'.
|
331 |
- Distorted or strange images often result from high prompt weights, so it's best to use low weights and scales, and consider using Classic variants like 'Classic-original'.
|
332 |
- For better results with Pony Diffusion, try using sampler DPM++ 1s or DPM2 with Compel or Classic prompt weights.
|
333 |
"""
|
|
|
340 |
3. ControlNet Canny SDXL
|
341 |
4. Optical pattern (Optical illusion) SDXL
|
342 |
5. Convert an image to a coloring drawing
|
343 |
+
6. ControlNet OpenPose SD 1.5 and Latent upscale
|
|
|
|
|
344 |
|
345 |
- Different tasks can be performed, such as img2img or using the IP adapter, to preserve a person's appearance or a specific style based on an image.
|
346 |
"""
|
|
|
449 |
20,
|
450 |
4.0,
|
451 |
-1,
|
452 |
+
"loras/Coloring_book_-_LineArt.safetensors",
|
453 |
1.0,
|
454 |
"DPM++ 2M SDE",
|
455 |
1024,
|
|
|
467 |
35,
|
468 |
False,
|
469 |
],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
470 |
[
|
471 |
"1girl,face,curly hair,red hair,white background,",
|
472 |
"(worst quality:2),(low quality:2),(normal quality:2),lowres,watermark,",
|
|
|
496 |
RESOURCES = (
|
497 |
"""### Resources
|
498 |
- John6666's space has some great features you might find helpful [link](https://huggingface.co/spaces/John6666/DiffuseCraftMod).
|
499 |
+
- You can also try the image generator in Colab’s free tier, which provides free GPU [link](https://github.com/R3gm/SD_diffusers_interactive).
|
|
|
500 |
"""
|
501 |
+
)
|
image_processor.py
CHANGED
@@ -92,8 +92,8 @@ def preprocessor_tab():
|
|
92 |
pre_processor_resolution = gr.Slider(minimum=64, maximum=2048, step=64, value=512, label="Preprocessor Resolution")
|
93 |
pre_low_threshold = gr.Slider(minimum=1, maximum=255, step=1, value=100, label="'CANNY' low threshold")
|
94 |
pre_high_threshold = gr.Slider(minimum=1, maximum=255, step=1, value=200, label="'CANNY' high threshold")
|
95 |
-
pre_value_threshold = gr.Slider(minimum=
|
96 |
-
pre_distance_threshold = gr.Slider(minimum=
|
97 |
pre_recolor_mode = gr.Dropdown(label="'RECOLOR' mode", choices=["luminance", "intensity"], value="luminance")
|
98 |
pre_recolor_gamma_correction = gr.Number(minimum=0., maximum=25., value=1., step=0.001, label="'RECOLOR' gamma correction")
|
99 |
pre_blur_k_size = gr.Number(minimum=0, maximum=100, value=9, step=1, label="'BLUR' sigma")
|
|
|
92 |
pre_processor_resolution = gr.Slider(minimum=64, maximum=2048, step=64, value=512, label="Preprocessor Resolution")
|
93 |
pre_low_threshold = gr.Slider(minimum=1, maximum=255, step=1, value=100, label="'CANNY' low threshold")
|
94 |
pre_high_threshold = gr.Slider(minimum=1, maximum=255, step=1, value=200, label="'CANNY' high threshold")
|
95 |
+
pre_value_threshold = gr.Slider(minimum=1, maximum=2.0, step=0.01, value=0.1, label="'MLSD' Hough value threshold")
|
96 |
+
pre_distance_threshold = gr.Slider(minimum=1, maximum=20.0, step=0.01, value=0.1, label="'MLSD' Hough distance threshold")
|
97 |
pre_recolor_mode = gr.Dropdown(label="'RECOLOR' mode", choices=["luminance", "intensity"], value="luminance")
|
98 |
pre_recolor_gamma_correction = gr.Number(minimum=0., maximum=25., value=1., step=0.001, label="'RECOLOR' gamma correction")
|
99 |
pre_blur_k_size = gr.Number(minimum=0, maximum=100, value=9, step=1, label="'BLUR' sigma")
|
packages.txt
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
git-lfs
|
2 |
-
aria2
|
3 |
ffmpeg
|
|
|
1 |
git-lfs
|
2 |
+
aria2 -y
|
3 |
ffmpeg
|
pre-requirements.txt
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
pip>=23.0.0
|
|
|
|
requirements.txt
CHANGED
@@ -1,13 +1,5 @@
|
|
1 |
-
stablepy
|
2 |
-
torch==2.
|
3 |
-
diffusers
|
4 |
gdown
|
5 |
opencv-python
|
6 |
-
unidecode
|
7 |
-
pydantic==2.10.6
|
8 |
-
huggingface_hub
|
9 |
-
hf_transfer
|
10 |
-
hf_xet
|
11 |
-
spaces
|
12 |
-
gradio==5.44.1
|
13 |
-
matplotlib-inline
|
|
|
1 |
+
git+https://github.com/R3gm/stablepy.git@a9fe2dc # -b refactor_sampler_fix
|
2 |
+
torch==2.2.0
|
|
|
3 |
gdown
|
4 |
opencv-python
|
5 |
+
unidecode
|
|
|
|
|
|
|
|
|
|
|
|
|
|
utils.py
CHANGED
@@ -9,7 +9,6 @@ from constants import (
|
|
9 |
DIRECTORY_LORAS,
|
10 |
DIRECTORY_MODELS,
|
11 |
DIFFUSECRAFT_CHECKPOINT_NAME,
|
12 |
-
CACHE_HF_ROOT,
|
13 |
CACHE_HF,
|
14 |
STORAGE_ROOT,
|
15 |
)
|
@@ -29,7 +28,6 @@ from urllib3.util import Retry
|
|
29 |
import shutil
|
30 |
import subprocess
|
31 |
|
32 |
-
IS_ZERO_GPU = bool(os.getenv("SPACES_ZERO_GPU"))
|
33 |
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:127.0) Gecko/20100101 Firefox/127.0'
|
34 |
|
35 |
|
@@ -64,12 +62,11 @@ class ModelInformation:
|
|
64 |
self.download_url = json_data.get("downloadUrl", "")
|
65 |
self.model_url = f"https://civitai.com/models/{self.model_id}?modelVersionId={self.model_version_id}"
|
66 |
self.filename_url = next(
|
67 |
-
(v.get("name", "") for v in json_data.get("files", []) if str(self.model_version_id) in v.get("downloadUrl", "")
|
68 |
)
|
69 |
self.filename_url = self.filename_url if self.filename_url else ""
|
70 |
self.description = json_data.get("description", "")
|
71 |
-
if self.description is None:
|
72 |
-
self.description = ""
|
73 |
self.model_name = json_data.get("model", {}).get("name", "")
|
74 |
self.model_type = json_data.get("model", {}).get("type", "")
|
75 |
self.nsfw = json_data.get("model", {}).get("nsfw", False)
|
@@ -79,175 +76,118 @@ class ModelInformation:
|
|
79 |
self.original_json = copy.deepcopy(json_data)
|
80 |
|
81 |
|
82 |
-
def
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
else:
|
89 |
-
ValueError("Invalid Civitai model URL")
|
90 |
-
except Exception as e:
|
91 |
-
print(f"Error retrieving Civitai metadata: {e} — fallback to direct download")
|
92 |
-
return url, None, None
|
93 |
-
|
94 |
-
|
95 |
-
def civ_redirect_down(url, dir_, civitai_api_key, romanize, alternative_name):
|
96 |
-
filename_base = filename = None
|
97 |
-
|
98 |
-
if alternative_name:
|
99 |
-
output_path = os.path.join(dir_, alternative_name)
|
100 |
-
if os.path.exists(output_path):
|
101 |
-
return output_path, alternative_name
|
102 |
-
|
103 |
-
# Follow the redirect to get the actual download URL
|
104 |
-
curl_command = (
|
105 |
-
f'curl -L -sI --connect-timeout 5 --max-time 5 '
|
106 |
-
f'-H "Content-Type: application/json" '
|
107 |
-
f'-H "Authorization: Bearer {civitai_api_key}" "{url}"'
|
108 |
-
)
|
109 |
-
|
110 |
-
headers = os.popen(curl_command).read()
|
111 |
-
|
112 |
-
# Look for the redirected "Location" URL
|
113 |
-
location_match = re.search(r'location: (.+)', headers, re.IGNORECASE)
|
114 |
|
115 |
-
if location_match:
|
116 |
-
redirect_url = location_match.group(1).strip()
|
117 |
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
encoded_filename = filename_match.group(1)
|
122 |
-
# Decode the URL-encoded filename
|
123 |
-
decoded_filename = urllib.parse.unquote(encoded_filename)
|
124 |
|
125 |
-
|
126 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
127 |
|
128 |
-
|
129 |
-
if not filename_base:
|
130 |
-
return None, None
|
131 |
-
elif os.path.exists(os.path.join(dir_, filename_base)):
|
132 |
-
return os.path.join(dir_, filename_base), filename_base
|
133 |
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
r_code = os.system(aria2_command) # noqa
|
139 |
|
140 |
-
|
141 |
-
# raise RuntimeError(f"Failed to download file: {filename_base}. Error code: {r_code}")
|
142 |
|
143 |
-
|
144 |
-
if not os.path.exists(output_path):
|
145 |
-
return None, filename_base
|
146 |
|
147 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
148 |
|
|
|
|
|
149 |
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
If an API key limit is reached, generating a new API key and using it can fix the issue.
|
154 |
-
"""
|
155 |
-
output_path = None
|
156 |
|
157 |
-
|
158 |
-
|
159 |
-
|
|
|
160 |
os.system(aria2_command)
|
161 |
-
else:
|
162 |
-
output_path = os.path.join(dir_, civ_filename)
|
163 |
-
if not os.path.exists(output_path):
|
164 |
-
aria2_command = (
|
165 |
-
f'aria2c --console-log-level=error --summary-interval=10 -c -x 16 '
|
166 |
-
f'-k 1M -s 16 -d "{dir_}" -o "{civ_filename}" "{url_dl}"'
|
167 |
-
)
|
168 |
-
os.system(aria2_command)
|
169 |
-
|
170 |
-
return output_path
|
171 |
-
|
172 |
-
|
173 |
-
def drive_down(url, dir_):
|
174 |
-
import gdown
|
175 |
-
|
176 |
-
output_path = None
|
177 |
|
178 |
-
|
179 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
180 |
|
181 |
-
for dfile in dir_files:
|
182 |
-
if drive_id in dfile:
|
183 |
-
output_path = os.path.join(dir_, dfile)
|
184 |
-
break
|
185 |
-
|
186 |
-
if not output_path:
|
187 |
-
original_path = gdown.download(url, f"{dir_}/", fuzzy=True)
|
188 |
-
|
189 |
-
dir_name, base_name = os.path.split(original_path)
|
190 |
-
name, ext = base_name.rsplit(".", 1)
|
191 |
-
new_name = f"{name}_{drive_id}.{ext}"
|
192 |
-
output_path = os.path.join(dir_name, new_name)
|
193 |
-
|
194 |
-
os.rename(original_path, output_path)
|
195 |
-
|
196 |
-
return output_path
|
197 |
-
|
198 |
-
|
199 |
-
def hf_down(url, dir_, hf_token, romanize):
|
200 |
-
url = url.replace("?download=true", "")
|
201 |
-
# url = urllib.parse.quote(url, safe=':/') # fix encoding
|
202 |
-
|
203 |
-
filename = unidecode(url.split('/')[-1]) if romanize else url.split('/')[-1]
|
204 |
-
output_path = os.path.join(dir_, filename)
|
205 |
-
|
206 |
-
if os.path.exists(output_path):
|
207 |
-
return output_path
|
208 |
-
|
209 |
-
if "/blob/" in url:
|
210 |
-
url = url.replace("/blob/", "/resolve/")
|
211 |
-
|
212 |
-
if hf_token:
|
213 |
-
user_header = f'"Authorization: Bearer {hf_token}"'
|
214 |
-
os.system(f"aria2c --console-log-level=error --summary-interval=10 --header={user_header} -c -x 16 -k 1M -s 16 {url} -d {dir_} -o {filename}")
|
215 |
-
else:
|
216 |
-
os.system(f"aria2c --optimize-concurrent-downloads --console-log-level=error --summary-interval=10 -c -x 16 -k 1M -s 16 {url} -d {dir_} -o {filename}")
|
217 |
-
|
218 |
-
return output_path
|
219 |
-
|
220 |
-
|
221 |
-
def download_things(directory, url, hf_token="", civitai_api_key="", romanize=False):
|
222 |
-
url = url.strip()
|
223 |
-
downloaded_file_path = None
|
224 |
-
|
225 |
-
if "drive.google.com" in url:
|
226 |
-
downloaded_file_path = drive_down(url, directory)
|
227 |
-
elif "huggingface.co" in url:
|
228 |
-
downloaded_file_path = hf_down(url, directory, hf_token, romanize)
|
229 |
-
elif "civitai.com" in url:
|
230 |
-
if not civitai_api_key:
|
231 |
-
msg = "You need an API key to download Civitai models."
|
232 |
-
print(f"\033[91m{msg}\033[0m")
|
233 |
-
gr.Warning(msg)
|
234 |
-
return None
|
235 |
-
|
236 |
-
url, civ_filename, civ_page = get_civit_params(url)
|
237 |
-
if civ_page and not IS_ZERO_GPU:
|
238 |
-
print(f"\033[92mCivitai model: {civ_filename} [page: {civ_page}]\033[0m")
|
239 |
-
|
240 |
-
downloaded_file_path, civ_filename = civ_redirect_down(url, directory, civitai_api_key, romanize, civ_filename)
|
241 |
-
|
242 |
-
if not downloaded_file_path:
|
243 |
-
msg = (
|
244 |
-
"Download failed.\n"
|
245 |
-
"If this is due to an API limit, generating a new API key may resolve the issue.\n"
|
246 |
-
"Attempting to download using the old method..."
|
247 |
-
)
|
248 |
-
print(msg)
|
249 |
-
gr.Warning(msg)
|
250 |
-
downloaded_file_path = civ_api_down(url, directory, civitai_api_key, civ_filename)
|
251 |
else:
|
252 |
os.system(f"aria2c --console-log-level=error --summary-interval=10 -c -x 16 -k 1M -s 16 -d {directory} {url}")
|
253 |
|
@@ -276,15 +216,14 @@ def extract_parameters(input_string):
|
|
276 |
if "Steps:" in input_string:
|
277 |
input_string = input_string.replace("Steps:", "Negative prompt: Steps:")
|
278 |
else:
|
279 |
-
|
280 |
-
gr.Warning(msg)
|
281 |
-
print(msg)
|
282 |
parameters["prompt"] = input_string
|
283 |
return parameters
|
284 |
|
285 |
parm = input_string.split("Negative prompt:")
|
286 |
parameters["prompt"] = parm[0].strip()
|
287 |
if "Steps:" not in parm[1]:
|
|
|
288 |
parameters["neg_prompt"] = parm[1].strip()
|
289 |
return parameters
|
290 |
parm = parm[1].split("Steps:")
|
@@ -361,14 +300,13 @@ def get_model_type(repo_id: str):
|
|
361 |
default = "SD 1.5"
|
362 |
try:
|
363 |
if os.path.exists(repo_id):
|
364 |
-
tag
|
365 |
return DIFFUSECRAFT_CHECKPOINT_NAME[tag]
|
366 |
else:
|
367 |
model = api.model_info(repo_id=repo_id, timeout=5.0)
|
368 |
tags = model.tags
|
369 |
for tag in tags:
|
370 |
-
if tag in MODEL_TYPE_CLASS.keys():
|
371 |
-
return MODEL_TYPE_CLASS.get(tag, default)
|
372 |
|
373 |
except Exception:
|
374 |
return default
|
@@ -495,9 +433,9 @@ def get_folder_size_gb(folder_path):
|
|
495 |
return total_size_gb
|
496 |
|
497 |
|
498 |
-
def get_used_storage_gb(
|
499 |
try:
|
500 |
-
used_gb = get_folder_size_gb(
|
501 |
print(f"Used Storage: {used_gb:.2f} GB")
|
502 |
except Exception as e:
|
503 |
used_gb = 999
|
@@ -517,21 +455,6 @@ def delete_model(removal_candidate):
|
|
517 |
shutil.rmtree(diffusers_model)
|
518 |
|
519 |
|
520 |
-
def clear_hf_cache():
|
521 |
-
"""
|
522 |
-
Clears the entire Hugging Face cache at ~/.cache/huggingface.
|
523 |
-
Hugging Face will re-download models as needed later.
|
524 |
-
"""
|
525 |
-
try:
|
526 |
-
if os.path.exists(CACHE_HF_ROOT):
|
527 |
-
shutil.rmtree(CACHE_HF_ROOT, ignore_errors=True)
|
528 |
-
print(f"Hugging Face cache cleared: {CACHE_HF_ROOT}")
|
529 |
-
else:
|
530 |
-
print(f"No Hugging Face cache found at: {CACHE_HF_ROOT}")
|
531 |
-
except Exception as e:
|
532 |
-
print(f"Error clearing Hugging Face cache: {e}")
|
533 |
-
|
534 |
-
|
535 |
def progress_step_bar(step, total):
|
536 |
# Calculate the percentage for the progress bar width
|
537 |
percentage = min(100, ((step / total) * 100))
|
|
|
9 |
DIRECTORY_LORAS,
|
10 |
DIRECTORY_MODELS,
|
11 |
DIFFUSECRAFT_CHECKPOINT_NAME,
|
|
|
12 |
CACHE_HF,
|
13 |
STORAGE_ROOT,
|
14 |
)
|
|
|
28 |
import shutil
|
29 |
import subprocess
|
30 |
|
|
|
31 |
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:127.0) Gecko/20100101 Firefox/127.0'
|
32 |
|
33 |
|
|
|
62 |
self.download_url = json_data.get("downloadUrl", "")
|
63 |
self.model_url = f"https://civitai.com/models/{self.model_id}?modelVersionId={self.model_version_id}"
|
64 |
self.filename_url = next(
|
65 |
+
(v.get("name", "") for v in reversed(json_data.get("files", [])) if str(self.model_version_id) in v.get("downloadUrl", "")), ""
|
66 |
)
|
67 |
self.filename_url = self.filename_url if self.filename_url else ""
|
68 |
self.description = json_data.get("description", "")
|
69 |
+
if self.description is None: self.description = ""
|
|
|
70 |
self.model_name = json_data.get("model", {}).get("name", "")
|
71 |
self.model_type = json_data.get("model", {}).get("type", "")
|
72 |
self.nsfw = json_data.get("model", {}).get("nsfw", False)
|
|
|
76 |
self.original_json = copy.deepcopy(json_data)
|
77 |
|
78 |
|
79 |
+
def retrieve_model_info(url):
|
80 |
+
json_data = request_json_data(url)
|
81 |
+
if not json_data:
|
82 |
+
return None
|
83 |
+
model_descriptor = ModelInformation(json_data)
|
84 |
+
return model_descriptor
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
85 |
|
|
|
|
|
86 |
|
87 |
+
def download_things(directory, url, hf_token="", civitai_api_key="", romanize=False):
|
88 |
+
url = url.strip()
|
89 |
+
downloaded_file_path = None
|
|
|
|
|
|
|
90 |
|
91 |
+
if "drive.google.com" in url:
|
92 |
+
original_dir = os.getcwd()
|
93 |
+
os.chdir(directory)
|
94 |
+
os.system(f"gdown --fuzzy {url}")
|
95 |
+
os.chdir(original_dir)
|
96 |
+
elif "huggingface.co" in url:
|
97 |
+
url = url.replace("?download=true", "")
|
98 |
+
# url = urllib.parse.quote(url, safe=':/') # fix encoding
|
99 |
+
if "/blob/" in url:
|
100 |
+
url = url.replace("/blob/", "/resolve/")
|
101 |
+
user_header = f'"Authorization: Bearer {hf_token}"'
|
102 |
|
103 |
+
filename = unidecode(url.split('/')[-1]) if romanize else url.split('/')[-1]
|
|
|
|
|
|
|
|
|
104 |
|
105 |
+
if hf_token:
|
106 |
+
os.system(f"aria2c --console-log-level=error --summary-interval=10 --header={user_header} -c -x 16 -k 1M -s 16 {url} -d {directory} -o {filename}")
|
107 |
+
else:
|
108 |
+
os.system(f"aria2c --optimize-concurrent-downloads --console-log-level=error --summary-interval=10 -c -x 16 -k 1M -s 16 {url} -d {directory} -o {filename}")
|
|
|
109 |
|
110 |
+
downloaded_file_path = os.path.join(directory, filename)
|
|
|
111 |
|
112 |
+
elif "civitai.com" in url:
|
|
|
|
|
113 |
|
114 |
+
if not civitai_api_key:
|
115 |
+
print("\033[91mYou need an API key to download Civitai models.\033[0m")
|
116 |
+
|
117 |
+
model_profile = retrieve_model_info(url)
|
118 |
+
if (
|
119 |
+
model_profile is not None
|
120 |
+
and model_profile.download_url
|
121 |
+
and model_profile.filename_url
|
122 |
+
):
|
123 |
+
url = model_profile.download_url
|
124 |
+
filename = unidecode(model_profile.filename_url) if romanize else model_profile.filename_url
|
125 |
+
else:
|
126 |
+
if "?" in url:
|
127 |
+
url = url.split("?")[0]
|
128 |
+
filename = ""
|
129 |
|
130 |
+
url_dl = url + f"?token={civitai_api_key}"
|
131 |
+
print(f"Filename: {filename}")
|
132 |
|
133 |
+
param_filename = ""
|
134 |
+
if filename:
|
135 |
+
param_filename = f"-o '{filename}'"
|
|
|
|
|
|
|
136 |
|
137 |
+
aria2_command = (
|
138 |
+
f'aria2c --console-log-level=error --summary-interval=10 -c -x 16 '
|
139 |
+
f'-k 1M -s 16 -d "{directory}" {param_filename} "{url_dl}"'
|
140 |
+
)
|
141 |
os.system(aria2_command)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
142 |
|
143 |
+
if param_filename and os.path.exists(os.path.join(directory, filename)):
|
144 |
+
downloaded_file_path = os.path.join(directory, filename)
|
145 |
+
|
146 |
+
# # PLAN B
|
147 |
+
# # Follow the redirect to get the actual download URL
|
148 |
+
# curl_command = (
|
149 |
+
# f'curl -L -sI --connect-timeout 5 --max-time 5 '
|
150 |
+
# f'-H "Content-Type: application/json" '
|
151 |
+
# f'-H "Authorization: Bearer {civitai_api_key}" "{url}"'
|
152 |
+
# )
|
153 |
+
|
154 |
+
# headers = os.popen(curl_command).read()
|
155 |
+
|
156 |
+
# # Look for the redirected "Location" URL
|
157 |
+
# location_match = re.search(r'location: (.+)', headers, re.IGNORECASE)
|
158 |
+
|
159 |
+
# if location_match:
|
160 |
+
# redirect_url = location_match.group(1).strip()
|
161 |
+
|
162 |
+
# # Extract the filename from the redirect URL's "Content-Disposition"
|
163 |
+
# filename_match = re.search(r'filename%3D%22(.+?)%22', redirect_url)
|
164 |
+
# if filename_match:
|
165 |
+
# encoded_filename = filename_match.group(1)
|
166 |
+
# # Decode the URL-encoded filename
|
167 |
+
# decoded_filename = urllib.parse.unquote(encoded_filename)
|
168 |
+
|
169 |
+
# filename = unidecode(decoded_filename) if romanize else decoded_filename
|
170 |
+
# print(f"Filename: {filename}")
|
171 |
+
|
172 |
+
# aria2_command = (
|
173 |
+
# f'aria2c --console-log-level=error --summary-interval=10 -c -x 16 '
|
174 |
+
# f'-k 1M -s 16 -d "{directory}" -o "{filename}" "{redirect_url}"'
|
175 |
+
# )
|
176 |
+
# return_code = os.system(aria2_command)
|
177 |
+
|
178 |
+
# # if return_code != 0:
|
179 |
+
# # raise RuntimeError(f"Failed to download file: {filename}. Error code: {return_code}")
|
180 |
+
# downloaded_file_path = os.path.join(directory, filename)
|
181 |
+
# if not os.path.exists(downloaded_file_path):
|
182 |
+
# downloaded_file_path = None
|
183 |
+
|
184 |
+
# if not downloaded_file_path:
|
185 |
+
# # Old method
|
186 |
+
# if "?" in url:
|
187 |
+
# url = url.split("?")[0]
|
188 |
+
# url = url + f"?token={civitai_api_key}"
|
189 |
+
# os.system(f"aria2c --console-log-level=error --summary-interval=10 -c -x 16 -k 1M -s 16 -d {directory} {url}")
|
190 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
191 |
else:
|
192 |
os.system(f"aria2c --console-log-level=error --summary-interval=10 -c -x 16 -k 1M -s 16 -d {directory} {url}")
|
193 |
|
|
|
216 |
if "Steps:" in input_string:
|
217 |
input_string = input_string.replace("Steps:", "Negative prompt: Steps:")
|
218 |
else:
|
219 |
+
print("Invalid metadata")
|
|
|
|
|
220 |
parameters["prompt"] = input_string
|
221 |
return parameters
|
222 |
|
223 |
parm = input_string.split("Negative prompt:")
|
224 |
parameters["prompt"] = parm[0].strip()
|
225 |
if "Steps:" not in parm[1]:
|
226 |
+
print("Steps not detected")
|
227 |
parameters["neg_prompt"] = parm[1].strip()
|
228 |
return parameters
|
229 |
parm = parm[1].split("Steps:")
|
|
|
300 |
default = "SD 1.5"
|
301 |
try:
|
302 |
if os.path.exists(repo_id):
|
303 |
+
tag = checkpoint_model_type(repo_id)
|
304 |
return DIFFUSECRAFT_CHECKPOINT_NAME[tag]
|
305 |
else:
|
306 |
model = api.model_info(repo_id=repo_id, timeout=5.0)
|
307 |
tags = model.tags
|
308 |
for tag in tags:
|
309 |
+
if tag in MODEL_TYPE_CLASS.keys(): return MODEL_TYPE_CLASS.get(tag, default)
|
|
|
310 |
|
311 |
except Exception:
|
312 |
return default
|
|
|
433 |
return total_size_gb
|
434 |
|
435 |
|
436 |
+
def get_used_storage_gb():
|
437 |
try:
|
438 |
+
used_gb = get_folder_size_gb(STORAGE_ROOT)
|
439 |
print(f"Used Storage: {used_gb:.2f} GB")
|
440 |
except Exception as e:
|
441 |
used_gb = 999
|
|
|
455 |
shutil.rmtree(diffusers_model)
|
456 |
|
457 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
458 |
def progress_step_bar(step, total):
|
459 |
# Calculate the percentage for the progress bar width
|
460 |
percentage = min(100, ((step / total) * 100))
|