Skip to content

Commit 3b9227c

Browse files
committed
add DeekSeek and Kimi-K2;support per-tensor and w4a8;support batch calibration in fp8 low_memory_run
1 parent 52e7992 commit 3b9227c

31 files changed

Lines changed: 3030 additions & 67 deletions

angelslim/compressor/quant/core/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@
1515
from .config import * # noqa: F401 F403
1616
from .hook import DiTHook, PTQHook # noqa: F401
1717
from .metrics import mse_loss, snr_loss # noqa: F401
18-
from .packing_utils import dequantize_gemm # noqa: F401
18+
from .packing_utils import dequantize_gemm, pack_weight_to_int8 # noqa: F401
1919
from .quant_func import * # noqa: F401 F403
2020
from .sample_func import EMASampler, MultiStepSampler # noqa: F401
21+
from .save import DeepseekV3HfPTQSave # noqa: F401
22+
from .save import DeepseekV3PTQSaveTRTLLM # noqa: F401
2123
from .save import PTQPTMSave # noqa: F401
2224
from .save import PTQSaveVllmHF # noqa: F401
2325
from .save import PTQTorchSave # noqa: F401

angelslim/compressor/quant/core/config.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,24 @@ def __init__(self, config, global_config=None):
7474
)
7575
self.weight_observer = WEIGHT_OBSERVERS_CLASS[weight_quant_method]
7676
self.kv_cache_observer = None
77-
self.quant_algo_info = {
78-
"w": f"fp8_{weight_quant_method}",
79-
"ignore_layers": quantization_args.ignore_layers,
80-
}
77+
78+
if "w4a8" in self.quant_algo:
79+
group_size = (
80+
128
81+
if quantization_args.quant_method["group_size"] == -1
82+
else quantization_args.quant_method["group_size"]
83+
)
84+
self.quant_algo_info = {
85+
"w": f"int4_{weight_quant_method}",
86+
"w_group_size": group_size,
87+
"ignore_layers": quantization_args.ignore_layers,
88+
}
89+
else:
90+
self.quant_algo_info = {
91+
"w": f"fp8_{weight_quant_method}",
92+
"ignore_layers": quantization_args.ignore_layers,
93+
}
94+
8195
if act_quant_method is not None:
8296
self.quant_algo_info["a"] = f"fp8_{act_quant_method}-{is_dynamic}"
8397
self.hidden_size = global_config.hidden_size

angelslim/compressor/quant/core/packing_utils.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
import numpy as np
1516
import torch
1617

1718
AWQ_ORDER = [0, 2, 4, 6, 1, 3, 5, 7]
@@ -115,3 +116,21 @@ def dequantize_gemm(qweight, qzeros, scales, bits, group_size):
115116
iweight = (iweight - izeros) * scales
116117

117118
return iweight
119+
120+
121+
def pack_weight_to_int8(weight):
122+
weight = weight.t().contiguous().cpu()
123+
weight = weight.to(torch.float32).numpy().astype(np.int8)
124+
125+
i = 0
126+
row = 0
127+
packed_weight = np.zeros((weight.shape[0] // 2, weight.shape[1]), dtype=np.int8)
128+
while row < packed_weight.shape[0]:
129+
for j in range(i, i + (8 // 4)):
130+
packed_weight[row] |= (weight[j] & 0x0F) << (4 * (j - i))
131+
i += 8 // 4
132+
row += 1
133+
134+
packed_weight = packed_weight.astype(np.int8)
135+
packed_weight = torch.from_numpy(packed_weight).t().contiguous()
136+
return packed_weight

angelslim/compressor/quant/core/quant_func.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
from typing import Tuple
1616

1717
import torch
18+
import triton
19+
import triton.language as tl
1820

1921
from .metrics import mse_loss
2022

@@ -314,3 +316,67 @@ def tensor_quant_dequant_fp8(x, scale, bits=8, mantissa_bit=3, sign_bits=1):
314316
)
315317
quant_dequant_x *= scale
316318
return quant_dequant_x
319+
320+
321+
# This function is copied from DeepSeek-V3 (MIT License):
322+
# Copyright (c) 2023 DeepSeek-AI
323+
# Original source: https://github.com/deepseek-ai/DeepSeek-V3
324+
@triton.jit
325+
def weight_dequant_kernel(x_ptr, s_ptr, y_ptr, M, N, BLOCK_SIZE: tl.constexpr):
326+
"""
327+
Dequantizes weights using the provided scaling factors and stores the result.
328+
329+
Args:
330+
x_ptr (tl.pointer): Pointer to the quantized weights.
331+
s_ptr (tl.pointer): Pointer to the scaling factors.
332+
y_ptr (tl.pointer): Pointer to the output buffer for dequantized weights.
333+
M (int): Number of rows in the weight matrix.
334+
N (int): Number of columns in the weight matrix.
335+
BLOCK_SIZE (tl.constexpr): Size of the block for tiling.
336+
337+
Returns:
338+
None
339+
"""
340+
pid_m = tl.program_id(axis=0)
341+
pid_n = tl.program_id(axis=1)
342+
n = tl.cdiv(N, BLOCK_SIZE)
343+
offs_m = pid_m * BLOCK_SIZE + tl.arange(0, BLOCK_SIZE)
344+
offs_n = pid_n * BLOCK_SIZE + tl.arange(0, BLOCK_SIZE)
345+
offs = offs_m[:, None] * N + offs_n[None, :]
346+
mask = (offs_m[:, None] < M) & (offs_n[None, :] < N)
347+
x = tl.load(x_ptr + offs, mask=mask).to(tl.float32)
348+
s = tl.load(s_ptr + pid_m * n + pid_n)
349+
y = x * s
350+
tl.store(y_ptr + offs, y, mask=mask)
351+
352+
353+
# This function is copied from DeepSeek-V3 (MIT License):
354+
# Copyright (c) 2023 DeepSeek-AI
355+
# Original source: https://github.com/deepseek-ai/DeepSeek-V3
356+
def weight_dequant(
357+
x: torch.Tensor, s: torch.Tensor, block_size: int = 128
358+
) -> torch.Tensor:
359+
"""
360+
Dequantizes the given weight tensor using the provided scale tensor.
361+
362+
Args:
363+
x (torch.Tensor): The quantized weight tensor of shape (M, N).
364+
s (torch.Tensor): The scale tensor of shape (M, N).
365+
block_size (int, optional): The block size to use for dequantization. Defaults to 128. # noqa: E501
366+
367+
Returns:
368+
torch.Tensor: The dequantized weight tensor of the same shape as `x`.
369+
370+
Raises:
371+
AssertionError: If `x` or `s` are not contiguous or if their dimensions are not 2. # noqa: E501
372+
"""
373+
assert x.is_contiguous() and s.is_contiguous(), "Input tensors must be contiguous"
374+
assert x.dim() == 2 and s.dim() == 2, "Input tensors must have 2 dimensions"
375+
M, N = x.size()
376+
y = torch.empty_like(x, dtype=torch.get_default_dtype())
377+
grid = lambda meta: ( # noqa: E731
378+
triton.cdiv(M, meta["BLOCK_SIZE"]),
379+
triton.cdiv(N, meta["BLOCK_SIZE"]),
380+
)
381+
weight_dequant_kernel[grid](x, s, y, M, N, BLOCK_SIZE=block_size)
382+
return y

0 commit comments

Comments
 (0)