-
Notifications
You must be signed in to change notification settings - Fork 693
[Feature] Unify quant ops #6021
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
9e15dfc
db6202a
3bc2769
4ca6e63
2ce15d8
63dcefa
01bed15
7c1bd99
6b0d374
af4fdd7
a9d23ea
3261a53
fcd8ef0
2e20113
b9e180f
0ef0a00
7f8c74e
b72882c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -155,9 +155,10 @@ def apply_ep_prefill( | |||||||||||||||||
| topk_ids_hookfunc(topk_ids=topk_idx) | ||||||||||||||||||
|
|
||||||||||||||||||
| # 2. Dynamic compute blockwise quantization scales | ||||||||||||||||||
| x, x_scale_tensor = fastdeploy.model_executor.ops.gpu.per_token_quant( | ||||||||||||||||||
| x, self.quant_config.weight_block_size[0] | ||||||||||||||||||
| x, x_scale_tensor = paddle.incubate.nn.functional.fp8_quant_blockwise( | ||||||||||||||||||
| x, using_pow2_scale=False, output_scale_transpose=False | ||||||||||||||||||
| ) | ||||||||||||||||||
|
||||||||||||||||||
| ) | |
| ) | |
| # fp8_quant_blockwise may return an extra padded dimension on the scale tensor | |
| # when output_scale_transpose=False. Slice by x.shape[0] to keep only the | |
| # valid batch entries so that x_scale_tensor matches the layout expected by EP. |
Copilot
AI
Jan 23, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里调用 fp8_quant_blockwise 时没有指定 output_scale_transpose 参数,根据代码上下文和其他地方的用法,这里应该显式指定 output_scale_transpose=True(因为后续有 .T 操作)或者 output_scale_transpose=False。建议明确指定这个参数以提高代码的可读性和一致性。
| ffn_out, using_pow2_scale=False | |
| ffn_out, | |
| using_pow2_scale=False, | |
| output_scale_transpose=True, |
Copilot
AI
Jan 23, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
调用 paddle.incubate.nn.functional.fp8_quant_blockwise 时没有指定 output_scale_transpose 参数。根据其他地方的用法,当没有指定这个参数时,默认行为可能是 False。在这里,返回的 scale tensor 会进行转置操作(.T)并切片。
为了提高代码的一致性和可读性,建议:
- 显式指定 output_scale_transpose=True(如果默认行为可以满足需求)
- 或者显式指定 output_scale_transpose=False 并保留 .T 操作
- 与 block_wise_fp8.py 中第 229 行的用法进行对比,那里使用了 output_scale_transpose=True 并且也有 .T 操作,这可能表明存在冗余操作
| ffn_out, using_pow2_scale=False | |
| ffn_out, | |
| using_pow2_scale=False, | |
| output_scale_transpose=False, |
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -1525,7 +1525,10 @@ def apply( | |||||||||||||||
|
|
||||||||||||||||
| from .triton_moe_kernels import fused_moe_kernel_paddle | ||||||||||||||||
|
|
||||||||||||||||
| x_q, x_scale = fastdeploy.model_executor.ops.gpu.per_token_quant(x, self.quant_config.weight_block_size[0]) | ||||||||||||||||
| x_q, x_scale = paddle.incubate.nn.functional.fp8_quant_blockwise( | ||||||||||||||||
| x, using_pow2_scale=False, output_scale_transpose=False | ||||||||||||||||
| ) | ||||||||||||||||
|
||||||||||||||||
| ) | |
| ) | |
| # fp8_quant_blockwise may pad the leading dimension of x_q/x_scale to | |
| # a multiple of the internal block size (e.g. BLOCK_SIZE_M). Only the | |
| # first x.shape[0] entries correspond to real tokens, so we slice here | |
| # to match the original token dimension. The padded region is handled | |
| # separately via max_num_tokens_padded and related Triton kernel args. |
Copilot
AI
Jan 23, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里对 x_scale 进行了切片操作 x_scale[: x_q.shape[0]],与上面类似的代码保持一致。但是应该添加注释说明为什么需要这个切片操作,以提高代码的可维护性。
| ) | |
| ) | |
| # Align the activation scale with the quantized activation rows. | |
| # fp8_quant_blockwise may return extra scale rows due to block padding, | |
| # but the fused Triton kernel expects one scale row per row in x_q. |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -18,7 +18,6 @@ | |||||||||||||||||
|
|
||||||||||||||||||
| import paddle | ||||||||||||||||||
|
|
||||||||||||||||||
| import fastdeploy | ||||||||||||||||||
| from fastdeploy import envs | ||||||||||||||||||
|
||||||||||||||||||
| from fastdeploy.model_executor.layers.linear import ( | ||||||||||||||||||
| MergedColumnParallelLinear, | ||||||||||||||||||
|
|
@@ -226,9 +225,10 @@ def process_prequanted_weights(self, layer, state_dict, is_rearrange: bool = Fal | |||||||||||||||||
| layer.weight_scale_inv.set_value(weight_scale) | ||||||||||||||||||
|
|
||||||||||||||||||
| def apply(self, layer, x): | ||||||||||||||||||
| x, x_scale_tensor = fastdeploy.model_executor.ops.gpu.per_token_quant_padding( | ||||||||||||||||||
| x, self.quant_config.weight_block_size[0] | ||||||||||||||||||
| x, x_scale_tensor = paddle.incubate.nn.functional.fp8_quant_blockwise( | ||||||||||||||||||
| x, using_pow2_scale=False, output_scale_transpose=True | ||||||||||||||||||
| ) | ||||||||||||||||||
| x_scale_tensor = x_scale_tensor.T | ||||||||||||||||||
|
Comment on lines
+228
to
+231
|
||||||||||||||||||
| x, x_scale_tensor = paddle.incubate.nn.functional.fp8_quant_blockwise( | |
| x, using_pow2_scale=False, output_scale_transpose=True | |
| ) | |
| x_scale_tensor = x_scale_tensor.T | |
| # output_scale_transpose=True returns the scale tensor in the layout required by deep_gemm | |
| x, x_scale_tensor = paddle.incubate.nn.functional.fp8_quant_blockwise( | |
| x, using_pow2_scale=False, output_scale_transpose=True | |
| ) |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -220,6 +220,35 @@ def group_wise_int4_weight_quantize(weight: paddle.Tensor, group_size: int = 128 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return quant_weight.astype(paddle.int8), weight_scale | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def scale_wrapper(x_amax: paddle.Tensor, eps: float = 0.0) -> paddle.Tensor: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Paddle implementation of CUDA ScaleWrapper logic. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Args: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| x_amax (paddle.Tensor): amax tensor (float32 recommended) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| eps (float): epsilon to avoid division by zero | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Returns: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| paddle.Tensor: scale tensor, same shape as x_amax | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fp8_max = 448.0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| float_max = paddle.finfo(paddle.float32).max | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| amax_mod = paddle.maximum( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| x_amax, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| paddle.full_like(x_amax, eps), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| scale = fp8_max / amax_mod | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| scale = paddle.where( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| amax_mod == 0, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| paddle.ones_like(scale), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| scale, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| scale = paddle.where( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+226
to
+244
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Args: | |
| x_amax (paddle.Tensor): amax tensor (float32 recommended) | |
| eps (float): epsilon to avoid division by zero | |
| Returns: | |
| paddle.Tensor: scale tensor, same shape as x_amax | |
| """ | |
| fp8_max = 448.0 | |
| float_max = paddle.finfo(paddle.float32).max | |
| amax_mod = paddle.maximum( | |
| x_amax, | |
| paddle.full_like(x_amax, eps), | |
| ) | |
| scale = fp8_max / amax_mod | |
| scale = paddle.where( | |
| amax_mod == 0, | |
| paddle.ones_like(scale), | |
| scale, | |
| ) | |
| scale = paddle.where( | |
| Args: | |
| x_amax (paddle.Tensor): amax tensor (float32 recommended) | |
| eps (float): Non-negative epsilon to avoid division by zero. | |
| When eps == 0.0 and x_amax contains zeros, the corresponding | |
| scale values are set to 1.0 to avoid infinite results. | |
| Returns: | |
| paddle.Tensor: scale tensor, same shape as x_amax | |
| """ | |
| fp8_max = 448.0 | |
| float_max = paddle.finfo(paddle.float32).max | |
| amax_floor = paddle.full_like(x_amax, eps) | |
| amax_mod = paddle.maximum(x_amax, amax_floor) | |
| scale = fp8_max / amax_mod | |
| # Only apply zero-guard when eps <= 0.0; for eps > 0.0, amax_mod is | |
| # already guaranteed to be at least eps, so this condition would be redundant. | |
| if eps <= 0.0: | |
| scale = paddle.where( | |
| amax_mod == 0, | |
| paddle.ones_like(scale), | |
| scale, | |
| ) | |
| scale = paddle.where( |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -84,8 +84,11 @@ def test_forward_cuda(self, mock_fused, mock_platform): | |
| layer = SiluAndMul(fd_config) | ||
| x = paddle.ones([2, 2]) | ||
| out = layer.forward(x) | ||
| self.assertTrue((out.numpy() == 1).all()) | ||
| mock_fused.assert_called_once() | ||
| if layer.bias is None and layer.quant_scale == -1: | ||
| self.assertTrue((out.numpy() == 0.73105854).all()) | ||
|
||
| else: | ||
| self.assertTrue((out.numpy() == 1).all()) | ||
| mock_fused.assert_called_once() | ||
|
Comment on lines
+87
to
+91
|
||
|
|
||
| # Test forward computation on GCU platform | ||
| @patch( | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR 的描述部分缺少详细信息。根据自定义规范,PR 描述至少应该解释为什么要进行这些修改以及解决了什么问题。当前的 "Modifications" 部分只有一句话"统一框架和推理所使用的量化算子,实现训推一致",建议补充以下信息:
此外,Checklist 中的多个项目未勾选,特别是单元测试和准确性测试,请补充相关信息或勾选相应的项目。