2024-08-11 12:50:34 +00:00
|
|
|
"""
|
|
|
|
This file is part of ComfyUI.
|
|
|
|
Copyright (C) 2024 Comfy
|
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
"""
|
|
|
|
|
2023-06-22 17:03:50 +00:00
|
|
|
import torch
|
|
|
|
from . import model_base
|
|
|
|
from . import utils
|
2023-08-30 03:58:32 +00:00
|
|
|
from . import latent_formats
|
2023-06-22 17:03:50 +00:00
|
|
|
|
|
|
|
class ClipTarget:
|
|
|
|
def __init__(self, tokenizer, clip):
|
|
|
|
self.clip = clip
|
|
|
|
self.tokenizer = tokenizer
|
|
|
|
self.params = {}
|
|
|
|
|
|
|
|
class BASE:
|
|
|
|
unet_config = {}
|
|
|
|
unet_extra_config = {
|
|
|
|
"num_heads": -1,
|
|
|
|
"num_head_channels": 64,
|
|
|
|
}
|
|
|
|
|
2024-03-31 05:25:16 +00:00
|
|
|
required_keys = {}
|
|
|
|
|
2023-06-22 17:03:50 +00:00
|
|
|
clip_prefix = []
|
|
|
|
clip_vision_prefix = None
|
|
|
|
noise_aug_config = None
|
2023-11-22 22:23:37 +00:00
|
|
|
sampling_settings = {}
|
2023-08-30 03:58:32 +00:00
|
|
|
latent_format = latent_formats.LatentFormat
|
2024-01-30 07:24:38 +00:00
|
|
|
vae_key_prefix = ["first_stage_model."]
|
2024-02-19 15:29:18 +00:00
|
|
|
text_encoder_key_prefix = ["cond_stage_model."]
|
2024-02-16 15:55:08 +00:00
|
|
|
supported_inference_dtypes = [torch.float16, torch.bfloat16, torch.float32]
|
2023-06-22 17:03:50 +00:00
|
|
|
|
2024-08-02 22:08:21 +00:00
|
|
|
memory_usage_factor = 2.0
|
|
|
|
|
2023-12-11 23:24:44 +00:00
|
|
|
manual_cast_dtype = None
|
2024-08-11 12:50:34 +00:00
|
|
|
custom_operations = None
|
2024-10-09 23:43:17 +00:00
|
|
|
optimizations = {"fp8": False}
|
2023-12-11 23:24:44 +00:00
|
|
|
|
2023-06-22 17:03:50 +00:00
|
|
|
@classmethod
|
2024-03-31 05:25:16 +00:00
|
|
|
def matches(s, unet_config, state_dict=None):
|
2023-06-22 17:03:50 +00:00
|
|
|
for k in s.unet_config:
|
2024-02-16 15:55:08 +00:00
|
|
|
if k not in unet_config or s.unet_config[k] != unet_config[k]:
|
2023-06-22 17:03:50 +00:00
|
|
|
return False
|
2024-03-31 05:25:16 +00:00
|
|
|
if state_dict is not None:
|
|
|
|
for k in s.required_keys:
|
|
|
|
if k not in state_dict:
|
|
|
|
return False
|
2023-06-22 17:03:50 +00:00
|
|
|
return True
|
|
|
|
|
2023-07-17 05:22:12 +00:00
|
|
|
def model_type(self, state_dict, prefix=""):
|
|
|
|
return model_base.ModelType.EPS
|
2023-06-22 17:03:50 +00:00
|
|
|
|
|
|
|
def inpaint_model(self):
|
|
|
|
return self.unet_config["in_channels"] > 4
|
|
|
|
|
|
|
|
def __init__(self, unet_config):
|
2024-04-10 03:20:43 +00:00
|
|
|
self.unet_config = unet_config.copy()
|
|
|
|
self.sampling_settings = self.sampling_settings.copy()
|
2023-06-23 06:14:12 +00:00
|
|
|
self.latent_format = self.latent_format()
|
2024-10-12 18:10:13 +00:00
|
|
|
self.optimizations = self.optimizations.copy()
|
2023-06-22 17:03:50 +00:00
|
|
|
for x in self.unet_extra_config:
|
|
|
|
self.unet_config[x] = self.unet_extra_config[x]
|
|
|
|
|
2023-07-29 18:51:56 +00:00
|
|
|
def get_model(self, state_dict, prefix="", device=None):
|
2023-09-01 19:18:25 +00:00
|
|
|
if self.noise_aug_config is not None:
|
|
|
|
out = model_base.SD21UNCLIP(self, self.noise_aug_config, model_type=self.model_type(state_dict, prefix), device=device)
|
2023-06-22 17:03:50 +00:00
|
|
|
else:
|
2023-09-01 19:18:25 +00:00
|
|
|
out = model_base.BaseModel(self, model_type=self.model_type(state_dict, prefix), device=device)
|
|
|
|
if self.inpaint_model():
|
|
|
|
out.set_inpaint()
|
|
|
|
return out
|
2023-06-22 17:03:50 +00:00
|
|
|
|
|
|
|
def process_clip_state_dict(self, state_dict):
|
2024-02-19 15:29:18 +00:00
|
|
|
state_dict = utils.state_dict_prefix_replace(state_dict, {k: "" for k in self.text_encoder_key_prefix}, filter_keys=True)
|
2023-06-22 17:03:50 +00:00
|
|
|
return state_dict
|
|
|
|
|
2023-11-21 03:27:36 +00:00
|
|
|
def process_unet_state_dict(self, state_dict):
|
|
|
|
return state_dict
|
|
|
|
|
2023-11-21 21:29:18 +00:00
|
|
|
def process_vae_state_dict(self, state_dict):
|
|
|
|
return state_dict
|
|
|
|
|
2023-06-26 16:21:07 +00:00
|
|
|
def process_clip_state_dict_for_saving(self, state_dict):
|
2024-02-19 15:29:18 +00:00
|
|
|
replace_prefix = {"": self.text_encoder_key_prefix[0]}
|
2023-09-03 02:33:37 +00:00
|
|
|
return utils.state_dict_prefix_replace(state_dict, replace_prefix)
|
2023-06-26 16:21:07 +00:00
|
|
|
|
2024-01-18 00:37:19 +00:00
|
|
|
def process_clip_vision_state_dict_for_saving(self, state_dict):
|
|
|
|
replace_prefix = {}
|
|
|
|
if self.clip_vision_prefix is not None:
|
|
|
|
replace_prefix[""] = self.clip_vision_prefix
|
|
|
|
return utils.state_dict_prefix_replace(state_dict, replace_prefix)
|
|
|
|
|
2023-06-26 16:21:07 +00:00
|
|
|
def process_unet_state_dict_for_saving(self, state_dict):
|
|
|
|
replace_prefix = {"": "model.diffusion_model."}
|
2023-09-03 02:33:37 +00:00
|
|
|
return utils.state_dict_prefix_replace(state_dict, replace_prefix)
|
2023-06-26 16:21:07 +00:00
|
|
|
|
|
|
|
def process_vae_state_dict_for_saving(self, state_dict):
|
2024-02-19 15:29:18 +00:00
|
|
|
replace_prefix = {"": self.vae_key_prefix[0]}
|
2023-09-03 02:33:37 +00:00
|
|
|
return utils.state_dict_prefix_replace(state_dict, replace_prefix)
|
2023-06-26 16:21:07 +00:00
|
|
|
|
2024-02-16 15:55:08 +00:00
|
|
|
def set_inference_dtype(self, dtype, manual_cast_dtype):
|
|
|
|
self.unet_config['dtype'] = dtype
|
2023-12-11 23:24:44 +00:00
|
|
|
self.manual_cast_dtype = manual_cast_dtype
|