dtype switch

This commit is contained in:
nullquant
2024-05-07 18:00:20 +03:00
parent fea35ab15d
commit afe7714601
2 changed files with 61 additions and 28 deletions
+10 -1
View File
@@ -20,8 +20,8 @@ Apr 11, 2024. Initial commit.
- [x] BrushNet SDXL
- [x] PowerPaint v2
- [ ] Compatibility with `jank HiDiffusion` and similar nodes
- [ ] Image batch
- [ ] Compatibility with `jank HiDiffusion` and similar nodes
## Installation
@@ -59,9 +59,18 @@ Below is an example for the intended workflow. The [workflow](example/BrushNet_b
### Parameters
#### Brushnet Loader
- `dtype`, defaults to `torch.float16`. The torch.dtype of BrushNet. If you have old GPU or NVIDIA 16 series card try to switch to `torch.float32`.
#### Brushnet
- `scale`, defaults to 1.0: The "strength" of BrushNet. The outputs of the BrushNet are multiplied by `scale` before they are added to the residual in the original unet.
- `start_at`, defaults to 0: step at which the BrushNet starts applying.
- `end_at`, defaults to 10000: step at which the BrushNet stops applying.
#### PowerPaint
- `CLIP`: PowerPaint CLIP that should be passed from PowerPaintCLIPLoader node.
- `fitting`: PowerPaint fitting degree.
- `function`: PowerPaint function, see its [page](https://github.com/open-mmlab/PowerPaint) for details.
+51 -27
View File
@@ -5,6 +5,7 @@ import os
import folder_paths
import sys
from sys import platform
# Get the parent directory of 'comfy' and add it to the Python path
comfy_parent_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../'))
sys.path.append(comfy_parent_dir)
@@ -30,10 +31,10 @@ brushnet_config_file = os.path.join(current_directory, 'brushnet', 'brushnet.jso
brushnet_xl_config_file = os.path.join(current_directory, 'brushnet', 'brushnet_xl.json')
powerpaint_config_file = os.path.join(current_directory,'brushnet', 'powerpaint.json')
torch_dtype = torch.float16
sd15_scaling_factor = 0.18215
sdxl_scaling_factor = 0.13025
class BrushNetLoader:
@classmethod
@@ -41,6 +42,7 @@ class BrushNetLoader:
return {"required":
{
"brushnet": (get_files_with_extension('inpaint'), ),
"dtype": (['float16', 'bfloat16', 'float32', 'float64'], ),
},
}
@@ -50,7 +52,7 @@ class BrushNetLoader:
FUNCTION = "brushnet_loading"
def brushnet_loading(self, brushnet):
def brushnet_loading(self, brushnet, dtype):
brushnet_file = os.path.join(folder_paths.models_dir, "inpaint", brushnet)
is_SDXL = False
@@ -89,6 +91,15 @@ class BrushNetLoader:
else:
print("BrushNet model file:", brushnet_file)
if dtype == 'float16':
torch_dtype = torch.float16
elif dtype == 'bfloat16':
torch_dtype = torch.bfloat16
elif dtype == 'float32':
torch_dtype = torch.float32
else:
torch_dtype = torch.float64
brushnet_model = load_checkpoint_and_dispatch(
brushnet_model,
brushnet_file,
@@ -107,7 +118,7 @@ class BrushNetLoader:
else:
print("BrushNet SD1.5 model is loaded")
return ({"brushnet": brushnet_model, "SDXL": is_SDXL, "PP": is_PP},)
return ({"brushnet": brushnet_model, "SDXL": is_SDXL, "PP": is_PP, "dtype": torch_dtype}, )
class PowerPaintCLIPLoader:
@@ -205,6 +216,8 @@ class PowerPaint:
else:
scaling_factor = sd15_scaling_factor
torch_dtype = powerpaint['dtype']
# prepare conditioning latents
conditioning_latents, conditioning_latents2 = get_image_latents(masked_image, mask, vae, scaling_factor)
conditioning_latents = conditioning_latents.to(dtype=torch_dtype).to(powerpaint['brushnet'].device)
@@ -275,6 +288,7 @@ class PowerPaint:
add_brushnet_patch(model,
powerpaint['brushnet'],
torch_dtype,
conditioning_latents,
conditioning_latents2,
(brushnet_conditioning_scale, control_guidance_start, control_guidance_end),
@@ -336,6 +350,8 @@ class BrushNet:
else:
scaling_factor = sd15_scaling_factor
torch_dtype = brushnet['dtype']
# prepare conditioning latents
conditioning_latents, conditioning_latents2 = get_image_latents(masked_image, mask, vae, scaling_factor)
conditioning_latents = conditioning_latents.to(dtype=torch_dtype).to(brushnet['brushnet'].device)
@@ -383,6 +399,7 @@ class BrushNet:
add_brushnet_patch(model,
brushnet['brushnet'],
torch_dtype,
conditioning_latents,
conditioning_latents2,
(brushnet_conditioning_scale, control_guidance_start, control_guidance_end),
@@ -480,6 +497,7 @@ def brushnet_blocks(sd):
brushnet_up_block += 1
return (brushnet_down_block, brushnet_mid_block, brushnet_up_block, len(sd))
# Check models compatibility
def check_compatibilty(model, brushnet):
is_SDXL = False
@@ -536,36 +554,36 @@ def prepare_image(image, mask):
# Prepare conditioning_latents
@torch.inference_mode()
def get_image_latents(masked_image, mask, vae, scaling_factor):
with torch.no_grad():
processed_image = masked_image.to(vae.device)
processed_image2 = torch.cat([masked_image] * 2).to(vae.device)
processed_image = masked_image.to(vae.device)
processed_image2 = torch.cat([masked_image] * 2).to(vae.device)
image_latents = vae.encode(processed_image[:,:,:,:3]) * scaling_factor
image_latents2 = vae.encode(processed_image2[:,:,:,:3]) * scaling_factor
image_latents = vae.encode(processed_image[:,:,:,:3]) * scaling_factor
image_latents2 = vae.encode(processed_image2[:,:,:,:3]) * scaling_factor
processed_mask = 1. - mask[None,:,:,:]
interpolated_mask = torch.nn.functional.interpolate(
processed_mask,
size=(
image_latents.shape[-2],
image_latents.shape[-1]
)
processed_mask = 1. - mask[None,:,:,:]
interpolated_mask = torch.nn.functional.interpolate(
processed_mask,
size=(
image_latents.shape[-2],
image_latents.shape[-1]
)
interpolated_mask = interpolated_mask.to(image_latents.device)
)
interpolated_mask = interpolated_mask.to(image_latents.device)
processed_mask2 = torch.cat([1. - mask[None,:,:,:]] * 2)
interpolated_mask2 = torch.nn.functional.interpolate(
processed_mask2,
size=(
image_latents2.shape[-2],
image_latents2.shape[-1]
)
processed_mask2 = torch.cat([1. - mask[None,:,:,:]] * 2)
interpolated_mask2 = torch.nn.functional.interpolate(
processed_mask2,
size=(
image_latents2.shape[-2],
image_latents2.shape[-1]
)
interpolated_mask2 = interpolated_mask2.to(image_latents2.device)
)
interpolated_mask2 = interpolated_mask2.to(image_latents2.device)
conditioning_latents = torch.concat([image_latents, interpolated_mask], 1)
conditioning_latents2 = torch.concat([image_latents2, interpolated_mask2], 1)
conditioning_latents = torch.concat([image_latents, interpolated_mask], 1)
conditioning_latents2 = torch.concat([image_latents2, interpolated_mask2], 1)
print('BrushNet CL: image_latents shape =', image_latents2.shape, 'interpolated_mask shape =', interpolated_mask2.shape)
@@ -634,6 +652,7 @@ def modified_sample(model, noise, positive, negative, cfg, device, sampler, sigm
return cfg_guider.sample(noise, latent_image, sampler, sigmas, denoise_mask, callback, disable_pbar, seed)
# Main function where magic happens
@torch.inference_mode()
def brushnet_inference(x, timesteps, transformer_options):
if 'model_patch' not in transformer_options:
print('BrushNet inference: there is no model_patch in transformer_options')
@@ -644,6 +663,7 @@ def brushnet_inference(x, timesteps, transformer_options):
return ([], 0, [])
brushnet = mp['brushnet_model']
if isinstance(brushnet, BrushNetModel) or isinstance(brushnet, PowerPaintModel):
torch_dtype = mp['brushnet_dtype']
cl = mp['brushnet_latents']
cl2 = mp['brushnet_latents2']
brushnet_conditioning_scale, control_guidance_start, control_guidance_end = mp['brushnet_controls']
@@ -752,6 +772,9 @@ def brushnet_inference(x, timesteps, transformer_options):
added_cond_kwargs=added_cond_kwargs,
return_dict=False,
)
else:
print('BrushNet model is not a BrushNetModel class')
return ([], 0, [])
@@ -766,12 +789,13 @@ def add_model_patch_option(model):
return to
# This is main patch function
def add_brushnet_patch(model, brushnet, conditioning_latents, conditioning_latents2,
def add_brushnet_patch(model, brushnet, torch_dtype, conditioning_latents, conditioning_latents2,
controls,
prompt_embeds, add_text_embeds, add_time_ids,
prompt_embeds2, add_text_embeds2, add_time_ids2):
to = add_model_patch_option(model)
to['model_patch']['brushnet_model'] = brushnet
to['model_patch']['brushnet_dtype'] = torch_dtype
to['model_patch']['brushnet_latents'] = conditioning_latents
to['model_patch']['brushnet_latents2'] = conditioning_latents2
to['model_patch']['brushnet_controls'] = controls