Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions megatron/core/models/gpt/gpt_layer_specs.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ def get_gpt_layer_with_transformer_engine_spec(
use_kitchen: bool = False,
use_te_activation_func: bool = False,
fallback_to_eager_attn: bool = False,
post_self_attn_layernorm: bool = False,
post_mlp_layernorm: bool = False,
) -> ModuleSpec:
"""Use this spec to use lower-level Transformer Engine modules (required for fp8 training).

Expand Down Expand Up @@ -260,6 +262,8 @@ def get_gpt_layer_with_transformer_engine_spec(
mlp=mlp,
sharded_state_dict_keys_map=sharded_state_dict_keys_map,
normalization=normalization,
post_self_attn_layernorm=post_self_attn_layernorm,
post_mlp_layernorm=post_mlp_layernorm,
)


Expand Down Expand Up @@ -349,6 +353,8 @@ def get_transformer_layer_spec_for_backend(
mlp: ModuleSpec,
sharded_state_dict_keys_map: Optional[dict] = None,
normalization: Optional[str] = None,
post_self_attn_layernorm: bool = False,
post_mlp_layernorm: bool = False,
) -> ModuleSpec:
"""Helper function to get module spec for TransformerLayer"""

Expand All @@ -371,9 +377,11 @@ def get_transformer_layer_spec_for_backend(
input_layernorm=input_layernorm,
self_attention=attention,
self_attn_bda=get_bias_dropout_add,
post_self_attn_layernorm=TENorm if post_self_attn_layernorm else IdentityOp,
pre_mlp_layernorm=pre_mlp_layernorm,
mlp=mlp,
mlp_bda=get_bias_dropout_add,
post_mlp_layernorm=TENorm if post_mlp_layernorm else IdentityOp,
sharded_state_dict_keys_map=sharded_state_dict_keys_map,
),
)
Expand Down
3 changes: 3 additions & 0 deletions megatron/core/transformer/transformer_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,9 @@ class TransformerConfig(ModelParallelConfig):
attention_output_gate: bool = False
"""Whether to apply output gate to the attention layers."""

post_self_attn_layernorm: bool = False
post_mlp_layernorm: bool = False

test_mode: bool = False
"""Whether to run real-time tests."""

Expand Down
24 changes: 24 additions & 0 deletions megatron/core/transformer/transformer_layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ class TransformerLayerSubmodules:
input_layernorm: Union[ModuleSpec, type] = IdentityOp
self_attention: Union[ModuleSpec, type] = IdentityOp
self_attn_bda: Union[ModuleSpec, type] = IdentityFuncOp
post_self_attn_layernorm: Union[ModuleSpec, type] = IdentityOp

pre_cross_attn_layernorm: Union[ModuleSpec, type] = IdentityOp
cross_attention: Union[ModuleSpec, type] = IdentityOp
Expand All @@ -231,6 +232,7 @@ class TransformerLayerSubmodules:
pre_mlp_layernorm: Union[ModuleSpec, type] = IdentityOp
mlp: Union[ModuleSpec, type] = IdentityOp
mlp_bda: Union[ModuleSpec, type] = IdentityFuncOp
post_mlp_layernorm: Union[ModuleSpec, type] = IdentityOp

# Mapping for sharded tensor keys to be applied in `sharded_state_dict` method
sharded_state_dict_keys_map: Dict[str, str] = field(default_factory=dict)
Expand Down Expand Up @@ -310,6 +312,13 @@ def __init__(
# [Module 3: BiasDropoutFusion]
self.self_attn_bda = build_module(submodules.self_attn_bda)

self.post_self_attn_layernorm = build_module(
submodules.post_self_attn_layernorm,
config=self.config,
hidden_size=self.config.hidden_size,
eps=self.config.layernorm_epsilon,
)

# [Module 4: Post SelfAttention] Optional Layernorm after self-attn
self.pre_cross_attn_layernorm = build_module(
submodules.pre_cross_attn_layernorm,
Expand Down Expand Up @@ -375,6 +384,13 @@ def __init__(

self.is_moe_layer = isinstance(self.mlp, MoELayer)

self.post_mlp_layernorm = build_module(
submodules.post_mlp_layernorm,
config=self.config,
hidden_size=self.config.hidden_size,
eps=self.config.layernorm_epsilon
)

self.recompute_input_layernorm = False
self.recompute_pre_mlp_layernorm = False
self.recompute_mlp = False
Expand Down Expand Up @@ -551,6 +567,10 @@ def _forward_attention(
attention_output_with_bias[0]
)

attention_output, attention_output_bias = attention_output_with_bias
attention_output = self.post_self_attn_layernorm(attention_output)
attention_output_with_bias = (attention_output, attention_output_bias)

# TODO: could we move `bias_dropout_add_exec_handler` itself
# inside the module provided in the `bias_dropout_add_spec` module?
nvtx_range_push(suffix="self_attn_bda")
Expand Down Expand Up @@ -677,6 +697,10 @@ def _forward_mlp(self, hidden_states, inference_context=None):
else:
mlp_output_with_bias = self.mlp(pre_mlp_layernorm_output)

mlp_output, mlp_output_bias = mlp_output_with_bias
mlp_output = self.post_mlp_layernorm(mlp_output)
mlp_output_with_bias = (mlp_output, mlp_output_bias)

if self.recompute_pre_mlp_layernorm:
# discard the output of the pre-mlp layernorm and register the recompute
# as a gradient hook of mlp_output_with_bias[0]
Expand Down
9 changes: 9 additions & 0 deletions megatron/training/arguments.py
Original file line number Diff line number Diff line change
Expand Up @@ -1398,6 +1398,9 @@ def core_transformer_config_from_args(args, config_class=None):

kw_args['inference_sampling_seed'] = args.seed

kw_args['post_self_attn_layernorm'] = args.post_self_attn_layernorm
kw_args['post_mlp_layernorm'] = args.post_mlp_layernorm

# handle quantization config
# NOTE: Kitchen arguments are only added to the namespace when
# Kitchen library is available.
Expand Down Expand Up @@ -1764,6 +1767,12 @@ def _add_network_size_args(parser):
action='store_true',
help='If set, use original BERT residula connection '
'ordering.')
group.add_argument('--post-self-attn-layernorm', action='store_true',
help='If set, use post self attention layernorm.')
group.add_argument('--post-mlp-layernorm', action='store_true',
help='If set, use post MLP layernorm.')
group.add_argument('--use-gated-attention', action='store_true',
help='If set, use gated attention as in Qwen3Next')
group.add_argument('--openai-gelu', action='store_true',
help='Use OpenAIs GeLU implementation. This option'
'should not be used unless for backward compatibility'
Expand Down