From f379407db25a30f96a27e2953c8559bcf43c5200 Mon Sep 17 00:00:00 2001 From: pluto <40908673+hc20k@users.noreply.github.com> Date: Thu, 16 Jul 2026 05:56:51 -0700 Subject: [PATCH] Dequantize non-weight/bias tensors that GGMLLayer can't intercept GGMLLayer only handles `weight` and `bias`, so bare nn.Parameters fall through to torch's default _load_from_state_dict, which needs a real float tensor. BF16 tensors skip the F32/F16 reshape and stay as raw uint8 byte buffers, so LTX-2's *_embeddings_connector.learnable_registers fail with "only Tensors of floating point dtype can require gradients" and a doubled final dim. Dequantize quantized tensors whose keys GGMLLayer cannot intercept. --- loader.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/loader.py b/loader.py index 7cefb11..698fb5b 100644 --- a/loader.py +++ b/loader.py @@ -142,6 +142,12 @@ def gguf_sd_loader(path, handle_prefix="model.diffusion_model.", is_text_model=F if len(shape) <= 1 and tensor.tensor_type == gguf.GGMLQuantizationType.BF16: state_dict[sd_key] = dequantize_tensor(state_dict[sd_key], dtype=torch.float32) + # GGMLLayer only intercepts weight/bias, so anything else (e.g. bare + # nn.Parameters such as LTX-2's learnable_registers) reaches torch's + # default load path and must already be a real float tensor. + elif not sd_key.endswith((".weight", ".bias")) and is_quantized(state_dict[sd_key]): + state_dict[sd_key] = dequantize_tensor(state_dict[sd_key], dtype=torch.float32) + # keep track of loaded tensor types tensor_type_str = getattr(tensor.tensor_type, "name", repr(tensor.tensor_type)) qtype_dict[tensor_type_str] = qtype_dict.get(tensor_type_str, 0) + 1