Skip to content

seperate_hypercontraction_module#5669

Open
liuzhenhai93 wants to merge 1 commit into
NVIDIA:devfrom
liuzhenhai93:seperate_hypercontraction_module
Open

seperate_hypercontraction_module#5669
liuzhenhai93 wants to merge 1 commit into
NVIDIA:devfrom
liuzhenhai93:seperate_hypercontraction_module

Conversation

@liuzhenhai93

@liuzhenhai93 liuzhenhai93 commented Jul 6, 2026

Copy link
Copy Markdown
  • I, the PR author, have personally reviewed every line of this PR.

What does this PR do?

refactor hyper connection contraction to a module

Issue tracking

For PRs from open-source community contributors:

  • New features: a linked issue is required. Please open a feature request and reference it here before submitting the PR.
  • Small updates (bug fixes, minor improvements): a linked issue is recommended and will accelerate the PR review process.

Linked issue:

#5670

Contribution process

Pre-checks

  • I have added relevant unit tests
  • I have added relevant functional tests
  • I have added proper typing to my code Typing guidelines
  • I have added relevant documentation
  • I have run the autoformatter.sh on my PR

Code review

Feel free to message or comment @NVIDIA/mcore-oncall to help accelerate your merge into main. The less complex your PR is, the faster it will be approved and merged!

All PRs start as draft. If you open a non-draft PR, it will be automatically converted to draft.

Step 1: Mark PR as "Ready for Review"

  1. When your PR is ready, click Ready for Review.
  2. An oncall reviewer is auto-assigned and expert reviewers are notified based on your changes.
    • Some PRs may jump straight to step 2. This is determined by .github/CODEOWNERS.

⚠️ Only mark as ready once merge-conflicts are resolved and the CI is passing.
Final Review might get declined if these requirements are not fulfilled.

Step 2: Final Review

For PRs that change megatron/core, once all expert reviewers have approved, the Final Review label is applied automatically and final reviewers are assigned.

For PRs outside megatron/core, this step is skipped.

Step 3: Approved

Once all required reviewers have approved, the Approved label is applied automatically.

Merge

Any member of mcore-engineers will be able to merge your PR.

@liuzhenhai93 liuzhenhai93 requested review from a team as code owners July 6, 2026 11:29
@copy-pr-bot

copy-pr-bot Bot commented Jul 6, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@hxbai

hxbai commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

/claude strict-review

@claude

claude Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Strict Review Summary

Findings: CRITICAL: 0, IMPORTANT: 2, SUGGESTION: 1

This PR is a clean, behavior-preserving refactor of the DSv4 mHC output-contraction params into a dedicated HyperConnectionContractModule. The runtime forward path (learned_output_contract args, init, xavier_uniform_, and sequence_parallel attribute tagging) is preserved verbatim, and the new module correctly inherits self.config from MegatronModule. Tests were updated for the new attribute nesting.

Most impactful findings

  • [IMPORTANT Compatibility] Checkpoint key rename with no migration path (both transformer_block.py and multi_token_prediction.py). Moving the params from bare block/MTP attributes into self.mhc_contract changes the saved state-dict keys from ...hc_head_fn to ...mhc_contract.hc_head_fn. The flat keys already shipped on dev (PR [dev] [DeepSeek-v4] Part 3: MTP support with mHC and new mHC contract #4518), so existing mHC / mHC+MTP checkpoints will fail to load or silently drop these learned params on resume. The new module's own docstring promises a apply_prefix_mapping remap, but no callsite actually performs it. Recommend adding the prefix strip in each owner's sharded_state_dict (MTP already overrides it for the mtp_model_layer remap — extend it there).

  • [SUGGESTION] Docstring describes unimplemented BC mechanism — reword or wire it up so the doc matches reality.

Risk assessment

Medium. The compute path is safe, but the checkpoint-key change is a real backward-compatibility regression for anyone with existing mHC checkpoints. Should not merge until either the prefix mapping is added or the break is explicitly acknowledged/documented. A sharded_state_dict round-trip unit test asserting the legacy keys load would de-risk this.

Comment on lines 1066 to +1069
# 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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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, hc_head_fn/hc_head_base/hc_head_scale were bare nn.Parameter attributes of the block, saved by the _save_to_state_dict(...) + make_sharded_tensors_for_checkpoint(local_state_dict, prefix, ...) path below — producing keys like decoder.hc_head_fn. Now they live under self.mhc_contract, so the named_children() loop (lines 1053-1064) saves them as decoder.mhc_contract.hc_head_fn, etc.

Impact: existing checkpoints from PR #4518 (already on dev) that contain ...hc_head_fn will no longer load into the new code — the keys won't match, causing a silent divergence or a load error on resume.

Fix: wire the remap the new module's own docstring promises. In this block's sharded_state_dict, after building sharded_state_dict, strip the new prefix for backward-compat, e.g.:

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.

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)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[IMPORTANT Compatibility] Same checkpoint-key rename issue as in transformer_block.py. Previously the MTP layer saved hc_head_fn/hc_head_base/hc_head_scale as bare params (keys ...mtp.layers.{i}.hc_head_fn); now they are under self.mhc_contract, producing ...mtp.layers.{i}.mhc_contract.hc_head_fn.

This layer already has a sharded_state_dict override (line 1763) that calls apply_prefix_mapping for the mtp_model_layer./transformer_layer. remap — extend it to also strip the mhc_contract. prefix when self.mhc_enabled, so existing mHC+MTP checkpoints keep loading. Otherwise resume from an old checkpoint silently loses these learned params.

Comment on lines +840 to +843
Parameters are named ``hc_head_fn`` / ``hc_head_base`` / ``hc_head_scale``
(matching their legacy flat checkpoint keys) so that owners only need to
strip the ``mhc_contract.`` prefix when remapping for backward-compatible
checkpoint loading via ``apply_prefix_mapping``.

Copy link
Copy Markdown
Contributor

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 (neither transformer_block.py nor multi_token_prediction.py) actually performs that remap. A docstring that describes behavior the code doesn't implement is worse than none — either wire up the apply_prefix_mapping call 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.

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.

3 participants