diff --git a/invokeai/app/services/config.py b/invokeai/app/services/config.py index e0f1ceeb25..e7f817fc0a 100644 --- a/invokeai/app/services/config.py +++ b/invokeai/app/services/config.py @@ -228,10 +228,10 @@ class InvokeAISettings(BaseSettings): upcase_environ = dict() for key,value in os.environ.items(): upcase_environ[key.upper()] = value - + fields = cls.__fields__ cls.argparse_groups = {} - + for name, field in fields.items(): if name not in cls._excluded(): current_default = field.default @@ -348,7 +348,7 @@ setting environment variables INVOKEAI_. ''' singleton_config: ClassVar[InvokeAIAppConfig] = None singleton_init: ClassVar[Dict] = None - + #fmt: off type: Literal["InvokeAI"] = "InvokeAI" host : str = Field(default="127.0.0.1", description="IP address to bind to", category='Web Server') @@ -367,7 +367,8 @@ setting environment variables INVOKEAI_. always_use_cpu : bool = Field(default=False, description="If true, use the CPU for rendering even if a GPU is available.", category='Memory/Performance') free_gpu_mem : bool = Field(default=False, description="If true, purge model from GPU after each generation.", category='Memory/Performance') - max_loaded_models : int = Field(default=3, gt=0, description="Maximum number of models to keep in memory for rapid switching", category='Memory/Performance') + max_loaded_models : int = Field(default=3, gt=0, description="(DEPRECATED: use max_cache_size) Maximum number of models to keep in memory for rapid switching", category='Memory/Performance') + max_cache_size : float = Field(default=6.0, gt=0, description="Maximum memory amount used by model cache for rapid switching", category='Memory/Performance') precision : Literal[tuple(['auto','float16','float32','autocast'])] = Field(default='float16',description='Floating point precision', category='Memory/Performance') sequential_guidance : bool = Field(default=False, description="Whether to calculate guidance in serial instead of in parallel, lowering memory requirements", category='Memory/Performance') xformers_enabled : bool = Field(default=True, description="Enable/disable memory-efficient attention", category='Memory/Performance') @@ -385,9 +386,9 @@ setting environment variables INVOKEAI_. outdir : Path = Field(default='outputs', description='Default folder for output images', category='Paths') from_file : Path = Field(default=None, description='Take command input from the indicated file (command-line client only)', category='Paths') use_memory_db : bool = Field(default=False, description='Use in-memory database for storing image metadata', category='Paths') - + model : str = Field(default='stable-diffusion-1.5', description='Initial model name', category='Models') - + log_handlers : List[str] = Field(default=["console"], description='Log handler. Valid options are "console", "file=", "syslog=path|address:host:port", "http="', category="Logging") # note - would be better to read the log_format values from logging.py, but this creates circular dependencies issues log_format : Literal[tuple(['plain','color','syslog','legacy'])] = Field(default="color", description='Log format. Use "plain" for text-only, "color" for colorized output, "legacy" for 2.3-style logging and "syslog" for syslog-style', category="Logging") @@ -396,7 +397,7 @@ setting environment variables INVOKEAI_. def parse_args(self, argv: List[str]=None, conf: DictConfig = None, clobber=False): ''' - Update settings with contents of init file, environment, and + Update settings with contents of init file, environment, and command-line settings. :param conf: alternate Omegaconf dictionary object :param argv: aternate sys.argv list @@ -411,7 +412,7 @@ setting environment variables INVOKEAI_. except: pass InvokeAISettings.initconf = conf - + # parse args again in order to pick up settings in configuration file super().parse_args(argv) @@ -431,7 +432,7 @@ setting environment variables INVOKEAI_. cls.singleton_config = cls(**kwargs) cls.singleton_init = kwargs return cls.singleton_config - + @property def root_path(self)->Path: ''' diff --git a/invokeai/app/services/model_manager_service.py b/invokeai/app/services/model_manager_service.py index 98b4d81ba8..455d9d021f 100644 --- a/invokeai/app/services/model_manager_service.py +++ b/invokeai/app/services/model_manager_service.py @@ -33,13 +33,13 @@ class ModelManagerServiceBase(ABC): logger: types.ModuleType, ): """ - Initialize with the path to the models.yaml config file. + Initialize with the path to the models.yaml config file. Optional parameters are the torch device type, precision, max_models, and sequential_offload boolean. Note that the default device type and precision are set up for a CUDA system running at half precision. """ pass - + @abstractmethod def get_model( self, @@ -50,8 +50,8 @@ class ModelManagerServiceBase(ABC): node: Optional[BaseInvocation] = None, context: Optional[InvocationContext] = None, ) -> ModelInfo: - """Retrieve the indicated model with name and type. - submodel can be used to get a part (such as the vae) + """Retrieve the indicated model with name and type. + submodel can be used to get a part (such as the vae) of a diffusers pipeline.""" pass @@ -115,8 +115,8 @@ class ModelManagerServiceBase(ABC): """ Update the named model with a dictionary of attributes. Will fail with an assertion error if the name already exists. Pass clobber=True to overwrite. - On a successful update, the config will be changed in memory. Will fail - with an assertion error if provided attributes are incorrect or + On a successful update, the config will be changed in memory. Will fail + with an assertion error if provided attributes are incorrect or the model name is missing. Call commit() to write changes to disk. """ pass @@ -129,8 +129,8 @@ class ModelManagerServiceBase(ABC): model_type: ModelType, ): """ - Delete the named model from configuration. If delete_files is true, - then the underlying weight file or diffusers directory will be deleted + Delete the named model from configuration. If delete_files is true, + then the underlying weight file or diffusers directory will be deleted as well. Call commit() to write to disk. """ pass @@ -176,7 +176,7 @@ class ModelManagerService(ModelManagerServiceBase): logger: types.ModuleType, ): """ - Initialize with the path to the models.yaml config file. + Initialize with the path to the models.yaml config file. Optional parameters are the torch device type, precision, max_models, and sequential_offload boolean. Note that the default device type and precision are set up for a CUDA system running at half precision. @@ -206,6 +206,8 @@ class ModelManagerService(ModelManagerServiceBase): if hasattr(config,'max_cache_size') \ else config.max_loaded_models * 2.5 + logger.debug(f"Maximum RAM cache size: {max_cache_size} GiB") + sequential_offload = config.sequential_guidance self.mgr = ModelManager( @@ -261,7 +263,7 @@ class ModelManagerService(ModelManagerServiceBase): submodel=submodel, model_info=model_info ) - + return model_info def model_exists( @@ -314,8 +316,8 @@ class ModelManagerService(ModelManagerServiceBase): """ Update the named model with a dictionary of attributes. Will fail with an assertion error if the name already exists. Pass clobber=True to overwrite. - On a successful update, the config will be changed in memory. Will fail - with an assertion error if provided attributes are incorrect or + On a successful update, the config will be changed in memory. Will fail + with an assertion error if provided attributes are incorrect or the model name is missing. Call commit() to write changes to disk. """ return self.mgr.add_model(model_name, base_model, model_type, model_attributes, clobber) @@ -328,8 +330,8 @@ class ModelManagerService(ModelManagerServiceBase): model_type: ModelType, ): """ - Delete the named model from configuration. If delete_files is true, - then the underlying weight file or diffusers directory will be deleted + Delete the named model from configuration. If delete_files is true, + then the underlying weight file or diffusers directory will be deleted as well. Call commit() to write to disk. """ self.mgr.del_model(model_name, base_model, model_type) @@ -383,7 +385,7 @@ class ModelManagerService(ModelManagerServiceBase): @property def logger(self): return self.mgr.logger - + def heuristic_import(self, items_to_import: Set[str], prediction_type_helper: Callable[[Path],SchedulerPredictionType]=None, @@ -404,4 +406,4 @@ class ModelManagerService(ModelManagerServiceBase): of the set is a dict corresponding to the newly-created OmegaConf stanza for that model. ''' - return self.mgr.heuristic_import(items_to_import, prediction_type_helper) + return self.mgr.heuristic_import(items_to_import, prediction_type_helper)