Skip to content

Commit 079edcc

Browse files
authored
fix(qlinear): size GPTQ buffers by pack_factor and skip Laguna g_proj quantization (#84) (#2983)
* fix(qlinear): use pack_factor for qweight/qzeros buffer sizing and mark Laguna g_proj as non-quantizable * test(qlinear): add buffer shape test for out_features=48/72
1 parent 581bfd9 commit 079edcc

3 files changed

Lines changed: 36 additions & 5 deletions

File tree

gptqmodel/models/definitions/laguna.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class LagunaQModel(BaseQModel):
2929
"q_proj:0",
3030
"k_proj:0",
3131
"v_proj:0",
32-
"g_proj:0",
32+
"g_proj:!",
3333
"o_proj:1",
3434
),
3535
"post_attention_layernorm": ("post_attention_layernorm:!",),

gptqmodel/nn_modules/qlinear/__init__.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -750,14 +750,14 @@ def _register_gptq_buffers(
750750

751751
self.register_buffer(
752752
"qweight",
753-
t.zeros((in_features // self.pack_dtype_bits * self.bits, out_features), dtype=self.pack_dtype),
753+
t.zeros((math.ceil(in_features / self.pack_factor), out_features), dtype=self.pack_dtype),
754754
)
755755
self.register_buffer(
756756
"qzeros",
757757
t.zeros(
758758
(
759759
math.ceil(in_features / self.group_size),
760-
out_features // self.pack_dtype_bits * self.bits,
760+
math.ceil(out_features / self.pack_factor),
761761
),
762762
dtype=self.pack_dtype,
763763
),
@@ -1395,7 +1395,7 @@ def pack_original(self, linear: nn.Module, scales: t.Tensor, zeros: t.Tensor, g_
13951395
int_weight = int_weight.to(t.int32).T.contiguous()
13961396
int_weight = int_weight.numpy().astype(self.pack_np_math_dtype)
13971397

1398-
qweight = np.zeros((int_weight.shape[0] // self.pack_dtype_bits * self.bits, int_weight.shape[1]),
1398+
qweight = np.zeros((math.ceil(int_weight.shape[0] / self.pack_factor), int_weight.shape[1]),
13991399
dtype=self.pack_np_math_dtype)
14001400
if self.bits in [2, 4, 8]:
14011401
for row in range(qweight.shape[0]):
@@ -1428,7 +1428,7 @@ def pack_original(self, linear: nn.Module, scales: t.Tensor, zeros: t.Tensor, g_
14281428
self.register_buffer("qweight", t.from_numpy(qweight.astype(self.pack_np_dtype)))
14291429

14301430
zeros = zeros.numpy().astype(self.pack_np_math_dtype)
1431-
qzeros = np.zeros((zeros.shape[0], zeros.shape[1] // self.pack_dtype_bits * self.bits), dtype=self.pack_np_math_dtype)
1431+
qzeros = np.zeros((zeros.shape[0], math.ceil(zeros.shape[1] / self.pack_factor)), dtype=self.pack_np_math_dtype)
14321432
if self.bits in [2, 4, 8]:
14331433
for col in range(qzeros.shape[1]):
14341434
for j in range(self.pack_factor):

tests/kernels/test_qlinear_hierarchy.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,3 +234,34 @@ def test_weight_only_kernels_do_not_declare_grouped_support_metadata():
234234
assert not hasattr(cls, "SUPPORTS_GROUP_SIZE")
235235
assert not hasattr(cls, "SUPPORTS_DESC_ACT")
236236
assert not hasattr(cls, "SUPPORTS_SYM")
237+
238+
239+
def test_gptq_quant_linear_buffer_shapes_for_non_word_aligned_out_features():
240+
"""Laguna's g_proj has out_features=48/72, which is a multiple of pack_factor (8) but not pack_dtype_bits (32)."""
241+
import math
242+
243+
for out_features in (48, 72):
244+
layer = TorchLinear(
245+
bits=4,
246+
group_size=32,
247+
sym=True,
248+
desc_act=False,
249+
in_features=3072,
250+
out_features=out_features,
251+
bias=False,
252+
)
253+
expected_qweight_rows = math.ceil(3072 / layer.pack_factor)
254+
expected_qzeros_cols = math.ceil(out_features / layer.pack_factor)
255+
assert layer.qweight.shape == (expected_qweight_rows, out_features)
256+
assert layer.qzeros.shape == (math.ceil(3072 / 32), expected_qzeros_cols)
257+
258+
# Ensure a checkpoint with the natural packed shapes loads cleanly.
259+
state = {
260+
"qweight": torch.zeros((expected_qweight_rows, out_features), dtype=torch.int32),
261+
"qzeros": torch.zeros((math.ceil(3072 / 32), expected_qzeros_cols), dtype=torch.int32),
262+
"scales": torch.zeros((math.ceil(3072 / 32), out_features), dtype=torch.float16),
263+
"g_idx": torch.tensor([i // 32 for i in range(3072)], dtype=torch.int32),
264+
}
265+
missing, unexpected = layer.load_state_dict(state, strict=False)
266+
assert not missing
267+
assert not unexpected

0 commit comments

Comments
 (0)