From 6b778afdc938427116cb72e683d28e42baf67082 Mon Sep 17 00:00:00 2001 From: blepping <157360029+blepping@users.noreply.github.com> Date: Mon, 8 Sep 2025 23:07:45 -0600 Subject: [PATCH 1/3] Fix attempt to create a tensor with dtype "target" (#330) * Fix attempt to create a tensor with dtype "target" * Check if dequant_dtype is None before string comparison with target --- ops.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ops.py b/ops.py index 41d42f5..ff9b960 100644 --- a/ops.py +++ b/ops.py @@ -153,7 +153,7 @@ class GGMLLayer(torch.nn.Module): # Take into account space required for dequantizing the largest tensor if self.largest_layer: shape = getattr(self.weight, "tensor_shape", self.weight.shape) - dtype = self.dequant_dtype or torch.float16 + dtype = (self.dequant_dtype and self.dequant_dtype != "target") or torch.float16 temp = torch.empty(*shape, device=torch.device("meta"), dtype=dtype) destination[prefix + "temp.weight"] = temp From be2a08330d7ec232d684e50ab938870d7529471e Mon Sep 17 00:00:00 2001 From: blepping <157360029+blepping@users.noreply.github.com> Date: Sun, 14 Sep 2025 15:10:50 -0600 Subject: [PATCH 2/3] Fix dequant_dtype handling (#334) * Fix dequant_dtype handling * Simplify dequant dtype selection expression --- ops.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ops.py b/ops.py index ff9b960..88a352e 100644 --- a/ops.py +++ b/ops.py @@ -153,7 +153,7 @@ class GGMLLayer(torch.nn.Module): # Take into account space required for dequantizing the largest tensor if self.largest_layer: shape = getattr(self.weight, "tensor_shape", self.weight.shape) - dtype = (self.dequant_dtype and self.dequant_dtype != "target") or torch.float16 + dtype = self.dequant_dtype if self.dequant_dtype and self.dequant_dtype != "target" else torch.float16 temp = torch.empty(*shape, device=torch.device("meta"), dtype=dtype) destination[prefix + "temp.weight"] = temp From 100c06cda840b0406f96fd7c3c57076d443f82b6 Mon Sep 17 00:00:00 2001 From: rattus <46076784+rattus128@users.noreply.github.com> Date: Tue, 4 Nov 2025 00:57:29 +1000 Subject: [PATCH 3/3] nodes: mmap detach weights before they are pinned (#355) Comfy core recently introduced a feature where weights may be pinned when loading, particularly for the case of offloading. Intercept this, and immediately detached each weight before the pinning. This avoids a crash that at least some users are experiencing. Use a little dict on the modules to keep track of whats already done, and when the catch-all detacher loop comes through, use this dict (which has already done modules removed) as the iterator basis. --- nodes.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/nodes.py b/nodes.py index 4159142..08849df 100644 --- a/nodes.py +++ b/nodes.py @@ -76,8 +76,21 @@ class GGUFModelPatcher(comfy.model_patcher.ModelPatcher): # TODO: Find another way to not unload after patches return super().unpatch_model(device_to=device_to, unpatch_weights=unpatch_weights) + + def pin_weight_to_device(self, key): + op_key = key.rsplit('.', 1)[0] + if self.named_modules_to_munmap is not None and op_key in self.named_modules_to_munmap: + # TODO: possible to OOM, find better way to detach + self.named_modules_to_munmap[op_key].to(self.load_device).to(self.offload_device) + del self.named_modules_to_munmap[op_key] + super().pin_weight_to_device(key) + mmap_released = False + def load(self, *args, force_patch_weights=False, **kwargs): + if not self.mmap_released: + self.named_modules_to_munmap = dict(self.model.named_modules()) + # always call `patch_weight_to_device` even for lowvram super().load(*args, force_patch_weights=True, **kwargs) @@ -85,7 +98,7 @@ class GGUFModelPatcher(comfy.model_patcher.ModelPatcher): if not self.mmap_released: linked = [] if kwargs.get("lowvram_model_memory", 0) > 0: - for n, m in self.model.named_modules(): + for n, m in self.named_modules_to_munmap.items(): if hasattr(m, "weight"): device = getattr(m.weight, "device", None) if device == self.offload_device: @@ -102,6 +115,7 @@ class GGUFModelPatcher(comfy.model_patcher.ModelPatcher): # TODO: possible to OOM, find better way to detach m.to(self.load_device).to(self.offload_device) self.mmap_released = True + self.named_modules_to_munmap = None def clone(self, *args, **kwargs): src_cls = self.__class__