Merge branch 'dev' into ipadapter-end

This commit is contained in:
AI-Casanova
2024-02-12 21:59:42 -06:00
committed by GitHub
16 changed files with 170 additions and 170 deletions
+7 -2
View File
@@ -1,6 +1,6 @@
# Change Log for SD.Next
## Update for 2024-02-10
## Update for 2024-02-12
- **improvements**:
- **IP Adapter** major refactor
@@ -9,7 +9,7 @@
*note*: you cannot mix & match ip adapters that use different *CLiP* models, for example `Base` and `Base ViT-G`
- unified interface in txt2img, img2img and control
- enhanced xyz grid support
- **FaceID** now works with multiple input images
- **FaceID** now also works with multiple input images!
- **CFG End** new param to control image generation guidance, thanks @AI-Casanova
sometimes you want strong control over composition, but you want it to stop at some point
for example, when used with ip-adapters or controlnet, high cfg scale can overpower the guided image
@@ -55,6 +55,11 @@
- lazy loading of image may prevent metadata from being loaded on time
- allow startup without valid models folder
- fix interrogate api endpoint
- control fix resize causing runtime errors
- control fix processor override image after processor change
- fix vae dtype mismatch, thanks @Disty0
- fix controlnet inpaint mask
- bind controlnet extension to last known working commit, thanks @Aptronymist
- handle extensions that install conflicting versions of packages
`onnxruntime`, `opencv2-python`
+2 -2
View File
@@ -4,12 +4,12 @@ Main ToDo list can be found at [GitHub projects](https://github.com/users/vladma
## Candidates for next release
- diffusers public callbacks
- control second pass: <https://github.com/vladmandic/automatic/issues/2783>
- onediff: <https://github.com/siliconflow/onediff>
- diffusers public callbacks
- image2video: pia and vgen pipelines
- video2video
- control api
- masking api
- preprocess api
- bind panZoom to control input
- onediff: <https://github.com/siliconflow/onediff>
+5 -8
View File
@@ -47,7 +47,7 @@ args = Dot({
})
git_commit = "unknown"
submodules_commit = {
# 'sd-webui-controlnet': 'ecd33eb',
'sd-webui-controlnet': 'ecd33eb',
# 'stable-diffusion-webui-images-browser': '27fe4a7',
}
@@ -456,12 +456,6 @@ def check_torch():
xformers_package = os.environ.get('XFORMERS_PACKAGE', 'none')
if rocm_ver is not None:
install(os.environ.get('ONNXRUNTIME_PACKAGE', get_onnxruntime_source_for_rocm(arr)), "onnxruntime-training built with ROCm", ignore=True)
try:
import onnxruntime
if "ROCMExecutionProvider" not in onnxruntime.get_available_providers():
log.warning('Failed to automatically install onxnruntime package for ROCm. Please manually install it if you need.')
except Exception:
pass
elif allow_ipex and (args.use_ipex or shutil.which('sycl-ls') is not None or shutil.which('sycl-ls.exe') is not None or os.environ.get('ONEAPI_ROOT') is not None or os.path.exists('/opt/intel/oneapi') or os.path.exists("C:/Program Files (x86)/Intel/oneAPI") or os.path.exists("C:/oneAPI")):
args.use_ipex = True # pylint: disable=attribute-defined-outside-init
log.info('Intel OneAPI Toolkit detected')
@@ -864,7 +858,10 @@ def get_onnxruntime_source_for_rocm(rocm_ver):
if rocm_ver is None:
command = subprocess.run('hipconfig --version', shell=True, check=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
rocm_ver = command.stdout.decode(encoding="utf8", errors="ignore").split('.')
return f"https://download.onnxruntime.ai/onnxruntime_training-{ort_version}%2Brocm{rocm_ver[0]}{rocm_ver[1]}-cp{cp_str}-cp{cp_str}-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"
if "linux" in sys.platform:
return f"https://download.onnxruntime.ai/onnxruntime_training-{ort_version}%2Brocm{rocm_ver[0]}{rocm_ver[1]}-cp{cp_str}-cp{cp_str}-manylinux_2_17_x86_64.manylinux2014_x86_64.whl"
else:
return 'onnxruntime-gpu'
# check version of the main repo and optionally upgrade it
+4 -4
View File
@@ -126,7 +126,7 @@ class Processor():
def __init__(self, processor_id: str = None, resize = True):
self.model = None
self.processor_id = None
# self.override = None
self.override = None
self.resize = resize
self.reset()
self.config(processor_id)
@@ -138,7 +138,7 @@ class Processor():
debug(f'Control Processor unloaded: id="{self.processor_id}"')
self.model = None
self.processor_id = processor_id
self.override = None
# self.override = None
devices.torch_gc()
self.load_config = { 'cache_dir': cache_dir }
@@ -215,8 +215,8 @@ class Processor():
if resize_mode != 0 and resize_name != 'None':
if scale_tab == 1:
width_before, height_before = int(image_input.width * scale_by), int(image_input.height * scale_by)
debug(f'Control resize: op=before image={image_input} width={width_before} height={height_before} mode={resize_mode} name={resize_name}')
image_input = images.resize_image(resize_mode, image_input, width_before, height_before, resize_name)
debug(f'Control resize: op=before image={image_input} width={width_before} height={height_before} mode={resize_mode} name={resize_name}')
image_input = images.resize_image(resize_mode, image_input, width_before, height_before, resize_name)
image_process = image_input
if image_input is None:
# log.error('Control Processor: no input')
+2 -2
View File
@@ -6,7 +6,7 @@ import json
from PIL import Image
import gradio as gr
from modules.paths import data_path
from modules import shared, ui_tempdir, script_callbacks, images
from modules import shared, gr_tempdir, script_callbacks, images
re_param_code = r'\s*([\w ]+):\s*("(?:\\"[^,]|\\"|\\|[^\"])+"|[^,]*)(?:,|$)'
@@ -58,7 +58,7 @@ def image_from_url_text(filedata):
filedata = filedata[0]
if type(filedata) == dict and filedata.get("is_file", False):
filename = filedata["name"]
is_in_right_dir = ui_tempdir.check_tmp_file(shared.demo, filename)
is_in_right_dir = gr_tempdir.check_tmp_file(shared.demo, filename)
if is_in_right_dir:
filename = filename.rsplit('?', 1)[0]
if not os.path.exists(filename):
+64
View File
@@ -1,6 +1,13 @@
from PIL import Image
import gradio as gr
import gradio.processing_utils
from modules import scripts, patches, gr_tempdir
original_IOComponent_init = None
original_Block_get_config = None
original_BlockContext_init = None
original_Blocks_get_config_file = None
def gr_image_preprocess(self, x):
@@ -25,5 +32,62 @@ def gr_image_preprocess(self, x):
return self._format_image(im) # pylint: disable=protected-access
def add_classes_to_gradio_component(comp):
"""
this adds gradio-* to the component for css styling (ie gradio-button to gr.Button), as well as some others
"""
comp.elem_classes = [f"gradio-{comp.get_block_name()}", *(comp.elem_classes or [])]
if getattr(comp, 'multiselect', False):
comp.elem_classes.append('multiselect')
def IOComponent_init(self, *args, **kwargs):
self.webui_tooltip = kwargs.pop('tooltip', None)
if scripts.scripts_current is not None:
scripts.scripts_current.before_component(self, **kwargs)
scripts.script_callbacks.before_component_callback(self, **kwargs)
res = original_IOComponent_init(self, *args, **kwargs) # pylint: disable=assignment-from-no-return
add_classes_to_gradio_component(self)
scripts.script_callbacks.after_component_callback(self, **kwargs)
if scripts.scripts_current is not None:
scripts.scripts_current.after_component(self, **kwargs)
return res
def Block_get_config(self):
config = original_Block_get_config(self)
webui_tooltip = getattr(self, 'webui_tooltip', None)
if webui_tooltip:
config["webui_tooltip"] = webui_tooltip
config.pop('example_inputs', None)
return config
def BlockContext_init(self, *args, **kwargs):
if scripts.scripts_current is not None:
scripts.scripts_current.before_component(self, **kwargs)
scripts.script_callbacks.before_component_callback(self, **kwargs)
res = original_BlockContext_init(self, *args, **kwargs) # pylint: disable=assignment-from-no-return
add_classes_to_gradio_component(self)
scripts.script_callbacks.after_component_callback(self, **kwargs)
if scripts.scripts_current is not None:
scripts.scripts_current.after_component(self, **kwargs)
return res
def Blocks_get_config_file(self, *args, **kwargs):
config = original_Blocks_get_config_file(self, *args, **kwargs)
for comp_config in config["components"]:
if "example_inputs" in comp_config:
comp_config["example_inputs"] = {"serialized": []}
return config
def init():
global original_IOComponent_init, original_Block_get_config, original_BlockContext_init, original_Blocks_get_config_file # pylint: disable=global-statement
gr.components.Image.preprocess = gr_image_preprocess
gr.components.IOComponent.pil_to_temp_file = gr_tempdir.pil_to_temp_file
original_IOComponent_init = patches.patch(__name__, obj=gr.components.IOComponent, field="__init__", replacement=IOComponent_init)
original_Block_get_config = patches.patch(__name__, obj=gr.blocks.Block, field="get_config", replacement=Block_get_config)
original_BlockContext_init = patches.patch(__name__, obj=gr.blocks.BlockContext, field="__init__", replacement=BlockContext_init)
original_Blocks_get_config_file = patches.patch(__name__, obj=gr.blocks.Blocks, field="get_config_file", replacement=Blocks_get_config_file)
@@ -2,7 +2,6 @@ import os
import tempfile
from collections import namedtuple
from pathlib import Path
import gradio as gr
from PIL import Image, PngImagePlugin
from modules import shared, errors, paths
@@ -79,7 +78,6 @@ def pil_to_temp_file(self, img: Image, dir: str, format="png") -> str: # pylint:
# override save to file function so that it also writes PNG info
gr.components.IOComponent.pil_to_temp_file = pil_to_temp_file # gradio >=3.32.0
def on_tmpdir_changed():
if shared.opts.temp_dir == "":
+27 -9
View File
@@ -12,6 +12,10 @@ from modules import shared, errors, devices, ui_components, ui_symbols, paths
from modules.memstats import memory_stats
debug = shared.log.trace if os.environ.get('SD_MASK_DEBUG', None) is not None else lambda *args, **kwargs: None
debug('Trace: MASK')
def get_crop_region(mask, pad=0):
"""finds a rectangular region that contains all masked ares in an image. Returns (x1, y1, x2, y2) coordinates of the rectangle.
For example, if a user has painted the top-right part of a 512x512 image", the result may be (256, 0, 512, 256)"""
@@ -36,12 +40,22 @@ def get_crop_region(mask, pad=0):
if not (mask[i] == 0).all():
break
crop_bottom += 1
return (
int(max(crop_left-pad, 0)),
int(max(crop_top-pad, 0)),
int(min(w - crop_right + pad, w)),
int(min(h - crop_bottom + pad, h))
x1 = max(crop_left - pad, 0)
y1 = max(crop_top - pad, 0)
x2 = max(w - crop_right + pad, 0)
y2 = max(h - crop_bottom + pad, 0)
if x2 < x1:
x1, x2 = x2, x1
if y2 < y1:
y1, y2 = y2, y1
crop_region = (
int(min(x1, w)),
int(min(y1, h)),
int(min(x2, w)),
int(min(y2, h)),
)
debug(f'Mask crop: mask={mask.shape} region={crop_region} pad={pad}')
return crop_region
def expand_crop_region(crop_region, processing_width, processing_height, image_width, image_height):
@@ -79,8 +93,14 @@ def expand_crop_region(crop_region, processing_width, processing_height, image_w
x1 -= x1
if x2 >= image_width:
x2 = image_width
return x1, y1, x2, y2
crop_expand = (
int(x1),
int(y1),
int(x2),
int(y2),
)
debug(f'Mask expand: region={crop_expand} processing={processing_width}x{processing_height} image={image_width}x{image_height}')
return crop_expand
def fill(image, mask):
@@ -123,8 +143,6 @@ MODELS = {
COLORMAP = ['autumn', 'bone', 'jet', 'winter', 'rainbow', 'ocean', 'summer', 'spring', 'cool', 'hsv', 'pink', 'hot', 'parula', 'magma', 'inferno', 'plasma', 'viridis', 'cividis', 'twilight', 'shifted', 'turbo', 'deepgreen']
cache_dir = 'models/control/segment'
generator: MaskGenerationPipeline = None
debug = shared.log.trace if os.environ.get('SD_MASK_DEBUG', None) is not None else lambda *args, **kwargs: None
debug('Trace: MASK')
busy = False
btn_mask = None
btn_lama = None
+2 -2
View File
@@ -44,8 +44,8 @@ def full_vae_decode(latents, model):
upcast = (model.vae.dtype == torch.float16) and getattr(model.vae.config, 'force_upcast', False) and hasattr(model, 'upcast_vae')
if upcast: # this is done by diffusers automatically if output_type != 'latent'
model.upcast_vae()
latents = latents.to(next(iter(model.vae.post_quant_conv.parameters())).dtype)
if hasattr(model.vae, "post_quant_conv"):
latents = latents.to(next(iter(model.vae.post_quant_conv.parameters())).dtype)
decoded = model.vae.decode(latents / model.vae.config.scaling_factor, return_dict=False)[0]
# Delete PyTorch VAE after OpenVINO compile
+1 -1
View File
@@ -9,7 +9,7 @@ import modules.errors as errors
def report_exception(e, c, job):
errors.display(e, f'executing callback: {c.script} {job}')
errors.display(e, f'Executing callback: {c.script} {job}')
class ImageSaveParams:
-83
View File
@@ -362,49 +362,6 @@ class ScriptRunner:
except Exception as e:
errors.log.error(f'Script initialize: {path} {e}')
"""
def create_script_ui(self, script):
import modules.api.models as api_models
script.args_from = len(self.inputs)
script.args_to = len(self.inputs)
controls = wrap_call(script.ui, script.filename, "ui", script.is_img2img)
if controls is None:
return
script.name = wrap_call(script.title, script.filename, "title", default=script.filename).lower()
api_args = []
for control in controls:
if not isinstance(control, gr.components.IOComponent):
log.error(f'Invalid script control: "{script.filename}" control={control}')
continue
control.custom_script_source = os.path.basename(script.filename)
arg_info = api_models.ScriptArg(label=control.label or "")
for field in ("value", "minimum", "maximum", "step", "choices"):
v = getattr(control, field, None)
if v is not None:
setattr(arg_info, field, v)
api_args.append(arg_info)
script.api_info = api_models.ScriptInfo(name=script.name, is_img2img=script.is_img2img, is_alwayson=script.alwayson, args=api_args)
if script.infotext_fields is not None:
self.infotext_fields += script.infotext_fields
if script.paste_field_names is not None:
self.paste_field_names += script.paste_field_names
self.inputs += controls
script.args_to = len(self.inputs)
def setup_ui_for_section(self, section, scriptlist=None):
if scriptlist is None:
scriptlist = self.alwayson_scripts
for script in scriptlist:
if script.alwayson and script.section != section:
continue
if script.create_group:
with gr.Group(visible=script.alwayson) as group:
self.create_script_ui(script)
script.group = group
else:
self.create_script_ui(script)
"""
def prepare_ui(self):
self.inputs = [None]
@@ -677,43 +634,3 @@ def reload_script_body_only():
scripts_txt2img.reload_sources(cache)
scripts_img2img.reload_sources(cache)
scripts_control.reload_sources(cache)
def add_classes_to_gradio_component(comp):
"""
this adds gradio-* to the component for css styling (ie gradio-button to gr.Button), as well as some others
"""
elem_classes = []
if hasattr(comp, "elem_classes"):
elem_classes = comp.elem_classes
if elem_classes is None:
elem_classes = []
comp.elem_classes = [f"gradio-{comp.get_block_name()}", *(comp.elem_classes or [])]
if getattr(comp, 'multiselect', False):
comp.elem_classes.append('multiselect')
def IOComponent_init(self, *args, **kwargs):
if scripts_current is not None:
scripts_current.before_component(self, **kwargs)
script_callbacks.before_component_callback(self, **kwargs)
res = original_IOComponent_init(self, *args, **kwargs) # pylint: disable=assignment-from-no-return
add_classes_to_gradio_component(self)
script_callbacks.after_component_callback(self, **kwargs)
if scripts_current is not None:
scripts_current.after_component(self, **kwargs)
return res
original_IOComponent_init = gr.components.IOComponent.__init__
gr.components.IOComponent.__init__ = IOComponent_init
def BlockContext_init(self, *args, **kwargs):
res = original_BlockContext_init(self, *args, **kwargs) # pylint: disable=assignment-from-no-return
add_classes_to_gradio_component(self)
return res
original_BlockContext_init = gr.blocks.BlockContext.__init__
gr.blocks.BlockContext.__init__ = BlockContext_init
+16 -6
View File
@@ -68,29 +68,39 @@ def ipex_optimize(sd_model):
def nncf_compress_weights(sd_model):
try:
t0 = time.time()
if sd_model.device.type == "meta":
shared.log.warning("Compress Weights is not compatible with Sequential CPU offload")
return sd_model
def nncf_compress_model(model):
return_device = model.device
model = nncf.compress_weights(model.to(devices.device)).to(return_device)
devices.torch_gc(force=True)
return model
import nncf
shared.compiled_model_state = CompiledModelState()
shared.compiled_model_state.is_compiled = True
if "Model" in shared.opts.nncf_compress_weights:
if hasattr(sd_model, 'unet') and hasattr(sd_model.unet, 'config'):
sd_model.unet = nncf.compress_weights(sd_model.unet)
sd_model.unet = nncf_compress_model(sd_model.unet)
elif hasattr(sd_model, 'transformer') and hasattr(sd_model.transformer, 'config'):
sd_model.transformer = nncf.compress_weights(sd_model.transformer)
sd_model.transformer = nncf_compress_model(sd_model.transformer)
else:
shared.log.warning('Compress Weights enabled but model has no Unet or Transformer')
if "VAE" in shared.opts.nncf_compress_weights:
if hasattr(sd_model, 'vae') and hasattr(sd_model.vae, 'decode'):
sd_model.vae = nncf.compress_weights(sd_model.vae)
sd_model.vae = nncf_compress_model(sd_model.vae)
elif hasattr(sd_model, 'movq') and hasattr(sd_model.movq, 'decode'):
sd_model.movq = nncf.compress_weights(sd_model.movq)
sd_model.movq = nncf_compress_model(sd_model.movq)
else:
shared.log.warning('Compress VAE Weights enabled but model has no VAE')
if "Text Encoder" in shared.opts.nncf_compress_weights:
if hasattr(sd_model, 'text_encoder') and hasattr(sd_model.text_encoder, 'config'):
sd_model.text_encoder = nncf.compress_weights(sd_model.text_encoder)
sd_model.text_encoder = nncf_compress_model(sd_model.text_encoder)
if hasattr(sd_model, 'text_encoder_2') and hasattr(sd_model.text_encoder_2, 'config'):
sd_model.text_encoder_2 = nncf.compress_weights(sd_model.text_encoder_2)
sd_model.text_encoder_2 = nncf_compress_model(sd_model.text_encoder_2)
else:
shared.log.warning('Compress VAE Text Encoder Weights enabled but model has no Text Encoder')
t1 = time.time()
+34 -43
View File
@@ -6,16 +6,10 @@ import platform
import subprocess
from functools import reduce
import gradio as gr
from modules import call_queue, shared, prompt_parser
from modules import generation_parameters_copypaste
from modules import ui_sections
from modules.ui_components import ToolButton
import modules.ui_symbols as symbols
import modules.images
import modules.script_callbacks
from modules import call_queue, shared, prompt_parser, ui_sections, ui_symbols, ui_components, generation_parameters_copypaste, images, scripts, script_callbacks
folder_symbol = symbols.folder
folder_symbol = ui_symbols.folder
debug = shared.log.trace if os.environ.get('SD_PASTE_DEBUG', None) is not None else lambda *args, **kwargs: None
debug('Trace: PASTE')
@@ -58,19 +52,19 @@ def infotext_to_html(text):
return code
def delete_files(js_data, images, _html_info, index):
def delete_files(js_data, files, _html_info, index):
try:
data = json.loads(js_data)
except Exception:
data = { 'index_of_first_image': 0 }
start_index = 0
if index > -1 and shared.opts.save_selected_only and (index >= data['index_of_first_image']):
images = [images[index]]
files = [files[index]]
start_index = index
filenames = []
filenames = []
fullfns = []
for _image_index, filedata in enumerate(images, start_index):
for _image_index, filedata in enumerate(files, start_index):
if 'name' in filedata and os.path.isfile(filedata['name']):
fullfn = filedata['name']
filenames.append(os.path.basename(fullfn))
@@ -84,11 +78,11 @@ def delete_files(js_data, images, _html_info, index):
shared.log.info(f"Deleting image: {fullfn}")
except Exception as e:
shared.log.error(f'Error deleting file: {fullfn} {e}')
images = [image for image in images if image['name'] not in fullfns]
return images, plaintext_to_html(f"Deleted: {filenames[0] if len(filenames) > 0 else 'none'}")
files = [image for image in files if image['name'] not in fullfns]
return files, plaintext_to_html(f"Deleted: {filenames[0] if len(filenames) > 0 else 'none'}")
def save_files(js_data, images, html_info, index):
def save_files(js_data, files, html_info, index):
os.makedirs(shared.opts.outdir_save, exist_ok=True)
class PObject: # pylint: disable=too-few-public-methods
@@ -117,11 +111,11 @@ def save_files(js_data, images, html_info, index):
p = PObject(data)
start_index = 0
if index > -1 and shared.opts.save_selected_only and (index >= p.index_of_first_image): # ensures we are looking at a specific non-grid picture, and we have save_selected_only # pylint: disable=no-member
images = [images[index]]
files = [files[index]]
start_index = index
filenames = []
fullfns = []
for image_index, filedata in enumerate(images, start_index):
for image_index, filedata in enumerate(files, start_index):
is_grid = image_index < p.index_of_first_image # pylint: disable=no-member
i = 0 if is_grid else (image_index - p.index_of_first_image) # pylint: disable=no-member
while len(p.all_seeds) <= i:
@@ -135,7 +129,7 @@ def save_files(js_data, images, html_info, index):
filenames.append(os.path.basename(fullfn))
fullfns.append(fullfn)
destination = shared.opts.outdir_save
namegen = modules.images.FilenameGenerator(p, seed=p.all_seeds[i], prompt=p.all_prompts[i], image=None) # pylint: disable=no-member
namegen = images.FilenameGenerator(p, seed=p.all_seeds[i], prompt=p.all_prompts[i], image=None) # pylint: disable=no-member
dirname = namegen.apply(shared.opts.directories_filename_pattern or "[prompt_words]").lstrip(' ').rstrip('\\ /')
destination = os.path.join(destination, dirname)
destination = namegen.sanitize(destination)
@@ -154,11 +148,11 @@ def save_files(js_data, images, html_info, index):
shared.log.debug(f'Saving: text="{filename_txt}"')
except Exception as e:
shared.log.warning(f'Image description save failed: {filename_txt} {e}')
modules.script_callbacks.image_save_btn_callback(tgt_filename)
script_callbacks.image_save_btn_callback(tgt_filename)
else:
image = generation_parameters_copypaste.image_from_url_text(filedata)
info = p.infotexts[i + 1] if len(p.infotexts) > len(p.all_seeds) else p.infotexts[i] # infotexts may be offset by 1 because the first image is the grid
fullfn, txt_fullfn = modules.images.save_image(image, shared.opts.outdir_save, "", seed=p.all_seeds[i], prompt=p.all_prompts[i], info=info, extension=shared.opts.samples_format, grid=is_grid, p=p)
fullfn, txt_fullfn = images.save_image(image, shared.opts.outdir_save, "", seed=p.all_seeds[i], prompt=p.all_prompts[i], info=info, extension=shared.opts.samples_format, grid=is_grid, p=p)
if fullfn is None:
continue
filename = os.path.relpath(fullfn, shared.opts.outdir_save)
@@ -167,7 +161,7 @@ def save_files(js_data, images, html_info, index):
if txt_fullfn:
filenames.append(os.path.basename(txt_fullfn))
# fullfns.append(txt_fullfn)
modules.script_callbacks.image_save_btn_callback(filename)
script_callbacks.image_save_btn_callback(filename)
if shared.opts.samples_save_zip and len(fullfns) > 1:
zip_filepath = os.path.join(shared.opts.outdir_save, "images.zip")
from zipfile import ZipFile
@@ -277,11 +271,11 @@ def create_output_panel(tabname, preview=True, prompt=None, height=None):
)
if tabname == "txt2img":
paste_field_names = modules.scripts.scripts_txt2img.paste_field_names
paste_field_names = scripts.scripts_txt2img.paste_field_names
elif tabname == "img2img":
paste_field_names = modules.scripts.scripts_img2img.paste_field_names
paste_field_names = scripts.scripts_img2img.paste_field_names
elif tabname == "control":
paste_field_names = modules.scripts.scripts_control.paste_field_names
paste_field_names = scripts.scripts_control.paste_field_names
else:
paste_field_names = []
for paste_tabname, paste_button in buttons.items():
@@ -299,7 +293,7 @@ def create_refresh_button(refresh_component, refresh_method, refreshed_args, ele
setattr(refresh_component, k, v)
return gr.update(**(args or {}))
refresh_button = ToolButton(value=symbols.refresh, elem_id=elem_id, visible=visible)
refresh_button = ui_components.ToolButton(value=ui_symbols.refresh, elem_id=elem_id, visible=visible)
refresh_button.click(fn=refresh, inputs=[], outputs=[refresh_component])
return refresh_button
@@ -311,7 +305,7 @@ def create_browse_button(browse_component, elem_id):
return gr.update(value = folder)
return gr.update()
browse_button = ToolButton(value=symbols.folder, elem_id=elem_id)
browse_button = ui_components.ToolButton(value=ui_symbols.folder, elem_id=elem_id)
browse_button.click(fn=browse, _js="async () => await browseFolder()", inputs=[browse_component], outputs=[browse_component])
# browse_button.click(fn=browse, inputs=[browse_component], outputs=[browse_component])
return browse_button
@@ -352,33 +346,30 @@ def connect_reuse_seed(seed: gr.Number, reuse_seed: gr.Button, generation_info:
def update_token_counter(text, steps):
from modules import extra_networks, sd_hijack
token_count = 0
max_length = 75
if shared.state.job_count > 0:
shared.log.info('Tokenizer busy')
return f"<span class='gr-box gr-text-input'>{token_count}/{max_length}</span>"
from modules import extra_networks
try:
text, _ = extra_networks.parse_prompt(text)
_, prompt_flat_list, _ = prompt_parser.get_multicond_prompt_list([text])
prompt_schedules = prompt_parser.get_learned_conditioning_prompt_schedules(prompt_flat_list, steps)
except Exception:
prompt_schedules = [[[steps, text]]]
flat_prompts = reduce(lambda list1, list2: list1+list2, prompt_schedules)
prompts = [prompt_text for step, prompt_text in flat_prompts]
if shared.backend == shared.Backend.ORIGINAL:
from modules import sd_hijack
token_count, max_length = max([sd_hijack.model_hijack.get_prompt_lengths(prompt) for prompt in prompts], key=lambda args: args[0])
elif shared.backend == shared.Backend.DIFFUSERS:
if shared.sd_model is not None and hasattr(shared.sd_model, 'tokenizer'):
tokenizer = shared.sd_model.tokenizer
if tokenizer is None:
token_count = 0
max_length = 75
else:
has_bos_token = tokenizer.bos_token_id is not None
has_eos_token = tokenizer.eos_token_id is not None
ids = [shared.sd_model.tokenizer(prompt) for prompt in prompts]
if len(ids) > 0 and hasattr(ids[0], 'input_ids'):
ids = [x.input_ids for x in ids]
token_count = max([len(x) for x in ids]) - int(has_bos_token) - int(has_eos_token)
max_length = tokenizer.model_max_length - int(has_bos_token) - int(has_eos_token)
else:
token_count = 0
max_length = 75
if shared.sd_model is not None and hasattr(shared.sd_model, 'tokenizer') and shared.sd_model.tokenizer is not None:
has_bos_token = shared.sd_model.tokenizer.bos_token_id is not None
has_eos_token = shared.sd_model.tokenizer.eos_token_id is not None
ids = [shared.sd_model.tokenizer(prompt) for prompt in prompts]
if len(ids) > 0 and hasattr(ids[0], 'input_ids'):
ids = [x.input_ids for x in ids]
token_count = max([len(x) for x in ids]) - int(has_bos_token) - int(has_eos_token)
max_length = shared.sd_model.tokenizer.model_max_length - int(has_bos_token) - int(has_eos_token)
return f"<span class='gr-box gr-text-input'>{token_count}/{max_length}</span>"
+4 -4
View File
@@ -13,7 +13,7 @@ import torch # pylint: disable=wrong-import-order
from modules import timer, errors, paths # pylint: disable=unused-import
from installer import log, git_commit, custom_excepthook
import ldm.modules.encoders.modules # pylint: disable=W0611,C0411,E0401
from modules import shared, extensions, ui_tempdir, modelloader # pylint: disable=ungrouped-imports
from modules import shared, extensions, gr_tempdir, modelloader # pylint: disable=ungrouped-imports
from modules import extra_networks, ui_extra_networks # pylint: disable=ungrouped-imports
from modules.paths import create_paths
from modules.call_queue import queue_lock, wrap_queued_call, wrap_gradio_gpu_call # pylint: disable=W0611,C0411,C0412
@@ -111,7 +111,7 @@ def initialize():
timer.startup.record("upscalers")
shared.opts.onchange("sd_vae", wrap_queued_call(lambda: modules.sd_vae.reload_vae_weights()), call=False)
shared.opts.onchange("temp_dir", ui_tempdir.on_tmpdir_changed)
shared.opts.onchange("temp_dir", gr_tempdir.on_tmpdir_changed)
timer.startup.record("onchange")
modules.textual_inversion.textual_inversion.list_textual_inversion_templates()
@@ -212,7 +212,7 @@ def start_common():
async_policy()
initialize()
if shared.opts.clean_temp_dir_at_start:
ui_tempdir.cleanup_tmpdr()
gr_tempdir.cleanup_tmpdr()
timer.startup.record("cleanup")
@@ -269,7 +269,7 @@ def start_ui():
_frontend=True and cmd_opts.share,
)
if cmd_opts.data_dir is not None:
ui_tempdir.register_tmp_file(shared.demo, os.path.join(cmd_opts.data_dir, 'x'))
gr_tempdir.register_tmp_file(shared.demo, os.path.join(cmd_opts.data_dir, 'x'))
shared.log.info(f'Local URL: {local_url}')
if cmd_opts.docs:
shared.log.info(f'API Docs: {local_url[:-1]}/docs') # pylint: disable=unsubscriptable-object
+1 -1
Submodule wiki updated: 102ab490f3...6fc48f5d84