diff --git a/invokeai/backend/install/invokeai_configure.py b/invokeai/backend/install/invokeai_configure.py index 322fc527c8..0fb2811f61 100755 --- a/invokeai/backend/install/invokeai_configure.py +++ b/invokeai/backend/install/invokeai_configure.py @@ -467,7 +467,7 @@ class editOptsForm(npyscreen.FormMultiPage): self.nextrely += 1 self.add_widget_intelligent( npyscreen.FixedText, - value="Directories containing textual inversion and LoRA models ( autocompletes, ctrl-N advances):", + value="Directories containing textual inversion, controlnet and LoRA models ( autocompletes, ctrl-N advances):", editable=False, color="CONTROL", ) @@ -493,6 +493,17 @@ class editOptsForm(npyscreen.FormMultiPage): begin_entry_at=32, scroll_exit=True, ) + self.controlnet_dir = self.add_widget_intelligent( + npyscreen.TitleFilename, + name=" ControlNets:", + value=str(default_controlnet_dir()), + select_dir=True, + must_exist=False, + use_two_lines=False, + labelColor="GOOD", + begin_entry_at=32, + scroll_exit=True, + ) self.nextrely += 1 self.add_widget_intelligent( npyscreen.TitleFixedText, @@ -582,6 +593,7 @@ class editOptsForm(npyscreen.FormMultiPage): "always_use_cpu", "embedding_dir", "lora_dir", + "controlnet_dir", ]: setattr(new_opts, attr, getattr(self, attr).value) @@ -659,6 +671,7 @@ def initialize_rootdir(root: str, yes_to_all: bool = False): "configs", "embeddings", "databases", + "loras", "controlnets", "text-inversion-output", "text-inversion-training-data", @@ -720,6 +733,10 @@ def default_embedding_dir() -> Path: def default_lora_dir() -> Path: return config.root / "loras" +# ------------------------------------- +def default_controlnet_dir() -> Path: + return config.root / "controlnets" + # ------------------------------------- def write_default_options(program_opts: Namespace, initfile: Path): opt = default_startup_options(initfile) diff --git a/invokeai/backend/model_management/model_manager.py b/invokeai/backend/model_management/model_manager.py index 8c122f94a0..f36988276f 100644 --- a/invokeai/backend/model_management/model_manager.py +++ b/invokeai/backend/model_management/model_manager.py @@ -936,34 +936,35 @@ class ModelManager(object): from . import convert_ckpt_to_diffusers - if diffusers_path.exists(): - self.logger.error( - f"The path {str(diffusers_path)} already exists. Please move or remove it and try again." - ) - return - model_name = model_name or diffusers_path.name model_description = model_description or f"Converted version of {model_name}" - self.logger.debug(f"Converting {model_name} to diffusers (30-60s)") + try: - # By passing the specified VAE to the conversion function, the autoencoder - # will be built into the model rather than tacked on afterward via the config file - vae_model = None - if vae: - vae_model = self._load_vae(vae) - vae_path = None - convert_ckpt_to_diffusers( - ckpt_path, - diffusers_path, - extract_ema=True, - original_config_file=original_config_file, - vae=vae_model, - vae_path=vae_path, - scan_needed=scan_needed, - ) - self.logger.debug( - f"Success. Converted model is now located at {str(diffusers_path)}" - ) + if diffusers_path.exists(): + self.logger.error( + f"The path {str(diffusers_path)} already exists. Installing previously-converted path." + ) + else: + self.logger.debug(f"Converting {model_name} to diffusers (30-60s)") + + # By passing the specified VAE to the conversion function, the autoencoder + # will be built into the model rather than tacked on afterward via the config file + vae_model = None + if vae: + vae_model = self._load_vae(vae) + vae_path = None + convert_ckpt_to_diffusers( + ckpt_path, + diffusers_path, + extract_ema=True, + original_config_file=original_config_file, + vae=vae_model, + vae_path=vae_path, + scan_needed=scan_needed, + ) + self.logger.debug( + f"Success. Converted model is now located at {str(diffusers_path)}" + ) self.logger.debug(f"Writing new config file entry for {model_name}") new_config = dict( path=str(diffusers_path), @@ -975,7 +976,7 @@ class ModelManager(object): self.add_model(model_name, new_config, True) if commit_to_conf: self.commit(commit_to_conf) - self.logger.debug("Conversion succeeded") + self.logger.debug(f"Model {model_name} installed") except Exception as e: self.logger.warning(f"Conversion failed: {str(e)}") self.logger.warning(traceback.format_exc()) diff --git a/invokeai/frontend/install/model_install.py b/invokeai/frontend/install/model_install.py index 624bc06905..07fa1d6c59 100644 --- a/invokeai/frontend/install/model_install.py +++ b/invokeai/frontend/install/model_install.py @@ -182,17 +182,15 @@ class addModelsForm(npyscreen.FormMultiPage): button_length += len(back_label) + 1 button_offset += len(back_label) + 1 self.back_button = self.add_widget_intelligent( - OffsetButtonPress, + npyscreen.ButtonPress, name=back_label, relx=(window_width - button_length) // 2, - offset=-3, rely=-3, when_pressed_function=self.on_back, ) self.ok_button = self.add_widget_intelligent( - OffsetButtonPress, + npyscreen.ButtonPress, # OffsetButtonPress, name=done_label, - offset=+3, relx=button_offset + 1 + (window_width - button_length) // 2, rely=-3, when_pressed_function=self.on_execute @@ -464,7 +462,7 @@ class addModelsForm(npyscreen.FormMultiPage): p = Process( target = process_and_execute, kwargs=dict( - opt = app.opt, + opt = app.program_opts, selections = app.user_selections, conn_out = child_conn, ) @@ -653,7 +651,7 @@ class addModelsForm(npyscreen.FormMultiPage): class AddModelApplication(npyscreen.NPSAppManaged): def __init__(self,opt): super().__init__() - self.opt = opt + self.program_opts = opt self.user_cancelled = False self.user_selections = UserSelections()