Skip to content

feat: convert SimpleDecoderLayer and SimpleMlpDecoderLayer to use nnx - #1974

Merged
copybara-service[bot] merged 1 commit into
AI-Hypercomputer:mainfrom
mesakhcienet:feat/simple-decoder-layer-nnx
Oct 16, 2025
Merged

feat: convert SimpleDecoderLayer and SimpleMlpDecoderLayer to use nnx #1974
copybara-service[bot] merged 1 commit into
AI-Hypercomputer:mainfrom
mesakhcienet:feat/simple-decoder-layer-nnx

Conversation

@mesakhcienet

@mesakhcienet mesakhcienet commented Jul 15, 2025

Copy link
Copy Markdown
Collaborator

Description

Use NNX for the SimpleDecodeLayer and SimpleMlpDecodeLayer modules.

We also implement a function to return class of the linen instead of an instantiated Linen object.

Tests

It should work.

Environment

Machine type : v5litepod-8 TPU VM
Software machine : tpu-ubuntu2204-base
Python Version : 3.10.12

Changes

SimpleDecodeLayer

Before change to NNX log : https://paste.googleplex.com/4892995450830848
After change to NNX log (train from scratch) : https://paste.googleplex.com/6179580754526208
After change to NNX log (continue train from main branch) : https://paste.googleplex.com/6264063394578432

Run command :

python -m MaxText.train MaxText/configs/base.yml \
  run_name=mesa-simple-test-small \
  base_output_directory=gs://mesa-maxtext/simple_test_small_1/  \
  decoder_block=simple dataset_type=synthetic \
  steps=10

SimpleMlpDecodeLayer

Before change to NNX log : https://paste.googleplex.com/5737594159366144
After change to NNX log (train from scratch) : https://paste.googleplex.com/5264591793422336
After change to NNX log (continue train from main branch) : https://paste.googleplex.com/4805767982743552

Run command :

python -m MaxText.train MaxText/configs/base.yml \
  run_name=mesa-simple-test-small-mlp  \
 base_output_directory=gs://mesa-maxtext/simple_test_small_2/ \ 
  decoder_block=simple_mlp \
  dataset_type=synthetic  \ 
  steps=10

Checklist

Before submitting this PR, please make sure (put X in square brackets):

  • I have performed a self-review of my code.
  • I have necessary comments in my code, particularly in hard-to-understand areas.
  • I have run end-to-end tests tests and provided workload links above if applicable.
  • I have made or will make corresponding changes to the doc if needed.

@mesakhcienet
mesakhcienet marked this pull request as ready for review July 16, 2025 03:07
@mesakhcienet
mesakhcienet force-pushed the feat/simple-decoder-layer-nnx branch from 38a123e to 89de7e2 Compare July 22, 2025 02:26
@mesakhcienet mesakhcienet changed the title feat: convert SimpleDecodeLayer and SimpleMlpDecodeLayer into nnx feat: convert SimpleDecoderLayer and SimpleMlpDecoderLayer into nnx Jul 22, 2025
@mesakhcienet
mesakhcienet force-pushed the feat/simple-decoder-layer-nnx branch 3 times, most recently from 4476b54 to eb99fd8 Compare July 28, 2025 01:39
Comment thread MaxText/layers/simple_layer.py Outdated
@mesakhcienet
mesakhcienet requested a review from bvandermoon July 28, 2025 05:58
@mesakhcienet
mesakhcienet force-pushed the feat/simple-decoder-layer-nnx branch from 8a6291b to 260271c Compare July 28, 2025 08:27
@mesakhcienet mesakhcienet changed the title feat: convert SimpleDecoderLayer and SimpleMlpDecoderLayer into nnx feat: convert SimpleDecoderLayer and SimpleMlpDecoderLayer to use nnx Jul 28, 2025
@mesakhcienet
mesakhcienet force-pushed the feat/simple-decoder-layer-nnx branch from 1606b5a to ece793f Compare July 29, 2025 03:16
Comment thread MaxText/layers/nnx_wrappers.py Outdated

@bvandermoon bvandermoon left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like the SimpleMlpDecoder test runs in the description are getting different perf before/after this change:

image

@mesakhcienet
mesakhcienet force-pushed the feat/simple-decoder-layer-nnx branch 2 times, most recently from ed83621 to ead2980 Compare July 29, 2025 07:50
@mesakhcienet

Copy link
Copy Markdown
Collaborator Author

It looks like the SimpleMlpDecoder test runs in the description are getting different perf before/after this change:

image

my bad, I used the wrong function to call SimpleMlpDecoderLayer by using simple_decoder_layer_class() instead of simple_mlp_decoder_layer_class.

Both code and the log are updated, thank you.

@mesakhcienet
mesakhcienet requested a review from bvandermoon July 29, 2025 08:11
Comment thread MaxText/layers/nnx_wrappers.py Outdated
@mesakhcienet
mesakhcienet requested a review from cgarciae August 6, 2025 09:25
@mesakhcienet
mesakhcienet force-pushed the feat/simple-decoder-layer-nnx branch 2 times, most recently from 6b913a3 to 5f3e877 Compare August 7, 2025 02:19
Comment thread MaxText/layers/simple_layer.py Outdated
@mesakhcienet
mesakhcienet force-pushed the feat/simple-decoder-layer-nnx branch 2 times, most recently from 86b4205 to e3d58ff Compare August 11, 2025 09:32
@mesakhcienet
mesakhcienet force-pushed the feat/simple-decoder-layer-nnx branch from e3d58ff to aa2cd98 Compare August 19, 2025 06:31
@mesakhcienet
mesakhcienet force-pushed the feat/simple-decoder-layer-nnx branch from aa2cd98 to 7da2050 Compare September 10, 2025 02:14
@mesakhcienet
mesakhcienet force-pushed the feat/simple-decoder-layer-nnx branch from 7da2050 to c0f964c Compare September 30, 2025 01:27
@mesakhcienet
mesakhcienet force-pushed the feat/simple-decoder-layer-nnx branch 4 times, most recently from d579507 to 0f6b007 Compare October 2, 2025 04:13
Comment thread src/MaxText/layers/simple_layer.py Outdated
Comment thread src/MaxText/layers/simple_layer.py
"weights",
nn.with_logical_partitioning(nn.initializers.lecun_normal(), ("embed", "mlp")),
(self.config.emb_dim, self.config.emb_dim),
init_fn = nnx.with_partitioning(nnx.initializers.lecun_normal(), sharding=("embed", "mlp"), mesh=self.mesh)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this needed? Not seeing it in the previous Linen version

@mesakhcienet mesakhcienet Oct 14, 2025

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for asking this part. We followed the previous Linen version as a reference to current change. For example:

self.weight_mat = self.param(
      "weights",
      nn.with_logical_partitioning(nn.initializers.lecun_normal(), ("embed", "mlp")),
      (self.config.emb_dim, self.config.emb_dim),
  )

Since self.param should now be replaced with nnx.Param in NNX, we updated the implementation accordingly.
We also replaced nn.with_logical_partitioning from Linen with nnx.with_partitioning from NNX. And for clarity, we moved the nnx.with_partitioning initializer wrapper ( in current case -- init_fn) as an independent variable.

If I am correct, we also have similar implemntation for self.param at different places, such as gpt3.py

Feel free to tell me if the change needs to be updated, thank you

Comment thread src/MaxText/layers/simple_layer.py Outdated
"ff_1",
nn.with_logical_partitioning(nn.initializers.lecun_normal(), ("embed", "mlp")),
(self.config.emb_dim, self.config.mlp_dim),
init_ff1_fn = nnx.with_partitioning(nnx.initializers.lecun_normal(), sharding=("embed", "mlp"), mesh=self.mesh)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this and the nnx.with_partitioning below added?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

similar with answer above, thank you

@NuojCheng NuojCheng left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM, the memory usages match for both cases.

@mesakhcienet
mesakhcienet force-pushed the feat/simple-decoder-layer-nnx branch from 7562255 to d2bc8f4 Compare October 14, 2025 03:23
Comment on lines +67 to +70
rngs = nnx.Rngs(params=0)
single_pipeline_stage = simple_layer.SimpleDecoderLayerToLinen(
config=config, mesh=mesh, model_mode=model_mode, rngs=rngs
)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since we update the implementation from Linen to NNX, we also need to update its related unit test

Comment on lines +97 to +100
rngs = nnx.Rngs(params=0)
single_pipeline_stage = simple_layer.SimpleDecoderLayerToLinen(
config=config, mesh=mesh, model_mode=model_mode, rngs=rngs
)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since we update the implementation from Linen to NNX, we also need to update its related unit test

@copybara-service
copybara-service Bot merged commit 44d6528 into AI-Hypercomputer:main Oct 16, 2025
27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants