diff --git a/modules/api/api.py b/modules/api/api.py index 12c814be8..36a22e423 100644 --- a/modules/api/api.py +++ b/modules/api/api.py @@ -148,6 +148,7 @@ class Api: self.add_api_route("/sdapi/v1/scripts", self.get_scripts_list, methods=["GET"], response_model=models.ScriptsList) self.add_api_route("/sdapi/v1/script-info", self.get_script_info, methods=["GET"], response_model=List[models.ScriptInfo]) self.add_api_route("/sdapi/v1/log", self.get_log_buffer, methods=["GET"], response_model=List) # bypass auth + self.add_api_route("/sdapi/v1/extra-networks", self.get_extra_networks, methods=["GET"], response_model=List[models.ExtraNetworkItem]) self.default_script_arg_txt2img = [] self.default_script_arg_img2img = [] @@ -502,6 +503,34 @@ class Api: "skipped": convert_embeddings(db.skipped_embeddings), } + def get_extra_networks(self, page: Optional[str] = None, name: Optional[str] = None, filename: Optional[str] = None, title: Optional[str] = None, fullname: Optional[str] = None, hash: Optional[str] = None): # pylint: disable=redefined-builtin + import modules.ui_extra_networks + res = [] + for pg in modules.ui_extra_networks.extra_pages: + if page is not None and pg.name != page.lower(): + continue + for item in pg.items: + if name is not None and item.get('name', '') != name: + continue + if title is not None and item.get('title', '') != title: + continue + if filename is not None and item.get('filename', '') != filename: + continue + if fullname is not None and item.get('fullname', '') != fullname: + continue + if hash is not None and (item.get('shorthash', None) or item.get('hash')) != hash: + continue + res.append({ + 'name': item.get('name', ''), + 'type': pg.name, + 'title': item.get('title', None), + 'fullname': item.get('fullname', None), + 'filename': item.get('filename', None), + 'hash': item.get('shorthash', None) or item.get('hash'), + "preview": item.get('preview', None), + }) + return res + def refresh_checkpoints(self): return shared.refresh_checkpoints() diff --git a/modules/api/models.py b/modules/api/models.py index 6bd4eccfe..9241592eb 100644 --- a/modules/api/models.py +++ b/modules/api/models.py @@ -272,6 +272,20 @@ class StyleItem(BaseModel): filename: Optional[str] = Field(title="Filename") preview: Optional[str] = Field(title="Preview") +class ExtraNetworkItem(BaseModel): + name: str = Field(title="Name") + type: str = Field(title="Type") + title: Optional[str] = Field(title="Title") + fullname: Optional[str] = Field(title="Fullname") + filename: Optional[str] = Field(title="Filename") + hash: Optional[str] = Field(title="Hash") + preview: Optional[str] = Field(title="Preview image URL") + # description: Optional[str] = Field(title="Description") + # info: Optional[str] = Field(title="Information") + # metadata: Optional[Any] = Field(title="Metadata") + # local: Optional[str] = Field(title="Local") + + class ArtistItem(BaseModel): name: str = Field(title="Name") score: float = Field(title="Score") diff --git a/modules/lora_diffusers.py b/modules/lora_diffusers.py index c6ce96d1e..1e9890f02 100644 --- a/modules/lora_diffusers.py +++ b/modules/lora_diffusers.py @@ -15,7 +15,7 @@ def unload_diffusers_lora(): try: pipe = shared.sd_model if shared.opts.diffusers_lora_loader == "diffusers": - if len(lora_state['loaded']) > 1: + if len(lora_state['loaded']) > 1 and hasattr(pipe, "unfuse_lora"): pipe.unfuse_lora() pipe.unload_lora_weights() pipe._remove_text_encoder_monkey_patch() # pylint: disable=W0212 @@ -51,7 +51,7 @@ def load_diffusers_lora(name, lora, strength = 1.0, num_loras = 1): fuse = 0 if shared.opts.diffusers_lora_loader.startswith("diffusers"): pipe.load_lora_weights(lora.filename, cache_dir=shared.opts.diffusers_dir, local_files_only=True, lora_scale=strength, low_cpu_mem_usage=True) - if num_loras > 1: + if num_loras > 1 and hasattr(pipe, "fuse_lora"): t2 = time.time() pipe.fuse_lora(lora_scale=strength) fuse = time.time() - t2 @@ -535,6 +535,6 @@ class LoRANetwork(torch.nn.Module): # pylint: disable=abstract-method for key in state_dict.keys(): if state_dict[key].size() != my_state_dict[key].size(): # pylint: disable=unsubscriptable-object # print(f"convert {key} from {state_dict[key].size()} to {my_state_dict[key].size()}") - state_dict[key] = state_dict[key].view(my_state_dict[key].size()) + state_dict[key] = state_dict[key].view(my_state_dict[key].size()) # pylint: disable=unsubscriptable-object return super().load_state_dict(state_dict, strict) diff --git a/modules/processing.py b/modules/processing.py index d4d635497..fe0e78e6a 100644 --- a/modules/processing.py +++ b/modules/processing.py @@ -1015,7 +1015,7 @@ class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing): decoded_samples = decode_first_stage(self.sd_model, samples.to(dtype=devices.dtype_vae)) lowres_samples = torch.clamp((decoded_samples + 1.0) / 2.0, min=0.0, max=1.0) batch_images = [] - for i, x_sample in enumerate(lowres_samples): + for _i, x_sample in enumerate(lowres_samples): x_sample = 255. * np.moveaxis(x_sample.cpu().numpy(), 0, 2) x_sample = validate_sample(x_sample) image = Image.fromarray(x_sample) diff --git a/modules/ui_extra_networks_checkpoints.py b/modules/ui_extra_networks_checkpoints.py index 7159445b5..4a4a18e1d 100644 --- a/modules/ui_extra_networks_checkpoints.py +++ b/modules/ui_extra_networks_checkpoints.py @@ -18,6 +18,7 @@ class ExtraNetworksPageCheckpoints(ui_extra_networks.ExtraNetworksPage): path, _ext = os.path.splitext(checkpoint.filename) yield { "name": checkpoint.name_for_extra, + "title": checkpoint.title, "filename": path, "fullname": checkpoint.filename, "hash": checkpoint.shorthash,