Skip to content

Commit 5fe5ca6

Browse files
Merge pull request #2162 from AI-Hypercomputer:migrate_gemma_to_nnx
PiperOrigin-RevId: 815762233
2 parents 5da271b + 70f91cd commit 5fe5ca6

3 files changed

Lines changed: 329 additions & 245 deletions

File tree

src/MaxText/layers/decoders.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -383,9 +383,9 @@ def get_decoder_layers(self):
383383
case DecoderBlockType.DEEPSEEK:
384384
return [deepseek.DeepSeekDenseLayer, deepseek.DeepSeekMoELayer]
385385
case DecoderBlockType.GEMMA:
386-
return [gemma.GemmaDecoderLayer]
386+
return [gemma.GemmaDecoderLayerToLinen]
387387
case DecoderBlockType.GEMMA2:
388-
return [gemma2.Gemma2DecoderLayer]
388+
return [gemma2.Gemma2DecoderLayerToLinen]
389389
case DecoderBlockType.GEMMA3:
390390
return [gemma3.Gemma3DecoderLayer]
391391
case DecoderBlockType.GPT3:

src/MaxText/layers/gemma.py

Lines changed: 107 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -14,30 +14,109 @@
1414

1515
"""Specialised layers for Gemma."""
1616

17+
from typing import Optional
18+
19+
from flax import linen as nn
20+
from flax import nnx
1721
from jax.ad_checkpoint import checkpoint_name
1822
from jax.sharding import Mesh
1923
import jax.numpy as jnp
2024

21-
from flax import linen as nn
22-
25+
from MaxText import max_utils
2326
from MaxText.common_types import Config
27+
from MaxText.layers import initializers
28+
from MaxText.layers import nnx_wrappers
2429
from MaxText.layers import quantizations
25-
from MaxText.layers.attentions import attention_as_linen
26-
from MaxText.layers.linears import mlp_block
27-
from MaxText.layers.normalizations import rms_norm
30+
from MaxText.layers.attentions import Attention
31+
from MaxText.layers.linears import Dropout, MlpBlock
32+
from MaxText.layers.normalizations import RMSNorm
2833
from MaxText.layers.quantizations import AqtQuantization as Quant
2934

3035

3136
# Decoder and Model definitions
32-
class GemmaDecoderLayer(nn.Module):
37+
class GemmaDecoderLayer(nnx.Module):
3338
"""Transformer decoder layer that attends to the encoder."""
3439

3540
config: Config
3641
mesh: Mesh
3742
model_mode: str
3843
quant: None | Quant = None
3944

40-
@nn.compact
45+
def __init__(
46+
self,
47+
config: Config,
48+
mesh: Mesh,
49+
model_mode: str,
50+
quant: Optional[Quant] = None,
51+
*,
52+
rngs: nnx.Rngs,
53+
):
54+
self.config = config
55+
self.mesh = mesh
56+
self.model_mode = model_mode
57+
self.quant = quant
58+
self.rngs = rngs
59+
60+
batch_size, seq_len = max_utils.get_batch_seq_len_for_mode(config, model_mode)
61+
dummy_inputs_shape = (batch_size, seq_len, config.emb_dim)
62+
63+
self.pre_self_attention_norm = RMSNorm(
64+
num_features=config.emb_dim,
65+
dtype=config.dtype,
66+
weight_dtype=config.weight_dtype,
67+
kernel_axes=("norm",),
68+
rngs=self.rngs,
69+
)
70+
71+
self.self_attention = Attention(
72+
config=config,
73+
num_query_heads=config.num_query_heads,
74+
num_kv_heads=config.num_kv_heads,
75+
head_dim=config.head_dim,
76+
max_target_length=config.max_target_length,
77+
max_prefill_predict_length=config.max_prefill_predict_length,
78+
attention_kernel=config.attention,
79+
inputs_q_shape=dummy_inputs_shape,
80+
inputs_kv_shape=dummy_inputs_shape,
81+
mesh=self.mesh,
82+
dtype=config.dtype,
83+
weight_dtype=config.weight_dtype,
84+
dropout_rate=config.dropout_rate,
85+
float32_qk_product=config.float32_qk_product,
86+
float32_logits=config.float32_logits,
87+
quant=self.quant,
88+
kv_quant=quantizations.configure_kv_quant(config),
89+
use_ragged_attention=config.use_ragged_attention,
90+
ragged_block_size=config.ragged_block_size,
91+
model_mode=self.model_mode,
92+
rngs=self.rngs,
93+
)
94+
95+
self.pre_ffw_norm = RMSNorm(
96+
num_features=config.emb_dim,
97+
dtype=config.dtype,
98+
weight_dtype=config.weight_dtype,
99+
kernel_axes=("norm",),
100+
rngs=self.rngs,
101+
)
102+
103+
self.mlp = MlpBlock(
104+
config=config,
105+
in_features=config.emb_dim,
106+
intermediate_dim=config.mlp_dim,
107+
activations=config.mlp_activations,
108+
intermediate_dropout_rate=config.dropout_rate,
109+
dtype=config.dtype,
110+
weight_dtype=config.weight_dtype,
111+
quant=self.quant,
112+
model_mode=self.model_mode,
113+
rngs=self.rngs,
114+
)
115+
116+
self.dropout = Dropout(rate=config.dropout_rate, broadcast_dims=(-2,), rngs=self.rngs)
117+
118+
self.activation_axis_names = ("activation_batch", "activation_norm_length", "activation_embed")
119+
41120
def __call__(
42121
self,
43122
inputs,
@@ -50,46 +129,14 @@ def __call__(
50129
page_state=None,
51130
slot=None,
52131
):
53-
cfg = self.config
54-
mesh = self.mesh
55-
inputs = nn.with_logical_constraint(inputs, ("activation_batch", "activation_norm_length", "activation_embed"))
132+
inputs = nn.with_logical_constraint(inputs, self.activation_axis_names)
56133
inputs = checkpoint_name(inputs, "decoder_layer_input")
57134
# inputs: embedded inputs to the decoder with shape [batch, length, emb_dim]
58-
lnx = rms_norm(
59-
num_features=inputs.shape[-1],
60-
dtype=cfg.dtype,
61-
weight_dtype=cfg.weight_dtype,
62-
name="pre_self_attention_norm",
63-
kernel_axes=("norm",),
64-
)(inputs)
65-
66-
lnx = nn.with_logical_constraint(lnx, ("activation_batch", "activation_norm_length", "activation_embed"))
67-
68-
attention_layer = attention_as_linen(
69-
config=cfg,
70-
num_query_heads=cfg.num_query_heads,
71-
num_kv_heads=cfg.num_kv_heads,
72-
head_dim=cfg.head_dim,
73-
max_target_length=cfg.max_target_length,
74-
max_prefill_predict_length=cfg.max_prefill_predict_length,
75-
attention_kernel=cfg.attention,
76-
inputs_q_shape=lnx.shape,
77-
inputs_kv_shape=lnx.shape,
78-
mesh=mesh,
79-
dtype=cfg.dtype,
80-
weight_dtype=cfg.weight_dtype,
81-
dropout_rate=cfg.dropout_rate,
82-
name="self_attention",
83-
float32_qk_product=cfg.float32_qk_product,
84-
float32_logits=cfg.float32_logits,
85-
quant=self.quant,
86-
kv_quant=quantizations.configure_kv_quant(cfg),
87-
use_ragged_attention=cfg.use_ragged_attention,
88-
ragged_block_size=cfg.ragged_block_size,
89-
model_mode=model_mode,
90-
)
135+
lnx = self.pre_self_attention_norm(inputs)
136+
137+
lnx = nn.with_logical_constraint(lnx, self.activation_axis_names)
91138

92-
attention_lnx = attention_layer(
139+
attention_lnx = self.self_attention(
93140
lnx,
94141
lnx,
95142
decoder_positions,
@@ -98,46 +145,26 @@ def __call__(
98145
model_mode=model_mode,
99146
)
100147

101-
attention_lnx = nn.with_logical_constraint(
102-
attention_lnx, ("activation_batch", "activation_norm_length", "activation_embed")
103-
)
148+
attention_lnx = nn.with_logical_constraint(attention_lnx, self.activation_axis_names)
104149
attention_lnx += inputs
105150
residual = attention_lnx
106-
attn_output = rms_norm(
107-
num_features=attention_lnx.shape[-1],
108-
dtype=cfg.dtype,
109-
weight_dtype=cfg.weight_dtype,
110-
name="pre_ffw_norm",
111-
kernel_axes=("norm",),
112-
)(attention_lnx)
113-
114-
# MLP block.
115-
mlp_lnx = mlp_block(
116-
in_features=attn_output.shape[-1],
117-
intermediate_dim=cfg.mlp_dim,
118-
activations=cfg.mlp_activations,
119-
intermediate_dropout_rate=cfg.dropout_rate,
120-
dtype=cfg.dtype,
121-
weight_dtype=cfg.weight_dtype,
122-
name="mlp",
123-
config=cfg,
124-
quant=self.quant,
125-
)(attn_output, deterministic=deterministic)
126-
mlp_lnx = nn.with_logical_constraint(mlp_lnx, ("activation_batch", "activation_norm_length", "activation_embed"))
151+
152+
attn_output = self.pre_ffw_norm(attention_lnx)
153+
154+
mlp_lnx = self.mlp(attn_output, deterministic=deterministic)
155+
mlp_lnx = nn.with_logical_constraint(mlp_lnx, self.activation_axis_names)
127156

128157
next_layer_addition = mlp_lnx + residual
129158

130-
next_layer_addition_dropped_out = nn.Dropout(rate=cfg.dropout_rate, broadcast_dims=(-2,))(
131-
next_layer_addition, deterministic=deterministic
132-
)
159+
next_layer_addition_dropped_out = self.dropout(next_layer_addition, deterministic=deterministic)
133160

134161
layer_output = next_layer_addition_dropped_out
135162
layer_output = nn.with_logical_constraint(
136163
layer_output,
137-
("activation_batch", "activation_norm_length", "activation_embed"),
164+
self.activation_axis_names,
138165
)
139166

140-
if cfg.record_internal_nn_metrics:
167+
if self.config.record_internal_nn_metrics:
141168
self.sow("intermediates", "activation_mean", jnp.mean(layer_output))
142169
self.sow("intermediates", "activation_stdev", jnp.std(layer_output))
143170
self.sow(
@@ -146,7 +173,13 @@ def __call__(
146173
jnp.sum(layer_output == 0) / jnp.size(layer_output),
147174
)
148175

149-
if cfg.scan_layers:
176+
if self.config.scan_layers:
150177
return layer_output, None
151178
else:
152179
return layer_output
180+
181+
182+
GemmaDecoderLayerToLinen = nnx_wrappers.to_linen_class(
183+
GemmaDecoderLayer,
184+
base_metadata_fn=initializers.variable_to_logically_partitioned,
185+
)

0 commit comments

Comments
 (0)