Skip to content

Commit 85690da

Browse files
Merge pull request AI-Hypercomputer#4197 from CaptainO5:integrate_v2
PiperOrigin-RevId: 934640357
2 parents 44276d9 + 748d5f6 commit 85690da

8 files changed

Lines changed: 2232 additions & 29 deletions

File tree

src/maxtext/configs/base.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,6 +1212,9 @@ partial_rotary_factor: 1.0
12121212

12131213
# Use tokamax library for gmm kernel implementation
12141214
use_tokamax_gmm: false
1215+
# Whether to use GMM v2 for MoE.
1216+
# Requires use_tokamax_gmm: true. Currently incompatible with quantization.
1217+
use_gmm_v2: false
12151218
use_tokamax_splash: false
12161219
# Setting this flag will use a non-pallas implementation.
12171220
use_jax_splash: false

src/maxtext/configs/types.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,13 @@ class Attention(BaseModel):
610610
False,
611611
description="Whether to use the Tokamax library for GMM kernel implementation.",
612612
)
613+
use_gmm_v2: bool = Field(
614+
False,
615+
description=(
616+
"Whether to use GMM v2 (with bf16 activations and weights) for MoE."
617+
" Requires use_tokamax_gmm: true. Currently incompatible with quantization."
618+
),
619+
)
613620
ragged_block_size: int = Field(256, description="Block size for ragged attention.")
614621
enable_padding_causal_mask: bool = Field(True, description="Temporary flag for TE padding.")
615622
use_tokamax_splash: bool = Field(False, description="Whether to use tokamax splash attention.")
@@ -3193,6 +3200,11 @@ def calculate_global_batch_sizes(per_device_batch_size, expansion_factor, num_de
31933200
if self.share_kv_projections and self.attention_type == "mla":
31943201
raise ValueError("`share_kv_projections` is not compatible with `attention_type='mla'`.")
31953202

3203+
if self.use_gmm_v2 and (self.quantization or self.use_qwix_quantization):
3204+
raise ValueError("Quantization with GMM v2 is not supported yet.")
3205+
if self.use_gmm_v2 and not self.use_tokamax_gmm:
3206+
raise ValueError("GMM v2 requires `use_tokamax_gmm=true`.")
3207+
31963208
for val in self.compress_ratios:
31973209
if val != 0 and val < 4:
31983210
raise ValueError(f"compress_ratio must be 0 (disabled) or >= 4, got {val}")

src/maxtext/kernels/megablox/ops.py

Lines changed: 85 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,20 @@
2222
import jax
2323
import jax.numpy as jnp
2424
from maxtext.kernels.megablox import backend
25+
from maxtext.kernels.megablox import pallas_mosaic_tpu_v2_gmm_kernel as gmm_v2
26+
from maxtext.kernels.megablox import pallas_mosaic_tpu_v2_tgmm_kernel as tgmm_v2
2527
from maxtext.layers import quantizations
2628
import qwix
2729
import qwix.pallas as qpl
2830
import tokamax
2931

3032

33+
DLHS_RAGGED_DOT_DIM_NUMS = jax.lax.RaggedDotDimensionNumbers(
34+
dot_dimension_numbers=(([1], [2]), ([], [])),
35+
lhs_ragged_dimensions=[0],
36+
rhs_group_dimensions=[0],
37+
)
38+
3139
DRHS_RAGGED_DOT_DIM_NUMS = jax.lax.RaggedDotDimensionNumbers(
3240
dot_dimension_numbers=(([0], [0]), ([], [])),
3341
lhs_ragged_dimensions=[0],
@@ -65,6 +73,7 @@ def gmm(
6573
# TODO(amandaliang): get rid of the qwix_rule in favor of Qwix's interception feature
6674
qwix_rule: qwix.QtRule | None = None,
6775
use_manual_quantization: bool = False, # used in batchsplit
76+
use_gmm_v2: bool = False,
6877
):
6978
"""Grouped matrix multiplication operation."""
7079
quantization_rule = None
@@ -84,7 +93,7 @@ def gmm(
8493
)
8594

8695
gmm_fwd_bwd = lambda *args: _gmm_fwd(*args)[0] # pylint: disable=C3001
87-
gmm_fwd_bwd = jax.custom_vjp(gmm_fwd_bwd, nondiff_argnums=(3, 4, 7, 8, 9, 10, 11, 12, 13, 14))
96+
gmm_fwd_bwd = jax.custom_vjp(gmm_fwd_bwd, nondiff_argnums=(3, 4, 7, 8, 9, 10, 11, 12, 13, 14, 15))
8897
gmm_fwd_bwd.defvjp(_gmm_fwd, functools.partial(_gmm_bwd, lhs.dtype, rhs.dtype))
8998
return gmm_fwd_bwd(
9099
lhs,
@@ -102,6 +111,7 @@ def gmm(
102111
use_manual_quantization,
103112
lhs_vma_axes,
104113
rhs_vma_axes,
114+
use_gmm_v2,
105115
)
106116

107117

@@ -131,6 +141,7 @@ def _gmm_fwd(
131141
use_manual_quantization: bool = False,
132142
lhs_vma_axes: tuple = tuple(),
133143
rhs_vma_axes: tuple = tuple(),
144+
use_gmm_v2: bool = False,
134145
) -> tuple[
135146
jnp.ndarray,
136147
tuple[
@@ -178,6 +189,19 @@ def _gmm_fwd(
178189
if transpose_rhs:
179190
rhs = rhs.swapaxes(1, 2)
180191

192+
if use_gmm_v2:
193+
out = gmm_v2.gmm_v2(
194+
lhs=lhs,
195+
rhs=rhs,
196+
group_sizes=group_sizes,
197+
tile_info=gmm_v2.TileSizes(
198+
tile_m=tiling[0],
199+
tile_k=tiling[1],
200+
tile_n=tiling[2],
201+
),
202+
preferred_element_type=preferred_element_type,
203+
)
204+
elif use_tokamax_backend:
181205
# manual_axis_type is for gmm with shard_map check_vma=True, needs tokamax > 0.0.12
182206
out_kwargs = {}
183207
if use_manual_quantization:
@@ -226,6 +250,7 @@ def _gmm_bwd(
226250
use_manual_quantization: bool,
227251
lhs_vma_axes: tuple,
228252
rhs_vma_axes: tuple,
253+
use_gmm_v2: bool,
229254
residual: tuple[
230255
jnp.ndarray | qpl.QArray,
231256
jnp.ndarray | qpl.QArray,
@@ -274,10 +299,10 @@ def _gmm_bwd(
274299
channelwise_axes=[] if quantization_rule.disable_channelwise_axes else [1],
275300
calibration_method=quantization_rule.bwd_calibration_method,
276301
)
277-
if use_tokamax_backend:
302+
if use_tokamax_backend or use_gmm_v2:
278303
# Handle transpose_rhs manually
279304
dlhs_rhs = rhs
280-
if not transpose_rhs:
305+
if transpose_rhs:
281306
dlhs_rhs = dlhs_rhs.swapaxes(1, 2)
282307

283308
# manual_axis_type is for gmm with shard_map check_vma=True, needs tokamax > 0.0.12
@@ -290,29 +315,63 @@ def _gmm_bwd(
290315
varying=frozenset(["expert"]), unreduced=frozenset(["data", "fsdp"])
291316
)
292317

293-
dlhs = tokamax.ragged_dot(
294-
lhs=dlhs_dout,
295-
rhs=dlhs_rhs,
296-
group_sizes=group_sizes,
297-
precision=jax.lax.Precision.DEFAULT,
298-
preferred_element_type=lhs_dtype,
299-
# `group_offset` is not yet supported
300-
group_offset=None,
301-
implementation="mosaic",
302-
**dlhs_kwargs,
303-
)
304-
drhs = tokamax.ragged_dot_general(
305-
lhs=lhs,
306-
rhs=drhs_dout,
307-
group_sizes=group_sizes,
308-
ragged_dot_dimension_numbers=DRHS_RAGGED_DOT_DIM_NUMS,
309-
precision=jax.lax.Precision.DEFAULT,
310-
preferred_element_type=rhs_dtype,
311-
# `group_offset` is not yet supported
312-
group_offset=None,
313-
implementation="mosaic",
314-
**drhs_kwargs,
315-
)
318+
if use_gmm_v2:
319+
dlhs = gmm_v2.gmm_v2(
320+
lhs=dlhs_dout,
321+
rhs=dlhs_rhs.swapaxes(1, 2), # requires rhs to be [g, n, k]
322+
group_sizes=group_sizes,
323+
tile_info=gmm_v2.TileSizes(
324+
tile_m=tiling[3],
325+
tile_k=tiling[4],
326+
tile_n=tiling[5],
327+
),
328+
preferred_element_type=lhs_dtype,
329+
)
330+
331+
# tgmm_v2_op requires lhs and rhs to have the same dtype.
332+
if lhs.dtype != drhs_dout.dtype:
333+
drhs_dout = drhs_dout.astype(lhs.dtype)
334+
335+
drhs = tgmm_v2.tgmm_v2(
336+
lhs=lhs,
337+
rhs=drhs_dout,
338+
group_sizes=group_sizes,
339+
num_actual_groups=num_actual_groups,
340+
precision=jax.lax.Precision.DEFAULT,
341+
preferred_element_type=rhs_dtype,
342+
group_offset=group_offset,
343+
tile_info=gmm_v2.TileSizes(
344+
tile_m=tiling[6],
345+
tile_k=tiling[7],
346+
tile_n=tiling[8],
347+
),
348+
)
349+
else:
350+
dlhs = tokamax.ragged_dot_general(
351+
lhs=dlhs_dout,
352+
rhs=dlhs_rhs,
353+
group_sizes=group_sizes,
354+
ragged_dot_dimension_numbers=DLHS_RAGGED_DOT_DIM_NUMS,
355+
precision=jax.lax.Precision.DEFAULT,
356+
preferred_element_type=lhs_dtype,
357+
# `group_offset` is not yet supported
358+
group_offset=None,
359+
implementation="mosaic",
360+
**dlhs_kwargs,
361+
)
362+
363+
drhs = tokamax.ragged_dot_general(
364+
lhs=lhs,
365+
rhs=drhs_dout,
366+
group_sizes=group_sizes,
367+
ragged_dot_dimension_numbers=DRHS_RAGGED_DOT_DIM_NUMS,
368+
precision=jax.lax.Precision.DEFAULT,
369+
preferred_element_type=rhs_dtype,
370+
# `group_offset` is not yet supported
371+
group_offset=None,
372+
implementation="mosaic",
373+
**drhs_kwargs,
374+
)
316375
if quantization_rule and quantization_rule.bwd_qtype and weight_gather_axes:
317376
# Scatter back in reverse order of gather
318377
for axis_name, axis_idx in reversed(weight_gather_axes):

0 commit comments

Comments
 (0)