diff --git a/CHANGELOG.md b/CHANGELOG.md index bfc6117b3..796cedf97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,23 +1,28 @@ # Change Log for SD.Next -## Update for 2026-05-18 +## Update for 2026-05-19 - **Models** - [CircleStone Anima 1.0](https://huggingface.co/circlestone-labs/Anima) in *Base* and *Turbo* (distilled) variants in both original precision and SDNQ-4bit quantiztion -- **Changes** - - all **Guidance** params are now set to *-1* by default to allow using model defaults and avoid confusion with different model behaviour - log will print default values used by model if not set by user - **Features** - **SDNQ** additional quantization algorithm: *Hadamard Rotations* much higher quality than base SDNQ, but runs slightly slower still faster than SVD and can be combined together with SVD for combined benefits + - **Metadata** + add *wildcards* (if used) info to image metadata + if wildcards or styles modify prompt, add original prompt to image metadata as *template* - **Captioning** new feature: analyze existing images for prompt adherence *tip*: image analysis requires larger VLM model to produce quality output new api endpoint: `/sdapi/v1/analyze` - **HF download** use `XET` by default see *settings -> huggingface -> download method* for options - **Nunchaku** consider DEV builds when auto-installing +- **Changes** + - all **Guidance** params are now set to *-1* by default to allow using model defaults and avoid confusion with different model behaviour + log will print default values used by model if not set by user + - restore params from image metadata will now prefer *template* field if present, otherwise use *prompt* field + this allows to preserve original prompt in case of wildcards or styles modifying the prompt - **Compute** - update `torch==2.12` for *CUDA, ROCm, IPEX* - **AI** diff --git a/modules/api/script.py b/modules/api/script.py index 75d0fc190..ac7914d41 100644 --- a/modules/api/script.py +++ b/modules/api/script.py @@ -1,7 +1,7 @@ from fastapi.exceptions import HTTPException import gradio as gr from modules.api import models -from modules.errors import log +from modules.logger import log from modules import scripts_manager diff --git a/modules/attention.py b/modules/attention.py index 2287ca90e..c9136693a 100644 --- a/modules/attention.py +++ b/modules/attention.py @@ -1,7 +1,7 @@ from functools import wraps import torch from modules import rocm -from modules.errors import log +from modules.logger import log from installer import install, installed, torch_info diff --git a/modules/dml/__init__.py b/modules/dml/__init__.py index 50bfea5c5..24d80a424 100644 --- a/modules/dml/__init__.py +++ b/modules/dml/__init__.py @@ -2,7 +2,7 @@ import platform from typing import NamedTuple, Optional from collections.abc import Callable import torch -from modules.errors import log +from modules.logger import log from modules.sd_hijack_utils import CondFunc diff --git a/modules/generation_parameters_copypaste.py b/modules/generation_parameters_copypaste.py index 9d55f13b9..1f9e14288 100644 --- a/modules/generation_parameters_copypaste.py +++ b/modules/generation_parameters_copypaste.py @@ -232,7 +232,7 @@ def connect_paste_params_buttons(): if binding.only_prompt: paste_field_names = ['Prompt', 'Negative prompt'] else: - paste_field_names = ['Prompt', 'Negative prompt', 'Steps'] + (["Seed"] if shared.opts.send_seed else []) + binding.paste_field_names + paste_field_names = ['Prompt', 'Negative prompt', 'Steps', 'Seed'] + binding.paste_field_names if "fields" in paste_fields[binding.source_tabname] and paste_fields[binding.source_tabname]["fields"] is not None: binding.paste_button.click( fn=lambda *x: x, diff --git a/modules/hidiffusion/hidiffusion.py b/modules/hidiffusion/hidiffusion.py index fd2c4b408..73860e2a1 100644 --- a/modules/hidiffusion/hidiffusion.py +++ b/modules/hidiffusion/hidiffusion.py @@ -116,7 +116,7 @@ def make_diffusers_transformer_block(block_class: Type[torch.nn.Module]) -> Type B, _N, C = x.shape x = x.view(B,H,W,C) if H % 2 != 0 or W % 2 != 0: - from modules.errors import log + from modules.logger import log log.warning('HiDiffusion: The feature size is not divisible by 2') x = F.interpolate(x.permute(0,3,1,2).contiguous(), size=(window_size[0]*2, window_size[1]*2), mode='bicubic').permute(0,2,3,1).contiguous() if type(shift_size) == list or type(shift_size) == tuple: diff --git a/modules/infotext.py b/modules/infotext.py index 407395c1e..f84948eed 100644 --- a/modules/infotext.py +++ b/modules/infotext.py @@ -4,7 +4,7 @@ import json if os.environ.get('SD_PASTE_DEBUG', None) is not None: - from modules.errors import log + from modules.logger import log debug = log.trace else: debug = lambda *args, **kwargs: None # pylint: disable=unnecessary-lambda-assignment @@ -20,6 +20,8 @@ def quote(text): def unquote(text): + if text is None: + return '' if len(text) == 0 or text[0] != '"' or text[-1] != '"': return text try: @@ -29,41 +31,49 @@ def unquote(text): def parse(infotext): - if not isinstance(infotext, str): + if not isinstance(infotext, str) or len(infotext.strip()) == 0: return {} debug(f'Raw: {infotext}') remaining = infotext.replace('\nSteps:', ' Steps:') - params = [' steps:', ' seed:', ' width:', ' height:', ' sampler:', ' size:', ' cfg scale:', ' pipeline:'] # first param is one of those - params += ['\nsteps:', '\nseed:', '\nwidth:', '\nheight:', '\nsampler:', '\nsize:', '\ncfg scale:', '\npipeline:'] - params += ['.steps:', '.seed:', '.width:', '.height:', '.sampler:', '.size:', '.cfg scale:', '.pipeline:'] + params = ['steps: ', 'seed: ', 'width: ', 'height: ', 'sampler: ', 'size: ', 'cfg scale: ', 'pipeline: '] # first param is one of those + prompts = ['negative prompt: ', 'template: ', 'negative template: '] # first prompt field is implied + search = params + prompts - prompt_end = [remaining.lower().find(p) for p in params if p in remaining.lower()] - prompt_end += [remaining.lower().find('negative prompt:')] - prompt_end = [p for p in prompt_end if p > -1] - prompt_end = min(prompt_end) if len(prompt_end) > 0 else 0 - prompt = remaining[:prompt_end] - remaining = remaining.replace(prompt, '') - if prompt.lower().startswith('prompt: '): - prompt = prompt[8:] - # debug(f'Prompt: {prompt}') + def extract(keyword, text): # attempt to extract prompt from params + debug(f'Params extract: keyword="{keyword}" text="{text}"') + if keyword not in text.lower(): + return '', text + if text.lower().startswith(f'{keyword}:'): + text = text[len(keyword) + 1:] + text = text.strip("\n").strip() + idxs = [text.lower().find(param) for param in search if param in text.lower()] + idx = min(idxs) if len(idxs) > 0 else 0 + res = text[:idx] + text = text.replace(res, '') + res = res.strip("\n").strip() + debug(f'Params extract: keyword="{keyword}" idx={idx} res="{res}"') + return res, text - param_idx = [remaining.lower().find(p) for p in params if p in remaining.lower()] - param_idx = [p for p in param_idx if p > -1] - param_idx = min(param_idx) if len(param_idx) > 0 else 0 - negative = remaining[:param_idx] if param_idx > 0 else '' - remaining = remaining.replace(negative, '') - if negative.lower().startswith('negative prompt: '): - negative = negative[16:] - # debug(f'Negative: {negative}') + prompt, remaining = extract('', remaining) # prompt is always first + negative, remaining = extract('negative prompt', remaining) + template, remaining = extract('template', remaining) + negative_template, remaining = extract('negative template', remaining) params = dict(re_param.findall(remaining)) if len(list(params)) == 0: params['Prompt'] = infotext return params - params['Prompt'] = prompt - params['Negative prompt'] = negative + params['Prompt'] = prompt if len(prompt) > 0 else None + params['Negative prompt'] = negative if len(negative) > 0 else None + params['Template'] = template if len(template) > 0 else None + params['Negative template'] = negative_template if len(negative_template) > 0 else None + if params['Template'] == params['Prompt']: + params.pop('Template', None) + if params['Negative template'] == params['Negative prompt']: + params.pop('Negative template', None) debug(f'Params: {params}') + for key, val in params.copy().items(): val = unquote(val).strip(" ,\n").replace('\\\n', '') size = re_size.match(val) diff --git a/modules/patches.py b/modules/patches.py index 655cf4534..97ddbe082 100644 --- a/modules/patches.py +++ b/modules/patches.py @@ -1,5 +1,5 @@ from collections import defaultdict -from modules.errors import log +from modules.logger import log def patch(key, obj, field, replacement, add_if_not_exists:bool = False): diff --git a/modules/processing.py b/modules/processing.py index 9f9a99150..8c49c1b83 100644 --- a/modules/processing.py +++ b/modules/processing.py @@ -279,7 +279,7 @@ def process_init(p: StableDiffusionProcessing): p.all_subseeds = [int(subseed) + x for x in range(len(p.all_prompts))] if reset_prompts: if not hasattr(p, 'keep_prompts'): - p.all_prompts, p.all_negative_prompts = shared.prompt_styles.apply_styles_to_prompts(p.all_prompts, p.all_negative_prompts, p.styles, p.all_seeds) + p.all_prompts, p.all_negative_prompts = shared.prompt_styles.apply_styles_to_prompts(p.all_prompts, p.all_negative_prompts, p.styles, p.all_seeds, p=p) p.prompts = p.all_prompts[(p.iteration * p.batch_size):((p.iteration+1) * p.batch_size)] p.negative_prompts = p.all_negative_prompts[(p.iteration * p.batch_size):((p.iteration+1) * p.batch_size)] diff --git a/modules/processing_class.py b/modules/processing_class.py index bf6c268f0..093da2bdd 100644 --- a/modules/processing_class.py +++ b/modules/processing_class.py @@ -579,6 +579,8 @@ class StableDiffusionProcessing: self.negative_prompts = [] self.all_prompts = [] self.all_negative_prompts = [] + self.all_templates = [] + self.all_negative_templates = [] self.seeds = [] self.subseeds = [] self.all_seeds = [] diff --git a/modules/processing_info.py b/modules/processing_info.py index 1bfba60f3..4312ceb41 100644 --- a/modules/processing_info.py +++ b/modules/processing_info.py @@ -22,6 +22,7 @@ def create_infotext(p: StableDiffusionProcessing, all_prompts=None, all_seeds=No return '' if not hasattr(shared.sd_model, 'sd_checkpoint_info'): return '' + if index is None: index = position_in_batch + iteration * p.batch_size if all_prompts is None: @@ -40,6 +41,13 @@ def create_infotext(p: StableDiffusionProcessing, all_prompts=None, all_seeds=No all_subseeds.insert(0, int(p.subseed)) while len(all_negative_prompts) <= index: all_negative_prompts.insert(0, p.negative_prompt) + if p.all_templates is not None: + while len(p.all_templates) <= index: + p.all_templates.insert(0, '') + if p.all_negative_templates is not None: + while len(p.all_negative_templates) <= index: + p.all_negative_templates.insert(0, '') + comment = ', '.join(comments) if comments is not None and type(comments) is list else None ops = list(set(p.ops)) args = { @@ -208,7 +216,12 @@ def create_infotext(p: StableDiffusionProcessing, all_prompts=None, all_seeds=No if type(v) is float or type(v) is int: if v <= -1: del args[k] - if isinstance(v, str): + if type(v) is list: + if len(v) == 0: + del args[k] + else: + args[k] = ', '.join([str(x) for x in v]) + if type(v) is str: if len(v) == 0 or v == '0x0': del args[k] debug(f'Infotext: args={args}') @@ -219,7 +232,13 @@ def create_infotext(p: StableDiffusionProcessing, all_prompts=None, all_seeds=No if hasattr(p, 'original_negative'): args['Original negative'] = p.original_negative + template = p.all_templates[index] if p.all_templates is not None and p.all_templates[index] else None + negative_template = p.all_negative_templates[index] if p.all_negative_templates is not None and p.all_negative_templates[index] else None + template_text = f"\nTemplate: {template}" if template else '' + negative_template_text = f"\nNegative template: {negative_template}" if negative_template else '' + negative_prompt_text = f"\nNegative prompt: {all_negative_prompts[index] if all_negative_prompts[index] else ''}" - infotext = f"{all_prompts[index]}{negative_prompt_text}\n{params_text}".strip() + infotext = f"{all_prompts[index]}{negative_prompt_text}{template_text}{negative_template_text}\n{params_text}".strip() + debug(f'Infotext: "{infotext}"') return infotext diff --git a/modules/shared_state.py b/modules/shared_state.py index 41e4bf7f0..ca017d9e9 100644 --- a/modules/shared_state.py +++ b/modules/shared_state.py @@ -4,7 +4,8 @@ import sys import uuid import time import datetime -from modules.errors import log, display +from modules.logger import log +from modules.errors import display debug_output = os.environ.get('SD_STATE_DEBUG', None) diff --git a/modules/styles.py b/modules/styles.py index b25fcd91a..25bccf70a 100644 --- a/modules/styles.py +++ b/modules/styles.py @@ -1,4 +1,5 @@ from __future__ import annotations +from typing import TYPE_CHECKING import re import os import csv @@ -8,6 +9,8 @@ import random from modules import files_cache, shared, infotext, sd_models, sd_vae from modules.logger import log +if TYPE_CHECKING: + from modules.processing_class import StableDiffusionProcessing debug_enabled = os.environ.get('SD_STYLES_DEBUG', None) is not None @@ -109,7 +112,7 @@ def apply_curly_braces_to_prompt(prompt, seed=-1): return prompt -def apply_file_wildcards(prompt, replaced = None, not_found = None, recursion=0, seed=-1): +def apply_file_wildcards(prompt, replaced = None, not_found = None, recursion=0, seed=-1, p: StableDiffusionProcessing | None = None): if not_found is None: not_found = [] if replaced is None: @@ -135,6 +138,8 @@ def apply_file_wildcards(prompt, replaced = None, not_found = None, recursion=0, prompt = prompt.replace(f"__{wildcard}__", choice, 1) log.debug(f'Apply wildcard: select="{wildcard}" choice="{choice}" file="{file}" choices={len(lines)}') replaced.append(wildcard) + if p is not None: + p.extra_generation_params['Wildcards'] = p.extra_generation_params.get('Wildcards', []) + [trimmed] return prompt, True except Exception as e: log.error(f'Wildcards: wildcard={wildcard} file={file} {e}') @@ -167,7 +172,7 @@ def apply_file_wildcards(prompt, replaced = None, not_found = None, recursion=0, return prompt, replaced, not_found -def apply_wildcards_to_prompt(prompt, all_wildcards, seed=-1, silent=False): +def apply_wildcards_to_prompt(prompt, all_wildcards, seed=-1, silent=False, p: StableDiffusionProcessing | None = None): if prompt is None or len(prompt) == 0: return prompt old_state = None @@ -189,7 +194,7 @@ def apply_wildcards_to_prompt(prompt, all_wildcards, seed=-1, silent=False): except Exception as e: log.error(f'Wildcards: wildcard="{wildcard}" error={e}') t1 = time.time() - prompt, replaced_file, not_found = apply_file_wildcards(prompt, [], [], recursion=0, seed=seed) + prompt, replaced_file, not_found = apply_file_wildcards(prompt, [], [], recursion=0, seed=seed, p=p) t2 = time.time() if replaced and not silent: log.debug(f'Apply wildcards: {replaced} path="{shared.opts.wildcards_dir}" type=style time={t1-t0:.2f}') @@ -231,7 +236,7 @@ def apply_styles_to_extra(p, style: Style): ] reference_style = get_reference_style() extra = infotext.parse(reference_style) if shared.opts.extra_network_reference_values else {} - style_extra = apply_wildcards_to_prompt(style.extra, [style.wildcards], silent=True) + style_extra = apply_wildcards_to_prompt(style.extra, [style.wildcards], silent=True, p=p) style_extra = ' ' + style_extra.lower() extra.update(infotext.parse(style_extra)) extra.pop('Prompt', None) @@ -374,7 +379,7 @@ class StyleDatabase: return [] return [self.find_style(x).negative_prompt for x in styles] - def apply_styles_to_prompts(self, prompts, negatives, styles, seeds): + def apply_styles_to_prompts(self, prompts, negatives, styles, seeds, p: StableDiffusionProcessing | None = None): if styles is None: return prompts, negatives if not isinstance(styles, list): @@ -383,9 +388,15 @@ class StyleDatabase: if prompts is None or not isinstance(prompts, list): log.error(f'Styles invalid prompts: {prompts}') return prompts, negatives - if seeds is None or not isinstance(prompts, list): + if seeds is None or not isinstance(seeds, list): log.error(f'Styles invalid seeds: {seeds}') return prompts, negatives + if p is not None: + if p.all_templates is None or len(p.all_templates) < len(prompts): + p.all_templates = prompts + if p.all_negative_templates is None or len(p.all_negative_templates) < len(negatives): + p.all_negative_templates = negatives + jobid = shared.state.begin('Styles') parsed_positive = [] parsed_negative = [] @@ -397,7 +408,7 @@ class StyleDatabase: prompt = prompts[i] prompt = apply_curly_braces_to_prompt(prompt, seeds[i]) prompt = apply_styles_to_prompt(prompt, [self.find_style(x).prompt for x in styles]) - prompt = apply_wildcards_to_prompt(prompt, [self.find_style(x).wildcards for x in styles], seeds[i]) + prompt = apply_wildcards_to_prompt(prompt, [self.find_style(x).wildcards for x in styles], seeds[i], p=p) parsed_positive.append(prompt) for i in range(len(negatives)): if seeds[i]> 0: @@ -405,7 +416,7 @@ class StyleDatabase: prompt = negatives[i] prompt = apply_curly_braces_to_prompt(prompt, seeds[i]) prompt = apply_styles_to_prompt(prompt, [self.find_style(x).negative_prompt for x in styles]) - prompt = apply_wildcards_to_prompt(prompt, [self.find_style(x).wildcards for x in styles], seeds[i]) + prompt = apply_wildcards_to_prompt(prompt, [self.find_style(x).wildcards for x in styles], seeds[i], p=p) parsed_negative.append(prompt) random.setstate(random_state) @@ -445,6 +456,7 @@ class StyleDatabase: if p.styles is None or not isinstance(p.styles, list): log.error(f'Styles invalid: {p.styles}') return + for style in p.styles: if style is None or style == '': continue diff --git a/modules/ui_common.py b/modules/ui_common.py index 4c1a52823..e171e0eb9 100644 --- a/modules/ui_common.py +++ b/modules/ui_common.py @@ -53,17 +53,42 @@ def plaintext_to_html(text, elem_classes=None): def infotext_to_html(text): res = infotext.parse(text) prompt = res.get('Prompt', '') - negative = res.get('Negative prompt', '') res.pop('Prompt', None) + negative = res.get('Negative prompt', '') res.pop('Negative prompt', None) + template = res.get('Template', '') + res.pop('Template', None) + negative_template = res.get('Negative template', '') + res.pop('Negative template', None) + + runtime = {} + runtime['App'] = res.get('App', '') + res.pop('App', None) + runtime['Version'] = res.get('Version', '') + res.pop('Version', None) + runtime['Pipeline'] = res.get('Pipeline', '') + res.pop('Pipeline', None) + runtime['Operations'] = res.get('Operations', '') + res.pop('Operations', None) + params = [f'{k}: {v}' for k, v in res.items() if v is not None and not k.endswith('-1') and not k.endswith('-2')] params = '| '.join(params) if len(params) > 0 else '' + + runtime = [f'{k}: {v}' for k, v in runtime.items() if v is not None and not k.endswith('-1') and not k.endswith('-2')] + runtime = '| '.join(runtime) if len(runtime) > 0 else '' + code = '' - if len(prompt) > 0: + if prompt is not None and len(prompt) > 0: code += f'

Prompt: {html.escape(prompt)}

' - if len(negative) > 0: + if negative is not None and len(negative) > 0: code += f'

Negative: {html.escape(negative)}

' - if len(params) > 0: + if template is not None and len(template) > 0: + code += f'

Template: {html.escape(template)}

' + if negative_template is not None and len(negative_template) > 0: + code += f'

Negative Template: {html.escape(negative_template)}

' + if runtime is not None and len(runtime) > 0: + code += f'

Runtime: {html.escape(runtime)}

' + if params is not None and len(params) > 0: code += f'

Parameters: {html.escape(params)}

' return code diff --git a/modules/ui_control.py b/modules/ui_control.py index c545b1ca6..fb3c44841 100644 --- a/modules/ui_control.py +++ b/modules/ui_control.py @@ -354,6 +354,8 @@ def create_ui(_blocks: gr.Blocks=None): # prompt (prompt, "Prompt"), (negative, "Negative prompt"), + (prompt, "Template"), # override prompt with template if available + (negative, "Negative template"), (styles, "Styles"), # input (denoising_strength, "Denoising strength"), diff --git a/modules/ui_img2img.py b/modules/ui_img2img.py index a190565e8..eb3a01ee5 100644 --- a/modules/ui_img2img.py +++ b/modules/ui_img2img.py @@ -247,6 +247,8 @@ def create_ui(): # prompt (img2img_prompt, "Prompt"), (img2img_negative_prompt, "Negative prompt"), + (img2img_prompt, "Template"), # override prompt with template if available + (img2img_negative_prompt, "Negative template"), (img2img_prompt_styles, "Styles"), # sampler (sampler_index, "Sampler"), diff --git a/modules/ui_txt2img.py b/modules/ui_txt2img.py index 082b9a400..d2bead137 100644 --- a/modules/ui_txt2img.py +++ b/modules/ui_txt2img.py @@ -98,6 +98,8 @@ def create_ui(): # prompt (txt2img_prompt, "Prompt"), (txt2img_negative_prompt, "Negative prompt"), + (txt2img_prompt, "Template"), # override prompt with template if available + (txt2img_negative_prompt, "Negative template"), (txt2img_prompt_styles, "Styles"), # main (width, "Size-1"), diff --git a/modules/ui_video.py b/modules/ui_video.py index 4d9362973..6caa70d0a 100644 --- a/modules/ui_video.py +++ b/modules/ui_video.py @@ -53,6 +53,8 @@ def create_ui(): paste_fields = [ (prompt, "Prompt"), # cannot add more fields as they are not defined yet (negative, "Negative prompt"), + (prompt, "Template"), # override prompt with template if available + (negative, "Negative template"), (width, "Width"), (height, "Height"), (frames, "Frames"), diff --git a/scripts/pulid/__init__.py b/scripts/pulid/__init__.py index 864b758d1..cd21936bf 100644 --- a/scripts/pulid/__init__.py +++ b/scripts/pulid/__init__.py @@ -4,7 +4,7 @@ Credit and original implementation: import os import sys -from modules.errors import log +from modules.logger import log sys.path.append(os.path.dirname(__file__)) try: from pulid_sdxl import StableDiffusionXLPuLIDPipeline, StableDiffusionXLPuLIDPipelineImage, StableDiffusionXLPuLIDPipelineInpaint diff --git a/scripts/pulid/pulid_sdxl.py b/scripts/pulid/pulid_sdxl.py index 989edabe8..b239aab3e 100644 --- a/scripts/pulid/pulid_sdxl.py +++ b/scripts/pulid/pulid_sdxl.py @@ -23,7 +23,7 @@ from .pulid_utils import img2tensor, tensor2img from eva_clip import create_model_and_transforms from eva_clip.constants import OPENAI_DATASET_MEAN, OPENAI_DATASET_STD from encoders_transformer import IDFormer, IDEncoder -from modules.errors import log +from modules.logger import log debug = log.trace if os.environ.get('SD_PULID_DEBUG', None) is not None else lambda *args, **kwargs: None diff --git a/test/test-flux2-native-adapters.py b/test/test-flux2-native-adapters.py index c84546943..b8a868317 100644 --- a/test/test-flux2-native-adapters.py +++ b/test/test-flux2-native-adapters.py @@ -50,7 +50,7 @@ finally: installer.add_args(modules.cmd_args.parser) modules.cmd_args.parsed, _ = modules.cmd_args.parser.parse_known_args([]) -from modules.errors import log # pylint: disable=wrong-import-position +from modules.logger import log # pylint: disable=wrong-import-position from modules import shared # pylint: disable=wrong-import-position from modules.lora import ( # pylint: disable=wrong-import-position network, network_lora, network_lokr, network_hada, network_oft, network_boft, diff --git a/test/test-grading.py b/test/test-grading.py index 0334faba6..8757369fd 100644 --- a/test/test-grading.py +++ b/test/test-grading.py @@ -18,7 +18,6 @@ import time import types import torch import numpy as np -from types import SimpleNamespace script_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, script_dir) @@ -40,7 +39,7 @@ _mock_taesd.CQYAN_MODELS = {} _mock_taesd.encode = lambda x: torch.zeros(1, 4, 8, 8) sys.modules['modules.vae.sd_vae_taesd'] = _mock_taesd -from modules.errors import log +from modules.logger import log # Results tracking results = { @@ -417,7 +416,7 @@ def _make_mock_p(**overrides): 'extra_generation_params': {}, } defaults.update(overrides) - return SimpleNamespace(**defaults) + return types.SimpleNamespace(**defaults) def test_correction_noop(): diff --git a/test/test-schedulers.py b/test/test-schedulers.py index 5faa95446..a26162dcf 100644 --- a/test/test-schedulers.py +++ b/test/test-schedulers.py @@ -7,7 +7,7 @@ import torch # Ensure we can import modules sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "../"))) -from modules.errors import log +from modules.logger import log from modules.res4lyf import ( BASE, SIMPLE, VARIANTS, RESUnifiedScheduler, RESMultistepScheduler, RESDEISMultistepScheduler,