Skip to content

Commit 44d6528

Browse files
Merge pull request #1974 from mesakhcienet:feat/simple-decoder-layer-nnx
PiperOrigin-RevId: 820006566
2 parents c8022db + d2bc8f4 commit 44d6528

3 files changed

Lines changed: 74 additions & 36 deletions

File tree

src/MaxText/layers/decoders.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -402,9 +402,9 @@ def get_decoder_layers(self):
402402
case DecoderBlockType.QWEN3_MOE:
403403
return [qwen3.Qwen3MoeDecoderLayerToLinen]
404404
case DecoderBlockType.SIMPLE:
405-
return [simple_layer.SimpleDecoderLayer]
405+
return [simple_layer.SimpleDecoderLayerToLinen]
406406
case DecoderBlockType.SIMPLE_MLP:
407-
return [simple_layer.SimpleMlpDecoderLayer]
407+
return [simple_layer.SimpleMlpDecoderLayerToLinen]
408408
case DecoderBlockType.LLAMA4:
409409
return [llama4.Llama4ScannableBlockToLinen] if self.config.scan_layers else [llama4.Llama4DecoderLayerToLinen]
410410
case _:

src/MaxText/layers/simple_layer.py

Lines changed: 63 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -17,56 +17,82 @@
1717
from jax import numpy as jnp
1818
from jax.sharding import Mesh
1919

20-
from flax import linen as nn
21-
20+
from flax import nnx
2221
from MaxText.common_types import Config
23-
from MaxText.layers import quantizations
22+
from MaxText.layers import quantizations, nnx_wrappers
23+
from MaxText.layers.initializers import variable_to_logically_partitioned
24+
2425

26+
from typing import Optional
2527
# pytype: disable=attribute-error
2628

2729

28-
class SimpleDecoderLayer(nn.Module):
30+
class SimpleDecoderLayer(nnx.Module):
2931
"""Decoder layer consisting of a single [embed, embed] weight matrix."""
3032

31-
config: Config
32-
mesh: Mesh
33-
model_mode: str
34-
quant: None | quantizations.AqtQuantization = None
33+
def __init__(
34+
self,
35+
config: Config,
36+
mesh: Mesh,
37+
model_mode: str,
38+
rngs: nnx.Rngs,
39+
quant: Optional[quantizations.AqtQuantization] = None,
40+
) -> None:
41+
42+
self.config = config
43+
self.mesh = mesh
44+
self.model_mode = model_mode
45+
self.rngs = rngs
46+
self.quant = quant
3547

36-
def setup(self):
37-
self.weight_mat = self.param(
38-
"weights",
39-
nn.with_logical_partitioning(nn.initializers.lecun_normal(), ("embed", "mlp")),
40-
(self.config.emb_dim, self.config.emb_dim),
48+
init_fn = nnx.with_partitioning(nnx.initializers.lecun_normal(), sharding=("embed", "mlp"), mesh=self.mesh)
49+
50+
self.weights = nnx.Param(
51+
init_fn(self.rngs.params(), (self.config.emb_dim, self.config.emb_dim)),
4152
)
4253

4354
def __call__(
4455
self, inputs: jnp.ndarray, positions, segmentation, deterministic, model_mode, previous_chunk=None, page_state=None
4556
):
4657
if self.config.scan_layers:
47-
return inputs @ self.weight_mat.astype(inputs.dtype), None
48-
else:
49-
return inputs @ self.weight_mat.astype(inputs.dtype)
58+
return inputs @ self.weights.astype(inputs.dtype), None
59+
return inputs @ self.weights.astype(inputs.dtype)
60+
61+
62+
SimpleDecoderLayerToLinen = nnx_wrappers.to_linen_class(
63+
SimpleDecoderLayer,
64+
base_metadata_fn=variable_to_logically_partitioned,
65+
)
5066

5167

52-
class SimpleMlpDecoderLayer(nn.Module):
68+
class SimpleMlpDecoderLayer(nnx.Module):
5369
"""Decoder layer consisting of [embed,mlp] followed by an [mlp,embed] matmul."""
5470

55-
config: Config
56-
mesh: Mesh
57-
model_mode: str
58-
quant: None | quantizations.AqtQuantization = None
71+
def __init__(
72+
self,
73+
config: Config,
74+
mesh: Mesh,
75+
model_mode: str,
76+
rngs: nnx.Rngs,
77+
quant: Optional[quantizations.AqtQuantization] = None,
78+
) -> None:
79+
80+
self.config = config
81+
self.mesh = mesh
82+
self.model_mode = model_mode
83+
self.rngs = rngs
84+
self.quant = quant
5985

60-
def setup(self):
61-
self.ff_1 = self.param(
62-
"ff_1",
63-
nn.with_logical_partitioning(nn.initializers.lecun_normal(), ("embed", "mlp")),
64-
(self.config.emb_dim, self.config.mlp_dim),
86+
init_ff1_fn = nnx.with_partitioning(nnx.initializers.lecun_normal(), sharding=("embed", "mlp"), mesh=self.mesh)
87+
88+
self.ff_1 = nnx.Param(
89+
init_ff1_fn(self.rngs.params(), (self.config.emb_dim, self.config.mlp_dim)),
6590
)
66-
self.ff_2 = self.param(
67-
"ff_2",
68-
nn.with_logical_partitioning(nn.initializers.lecun_normal(), ("mlp", "embed")),
69-
(self.config.mlp_dim, self.config.emb_dim),
91+
92+
init_ff2_fn = nnx.with_partitioning(nnx.initializers.lecun_normal(), sharding=("mlp", "embed"), mesh=self.mesh)
93+
94+
self.ff_2 = nnx.Param(
95+
init_ff2_fn(self.rngs.params(), (self.config.mlp_dim, self.config.emb_dim)),
7096
)
7197

7298
def __call__(
@@ -84,5 +110,10 @@ def __call__(
84110
output = intermediate @ self.ff_2.astype(inputs.dtype)
85111
if self.config.scan_layers:
86112
return output, None
87-
else:
88-
return output
113+
return output
114+
115+
116+
SimpleMlpDecoderLayerToLinen = nnx_wrappers.to_linen_class(
117+
SimpleMlpDecoderLayer,
118+
base_metadata_fn=variable_to_logically_partitioned,
119+
)

tests/pipeline_parallelism_test.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
from flax.core import meta
2929
from flax import linen as nn
30+
from flax import nnx
3031

3132
from MaxText import maxtext_utils
3233
from MaxText import pyconfig
@@ -63,7 +64,10 @@ def assert_pipeline_same_output_and_grad(self, config, single_pipeline_stage_cla
6364
mesh = Mesh(devices_array, config.mesh_axes)
6465
model_mode = MODEL_MODE_TRAIN
6566
if single_pipeline_stage_class is None:
66-
single_pipeline_stage = simple_layer.SimpleDecoderLayer(config=config, mesh=mesh, model_mode=model_mode)
67+
rngs = nnx.Rngs(params=0)
68+
single_pipeline_stage = simple_layer.SimpleDecoderLayerToLinen(
69+
config=config, mesh=mesh, model_mode=model_mode, rngs=rngs
70+
)
6771
else:
6872
single_pipeline_stage = single_pipeline_stage_class(config=config, mesh=mesh, model_mode=model_mode)
6973

@@ -90,7 +94,10 @@ def get_inputs(batch_size, sequence, features):
9094
)
9195
deterministic = True
9296
# We use a simpler single matmul decoder layer for fast compilation in these tests.
93-
single_pipeline_stage = simple_layer.SimpleDecoderLayer(config=config, mesh=mesh, model_mode=model_mode)
97+
rngs = nnx.Rngs(params=0)
98+
single_pipeline_stage = simple_layer.SimpleDecoderLayerToLinen(
99+
config=config, mesh=mesh, model_mode=model_mode, rngs=rngs
100+
)
94101
my_pipeline = pipeline.Pipeline(config=config, layers=single_pipeline_stage, mesh=mesh)
95102
init_pipeline_params = my_pipeline.init(
96103
jax.random.PRNGKey(0), inputs, inputs_position, inputs_segmentation, deterministic, model_mode

0 commit comments

Comments
 (0)