Skip to content

Commit 4ffe41a

Browse files
authored
WINT4/WINT8 dense gemm default use Machete (#4451)
1 parent a240425 commit 4ffe41a

12 files changed

Lines changed: 310 additions & 15 deletions

File tree

custom_ops/gpu_ops/machete/machete_mm.cu

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,52 @@ std::vector<paddle::Tensor> MacheteMMKernel(
8686
maybe_schedule);
8787
return {out};
8888
}
89+
90+
std::vector<std::vector<int64_t>> MacheteMMKernelInferShape(
91+
std::vector<int64_t> const& A_shape,
92+
std::vector<int64_t> const& B_shape,
93+
paddle::optional<std::vector<int64_t>> const& maybe_group_scales_shape,
94+
paddle::optional<std::vector<int64_t>> const& maybe_group_zeros_shape,
95+
paddle::optional<std::vector<int64_t>> const& maybe_channel_scales_shape,
96+
paddle::optional<std::vector<int64_t>> const& maybe_token_scales_shape,
97+
std::string const& b_type_str,
98+
std::string const& maybe_out_type_str,
99+
int64_t const& maybe_group_size,
100+
std::string const& maybe_schedule) {
101+
return {{A_shape[0], B_shape[1]}};
102+
}
103+
104+
std::vector<paddle::DataType> MacheteMMKernelInferDtype(
105+
paddle::DataType const& A_dtype,
106+
paddle::DataType const& B_dtype,
107+
paddle::optional<paddle::DataType> const& maybe_group_scales_dtype,
108+
paddle::optional<paddle::DataType> const& maybe_group_zeros_dtype,
109+
paddle::optional<paddle::DataType> const& maybe_channel_scales_dtype,
110+
paddle::optional<paddle::DataType> const& maybe_token_scales_dtype,
111+
std::string const& b_type_str,
112+
std::string const& maybe_out_type_str,
113+
int64_t const& maybe_group_size,
114+
std::string const& maybe_schedule) {
115+
116+
paddle::DataType maybe_out_type;
117+
if (maybe_out_type_str == "float16") {
118+
maybe_out_type = paddle::DataType::FLOAT16;
119+
} else if (maybe_out_type_str == "bfloat16") {
120+
maybe_out_type = paddle::DataType::BFLOAT16;
121+
} else {
122+
maybe_out_type = A_dtype;
123+
}
124+
return {maybe_out_type};
125+
}
126+
127+
PD_BUILD_STATIC_OP(machete_mm)
128+
.Inputs({"A", "B",
129+
paddle::Optional("maybe_group_scales"),
130+
paddle::Optional("maybe_group_zeros"),
131+
paddle::Optional("maybe_channel_scales"),
132+
paddle::Optional("maybe_token_scales")})
133+
.Outputs({"out"})
134+
.Attrs({"b_type_str:std::string", "maybe_out_type_str:std::string", "maybe_group_size:int64_t", "maybe_schedule:std::string"})
135+
.SetKernelFn(PD_KERNEL(MacheteMMKernel))
136+
.SetInferShapeFn(PD_INFER_SHAPE(MacheteMMKernelInferShape))
137+
.SetInferDtypeFn(PD_INFER_DTYPE(MacheteMMKernelInferDtype));

custom_ops/gpu_ops/machete/machete_prepack_B.cu

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,23 @@ std::vector<paddle::Tensor> MachetePrepackBKernel(
7171
return {B_prepacked};
7272

7373
}
74+
75+
std::vector<std::vector<int64_t>> MachetePrepackBKernelInferShape(
76+
std::vector<int64_t> const& B_shape, std::string const& a_type_str, std::string const& b_type_str,
77+
std::string const& maybe_group_scales_type_str) {
78+
return {{B_shape[1], B_shape[0]}};
79+
}
80+
81+
std::vector<paddle::DataType> MachetePrepackBKernelInferDtype(
82+
paddle::DataType const& B_dtype, std::string const& a_type_str, std::string const& b_type_str,
83+
std::string const& maybe_group_scales_type_str) {
84+
return {B_dtype};
85+
}
86+
87+
PD_BUILD_STATIC_OP(machete_prepack_B)
88+
.Inputs({"B"})
89+
.Outputs({"B_prepacked"})
90+
.Attrs({"a_type_str:std::string", "b_type_str:std::string", "maybe_group_scales_type_str:std::string"})
91+
.SetKernelFn(PD_KERNEL(MachetePrepackBKernel))
92+
.SetInferShapeFn(PD_INFER_SHAPE(MachetePrepackBKernelInferShape))
93+
.SetInferDtypeFn(PD_INFER_DTYPE(MachetePrepackBKernelInferDtype));

docs/usage/environment_variables.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ environment_variables: dict[str, Callable[[], Any]] = {
7878
"FD_ENABLE_MODEL_LOAD_CACHE": lambda: bool(int(os.getenv("FD_ENABLE_MODEL_LOAD_CACHE", "0"))),
7979

8080
# Whether to use Machete for wint4 dense GEMM.
81-
"FD_USE_MACHETE": lambda: os.getenv("FD_USE_MACHETE", "0"),
81+
"FD_USE_MACHETE": lambda: os.getenv("FD_USE_MACHETE", "1"),
8282

8383
# Used to truncate the string inserted during thinking when reasoning in a model. (</think> for ernie4_5_vl, \n</think>\n\n for ernie_x1)
8484
"FD_LIMIT_THINKING_CONTENT_TRUNCATE_STR": lambda: os.getenv("FD_LIMIT_THINKING_CONTENT_TRUNCATE_STR", "</think>"),

docs/zh/usage/environment_variables.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ environment_variables: dict[str, Callable[[], Any]] = {
7878
"FD_ENABLE_MODEL_LOAD_CACHE": lambda: bool(int(os.getenv("FD_ENABLE_MODEL_LOAD_CACHE", "0"))),
7979

8080
# 是否使用 Machete 后端的 wint4 GEMM.
81-
"FD_USE_MACHETE": lambda: os.getenv("FD_USE_MACHETE", "0"),
81+
"FD_USE_MACHETE": lambda: os.getenv("FD_USE_MACHETE", "1"),
8282

8383
# Used to truncate the string inserted during thinking when reasoning in a model. (</think> for ernie4_5_vl, \n</think>\n\n for ernie_x1)
8484
"FD_LIMIT_THINKING_CONTENT_TRUNCATE_STR": lambda: os.getenv("FD_LIMIT_THINKING_CONTENT_TRUNCATE_STR", "</think>"),
@@ -87,6 +87,5 @@ environment_variables: dict[str, Callable[[], Any]] = {
8787
"FD_CACHE_PROC_EXIT_TIMEOUT": lambda: int(os.getenv("FD_CACHE_PROC_EXIT_TIMEOUT", "600")),
8888

8989
# cache_transfer_manager 进程残留时连续错误阈值
90-
"FD_CACHE_PROC_ERROR_COUNT": lambda: int(os.getenv("FD_CACHE_PROC_ERROR_COUNT", "10")),
91-
}
90+
"FD_CACHE_PROC_ERROR_COUNT": lambda: int(os.getenv("FD_CACHE_PROC_ERROR_COUNT", "10")),}
9291
```

fastdeploy/envs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
# Set moe backend."cutlass","marlin" and "triton" can be set currently.
5656
"FD_MOE_BACKEND": lambda: os.getenv("FD_MOE_BACKEND", "cutlass"),
5757
# Whether to use Machete for wint4 dense gemm.
58-
"FD_USE_MACHETE": lambda: os.getenv("FD_USE_MACHETE", "0"),
58+
"FD_USE_MACHETE": lambda: os.getenv("FD_USE_MACHETE", "1"),
5959
# Set whether to disable recompute the request when the KV cache is full.
6060
"FD_DISABLED_RECOVER": lambda: os.getenv("FD_DISABLED_RECOVER", "0"),
6161
# Set triton kernel JIT compilation directory.

fastdeploy/model_executor/layers/quantization/ops/machete_mm.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ def machete_quantize_and_pack(
167167
atype,
168168
quant_type,
169169
scale_type,
170-
)[0]
170+
)
171171
return w_q_prepack, w_s
172172

173173

@@ -194,5 +194,5 @@ def machete_wint_mm(
194194
out_dtype, # out_dtype
195195
group_size, # group_size
196196
scheduler, # scheduler
197-
)[0]
197+
)
198198
return out

fastdeploy/model_executor/layers/quantization/weight_only.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,18 @@
3838
else:
3939
from paddle.nn.quant import weight_only_linear
4040

41+
from fastdeploy.model_executor.layers.quantization.ops.machete_mm import _ENABLE_MACHETE
42+
4143
from ..moe import FusedMoE
4244
from ..utils import get_tensor
4345
from .quant_base import QuantConfigBase, QuantMethodBase
4446

47+
if _ENABLE_MACHETE:
48+
from fastdeploy.model_executor.layers.quantization.ops import (
49+
machete_quantize_and_pack,
50+
machete_wint_mm,
51+
)
52+
4553

4654
class WeightOnlyConfig(QuantConfigBase):
4755
"""
@@ -154,14 +162,11 @@ def get_quant_method(self, layer) -> Optional[QuantMethodBase]:
154162
else:
155163
raise ValueError(f"Unsupported MOE backend {layer.use_method}")
156164
else:
157-
from fastdeploy.model_executor.layers.quantization.ops.machete_mm import (
158-
_ENABLE_MACHETE,
159-
)
160-
161165
if (
162166
_ENABLE_MACHETE
163167
and envs.FD_USE_MACHETE == "1"
164168
and not layer.is_quantized
169+
and not layer.fd_config.load_config.dynamic_load_weight
165170
and layer.weight_shape[1]
166171
and layer.weight_shape[1] % 128 == 0
167172
):
@@ -406,9 +411,6 @@ def process_prequanted_weights(self, layer, state_dict) -> None:
406411
raise NotImplementedError("Machete kernel doesn't support prequant. Please set FD_USE_MACHETE to 0.")
407412

408413
def process_loaded_weights(self, layer, weight) -> None:
409-
from fastdeploy.model_executor.layers.quantization.ops import (
410-
machete_quantize_and_pack,
411-
)
412414

413415
# Using group scale for machete, group size is 128
414416
quanted_weight_tensor, weight_scale_tensor = machete_quantize_and_pack(
@@ -421,7 +423,6 @@ def process_loaded_weights(self, layer, weight) -> None:
421423
layer.weight_scale.set_value(weight_scale_tensor.astype(paddle.get_default_dtype()))
422424

423425
def apply(self, layer, x):
424-
from fastdeploy.model_executor.layers.quantization.ops import machete_wint_mm
425426

426427
# Using group scale for machete, group size is 128
427428
linear_out = machete_wint_mm(

tests/ci_use/EB_VL_Lite/test_EB_VL_Lite_serving.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
# List of ports to clean before and after tests
3535
PORTS_TO_CLEAN = [FD_API_PORT, FD_ENGINE_QUEUE_PORT, FD_METRICS_PORT, FD_CACHE_QUEUE_PORT]
3636

37+
os.environ["FD_USE_MACHETE"] = "0"
38+
3739

3840
def is_port_open(host: str, port: int, timeout=1.0):
3941
"""

tests/e2e/test_EB_VL_Lite_serving.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
# List of ports to clean before and after tests
3636
PORTS_TO_CLEAN = [FD_API_PORT, FD_ENGINE_QUEUE_PORT, FD_METRICS_PORT, FD_CACHE_QUEUE_PORT]
3737

38+
os.environ["FD_USE_MACHETE"] = "0"
39+
3840

3941
def is_port_open(host: str, port: int, timeout=1.0):
4042
"""

0 commit comments

Comments
 (0)