Files
city96-ComfyUI-GGUF/ops.py
T
2024-08-15 05:50:54 +02:00

79 lines
2.4 KiB
Python

# (c) City96 || Apache-2.0 (apache.org/licenses/LICENSE-2.0)
import gguf
import torch
import numpy as np
import comfy.ops
from .dequant import dequantize_tensor
class GGMLTensor(torch.Tensor):
"""
Main tensor-like class for storing quantized weights
"""
def __init__(self, tensor, *args, **kwargs):
super().__init__()
self.tensor_type = tensor.tensor_type
self.tensor_shape = torch.Size(
np.flip(list(tensor.shape))
)
def __new__(cls, tensor, *args, **kwargs):
data = torch.tensor(tensor.data)
return super().__new__(cls, data, *args, **kwargs)
def to(self, *args, **kwargs):
new = super().to(*args, **kwargs)
new.tensor_type = self.tensor_type
new.tensor_shape = self.tensor_shape
return new
@property
def shape(self):
return self.tensor_shape
class GGMLLayer(torch.nn.Module):
"""
This (should) be responsible for de-quantizing on the fly
"""
def __init__(self, *args, **kwargs):
super().__init__()
self.weight = None
self.bias = None
def _load_from_state_dict(self, state_dict, prefix, local_metadata, strict, missing_keys, unexpected_keys, error_msgs):
for k,v in state_dict.items():
if k[len(prefix):] == "weight":
self.weight = v
elif k[len(prefix):] == "bias":
self.bias = v
else:
missing_keys.append(k)
def _apply(self, fn):
if self.weight is not None:
self.weight = fn(self.weight)
if self.bias is not None:
self.bias = fn(self.bias)
super()._apply(fn)
return self
def get_weights(self, dtype=torch.float16):
weight = dequantize_tensor(self.weight, dtype)
bias = dequantize_tensor(self.bias, dtype)
return (weight, bias)
class GGMLOps(comfy.ops.disable_weight_init):
"""
Dequantize weights on the fly before doing the compute
"""
class Linear(GGMLLayer):
def __init__(self, *args, device=None, dtype=None, **kwargs):
super().__init__(device=device, dtype=dtype)
self.parameters_manual_cast = torch.float32
def forward(self, x):
weight, bias = self.get_weights(x.dtype)
x = torch.nn.functional.linear(x, weight, bias)
del weight, bias
return x