diff --git a/extensions-builtin/sd-webui-controlnet b/extensions-builtin/sd-webui-controlnet index 817155ea7..6be213fef 160000 --- a/extensions-builtin/sd-webui-controlnet +++ b/extensions-builtin/sd-webui-controlnet @@ -1 +1 @@ -Subproject commit 817155ea7a43a78982202a2456088acd6ffd95d5 +Subproject commit 6be213feff25cbbb17f31479391f5644008e7bba diff --git a/modules/devices.py b/modules/devices.py index 7f66f0d54..840f0de33 100644 --- a/modules/devices.py +++ b/modules/devices.py @@ -77,11 +77,13 @@ def test_fp16(): x = torch.tensor([[1.5,.0,.0,.0]]).to(device).half() layerNorm = torch.nn.LayerNorm(4, eps=0.00001, elementwise_affine=True, dtype=torch.float16, device=device) _y = layerNorm(x) + return True except: shared.log.warning('Torch FP16 test failed: Forcing FP32 operations') shared.opts.cuda_dtype = 'FP32' shared.opts.no_half = True shared.opts.no_half_vae = True + return False def set_cuda_params(): @@ -101,22 +103,23 @@ def set_cuda_params(): pass global dtype, dtype_vae, dtype_unet, unet_needs_upcast # pylint: disable=global-statement # set dtype - test_fp16() - if shared.opts.cuda_dtype == 'FP16': + ok = test_fp16() + if shared.opts.cuda_dtype == 'FP16' and ok: dtype = torch.float16 dtype_vae = torch.float16 dtype_unet = torch.float16 - if shared.opts.cuda_dtype == 'BP16': + if shared.opts.cuda_dtype == 'BP16' and ok: dtype = torch.bfloat16 dtype_vae = torch.bfloat16 dtype_unet = torch.bfloat16 - if shared.opts.cuda_dtype == 'FP32' or shared.opts.no_half: + if shared.opts.cuda_dtype == 'FP32' or shared.opts.no_half or not ok: dtype = torch.float32 dtype_vae = torch.float32 dtype_unet = torch.float32 if shared.opts.no_half_vae: # set dtype again as no-half-vae options take priority dtype_vae = torch.float32 unet_needs_upcast = shared.opts.upcast_sampling + shared.log.debug(f'Setting CUDA parameters: dtype={dtype} vae={dtype_vae} unet={dtype_unet}') args = cmd_args.parser.parse_args() @@ -182,11 +185,11 @@ def test_for_nans(x, where): return if where == "unet": message = "A tensor with all NaNs was produced in Unet." - if not shared.cmd_opts.no_half: + if not shared.opts.no_half: message += " This could be either because there's not enough precision to represent the picture, or because your video card does not support half type. Try setting the \"Upcast cross attention layer to float32\" option in Settings > Stable Diffusion or using the --no-half commandline argument to fix this." elif where == "vae": message = "A tensor with all NaNs was produced in VAE." - if not shared.cmd_opts.no_half and not shared.cmd_opts.no_half_vae: + if not shared.opts.no_half and not shared.opts.no_half_vae: message += " This could be because there's not enough precision to represent the picture. Try adding --no-half-vae commandline argument to fix this." else: message = "A tensor with all NaNs was produced." diff --git a/modules/img2img.py b/modules/img2img.py index d0b5183f4..893f7cabb 100644 --- a/modules/img2img.py +++ b/modules/img2img.py @@ -60,7 +60,7 @@ def process_batch(p, input_dir, output_dir, inpaint_mask_dir, args): if processed_image.mode == 'RGBA': processed_image = processed_image.convert("RGB") processed_image.save(os.path.join(output_dir, filename)) - shared.debug(f'Processed: {len(images)} Memory: {memory_stats()} batch') + shared.log.debug(f'Processed: {len(images)} Memory: {memory_stats()} batch') def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_styles, init_img, sketch, init_img_with_mask, inpaint_color_sketch, inpaint_color_sketch_orig, init_img_inpaint, init_mask_inpaint, steps: int, sampler_index: int, mask_blur: int, mask_alpha: float, inpainting_fill: int, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, image_cfg_scale: float, denoising_strength: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, selected_scale_tab: int, height: int, width: int, scale_by: float, resize_mode: int, inpaint_full_res: bool, inpaint_full_res_padding: int, inpainting_mask_invert: int, img2img_batch_input_dir: str, img2img_batch_output_dir: str, img2img_batch_inpaint_mask_dir: str, override_settings_texts, *args): # pylint: disable=unused-argument @@ -154,5 +154,5 @@ def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_s processed = process_images(p) p.close() generation_info_js = processed.js() - shared.debug(f'Processed: {len(processed.images)} Memory: {memory_stats()} img') + shared.log.debug(f'Processed: {len(processed.images)} Memory: {memory_stats()} img') return processed.images, generation_info_js, plaintext_to_html(processed.info), plaintext_to_html(processed.comments) diff --git a/modules/interrogate.py b/modules/interrogate.py index 38956a8aa..91c00e129 100644 --- a/modules/interrogate.py +++ b/modules/interrogate.py @@ -118,14 +118,14 @@ class InterrogateModels: def load(self): if self.blip_model is None: self.blip_model = self.load_blip_model() - if not shared.cmd_opts.no_half and not self.running_on_cpu: + if not shared.opts.no_half and not self.running_on_cpu: self.blip_model = self.blip_model.half() self.blip_model = self.blip_model.to(devices.device_interrogate) if self.clip_model is None: self.clip_model, self.clip_preprocess = self.load_clip_model() - if not shared.cmd_opts.no_half and not self.running_on_cpu: + if not shared.opts.no_half and not self.running_on_cpu: self.clip_model = self.clip_model.half() self.clip_model = self.clip_model.to(devices.device_interrogate) diff --git a/modules/processing.py b/modules/processing.py index 0d1b52ae9..13124bbfa 100644 --- a/modules/processing.py +++ b/modules/processing.py @@ -680,7 +680,7 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed: for x in x_samples_ddim: devices.test_for_nans(x, "vae") except devices.NansException as e: - if not shared.cmd_opts.no_half and not shared.cmd_opts.no_half_vae and shared.cmd_opts.rollback_vae: + if not shared.opts.no_half and not shared.opts.no_half_vae and shared.cmd_opts.rollback_vae: log.warning('Tensor with all NaNs was produced in VAE') devices.dtype_vae = torch.bfloat16 vae_file, vae_source = sd_vae.resolve_vae(p.sd_model.sd_model_checkpoint) diff --git a/modules/realesrgan_model.py b/modules/realesrgan_model.py index 5b6109eac..75dccf1ac 100644 --- a/modules/realesrgan_model.py +++ b/modules/realesrgan_model.py @@ -57,7 +57,7 @@ class UpscalerRealESRGAN(Upscaler): scale=info.scale, model_path=info.local_data_path, model=info.model(), - half=not cmd_opts.no_half and not opts.upcast_sampling, + half=not opts.no_half and not opts.upcast_sampling, tile=opts.ESRGAN_tile, tile_pad=opts.ESRGAN_tile_overlap, device=device, diff --git a/modules/sd_models.py b/modules/sd_models.py index 78e1e222d..b58df9b90 100644 --- a/modules/sd_models.py +++ b/modules/sd_models.py @@ -262,11 +262,11 @@ def load_model_weights(model: torch.nn.Module, checkpoint_info: CheckpointInfo, if shared.opts.opt_channelslast: model.to(memory_format=torch.channels_last) timer.record("channels") - if not shared.cmd_opts.no_half: + if not shared.opts.no_half: vae = model.first_stage_model depth_model = getattr(model, 'depth_model', None) # with --no-half-vae, remove VAE from model when doing half() to prevent its weights from being converted to float16 - if shared.cmd_opts.no_half_vae: + if shared.opts.no_half_vae: model.first_stage_model = None # with --upcast-sampling, don't convert the depth model weights to float16 if shared.opts.upcast_sampling and depth_model: @@ -275,7 +275,6 @@ def load_model_weights(model: torch.nn.Module, checkpoint_info: CheckpointInfo, model.first_stage_model = vae if depth_model: model.depth_model = depth_model - devices.set_cuda_params() devices.dtype_unet = model.model.diffusion_model.dtype model.first_stage_model.to(devices.dtype_vae) # clean up cache if limit is reached @@ -330,7 +329,7 @@ def enable_midas_autodownload(): def repair_config(sd_config): if not "use_ema" in sd_config.model.params: sd_config.model.params.use_ema = False - if shared.cmd_opts.no_half: + if shared.opts.no_half: sd_config.model.params.unet_config.params.use_fp16 = False elif shared.opts.upcast_sampling: sd_config.model.params.unet_config.params.use_fp16 = True @@ -347,7 +346,7 @@ sd2_clip_weight = 'cond_stage_model.model.transformer.resblocks.0.attn.in_proj_w def load_model(checkpoint_info=None, already_loaded_state_dict=None, timer=None): - shared.debug(f'Load model: {checkpoint_info} {already_loaded_state_dict}') + shared.log.debug(f'Load model: info={checkpoint_info is not None} dict={already_loaded_state_dict is not None}') from modules import lowvram, sd_hijack checkpoint_info = checkpoint_info or select_checkpoint() if checkpoint_info is None: @@ -361,8 +360,9 @@ def load_model(checkpoint_info=None, already_loaded_state_dict=None, timer=None) shared.sd_model = None gc.collect() devices.torch_gc() - shared.debug(f'Model unloaded: {memory_stats()}') + shared.log.debug(f'Model unloaded: {memory_stats()}') do_inpainting_hijack() + devices.set_cuda_params() if already_loaded_state_dict is not None: state_dict = already_loaded_state_dict else: @@ -374,12 +374,12 @@ def load_model(checkpoint_info=None, already_loaded_state_dict=None, timer=None) shared.log.info(f"Restoring previous checkpoint: {current_checkpoint_info.filename}") load_model(current_checkpoint_info, None) return - shared.debug(f'Model dict loaded: {memory_stats()}') + shared.log.debug(f'Model dict loaded: {memory_stats()}') clip_is_included_into_sd = sd1_clip_weight in state_dict or sd2_clip_weight in state_dict sd_config = OmegaConf.load(checkpoint_config) repair_config(sd_config) timer.record("config") - shared.debug(f'Model config loaded: {memory_stats()}') + shared.log.debug(f'Model config loaded: {memory_stats()}') shared.log.info(f"Creating model from config: {checkpoint_config}") sd_model = None try: @@ -391,13 +391,13 @@ def load_model(checkpoint_info=None, already_loaded_state_dict=None, timer=None) timer.record("create") load_model_weights(sd_model, checkpoint_info, state_dict, timer) timer.record("load") - shared.debug(f'Model weights loaded: {memory_stats()}') + shared.log.debug(f'Model weights loaded: {memory_stats()}') if shared.cmd_opts.lowvram or shared.cmd_opts.medvram: lowvram.setup_for_low_vram(sd_model, shared.cmd_opts.medvram) else: sd_model.to(devices.device) timer.record("move") - shared.debug(f'Model weights moved: {memory_stats()}') + shared.log.debug(f'Model weights moved: {memory_stats()}') sd_hijack.model_hijack.hijack(sd_model) timer.record("hijack") sd_model.eval() @@ -411,16 +411,16 @@ def load_model(checkpoint_info=None, already_loaded_state_dict=None, timer=None) timer.record("callbacks") shared.log.info(f"Model loaded in {timer.summary()}") gc.collect() - shared.debug(f'Model load finished: {memory_stats()}') + shared.log.debug(f'Model load finished: {memory_stats()}') def reload_model_weights(sd_model=None, info=None): global skip_next_load # pylint: disable=global-statement if skip_next_load: - shared.debug('Reload model weights skip') + shared.log.debug('Reload model weights skip') skip_next_load = False return - shared.debug(f'Reload model weights: {sd_model} {info}') + shared.log.debug(f'Reload model weights: {sd_model} {info}') from modules import lowvram, sd_hijack checkpoint_info = info or select_checkpoint() if not sd_model: diff --git a/modules/shared.py b/modules/shared.py index 66aba96fa..0875dda66 100644 --- a/modules/shared.py +++ b/modules/shared.py @@ -166,11 +166,6 @@ interrogator = modules.interrogate.InterrogateModels("interrogate") face_restorers = [] -def debug(message): - if cmd_opts.debug: - log.debug(message) - - class OptionInfo: def __init__(self, default=None, label="", component=None, component_args=None, onchange=None, section=None, refresh=None): self.default = default diff --git a/modules/txt2img.py b/modules/txt2img.py index d7533f4b2..d16a0f011 100644 --- a/modules/txt2img.py +++ b/modules/txt2img.py @@ -50,5 +50,5 @@ def txt2img(id_task: str, prompt: str, negative_prompt: str, prompt_styles, step processed = process_images(p) p.close() generation_info_js = processed.js() - shared.debug(f'Processed: {len(processed.images)} Memory: {memory_stats()} txt') + shared.log.debug(f'Processed: {len(processed.images)} Memory: {memory_stats()} txt') return processed.images, generation_info_js, plaintext_to_html(processed.info), plaintext_to_html(processed.comments) diff --git a/modules/upscaler.py b/modules/upscaler.py index 560ca6167..a71c22024 100644 --- a/modules/upscaler.py +++ b/modules/upscaler.py @@ -30,7 +30,7 @@ class Upscaler: self.img = None self.output = None self.scale = 1 - self.half = not shared.cmd_opts.no_half + self.half = not shared.opts.no_half self.pre_pad = 0 self.mod_scale = None