-
Notifications
You must be signed in to change notification settings - Fork 4.2k
seperate_hypercontraction_module #5669
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -28,7 +28,7 @@ | |
| inference_all_gather_from_tensor_model_parallel_region, | ||
| ) | ||
| from megatron.core.transformer.enums import AttnMaskType, LayerType | ||
| from megatron.core.transformer.hyper_connection import learned_output_contract | ||
| from megatron.core.transformer.hyper_connection import HyperConnectionContractModule | ||
| from megatron.core.transformer.module import MegatronModule | ||
| from megatron.core.transformer.spec_utils import ModuleSpec, build_module | ||
| from megatron.core.transformer.torch_norm import LayerNormBuilder | ||
|
|
@@ -1235,16 +1235,7 @@ def __init__( | |
| ) | ||
|
|
||
| if self.mhc_enabled: | ||
| hc_mult = self.config.num_residual_streams | ||
| hc_dim = self.config.hidden_size * hc_mult | ||
| self.hc_head_fn = nn.Parameter(torch.randn(hc_mult, hc_dim)) | ||
| self.hc_head_base = nn.Parameter(torch.zeros(hc_mult)) | ||
| self.hc_head_scale = nn.Parameter(torch.ones(1)) | ||
| nn.init.xavier_uniform_(self.hc_head_fn) | ||
| if self.config.sequence_parallel: | ||
| setattr(self.hc_head_fn, 'sequence_parallel', True) | ||
| setattr(self.hc_head_base, 'sequence_parallel', True) | ||
| setattr(self.hc_head_scale, 'sequence_parallel', True) | ||
| self.mhc_contract = HyperConnectionContractModule(self.config) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [IMPORTANT Compatibility] Same checkpoint-key rename issue as in This layer already has a |
||
|
|
||
| self.offload_context = nullcontext() | ||
|
|
||
|
|
@@ -1453,14 +1444,7 @@ def _postprocess(self, hidden_states: torch.Tensor): | |
| """ | ||
|
|
||
| if self.mhc_enabled: | ||
| hidden_states = learned_output_contract( | ||
| hidden_states, | ||
| self.hc_head_fn, | ||
| self.hc_head_base, | ||
| self.hc_head_scale, | ||
| self.config.num_residual_streams, | ||
| self.config.layernorm_epsilon, | ||
| ) | ||
| hidden_states = self.mhc_contract(hidden_states) | ||
|
|
||
| # Layer norm before shared head layer. | ||
| hidden_states = apply_module(self.final_layernorm)(hidden_states) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,8 +25,8 @@ | |
| from megatron.core.tensor_parallel.random import CheckpointManager | ||
| from megatron.core.transformer.enums import InferenceCudaGraphScope, LayerType | ||
| from megatron.core.transformer.hyper_connection import ( | ||
| HyperConnectionContractModule, | ||
| HyperConnectionModule, | ||
| learned_output_contract, | ||
| ) | ||
| from megatron.core.transformer.module import GraphableMegatronModule, MegatronModule | ||
| from megatron.core.transformer.spec_utils import ModuleSpec, build_module | ||
|
|
@@ -391,16 +391,7 @@ def build_layer(layer_spec, layer_number): | |
| eps=self.config.layernorm_epsilon, | ||
| ) | ||
| if self.config.enable_hyper_connections: | ||
| hc_mult = self.config.num_residual_streams | ||
| hc_dim = self.config.hidden_size * hc_mult | ||
| self.hc_head_fn = nn.Parameter(torch.randn(hc_mult, hc_dim)) | ||
| self.hc_head_base = nn.Parameter(torch.zeros(hc_mult)) | ||
| self.hc_head_scale = nn.Parameter(torch.ones(1)) | ||
| nn.init.xavier_uniform_(self.hc_head_fn) | ||
| if self.config.sequence_parallel: | ||
| setattr(self.hc_head_fn, 'sequence_parallel', True) | ||
| setattr(self.hc_head_base, 'sequence_parallel', True) | ||
| setattr(self.hc_head_scale, 'sequence_parallel', True) | ||
| self.mhc_contract = HyperConnectionContractModule(self.config) | ||
| else: | ||
| self.final_layernorm = None # Either this or nn.Identity | ||
|
|
||
|
|
@@ -956,14 +947,7 @@ def forward( | |
| mhc_multistream = hidden_states | ||
| # DSv4 introduced the new output contraction for mHC. | ||
| # [s, b, n*C] -> [s, b, C] | ||
| hidden_states = learned_output_contract( | ||
| hidden_states, | ||
| self.hc_head_fn, | ||
| self.hc_head_base, | ||
| self.hc_head_scale, | ||
| self.config.num_residual_streams, | ||
| self.config.layernorm_epsilon, | ||
| ) | ||
| hidden_states = self.mhc_contract(hidden_states) | ||
|
|
||
| # Final layer norm. | ||
| if self.final_layernorm is not None: | ||
|
|
@@ -1080,10 +1064,9 @@ def sharded_state_dict( | |
| ) | ||
|
|
||
| # Save bare parameters/buffers that are direct attributes of this block | ||
| # (e.g. hyper-connection learned weights: hc_head_fn, hc_head_base, | ||
| # hc_head_scale). The named_children loop above would silently drop | ||
| # these since they are not nn.Module children. Mirrors the handling in | ||
| # MegatronModule.sharded_state_dict. | ||
| # (not nn.Module children — the named_children loop above would silently | ||
| # drop them). mhc_contract is now a proper child module and is handled | ||
| # above; this catches any other bare params on the block itself. | ||
|
Comment on lines
1066
to
+1069
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [IMPORTANT Compatibility] This refactor silently renames the checkpoint keys for the mHC contraction params without any migration path. Before this PR, Impact: existing checkpoints from PR #4518 (already on Fix: wire the remap the new module's own docstring promises. In this block's from megatron.core.dist_checkpointing.utils import apply_prefix_mapping
if self.config.enable_hyper_connections:
apply_prefix_mapping(
sharded_state_dict,
{f'{prefix}mhc_contract.hc_head_fn': f'{prefix}hc_head_fn',
f'{prefix}mhc_contract.hc_head_base': f'{prefix}hc_head_base',
f'{prefix}mhc_contract.hc_head_scale': f'{prefix}hc_head_scale'},
)(or otherwise document that this breaks existing mHC checkpoints). As written, the docstring claims a migration that no callsite actually performs. |
||
| local_state_dict: dict = {} | ||
| self._save_to_state_dict(local_state_dict, '', keep_vars=True) | ||
| if local_state_dict: | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[SUGGESTION Other] This docstring describes backward-compatible checkpoint loading "via
apply_prefix_mapping" as if it were an available/used mechanism, but no callsite in this PR (neithertransformer_block.pynormulti_token_prediction.py) actually performs that remap. A docstring that describes behavior the code doesn't implement is worse than none — either wire up theapply_prefix_mappingcall at the owners (see the block/MTP comments) or reword this to state plainly that owners must add the remap themselves for BC, and that this module alone does not preserve the legacy flat keys.