SDXL checks

This commit is contained in:
nullquant
2024-04-29 19:42:40 +03:00
parent 60fc4f88e1
commit 356eb8490b
4 changed files with 1656 additions and 81 deletions
+2 -2
View File
@@ -482,9 +482,9 @@ class BrushNetModel(ModelMixin, ConfigMixin):
conditioning_channels=conditioning_channels,
flip_sin_to_cos=unet.config.flip_sin_to_cos,
freq_shift=unet.config.freq_shift,
down_block_types=['DownBlock2D','DownBlock2D','DownBlock2D','DownBlock2D'],
down_block_types=["DownBlock2D" for block_name in unet.config.down_block_types],
mid_block_type='MidBlock2D',
up_block_types=['UpBlock2D','UpBlock2D','UpBlock2D','UpBlock2D'],
up_block_types=["UpBlock2D" for block_name in unet.config.down_block_types],
only_cross_attention=unet.config.only_cross_attention,
block_out_channels=unet.config.block_out_channels,
layers_per_block=unet.config.layers_per_block,
+63
View File
@@ -0,0 +1,63 @@
{
"_class_name": "BrushNetModel",
"_diffusers_version": "0.27.0.dev0",
"_name_or_path": "runs/logs/brushnetsdxl_randommask/checkpoint-80000",
"act_fn": "silu",
"addition_embed_type": "text_time",
"addition_embed_type_num_heads": 64,
"addition_time_embed_dim": 256,
"attention_head_dim": [
5,
10,
20
],
"block_out_channels": [
320,
640,
1280
],
"brushnet_conditioning_channel_order": "rgb",
"class_embed_type": null,
"conditioning_channels": 5,
"conditioning_embedding_out_channels": [
16,
32,
96,
256
],
"cross_attention_dim": 2048,
"down_block_types": [
"DownBlock2D",
"DownBlock2D",
"DownBlock2D"
],
"downsample_padding": 1,
"encoder_hid_dim": null,
"encoder_hid_dim_type": null,
"flip_sin_to_cos": true,
"freq_shift": 0,
"global_pool_conditions": false,
"in_channels": 4,
"layers_per_block": 2,
"mid_block_scale_factor": 1,
"mid_block_type": "MidBlock2D",
"norm_eps": 1e-05,
"norm_num_groups": 32,
"num_attention_heads": null,
"num_class_embeds": null,
"only_cross_attention": false,
"projection_class_embeddings_input_dim": 2816,
"resnet_time_scale_shift": "default",
"transformer_layers_per_block": [
1,
2,
10
],
"up_block_types": [
"UpBlock2D",
"UpBlock2D",
"UpBlock2D"
],
"upcast_attention": null,
"use_linear_projection": true
}
File diff suppressed because it is too large Load Diff
+56 -79
View File
@@ -36,6 +36,7 @@ warnings.filterwarnings("ignore", category=UserWarning, module="safetensors")
current_directory = os.path.dirname(os.path.abspath(__file__))
original_config_file = os.path.join(current_directory, 'brushnet', 'v1-inference.yaml')
brushnet_config_file = os.path.join(current_directory, 'brushnet', 'brushnet.json')
brushnet_xl_config_file = os.path.join(current_directory, 'brushnet', 'brushnet_xl.json')
torch_dtype = torch.float16
class BrushNetLoader:
@@ -57,8 +58,23 @@ class BrushNetLoader:
def brushnet_loading(self, brushnet):
brushnet_file = os.path.join(folder_paths.models_dir, "inpaint", brushnet)
is_SDXL = False
sd = comfy.utils.load_torch_file(brushnet_file)
brushnet_down_block, brushnet_mid_block, brushnet_up_block = brushnet_blocks(sd)
if brushnet_down_block == 24 and brushnet_mid_block == 2 and brushnet_up_block == 30:
print('Loading SD1.5 BrushNet model')
is_SDXL = False
elif brushnet_down_block == 18 and brushnet_mid_block == 2 and brushnet_up_block == 22:
print('Loading SDXL BrushNet model')
is_SDXL = True
else:
raise Exception("Unknown BrushNet model")
with init_empty_weights():
brushnet_config = BrushNetModel.load_config(brushnet_config_file)
if is_SDXL:
brushnet_config = BrushNetModel.load_config(brushnet_xl_config_file)
else:
brushnet_config = BrushNetModel.load_config(brushnet_config_file)
brushnet_model = BrushNetModel.from_config(brushnet_config)
brushnet_model = load_checkpoint_and_dispatch(
@@ -72,9 +88,9 @@ class BrushNetLoader:
force_hooks=False,
)
print("BrushNet model is loaded")
print("BrushNet model is loaded, SDXL? ", is_SDXL)
return (brushnet_model,)
return ({"brushnet": brushnet_model, "SDXL": is_SDXL},)
def inpaint_safetensors():
@@ -98,6 +114,19 @@ def inpaint_safetensors():
names.append(y)
return names
def brushnet_blocks(sd):
brushnet_down_block = 0
brushnet_mid_block = 0
brushnet_up_block = 0
for key in sd:
if 'brushnet_down_block' in key:
brushnet_down_block += 1
if 'brushnet_mid_block' in key:
brushnet_mid_block += 1
if 'brushnet_up_block' in key:
brushnet_up_block += 1
return (brushnet_down_block, brushnet_mid_block, brushnet_up_block, )
class BrushNet:
@@ -129,6 +158,22 @@ class BrushNet:
#if len(mask.shape) > 2:
# mask = mask[0]
is_SDXL = False
if isinstance(model.model.model_config, comfy.supported_models.SD15):
print('Base model type: SD1.5')
is_SDXL = False
if brushnet["SDXL"]:
raise Exception("Base model is SD15, but BrushNet is SDXL type")
elif isinstance(model.model.model_config, comfy.supported_models.SDXL):
print('Base model type: SDXL')
is_SDXL = True
if not brushnet["SDXL"]:
raise Exception("Base model is SDXL, but BrushNet is SD15 type")
raise Exception("SDXL support is not implemented yet")
else:
print('Base model type: ', type(model.model.model_config))
raise Exception("Unsupported model type: " + str(type(model.model.model_config)))
masked_image = image * (1.0 - mask[:,:,:,None])
masked_image = masked_image.permute(0, 3, 1, 2)
@@ -172,7 +217,7 @@ class BrushNet:
)
interpolated_mask = interpolated_mask.to(device=diff_vae.device, dtype=diff_vae.dtype)
conditioning_latents = torch.concat([image_latents, interpolated_mask], 1).to(dtype=torch_dtype).to(brushnet.device)
conditioning_latents = torch.concat([image_latents, interpolated_mask], 1).to(dtype=torch_dtype).to(brushnet["brushnet"].device)
del diff_vae
@@ -193,7 +238,7 @@ class BrushNet:
# apply patch to model
add_brushnet_patch(model, brushnet, conditioning_latents,
add_brushnet_patch(model, brushnet["brushnet"], conditioning_latents,
[brushnet_conditioning_scale, control_guidance_start, control_guidance_end])
add_model_patch(model, brushnet_inference, ('input', 0), (0, 'before'))
@@ -208,73 +253,6 @@ class BrushNet:
return (model,)
class BrushNetInpaint:
@classmethod
def INPUT_TYPES(s):
return {"required":
{
"BRPL": ("BRPL", ),
"image": ("IMAGE",),
"mask": ("MASK",),
"positive": ("CONDITIONING", ),
"negative": ("CONDITIONING", ),
"seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
"steps": ("INT", {"default": 50, "min": 1, "max": 10000}),
"scale": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0}),
},
}
CATEGORY = "inpaint"
RETURN_TYPES = ("IMAGE",)
RETURN_NAMES = ("image",)
FUNCTION = "brushnet_inpaint"
def brushnet_inpaint(self, BRPL, image: torch.Tensor, mask: torch.Tensor, positive, negative, seed: int,
steps: int, scale: float) -> Tuple[torch.Tensor]:
print("Working on image")
# no batches
if len(image.shape) > 3:
image = image[0]
if len(mask.shape) > 2:
mask = mask[0]
init_image = image_from_tensor(image)
mask_image = image_from_tensor(mask)
mask_image = 1.*(mask_image>250)[:,:,np.newaxis]
init_image = init_image * (1-mask_image)
init_image = Image.fromarray(init_image.astype(np.uint8)).convert("RGB")
mask_image = Image.fromarray(mask_image.astype(np.uint8).repeat(3,-1)*255).convert("RGB")
print("Inference started")
pos_embeds = positive
while isinstance(pos_embeds, list):
pos_embeds = pos_embeds[0]
neg_embeds = negative
while isinstance(neg_embeds, list):
neg_embeds = neg_embeds[0]
generator = torch.Generator("cuda").manual_seed(seed)
result = BRPL(
image=init_image,
mask=mask_image,
prompt_embeds=pos_embeds,
negative_prompt_embeds=neg_embeds,
num_inference_steps=steps,
generator=generator,
brushnet_conditioning_scale=scale
).images[0]
return (torch.stack([numpy_to_tensor(np.array(result)).squeeze(0)]),)
class BlendInpaint:
@classmethod
@@ -429,8 +407,8 @@ def brushnet_inference(x, emb, context, loc, transformer_options):
# loc = (('input'|'middle'|'output', i), j, 'before'|'after')
if 'model_patch' not in transformer_options:
print('BrushNet inference: there is no model_patch in transformer_options')
return x
raise Exception('BrushNet inference: there is no model_patch in transformer_options')
mp = transformer_options['model_patch']
brushnet = mp['brushnet_model']
if isinstance(brushnet, BrushNetModel):
@@ -458,7 +436,7 @@ def brushnet_inference(x, emb, context, loc, transformer_options):
transformer_options['model_patch']['middle_sample'] = mid_sample
transformer_options['model_patch']['output_samples'] = up_samples
else:
print('BrushNet model is not a BrushNetModel class')
raise Exception('BrushNet model is not a BrushNetModel class')
return x
@@ -467,16 +445,15 @@ def apply_brushnet(x, emb, context, loc, transformer_options):
if len(transformer_options['model_patch']['input_samples']) > 0:
return x + transformer_options['model_patch']['input_samples'].pop(0)
else:
print('BrushNet: something is not right, input samples are empty', loc)
return x
raise Exception('BrushNet: something is not right, input samples are empty, ' + str(loc))
elif loc[0][0] == 'middle':
return x + transformer_options['model_patch']['middle_sample']
else:
if len(transformer_options['model_patch']['output_samples']) > 0:
return x + transformer_options['model_patch']['output_samples'].pop(0)
else:
print('BrushNet: something is not right, output samples are empty', loc)
return x
raise Exception('BrushNet: something is not right, output samples are empty, ' + str(loc))
def image_from_tensor(t: torch.Tensor) -> np.ndarray:
image_np = t.numpy()