mirror of
https://github.com/vladmandic/automatic
synced 2026-08-26 15:16:01 +02:00
optional model loader and integrate image info
This commit is contained in:
@@ -19,18 +19,23 @@ body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Any issues without version information will be closed
|
||||
Look at console log and copy the version string from there
|
||||
For example: `Version: f256fb8b Fri Apr 14 17:41:30 2023 -0400`
|
||||
Any issues without version information will be closed
|
||||
Look at console log and copy the version string from there
|
||||
For example: `Version: f256fb8b Fri Apr 14 17:41:30 2023 -0400`
|
||||
|
||||
Additionally provide any relevant platorm information (OS, browser, versions)
|
||||
Additionally provide any relevant platorm information (OS, browser, versions)
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
If issue is setup, installation or startup related, please check `setup.log` before reporting
|
||||
And when posting console logs, please use code blocks (\`\`\`) to format them insead of uploading screenshots
|
||||
And when posting console logs, please use code blocks ( \`\`\` ) to format them insead of uploading screenshots
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
If possible update to latest version before reporting the issue as older versions cannot be properly supported
|
||||
And search existing **issues** and **discussions** before creating a new one
|
||||
If you have additional extensions installed, try to reproduce the issue with user extensions disabled
|
||||
And if the issue is with compatibility with specific extension, mark it as such when creating the issue
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
If possible update to latest version before reporting the issue as older versions cannot be properly supported
|
||||
And search existing **issues** and **discussions** before creating a new one
|
||||
|
||||
@@ -1,24 +1,29 @@
|
||||
# TODO
|
||||
|
||||
## Always-on
|
||||
|
||||
- Pick & merge PRs from main repo
|
||||
|
||||
## Fixes
|
||||
|
||||
Stuff to be fixed...
|
||||
|
||||
- Reconnect UI to ops in progress on browser restart
|
||||
- Redo Extensions tab: see <https://vladmandic.github.io/sd-extension-manager/pages/extensions.html>
|
||||
- Cleanup & integrate CSS into single file
|
||||
- Replace PngInfo/EXIF metadata handler
|
||||
- Pick & merge PRs from main repo
|
||||
- Create new GitHub hooks/actions for CI/CD
|
||||
- Investigate integration with `Torch-DirectML`
|
||||
- Set defaults for Apple M1
|
||||
- Revisit `torch.compile`
|
||||
- Ask to download default model
|
||||
- Stream-load as option
|
||||
- Dont spawn extensions installer
|
||||
- Remove `models` from git repo
|
||||
- Merge `Image Info` into `Process`
|
||||
- Refresh theme list
|
||||
|
||||
## Features
|
||||
|
||||
- Redo Extensions tab: see <https://vladmandic.github.io/sd-extension-manager/pages/extensions.html>
|
||||
- Stream-load models as option for slow storage
|
||||
- Replace **PngInfo** / **EXIF** metadata handler
|
||||
- Investigate integration with `Torch-DirectML`
|
||||
- Investigate best practices for **Apple M1**
|
||||
- Investigate best practices for **AMD GPUs**
|
||||
|
||||
## Investigate
|
||||
|
||||
- Revisit `torch.compile`
|
||||
|
||||
## Integration
|
||||
|
||||
|
||||
Submodule extensions-builtin/sd-webui-controlnet updated: 1dc09b161a...80c7a6cc95
@@ -50,7 +50,7 @@ def load_models(model_path: str, model_url: str = None, command_path: str = None
|
||||
if ext_blacklist is not None and any([full_path.endswith(x) for x in ext_blacklist]):
|
||||
continue
|
||||
if len(ext_filter) != 0:
|
||||
model_name, extension = os.path.splitext(file)
|
||||
_model_name, extension = os.path.splitext(file)
|
||||
if extension not in ext_filter:
|
||||
continue
|
||||
if file not in output:
|
||||
@@ -75,7 +75,7 @@ def friendly_name(file: str):
|
||||
file = urlparse(file).path
|
||||
|
||||
file = os.path.basename(file)
|
||||
model_name, extension = os.path.splitext(file)
|
||||
model_name, _extension = os.path.splitext(file)
|
||||
return model_name
|
||||
|
||||
|
||||
|
||||
+21
-28
@@ -22,7 +22,7 @@ model_dir = "Stable-diffusion"
|
||||
model_path = os.path.abspath(os.path.join(paths.models_path, model_dir))
|
||||
|
||||
checkpoints_list = {}
|
||||
checkpoint_alisases = {}
|
||||
checkpoint_aliases = {}
|
||||
checkpoints_loaded = collections.OrderedDict()
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ class CheckpointInfo:
|
||||
def register(self):
|
||||
checkpoints_list[self.title] = self
|
||||
for i in self.ids:
|
||||
checkpoint_alisases[i] = self
|
||||
checkpoint_aliases[i] = self
|
||||
|
||||
def calculate_shorthash(self):
|
||||
self.sha256 = hashes.sha256(self.filename, "checkpoint/" + self.name)
|
||||
@@ -103,32 +103,31 @@ def checkpoint_tiles():
|
||||
|
||||
def list_models():
|
||||
checkpoints_list.clear()
|
||||
checkpoint_alisases.clear()
|
||||
|
||||
cmd_ckpt = shared.cmd_opts.ckpt
|
||||
if shared.cmd_opts.no_download_sd_model or cmd_ckpt != shared.sd_model_file or os.path.exists(cmd_ckpt):
|
||||
model_url = None
|
||||
else:
|
||||
model_url = "https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/main/v1-5-pruned-emaonly.safetensors"
|
||||
|
||||
model_list = modelloader.load_models(model_path=model_path, model_url=model_url, command_path=shared.opts.ckpt_dir, ext_filter=[".ckpt", ".safetensors"], download_name="v1-5-pruned-emaonly.safetensors", ext_blacklist=[".vae.ckpt", ".vae.safetensors"])
|
||||
|
||||
if os.path.exists(cmd_ckpt):
|
||||
checkpoint_info = CheckpointInfo(cmd_ckpt)
|
||||
checkpoint_aliases.clear()
|
||||
model_list = modelloader.load_models(model_path=model_path, model_url=None, command_path=shared.opts.ckpt_dir, ext_filter=[".ckpt", ".safetensors"], download_name=None, ext_blacklist=[".vae.ckpt", ".vae.safetensors"])
|
||||
if shared.cmd_opts.ckpt is not None and os.path.exists(shared.cmd_opts.ckpt):
|
||||
checkpoint_info = CheckpointInfo(shared.cmd_opts.ckpt)
|
||||
checkpoint_info.register()
|
||||
shared.opts.data['sd_model_checkpoint'] = checkpoint_info.title
|
||||
elif cmd_ckpt is not None and cmd_ckpt != shared.default_sd_model_file:
|
||||
print("Checkpoint in --ckpt argument not found", file=sys.stderr)
|
||||
|
||||
elif shared.cmd_opts.ckpt != shared.default_sd_model_file:
|
||||
print(f"Checkpoint not found: {shared.cmd_opts.ckpt}", file=sys.stderr)
|
||||
for filename in sorted(model_list, key=str.lower):
|
||||
checkpoint_info = CheckpointInfo(filename)
|
||||
checkpoint_info.register()
|
||||
|
||||
shared.log.info(f'Available models: {shared.opts.ckpt_dir} {len(checkpoints_list)}')
|
||||
print(f'Available models: {shared.opts.ckpt_dir} {len(checkpoints_list)}')
|
||||
if len(checkpoints_list) == 0:
|
||||
if not shared.cmd_opts.no_download_sd_model:
|
||||
key = input('Download the default model? (y/N) ')
|
||||
if key.lower().startswith == 'y':
|
||||
model_url = "https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/main/v1-5-pruned-emaonly.safetensors"
|
||||
model_list = modelloader.load_models(model_path=model_path, model_url=model_url, command_path=shared.opts.ckpt_dir, ext_filter=[".ckpt", ".safetensors"], download_name="v1-5-pruned-emaonly.safetensors", ext_blacklist=[".vae.ckpt", ".vae.safetensors"])
|
||||
for filename in sorted(model_list, key=str.lower):
|
||||
checkpoint_info = CheckpointInfo(filename)
|
||||
checkpoint_info.register()
|
||||
|
||||
|
||||
def get_closet_checkpoint_match(search_string):
|
||||
checkpoint_info = checkpoint_alisases.get(search_string, None)
|
||||
checkpoint_info = checkpoint_aliases.get(search_string, None)
|
||||
if checkpoint_info is not None:
|
||||
return checkpoint_info
|
||||
|
||||
@@ -157,18 +156,12 @@ def model_hash(filename):
|
||||
def select_checkpoint():
|
||||
model_checkpoint = shared.opts.sd_model_checkpoint
|
||||
|
||||
checkpoint_info = checkpoint_alisases.get(model_checkpoint, None)
|
||||
checkpoint_info = checkpoint_aliases.get(model_checkpoint, None)
|
||||
if checkpoint_info is not None:
|
||||
return checkpoint_info
|
||||
|
||||
if len(checkpoints_list) == 0:
|
||||
print("No checkpoints found. When searching for checkpoints, looked at:", file=sys.stderr)
|
||||
if shared.cmd_opts.ckpt is not None:
|
||||
print(f" - file {os.path.abspath(shared.cmd_opts.ckpt)}", file=sys.stderr)
|
||||
print(f" - directory {model_path}", file=sys.stderr)
|
||||
if shared.opts.ckpt_dir is not None:
|
||||
print(f" - directory {os.path.abspath(shared.opts.ckpt_dir)}", file=sys.stderr)
|
||||
print("Can't run without a checkpoint. Find and place a .ckpt or .safetensors file into any of those locations. The program will exit.", file=sys.stderr)
|
||||
print("Cannot run without a checkpoint", file=sys.stderr)
|
||||
exit(1)
|
||||
|
||||
checkpoint_info = next(iter(checkpoints_list.values()))
|
||||
|
||||
+4
-2
@@ -925,6 +925,7 @@ def create_ui():
|
||||
with gr.Blocks(analytics_enabled=False) as extras_interface:
|
||||
ui_postprocessing.create_ui()
|
||||
|
||||
"""
|
||||
with gr.Blocks(analytics_enabled=False) as pnginfo_interface:
|
||||
with gr.Row().style(equal_height=False):
|
||||
with gr.Column(variant='panel'):
|
||||
@@ -947,6 +948,7 @@ def create_ui():
|
||||
inputs=[image],
|
||||
outputs=[html, generation_info, html2],
|
||||
)
|
||||
"""
|
||||
|
||||
def update_interp_description(value):
|
||||
interp_description_css = "<p style='margin-bottom: 2.5em'>{}</p>"
|
||||
@@ -1480,8 +1482,8 @@ def create_ui():
|
||||
interfaces = [
|
||||
(txt2img_interface, "From Text", "txt2img"),
|
||||
(img2img_interface, "From Image", "img2img"),
|
||||
(extras_interface, "Process", "extras"),
|
||||
(pnginfo_interface, "Image Info", "pnginfo"),
|
||||
(extras_interface, "Process Image", "extras"),
|
||||
# (pnginfo_interface, "Image Info", "pnginfo"),
|
||||
# (modelmerger_interface, "Checkpoint Merger", "modelmerger"),
|
||||
(train_interface, "Train", "ti"),
|
||||
]
|
||||
|
||||
@@ -119,7 +119,7 @@ Requested path was: {f}
|
||||
if not shared.cmd_opts.hide_ui_dir_config:
|
||||
path = os.path.normpath(f)
|
||||
if platform.system() == "Windows":
|
||||
os.startfile(path)
|
||||
os.startfile(path) # pylint: disable=no-member
|
||||
elif platform.system() == "Darwin":
|
||||
sp.Popen(["open", path])
|
||||
elif "microsoft-standard-WSL2" in platform.uname().release:
|
||||
@@ -134,7 +134,7 @@ Requested path was: {f}
|
||||
generation_info = None
|
||||
with gr.Column():
|
||||
with gr.Row(elem_id=f"image_buttons_{tabname}", elem_classes="image-buttons"):
|
||||
open_folder_button = gr.Button('Load', visible=not shared.cmd_opts.hide_ui_dir_config)
|
||||
open_folder_button = gr.Button('show', visible=not shared.cmd_opts.hide_ui_dir_config)
|
||||
|
||||
if tabname != "extras":
|
||||
save = gr.Button('Save', elem_id=f'save_{tabname}')
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import gradio as gr
|
||||
from modules import scripts_postprocessing, scripts, shared, gfpgan_model, codeformer_model, ui_common, postprocessing, call_queue
|
||||
import modules.generation_parameters_copypaste as parameters_copypaste
|
||||
|
||||
from modules.call_queue import wrap_gradio_gpu_call, wrap_queued_call, wrap_gradio_call
|
||||
from modules.extras import run_pnginfo
|
||||
|
||||
def create_ui():
|
||||
tab_index = gr.State(value=0)
|
||||
@@ -9,28 +10,44 @@ def create_ui():
|
||||
with gr.Row().style(equal_height=False, variant='compact'):
|
||||
with gr.Column(variant='compact'):
|
||||
with gr.Tabs(elem_id="mode_extras"):
|
||||
with gr.TabItem('Single Image', elem_id="extras_single_tab") as tab_single:
|
||||
|
||||
with gr.TabItem('Process Image', elem_id="extras_single_tab") as tab_single:
|
||||
extras_image = gr.Image(label="Source", source="upload", interactive=True, type="pil", elem_id="extras_image")
|
||||
|
||||
with gr.TabItem('Batch Process', elem_id="extras_batch_process_tab") as tab_batch:
|
||||
with gr.TabItem('Process Batch', elem_id="extras_batch_process_tab") as tab_batch:
|
||||
image_batch = gr.File(label="Batch Process", file_count="multiple", interactive=True, type="file", elem_id="extras_image_batch")
|
||||
|
||||
with gr.TabItem('Batch from Directory', elem_id="extras_batch_directory_tab") as tab_batch_dir:
|
||||
with gr.TabItem('Process Folder', elem_id="extras_batch_directory_tab") as tab_batch_dir:
|
||||
extras_batch_input_dir = gr.Textbox(label="Input directory", **shared.hide_dirs, placeholder="A directory on the same machine where the server is running.", elem_id="extras_batch_input_dir")
|
||||
extras_batch_output_dir = gr.Textbox(label="Output directory", **shared.hide_dirs, placeholder="Leave blank to save images to the default path.", elem_id="extras_batch_output_dir")
|
||||
show_extras_results = gr.Checkbox(label='Show result images', value=True, elem_id="extras_show_extras_results")
|
||||
|
||||
with gr.Row():
|
||||
buttons = parameters_copypaste.create_buttons(["txt2img", "img2img", "inpaint"])
|
||||
|
||||
submit = gr.Button('Generate', elem_id="extras_generate", variant='primary')
|
||||
|
||||
script_inputs = scripts.scripts_postproc.setup_ui()
|
||||
|
||||
with gr.Column():
|
||||
result_images, html_info_x, html_info, html_log = ui_common.create_output_panel("extras", shared.opts.outdir_extras_samples)
|
||||
html_info = gr.HTML()
|
||||
generation_info = gr.Textbox(visible=False, elem_id="pnginfo_generation_info")
|
||||
html2_info = gr.HTML()
|
||||
|
||||
for tabname, button in buttons.items():
|
||||
parameters_copypaste.register_paste_params_button(parameters_copypaste.ParamBinding(paste_button=button, tabname=tabname, source_text_component=generation_info, source_image_component=extras_image))
|
||||
|
||||
tab_single.select(fn=lambda: 0, inputs=[], outputs=[tab_index])
|
||||
tab_batch.select(fn=lambda: 1, inputs=[], outputs=[tab_index])
|
||||
tab_batch_dir.select(fn=lambda: 2, inputs=[], outputs=[tab_index])
|
||||
|
||||
extras_image.change(
|
||||
fn=wrap_gradio_call(run_pnginfo),
|
||||
inputs=[extras_image],
|
||||
outputs=[html_info, generation_info, html2_info],
|
||||
)
|
||||
|
||||
submit.click(
|
||||
fn=call_queue.wrap_gradio_gpu_call(postprocessing.run_postprocessing, extra_outputs=[None, '']),
|
||||
inputs=[
|
||||
|
||||
@@ -349,7 +349,7 @@ def check_extensions():
|
||||
newest = max(newest, ts)
|
||||
newest_all = max(newest_all, newest)
|
||||
log.debug(f'Extension version: {time.ctime(newest)} {folder}{os.pathsep}{ext}')
|
||||
return newest_all
|
||||
return round(newest_all)
|
||||
|
||||
|
||||
# check version of the main repo and optionally upgrade it
|
||||
@@ -393,10 +393,9 @@ def check_version():
|
||||
|
||||
# check if we can run setup in quick mode
|
||||
def check_timestamp():
|
||||
if not quick_allowed:
|
||||
return False
|
||||
if not os.path.isfile('setup.log'):
|
||||
if not quick_allowed or not os.path.isfile('setup.log'):
|
||||
return False
|
||||
ok = True
|
||||
setup_time = -1
|
||||
with open('setup.log', 'r', encoding='utf8') as f:
|
||||
lines = f.readlines()
|
||||
@@ -410,15 +409,16 @@ def check_timestamp():
|
||||
exit(1)
|
||||
log.debug(f'Repository update time: {time.ctime(int(version_time))}')
|
||||
if setup_time == -1:
|
||||
return False
|
||||
ok = False
|
||||
log.debug(f'Previous setup time: {time.ctime(setup_time)}')
|
||||
if setup_time < version_time:
|
||||
return False
|
||||
ok = False
|
||||
extension_time = check_extensions()
|
||||
log.debug(f'Latest extensions time: {time.ctime(extension_time)}')
|
||||
if setup_time < extension_time:
|
||||
return False
|
||||
return True
|
||||
ok = False
|
||||
log.debug(f'Timestamps: version:{version_time} setup:{setup_time} extension:{extension_time}')
|
||||
return ok
|
||||
|
||||
|
||||
def parse_args():
|
||||
|
||||
Reference in New Issue
Block a user