Kernels
danieldk HF Staff commited on
Commit
6d19dd0
·
1 Parent(s): fbbc5a8

Add Llama MoE

Browse files
torch-ext/moe/__init__.py CHANGED
@@ -1,5 +1,6 @@
1
  import torch
2
 
 
3
  from ._ops import ops
4
  from .fp8_utils import per_token_group_quant_fp8, w8a8_block_fp8_matmul
5
  from .fused_marlin_moe import fused_marlin_moe
@@ -87,6 +88,7 @@ __all__ = [
87
  "fused_topk",
88
  "gptq_marlin_moe_repack",
89
  "grouped_topk",
 
90
  "moe_align_block_size",
91
  "moe_sum",
92
  "per_token_group_quant_fp8",
 
1
  import torch
2
 
3
+ from . import layers
4
  from ._ops import ops
5
  from .fp8_utils import per_token_group_quant_fp8, w8a8_block_fp8_matmul
6
  from .fused_marlin_moe import fused_marlin_moe
 
88
  "fused_topk",
89
  "gptq_marlin_moe_repack",
90
  "grouped_topk",
91
+ "layers",
92
  "moe_align_block_size",
93
  "moe_sum",
94
  "per_token_group_quant_fp8",
torch-ext/moe/fused_moe.py CHANGED
@@ -1022,6 +1022,7 @@ def inplace_fused_experts(
1022
  w2: torch.Tensor,
1023
  topk_weights: torch.Tensor,
1024
  topk_ids: torch.Tensor,
 
1025
  use_fp8_w8a8: bool = False,
1026
  use_int8_w8a16: bool = False,
1027
  use_int4_w4a16: bool = False,
@@ -1034,22 +1035,23 @@ def inplace_fused_experts(
1034
  block_shape: Optional[List[int]] = None,
1035
  ) -> None:
1036
  fused_experts_impl(
1037
- hidden_states,
1038
- w1,
1039
- w2,
1040
- topk_weights,
1041
- topk_ids,
1042
- True,
1043
- use_fp8_w8a8,
1044
- use_int8_w8a16,
1045
- use_int4_w4a16,
1046
- w1_scale,
1047
- w2_scale,
1048
- w1_zp,
1049
- w2_zp,
1050
- a1_scale,
1051
- a2_scale,
1052
- block_shape,
 
1053
  )
1054
 
1055
 
@@ -1059,6 +1061,7 @@ def outplace_fused_experts(
1059
  w2: torch.Tensor,
1060
  topk_weights: torch.Tensor,
1061
  topk_ids: torch.Tensor,
 
1062
  use_fp8_w8a8: bool = False,
1063
  use_int8_w8a16: bool = False,
1064
  use_int4_w4a16: bool = False,
@@ -1071,22 +1074,23 @@ def outplace_fused_experts(
1071
  block_shape: Optional[List[int]] = None,
1072
  ) -> torch.Tensor:
1073
  return fused_experts_impl(
1074
- hidden_states,
1075
- w1,
1076
- w2,
1077
- topk_weights,
1078
- topk_ids,
1079
- False,
1080
- use_fp8_w8a8,
1081
- use_int8_w8a16,
1082
- use_int4_w4a16,
1083
- w1_scale,
1084
- w2_scale,
1085
- w1_zp,
1086
- w2_zp,
1087
- a1_scale,
1088
- a2_scale,
1089
- block_shape,
 
1090
  )
1091
 
1092
 
@@ -1097,6 +1101,7 @@ def fused_experts(
1097
  topk_weights: torch.Tensor,
1098
  topk_ids: torch.Tensor,
1099
  inplace: bool = False,
 
1100
  use_fp8_w8a8: bool = False,
1101
  use_int8_w8a16: bool = False,
1102
  use_int4_w4a16: bool = False,
@@ -1110,40 +1115,42 @@ def fused_experts(
1110
  ):
1111
  if inplace:
1112
  inplace_fused_experts(
1113
- hidden_states,
1114
- w1,
1115
- w2,
1116
- topk_weights,
1117
- topk_ids,
1118
- use_fp8_w8a8,
1119
- use_int8_w8a16,
1120
- use_int4_w4a16,
1121
- w1_scale,
1122
- w2_scale,
1123
- w1_zp,
1124
- w2_zp,
1125
- a1_scale,
1126
- a2_scale,
1127
- block_shape,
 
1128
  )
1129
  return hidden_states
1130
  else:
1131
  return outplace_fused_experts(
1132
- hidden_states,
1133
- w1,
1134
- w2,
1135
- topk_weights,
1136
- topk_ids,
1137
- use_fp8_w8a8,
1138
- use_int8_w8a16,
1139
- use_int4_w4a16,
1140
- w1_scale,
1141
- w2_scale,
1142
- w1_zp,
1143
- w2_zp,
1144
- a1_scale,
1145
- a2_scale,
1146
- block_shape,
 
1147
  )
1148
 
1149
 
@@ -1154,6 +1161,7 @@ def fused_experts_impl(
1154
  topk_weights: torch.Tensor,
1155
  topk_ids: torch.Tensor,
1156
  inplace: bool = False,
 
1157
  use_fp8_w8a8: bool = False,
1158
  use_int8_w8a16: bool = False,
1159
  use_int4_w4a16: bool = False,
@@ -1281,7 +1289,12 @@ def fused_experts_impl(
1281
  block_shape=block_shape,
1282
  )
1283
 
1284
- ops.silu_and_mul(intermediate_cache2, intermediate_cache1.view(-1, N))
 
 
 
 
 
1285
 
1286
  invoke_fused_moe_kernel(
1287
  intermediate_cache2,
@@ -1320,6 +1333,7 @@ def fused_moe(
1320
  topk: int,
1321
  renormalize: bool,
1322
  inplace: bool = False,
 
1323
  use_grouped_topk: bool = False,
1324
  num_expert_group: Optional[int] = None,
1325
  topk_group: Optional[int] = None,
@@ -1404,6 +1418,7 @@ def fused_moe(
1404
  topk_weights,
1405
  topk_ids,
1406
  inplace=inplace,
 
1407
  use_fp8_w8a8=use_fp8_w8a8,
1408
  use_int8_w8a16=use_int8_w8a16,
1409
  use_int4_w4a16=use_int4_w4a16,
 
1022
  w2: torch.Tensor,
1023
  topk_weights: torch.Tensor,
1024
  topk_ids: torch.Tensor,
1025
+ activation: str = "silu",
1026
  use_fp8_w8a8: bool = False,
1027
  use_int8_w8a16: bool = False,
1028
  use_int4_w4a16: bool = False,
 
1035
  block_shape: Optional[List[int]] = None,
1036
  ) -> None:
1037
  fused_experts_impl(
1038
+ hidden_states=hidden_states,
1039
+ w1=w1,
1040
+ w2=w2,
1041
+ topk_weights=topk_weights,
1042
+ topk_ids=topk_ids,
1043
+ inplace=True,
1044
+ activation=activation,
1045
+ use_fp8_w8a8=use_fp8_w8a8,
1046
+ use_int8_w8a16=use_int8_w8a16,
1047
+ use_int4_w4a16=use_int4_w4a16,
1048
+ w1_scale=w1_scale,
1049
+ w2_scale=w2_scale,
1050
+ w1_zp=w1_zp,
1051
+ w2_zp=w2_zp,
1052
+ a1_scale=a1_scale,
1053
+ a2_scale=a2_scale,
1054
+ block_shape=block_shape,
1055
  )
1056
 
1057
 
 
1061
  w2: torch.Tensor,
1062
  topk_weights: torch.Tensor,
1063
  topk_ids: torch.Tensor,
1064
+ activation: str = "silu",
1065
  use_fp8_w8a8: bool = False,
1066
  use_int8_w8a16: bool = False,
1067
  use_int4_w4a16: bool = False,
 
1074
  block_shape: Optional[List[int]] = None,
1075
  ) -> torch.Tensor:
1076
  return fused_experts_impl(
1077
+ hidden_states=hidden_states,
1078
+ w1=w1,
1079
+ w2=w2,
1080
+ topk_weights=topk_weights,
1081
+ topk_ids=topk_ids,
1082
+ inplace=False,
1083
+ activation=activation,
1084
+ use_fp8_w8a8=use_fp8_w8a8,
1085
+ use_int8_w8a16=use_int8_w8a16,
1086
+ use_int4_w4a16=use_int4_w4a16,
1087
+ w1_scale=w1_scale,
1088
+ w2_scale=w2_scale,
1089
+ w1_zp=w1_zp,
1090
+ w2_zp=w2_zp,
1091
+ a1_scale=a1_scale,
1092
+ a2_scale=a2_scale,
1093
+ block_shape=block_shape,
1094
  )
1095
 
1096
 
 
1101
  topk_weights: torch.Tensor,
1102
  topk_ids: torch.Tensor,
1103
  inplace: bool = False,
1104
+ activation: str = "silu",
1105
  use_fp8_w8a8: bool = False,
1106
  use_int8_w8a16: bool = False,
1107
  use_int4_w4a16: bool = False,
 
1115
  ):
1116
  if inplace:
1117
  inplace_fused_experts(
1118
+ hidden_states=hidden_states,
1119
+ w1=w1,
1120
+ w2=w2,
1121
+ topk_weights=topk_weights,
1122
+ topk_ids=topk_ids,
1123
+ activation=activation,
1124
+ use_fp8_w8a8=use_fp8_w8a8,
1125
+ use_int8_w8a16=use_int8_w8a16,
1126
+ use_int4_w4a16=use_int4_w4a16,
1127
+ w1_scale=w1_scale,
1128
+ w2_scale=w2_scale,
1129
+ w1_zp=w1_zp,
1130
+ w2_zp=w2_zp,
1131
+ a1_scale=a1_scale,
1132
+ a2_scale=a2_scale,
1133
+ block_shape=block_shape,
1134
  )
1135
  return hidden_states
1136
  else:
1137
  return outplace_fused_experts(
1138
+ hidden_states=hidden_states,
1139
+ w1=w1,
1140
+ w2=w2,
1141
+ topk_weights=topk_weights,
1142
+ topk_ids=topk_ids,
1143
+ activation=activation,
1144
+ use_fp8_w8a8=use_fp8_w8a8,
1145
+ use_int8_w8a16=use_int8_w8a16,
1146
+ use_int4_w4a16=use_int4_w4a16,
1147
+ w1_scale=w1_scale,
1148
+ w2_scale=w2_scale,
1149
+ w1_zp=w1_zp,
1150
+ w2_zp=w2_zp,
1151
+ a1_scale=a1_scale,
1152
+ a2_scale=a2_scale,
1153
+ block_shape=block_shape,
1154
  )
1155
 
1156
 
 
1161
  topk_weights: torch.Tensor,
1162
  topk_ids: torch.Tensor,
1163
  inplace: bool = False,
1164
+ activation: str = "silu",
1165
  use_fp8_w8a8: bool = False,
1166
  use_int8_w8a16: bool = False,
1167
  use_int4_w4a16: bool = False,
 
1289
  block_shape=block_shape,
1290
  )
1291
 
1292
+ if activation == "silu":
1293
+ ops.silu_and_mul(intermediate_cache2, intermediate_cache1.view(-1, N))
1294
+ elif activation == "gelu":
1295
+ ops.gelu_and_mul(intermediate_cache2, intermediate_cache1.view(-1, N))
1296
+ else:
1297
+ raise ValueError(f"Unsupported FusedMoe activation: {activation}")
1298
 
1299
  invoke_fused_moe_kernel(
1300
  intermediate_cache2,
 
1333
  topk: int,
1334
  renormalize: bool,
1335
  inplace: bool = False,
1336
+ activation: str = "silu",
1337
  use_grouped_topk: bool = False,
1338
  num_expert_group: Optional[int] = None,
1339
  topk_group: Optional[int] = None,
 
1418
  topk_weights,
1419
  topk_ids,
1420
  inplace=inplace,
1421
+ activation=activation,
1422
  use_fp8_w8a8=use_fp8_w8a8,
1423
  use_int8_w8a16=use_int8_w8a16,
1424
  use_int4_w4a16=use_int4_w4a16,
torch-ext/moe/layers.py ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+
4
+ from .fused_moe import fused_moe
5
+
6
+
7
+ def _llama4_topk(
8
+ hidden_states: torch.Tensor,
9
+ gating_output: torch.Tensor,
10
+ topk: int,
11
+ renormalize: bool,
12
+ ):
13
+ assert hidden_states.shape[0] == gating_output.shape[0], "Number of tokens mismatch"
14
+ topk_weights, topk_ids = torch.topk(gating_output, topk, dim=1)
15
+ topk_weights = torch.sigmoid(topk_weights.float()).to(hidden_states.dtype)
16
+ return topk_weights, topk_ids
17
+
18
+
19
+ class Llama4TextMoe(nn.Module):
20
+ experts: nn.Module
21
+ router: nn.Linear
22
+ shared_expert: nn.Module
23
+ top_k: int
24
+
25
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
26
+ hidden_states = hidden_states.reshape(-1, hidden_states.shape[-1])
27
+
28
+ router_logits = self.router(hidden_states)
29
+ out = fused_moe(
30
+ hidden_states,
31
+ w1=self.experts.gate_up_proj,
32
+ w2=self.experts.down_proj,
33
+ gating_output=router_logits,
34
+ topk=self.top_k,
35
+ renormalize=False,
36
+ custom_routing_function=_llama4_topk,
37
+ )
38
+
39
+ out += self.shared_expert(hidden_states)
40
+
41
+ return out, router_logits.t()