Async patch load with GPU support

This commit is contained in:
City
2024-08-17 07:38:55 +02:00
parent fed8ff1e70
commit 22e2c885f0
2 changed files with 45 additions and 3 deletions
+22 -1
View File
@@ -76,6 +76,7 @@ class LoraLoaderGGUFModelOnly:
"model": ("MODEL",),
"lora_name": (folder_paths.get_filename_list("loras"), ),
"strength_model": ("FLOAT", {"default": 1.0, "min": -100.0, "max": 100.0, "step": 0.01}),
"lora_on_gpu": ("BOOLEAN", {"default": True}),
}
}
@@ -84,7 +85,7 @@ class LoraLoaderGGUFModelOnly:
CATEGORY = "bootleg"
TITLE = "LoRA Loader Model Only (GGUF)"
def load_lora(self, model, lora_name, strength_model):
def load_lora(self, model, lora_name, strength_model, lora_on_gpu):
if strength_model == 0:
return (model,)
@@ -102,6 +103,26 @@ class LoraLoaderGGUFModelOnly:
lora = comfy.utils.load_torch_file(lora_path, safe_load=True)
self.loaded_lora = (lora_path, lora)
# This is a super hacky method to get it to load alongside the model
param_dict_name = f"lora_state_dict"#_{lora_name}".replace('.', '_')
target_model = model.model.diffusion_model
if lora_on_gpu:
print(f"WARNING! Loading the LoRA to GPU memory may cause OOM issues or memory leaks!")
temp = {}
params = torch.nn.ParameterDict()
for k,v in lora.items():
param = torch.nn.Parameter(v, requires_grad=False)
temp[k] = param
params[k.replace('.', '_')] = param
params.to(model.load_device, dtype=torch.float16)
target_model.register_module(param_dict_name, params)
lora = temp
else:
params = getattr(target_model, param_dict_name, None)
if params:
params.to("cpu", dtype=torch.float16)
delattr(target_model, param_dict_name)
model_lora = load_lora_gguf(model, lora, strength_model)
return (model_lora,)
+23 -2
View File
@@ -83,12 +83,33 @@ class GGMLLayer(torch.nn.Module):
super()._apply(fn)
return self
def move_patch_to_cuda(self, item, device):
if isinstance(item, torch.Tensor):
return item.to(device, non_blocking=True)
elif isinstance(item, tuple):
return tuple(self.move_patch_to_cuda(x, device) for x in item)
elif isinstance(item, list):
return [self.move_patch_to_cuda(x, device) for x in item]
else:
return item
def get_weight(self, tensor, dtype):
if tensor is None:
return
# consolidate and load patches to GPU in async
patch_list = []
device = tensor.device
t_move = lambda x: x.to(device) if torch.is_tensor(x) else x
for function, patches, _ in getattr(tensor, "patches", []):
patch_list += self.move_patch_to_cuda(patches, device)
# dequantize tensor while patches load
weight = dequantize_tensor(tensor, dtype)
for function, patches, key in getattr(tensor, "patches", []):
weight = function(patches, weight, key)
# apply patches
if patch_list:
weight = function(patch_list, weight, "dequant.name.unknown")
return weight
def get_weights(self, dtype=torch.float16):