Skip to content

Fix GTP checkpoint load failing across different GTP degrees - #7293

Merged
fanshiqing merged 5 commits into
NVIDIA:mainfrom
fanshiqing:shiqingf/fix_gtp_ckpt_load_across_different_gtp_degree
Sep 15, 2026
Merged

fanshiqing merged 5 commits into
NVIDIA:mainfrom
fanshiqing:shiqingf/fix_gtp_ckpt_load_across_different_gtp_degree

Conversation

@fanshiqing

@fanshiqing fanshiqing commented Sep 14, 2026 •

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

Summary

A checkpoint saved with GTP (Generalized Tensor Parallelism) alignment padding at one gtp_remat_size could fail to load at a different gtp_remat_size, or when loaded by a non-GTP process — the checkpoint's declared shape (padded) didn't match the loader's expected shape (possibly unpadded or padded differently), and allow_shape_mismatch was never set to tolerate the difference.

Here are two typical cases this MR should fix:

Example-1: GTP-save-with-padding -> GTP-load-w/o-padding

image

Example-2: GTP-save --> GTP load but with different padding requirement

image

Coverage matrix

Save \ Load Plain 3D (TP×PP×DP, no GTP) GTP (any gtp_remat_size)
Plain 3D (no GTP) n/a — no padding involved, unaffected Fixed — load-side padding recognized (declared == dim0_unpadded, e.g. non-tile-aligned hidden dims)
GTP (padded) Fixed — the originally reported gap; a GTP-saved checkpoint loaded by a GTP-unaware process now recognizes the padding Fixed — the originally reported bug; save/load at different GTP degrees now reconciles correctly

All "Fixed" cells are validated for plain TP×DP. Pipeline parallelism (PP > 1) is a known gap, not covered by this fix — see below.

Fix

Add infer_gtp_allow_shape_mismatch() (megatron/core/utils.py), called right before dist_checkpointing.load(). It reads the checkpoint's real on-disk shape and sets allow_shape_mismatch per tensor — but only when the declared-vs-expected difference is actually explainable as GTP padding (bounded by the recipe's alignment size), not for every mismatch.

pad_for_alignment (the recipe's alignment tile size) is resolved via a new megatron/core/tensor_parallel/gtp_recipe.py — a small, zero-dependency module so it can be computed during checkpoint load without importing TE-dependent GTP modules.

Testing

  • Real end-to-end functional verification: test_cross_gtp_degree_save_load_roundtrip does a genuine dist_checkpointing.save()/load() roundtrip for the originally-reported case — GTP4-padded save (dim0=192 → 256) loaded by GTP2 (no padding needed, 192 % 64 == 0). The load-side buffer is pre-scribbled with a sentinel value before loading (so a no-op or partial load can't accidentally pass), and the result is checked bit-exact (rtol=0, atol=0) against an independently-constructed golden tensor. This confirms the fix doesn't just flip a boolean — the actual loaded weight data is correct.
  • Additional unit tests pin the padding-explainability bound directly: legitimate padding, an unrelated/incompatible shape (must stay rejected), a GTP-saved checkpoint loaded by a non-GTP process, a pre-set allow_shape_mismatch from an unrelated reason (must not be clobbered), and the bf16 (pad_for_alignment=1) case (must not vacuously accept any size).
  • Full tests/unit_tests/generalized_tensor_parallel/ suite (all 18 files, ~200+ cases) passes cleanly, including this one.

Known limitations (not in the scope of this MR)

  • SwiGLU linear_fc1.weight + GTP is unreconciled by this fix
    • and separately, there's an open question about whether the GTP+SwiGLU factory split is even correct pre-existing, worth its own dedicated investigation.
  • The padding-explainability check has no upper bound on accepted shape growth beyond
    alignment/exact-match.

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

@fanshiqing fanshiqing self-assigned this Sep 14, 2026
@fanshiqing
fanshiqing requested a review from a team as a code owner September 14, 2026 05:38
@fanshiqing
fanshiqing requested a review from a team September 14, 2026 05:38
@fanshiqing
fanshiqing requested review from a team as code owners September 14, 2026 05:38
@copy-pr-bot

copy-pr-bot Bot commented Sep 14, 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.

@svcnvidia-nemo-ci
svcnvidia-nemo-ci marked this pull request as draft September 14, 2026 05:38
@github-actions

Copy link
Copy Markdown
Contributor

This PR has been automatically converted to draft because all PRs must start as drafts.

When you are ready for review, click Ready for Review to begin the review process. This will:

  1. Add the oncall reviewer (optional reviewer)
  2. Add required review teams based on your changes

See the contribution guide for more details.

@fanshiqing
fanshiqing marked this pull request as ready for review September 14, 2026 05:38
@fanshiqing
fanshiqing force-pushed the shiqingf/fix_gtp_ckpt_load_across_different_gtp_degree branch from 60a2ce4 to f8592c4 Compare September 14, 2026 05:52
Comment thread megatron/core/utils.py Resolved
Comment thread megatron/core/utils.py Resolved
Comment thread megatron/training/checkpointing.py Resolved
@claude

This comment was marked as resolved.

Signed-off-by: Shiqing Fan <shiqingf@nvidia.com>
@fanshiqing
fanshiqing force-pushed the shiqingf/fix_gtp_ckpt_load_across_different_gtp_degree branch from f8592c4 to df1fc42 Compare September 14, 2026 06:04
Signed-off-by: Shiqing Fan <shiqingf@nvidia.com>
Comment thread megatron/training/checkpointing.py Resolved
Signed-off-by: Shiqing Fan <shiqingf@nvidia.com>
@fanshiqing

Copy link
Copy Markdown
Member Author

/ok to test feeaaa2

@Phlip79
Phlip79 requested a review from a team September 15, 2026 03:41
@svcnvidia-nemo-ci svcnvidia-nemo-ci added the Approved All necessary approvals have been made label Sep 15, 2026
@fanshiqing
fanshiqing added this pull request to the merge queue Sep 15, 2026
@nemo-automation-bot

Copy link
Copy Markdown

🔄 Merge queue validation started!

You can track the progress here: https://github.com/NVIDIA/Megatron-LM/actions/runs/34933415391

Merged via the queue into NVIDIA:main with commit 8349ade Sep 15, 2026
107 of 112 checks passed
@fanshiqing
fanshiqing deleted the shiqingf/fix_gtp_ckpt_load_across_different_gtp_degree branch September 15, 2026 07:46
xuwchen pushed a commit to xuwchen/Megatron-LM that referenced this pull request Sep 22, 2026
…7293)

Signed-off-by: Shiqing Fan <shiqingf@nvidia.com>
(cherry picked from commit 8349ade)
xuwchen added a commit to xuwchen/Megatron-LM that referenced this pull request Sep 22, 2026
xuwchen added a commit to xuwchen/Megatron-LM that referenced this pull request Sep 22, 2026
xuwchen pushed a commit to xuwchen/Megatron-LM that referenced this pull request Sep 22, 2026
…7293)

Signed-off-by: Shiqing Fan <shiqingf@nvidia.com>
(cherry picked from commit 8349ade)
xuwchen added a commit to xuwchen/Megatron-LM that referenced this pull request Sep 22, 2026
…ffset

With gtp_remat_pad_for_alignment > 0 a GTP weight is allocated padded to
pad_for_alignment * gtp_remat_size rows, and every shard -- padding included -- was
described to the checkpoint as if it were real data. ShardedTensor.from_rank_offsets
computes global_offset[axis] = axis_rank_offset * local_axis_shape, so passing the PADDED
shard size shifted every tp_rank > 0 by pad_length: those ranks read their neighbour's rows
and their own tail came back as zeros. allow_shape_mismatch, set to absorb the inflated
global shape, suppressed the validation that would have caught it. The symptom was a grad
norm of 7.75e9 at pad_for_alignment=128; at the default of 16 it still corrupted every
weight whose dim0 is not already aligned (vision fc1 pads 24 rows).

Describe the checkpoint in LOGICAL layout instead. _make_gtp_logical_sharded_tensor sizes
and offsets the global tensor from the unpadded row count and trims this rank's pad tail,
so padding never reaches the checkpoint and allow_shape_mismatch is no longer needed. A
shard that is entirely padding (vision linear_proj: dim0 1152, alignment 512) contributes
an empty slice rather than raising.

Trimming changes object identity, which the optimizer depends on -- it maps optimizer
params to model entries by id(entry.data). The trimmed shard therefore carries a
gtp_pad_src backlink to the live param, resolved by gtp_entry_backlink() in both the
distributed-Adam and distributed-Muon lookups. The backlink lives on the ShardedTensor and
not on its data, because the torch strategy does sh_ten.data = sh_ten.data.detach(), which
drops tensor attributes. A full-length shard is handed back as the SAME object so identity
still holds. A padded native-FP8 param points its backlink at the live param rather than at
the dequantized copy, or the trimmed rank resolves to a copy the _gtp_dequant_src lookup can
no longer see and its optimizer state silently vanishes.

Two consumers need the untrimmed shard: an all-gather over the GTP group sizes itself off
the short trailing rank and HANGS otherwise (untrimmed_gtp_shard()), and the
fully-reshardable optimizer load expresses flat param ranges over the padded shard, so it
zero-fills the excluded rows before applying the range.

Covered by test_padded_shard_logical_offsets, test_padded_ep_egtp_offsets,
test_padded_optimizer_state_mapping, test_padded_fused_projection_gather,
test_padded_save_load_roundtrip and test_non_gtp_checkpoint_into_padded_gtp -- the last of
which is the discriminating one: it writes with a non-GTP layout and reads into a padded
GTP model, and is the only one that fails on the pre-fix mapping (want rows [10..15], got
[12..17], +2 = pad_length). The symmetric round-trip cannot catch a self-consistently wrong
mapping. Run them with scripts/gtp_dcp_unit_test.sh: the file gates on world_size == 4 and
needs the TE >= 2.19 overlay, and getting either wrong skips the whole file while the
command still exits 0.

Rebase note (dev @ 0e704ed): the base now carries NVIDIA#7293, which handled the same symptom
by keeping the padded global and waiving the shape check at load time
(grant_shape_mismatch_for_gtp_padding). This commit supersedes that mechanism -- the
checkpoint is logical, so a current save never mismatches -- and keeps the grant only as a
reader for checkpoints written before the logical layout. Such a checkpoint is recoverable
only at TP=1 (data rows, then the pad tail); the logical shard is tagged gtp_tp_size and the
grant refuses TP>1, where the old grid shifted every TP rank past 0 by pad_length. NVIDIA#7293's
tests were adapted: the cross-degree round trip now asserts that no waiver is needed, the
grant-decision test writes its padded checkpoint by hand as a legacy artifact, and the
"padded GTP save -> non-GTP load" case became an exact round trip instead of a hard failure.

Signed-off-by: xuwenc <xuwenc@nvidia.com>
xuwchen added a commit to xuwchen/Megatron-LM that referenced this pull request Sep 22, 2026
…ffset

With gtp_remat_pad_for_alignment > 0 a GTP weight is allocated padded to
pad_for_alignment * gtp_remat_size rows, and every shard -- padding included -- was
described to the checkpoint as if it were real data. ShardedTensor.from_rank_offsets
computes global_offset[axis] = axis_rank_offset * local_axis_shape, so passing the PADDED
shard size shifted every tp_rank > 0 by pad_length: those ranks read their neighbour's rows
and their own tail came back as zeros. allow_shape_mismatch, set to absorb the inflated
global shape, suppressed the validation that would have caught it. The symptom was a grad
norm of 7.75e9 at pad_for_alignment=128; at the default of 16 it still corrupted every
weight whose dim0 is not already aligned (vision fc1 pads 24 rows).

Describe the checkpoint in LOGICAL layout instead. _make_gtp_logical_sharded_tensor sizes
and offsets the global tensor from the unpadded row count and trims this rank's pad tail,
so padding never reaches the checkpoint and allow_shape_mismatch is no longer needed. A
shard that is entirely padding (vision linear_proj: dim0 1152, alignment 512) contributes
an empty slice rather than raising.

Trimming changes object identity, which the optimizer depends on -- it maps optimizer
params to model entries by id(entry.data). The trimmed shard therefore carries a
gtp_pad_src backlink to the live param, resolved by gtp_entry_backlink() in both the
distributed-Adam and distributed-Muon lookups. The backlink lives on the ShardedTensor and
not on its data, because the torch strategy does sh_ten.data = sh_ten.data.detach(), which
drops tensor attributes. A full-length shard is handed back as the SAME object so identity
still holds. A padded native-FP8 param points its backlink at the live param rather than at
the dequantized copy, or the trimmed rank resolves to a copy the _gtp_dequant_src lookup can
no longer see and its optimizer state silently vanishes.

Two consumers need the untrimmed shard: an all-gather over the GTP group sizes itself off
the short trailing rank and HANGS otherwise (untrimmed_gtp_shard()), and the
fully-reshardable optimizer load expresses flat param ranges over the padded shard, so it
zero-fills the excluded rows before applying the range.

Covered by test_padded_shard_logical_offsets, test_padded_ep_egtp_offsets,
test_padded_optimizer_state_mapping, test_padded_fused_projection_gather,
test_padded_save_load_roundtrip and test_non_gtp_checkpoint_into_padded_gtp -- the last of
which is the discriminating one: it writes with a non-GTP layout and reads into a padded
GTP model, and is the only one that fails on the pre-fix mapping (want rows [10..15], got
[12..17], +2 = pad_length). The symmetric round-trip cannot catch a self-consistently wrong
mapping. Run them with scripts/gtp_dcp_unit_test.sh: the file gates on world_size == 4 and
needs the TE >= 2.19 overlay, and getting either wrong skips the whole file while the
command still exits 0.

Rebase note (dev @ 0e704ed): the base now carries NVIDIA#7293, which handled the same symptom
by keeping the padded global and waiving the shape check at load time
(grant_shape_mismatch_for_gtp_padding). This commit supersedes that mechanism -- the
checkpoint is logical, so a current save never mismatches -- and keeps the grant only as a
reader for checkpoints written before the logical layout. Such a checkpoint is recoverable
only at TP=1 (data rows, then the pad tail); the logical shard is tagged gtp_tp_size and the
grant refuses TP>1, where the old grid shifted every TP rank past 0 by pad_length. NVIDIA#7293's
tests were adapted: the cross-degree round trip now asserts that no waiver is needed, the
grant-decision test writes its padded checkpoint by hand as a legacy artifact, and the
"padded GTP save -> non-GTP load" case became an exact round trip instead of a hard failure.

Signed-off-by: xuwenc <xuwenc@nvidia.com>
xuwchen added a commit to xuwchen/Megatron-LM that referenced this pull request Sep 22, 2026
…#7168)

Replay of NVIDIA/Megatron-LM PR NVIDIA#7168 (branch gtp-alignment-pad-ckpt-layout @ 5a837a9)
onto dev, squashed into one commit: the tree difference between the NVIDIA#7162 merge dcabf80
and the NVIDIA#7168 merge 5a837a9. The PR's commits beyond NVIDIA#7162, in order:

  0768d59 feat(gtp): expose weight rematerialization alignment
  019618e fix(gtp): checkpoint alignment padding in logical coordinates
  d279514 feat(egtp): checkpoint grouped gated projections in logical layout

dev-only adaptations:
  - configure_gtp_remat_from_recipe: dev (via NVIDIA#7293) already resolves the recipe default in
    resolve_gtp_pad_for_alignment; an explicit --gtp-remat-pad-for-alignment wins over it.
  - The flag is registered in _add_distributed_args, since dev derives the other GTP flags
    from the config dataclasses and has no hand-written --gtp-remat-* group.
  - dist_checkpointing/strategies/torch.py: import get_torch_version at module level; the
    uneven-sharding error message uses it outside the function that imports it locally.
  - Reconciliation with NVIDIA#7293 (on dev, not on main when NVIDIA#7168 was written): the checkpoint is
    logical, so a current save never mismatches; grant_shape_mismatch_for_gtp_padding is kept
    only as a reader for checkpoints written before the logical layout. Such a checkpoint is
    recoverable only at TP=1; logical shards carry gtp_tp_size and the grant refuses TP>1,
    where the old grid shifted every TP rank past 0 by pad_length. NVIDIA#7293's tests were adapted:
    the cross-degree round trip asserts that no waiver is needed, the grant-decision test
    writes its padded checkpoint by hand as a legacy artifact, and the "padded GTP save ->
    non-GTP load" case became an exact round trip instead of a hard failure.

Signed-off-by: xuwenc <xuwenc@nvidia.com>
xuwchen added a commit to xuwchen/Megatron-LM that referenced this pull request Sep 22, 2026
…#7168)

Replay of NVIDIA/Megatron-LM PR NVIDIA#7168 (branch gtp-alignment-pad-ckpt-layout @ 5a837a9)
onto dev, squashed into one commit: the tree difference between the NVIDIA#7162 merge dcabf80
and the NVIDIA#7168 merge 5a837a9. The PR's commits beyond NVIDIA#7162, in order:

  0768d59 feat(gtp): expose weight rematerialization alignment
  019618e fix(gtp): checkpoint alignment padding in logical coordinates
  d279514 feat(egtp): checkpoint grouped gated projections in logical layout

dev-only adaptations:
  - configure_gtp_remat_from_recipe: dev (via NVIDIA#7293) already resolves the recipe default in
    resolve_gtp_pad_for_alignment; an explicit --gtp-remat-pad-for-alignment wins over it.
  - The flag is registered in _add_distributed_args, since dev derives the other GTP flags
    from the config dataclasses and has no hand-written --gtp-remat-* group.
  - dist_checkpointing/strategies/torch.py: the uneven-sharding error message uses
    get_torch_version outside the function that imports it locally; add a local import there
    (a module-level one is circular: megatron.core.utils imports dist_checkpointing).
  - Reconciliation with NVIDIA#7293 (on dev, not on main when NVIDIA#7168 was written): the checkpoint is
    logical, so a current save never mismatches; grant_shape_mismatch_for_gtp_padding is kept
    only as a reader for checkpoints written before the logical layout. Such a checkpoint is
    recoverable only at TP=1; logical shards carry gtp_tp_size and the grant refuses TP>1,
    where the old grid shifted every TP rank past 0 by pad_length. NVIDIA#7293's tests were adapted:
    the cross-degree round trip asserts that no waiver is needed, the grant-decision test
    writes its padded checkpoint by hand as a legacy artifact, and the "padded GTP save ->
    non-GTP load" case became an exact round trip instead of a hard failure.

Signed-off-by: xuwenc <xuwenc@nvidia.com>
xuwchen added a commit to xuwchen/Megatron-LM that referenced this pull request Sep 22, 2026
…#7168)

Replay of NVIDIA/Megatron-LM PR NVIDIA#7168 (branch gtp-alignment-pad-ckpt-layout @ 5a837a9)
onto dev, squashed into one commit: the tree difference between the NVIDIA#7162 merge dcabf80
and the NVIDIA#7168 merge 5a837a9. The PR's commits beyond NVIDIA#7162, in order:

  0768d59 feat(gtp): expose weight rematerialization alignment
  019618e fix(gtp): checkpoint alignment padding in logical coordinates
  d279514 feat(egtp): checkpoint grouped gated projections in logical layout

dev-only adaptations:
  - configure_gtp_remat_from_recipe: dev (via NVIDIA#7293) already resolves the recipe default in
    resolve_gtp_pad_for_alignment; an explicit --gtp-remat-pad-for-alignment wins over it.
  - The flag is registered in _add_distributed_args, since dev derives the other GTP flags
    from the config dataclasses and has no hand-written --gtp-remat-* group.
  - dist_checkpointing/strategies/torch.py: the uneven-sharding error message uses
    get_torch_version outside the function that imports it locally; add a local import there
    (a module-level one is circular: megatron.core.utils imports dist_checkpointing).
  - Reconciliation with NVIDIA#7293 (on dev, not on main when NVIDIA#7168 was written): the checkpoint is
    logical, so a current save never mismatches; grant_shape_mismatch_for_gtp_padding is kept
    only as a reader for checkpoints written before the logical layout. Such a checkpoint is
    recoverable only at TP=1; logical shards carry gtp_tp_size and the grant refuses TP>1,
    where the old grid shifted every TP rank past 0 by pad_length. NVIDIA#7293's tests were adapted:
    the cross-degree round trip asserts that no waiver is needed, the grant-decision test
    writes its padded checkpoint by hand as a legacy artifact, and the "padded GTP save ->
    non-GTP load" case became an exact round trip instead of a hard failure.

Signed-off-by: xuwenc <xuwenc@nvidia.com>
xuwchen added a commit to xuwchen/Megatron-LM that referenced this pull request Sep 22, 2026
…#7168)

Replay of NVIDIA/Megatron-LM PR NVIDIA#7168 (branch gtp-alignment-pad-ckpt-layout @ 5a837a9)
onto dev, squashed into one commit: the tree difference between the NVIDIA#7162 merge dcabf80
and the NVIDIA#7168 merge 5a837a9. The PR's commits beyond NVIDIA#7162, in order:

  0768d59 feat(gtp): expose weight rematerialization alignment
  019618e fix(gtp): checkpoint alignment padding in logical coordinates
  d279514 feat(egtp): checkpoint grouped gated projections in logical layout

dev-only adaptations:
  - configure_gtp_remat_from_recipe: dev (via NVIDIA#7293) already resolves the recipe default in
    resolve_gtp_pad_for_alignment; an explicit --gtp-remat-pad-for-alignment wins over it.
  - The flag is registered in _add_distributed_args, since dev derives the other GTP flags
    from the config dataclasses and has no hand-written --gtp-remat-* group.
  - dist_checkpointing/strategies/torch.py: the uneven-sharding error message uses
    get_torch_version outside the function that imports it locally; add a local import there
    (a module-level one is circular: megatron.core.utils imports dist_checkpointing).
  - Reconciliation with NVIDIA#7293 (on dev, not on main when NVIDIA#7168 was written): the checkpoint is
    logical, so a current save never mismatches; grant_shape_mismatch_for_gtp_padding is kept
    only as a reader for checkpoints written before the logical layout. Such a checkpoint is
    recoverable only at TP=1; logical shards carry gtp_tp_size and the grant refuses TP>1,
    where the old grid shifted every TP rank past 0 by pad_length. NVIDIA#7293's tests were adapted:
    the cross-degree round trip asserts that no waiver is needed, the grant-decision test
    writes its padded checkpoint by hand as a legacy artifact, and the "padded GTP save ->
    non-GTP load" case became an exact round trip instead of a hard failure.

Signed-off-by: xuwenc <xuwenc@nvidia.com>
xuwchen added a commit to xuwchen/Megatron-LM that referenced this pull request Sep 22, 2026
…#7168)

Replay of NVIDIA/Megatron-LM PR NVIDIA#7168 (branch gtp-alignment-pad-ckpt-layout @ 5a837a9)
onto dev, squashed into one commit: the tree difference between the NVIDIA#7162 merge dcabf80
and the NVIDIA#7168 merge 5a837a9, applied on top of the rebased NVIDIA#7162 (23fcbe5). The PR's commits beyond NVIDIA#7162, in order:

  0768d59 feat(gtp): expose weight rematerialization alignment
  019618e fix(gtp): checkpoint alignment padding in logical coordinates
  d279514 feat(egtp): checkpoint grouped gated projections in logical layout

dev-only adaptations:
  - NVIDIA#7162 (rebased) indexes optimizer metadata once in _get_param_id_to_sharded_metadata;
    the pad-trimmed shard's gtp_pad_src backlink joins the dequantized-source hop there via
    gtp_entry_backlink, instead of the per-parameter lookup NVIDIA#7168 was written against.
  - configure_gtp_remat_from_recipe: dev (via NVIDIA#7293) already resolves the recipe default in
    resolve_gtp_pad_for_alignment; an explicit --gtp-remat-pad-for-alignment wins over it.
  - The flag is registered in _add_distributed_args, since dev derives the other GTP flags
    from the config dataclasses and has no hand-written --gtp-remat-* group.
  - dist_checkpointing/strategies/torch.py: the uneven-sharding error message uses
    get_torch_version outside the function that imports it locally; add a local import there
    (a module-level one is circular: megatron.core.utils imports dist_checkpointing).
  - Reconciliation with NVIDIA#7293 (on dev, not on main when NVIDIA#7168 was written): the checkpoint is
    logical, so a current save never mismatches; grant_shape_mismatch_for_gtp_padding is kept
    only as a reader for checkpoints written before the logical layout. Such a checkpoint is
    recoverable only at TP=1; logical shards carry gtp_tp_size and the grant refuses TP>1,
    where the old grid shifted every TP rank past 0 by pad_length. NVIDIA#7293's tests were adapted:
    the cross-degree round trip asserts that no waiver is needed, the grant-decision test
    writes its padded checkpoint by hand as a legacy artifact, and the "padded GTP save ->
    non-GTP load" case became an exact round trip instead of a hard failure.

Signed-off-by: xuwenc <xuwenc@nvidia.com>
xuwchen added a commit to xuwchen/Megatron-LM that referenced this pull request Sep 22, 2026
…#7168)

Replay of NVIDIA/Megatron-LM PR NVIDIA#7168 (branch gtp-alignment-pad-ckpt-layout @ 5a837a9)
onto dev, squashed into one commit: the tree difference between the NVIDIA#7162 merge dcabf80
and the NVIDIA#7168 merge 5a837a9, applied on top of the rebased NVIDIA#7162 (23fcbe5). The PR's commits beyond NVIDIA#7162, in order:

  0768d59 feat(gtp): expose weight rematerialization alignment
  019618e fix(gtp): checkpoint alignment padding in logical coordinates
  d279514 feat(egtp): checkpoint grouped gated projections in logical layout

dev-only adaptations:
  - NVIDIA#7162 (rebased) indexes optimizer metadata once in _get_param_id_to_sharded_metadata;
    _resolve_gtp_sharded_metadata, which this PR's tests call, is kept as a thin per-parameter
    view over that index;
    the pad-trimmed shard's gtp_pad_src backlink joins the dequantized-source hop there via
    gtp_entry_backlink, instead of the per-parameter lookup NVIDIA#7168 was written against.
  - configure_gtp_remat_from_recipe: dev (via NVIDIA#7293) already resolves the recipe default in
    resolve_gtp_pad_for_alignment; an explicit --gtp-remat-pad-for-alignment wins over it.
  - The flag is registered in _add_distributed_args, since dev derives the other GTP flags
    from the config dataclasses and has no hand-written --gtp-remat-* group.
  - dist_checkpointing/strategies/torch.py: the uneven-sharding error message uses
    get_torch_version outside the function that imports it locally; add a local import there
    (a module-level one is circular: megatron.core.utils imports dist_checkpointing).
  - Reconciliation with NVIDIA#7293 (on dev, not on main when NVIDIA#7168 was written): the checkpoint is
    logical, so a current save never mismatches; grant_shape_mismatch_for_gtp_padding is kept
    only as a reader for checkpoints written before the logical layout. Such a checkpoint is
    recoverable only at TP=1; logical shards carry gtp_tp_size and the grant refuses TP>1,
    where the old grid shifted every TP rank past 0 by pad_length. NVIDIA#7293's tests were adapted:
    the cross-degree round trip asserts that no waiver is needed, the grant-decision test
    writes its padded checkpoint by hand as a legacy artifact, and the "padded GTP save ->
    non-GTP load" case became an exact round trip instead of a hard failure.

Signed-off-by: xuwenc <xuwenc@nvidia.com>
xuwchen added a commit to xuwchen/Megatron-LM that referenced this pull request Sep 22, 2026
…#7168)

Replay of NVIDIA/Megatron-LM PR NVIDIA#7168 (branch gtp-alignment-pad-ckpt-layout @ 5a837a9)
onto dev, squashed into one commit: the tree difference between the NVIDIA#7162 merge dcabf80
and the NVIDIA#7168 merge 5a837a9, applied on top of the rebased NVIDIA#7162 (23fcbe5). The PR's commits beyond NVIDIA#7162, in order:

  0768d59 feat(gtp): expose weight rematerialization alignment
  019618e fix(gtp): checkpoint alignment padding in logical coordinates
  d279514 feat(egtp): checkpoint grouped gated projections in logical layout

dev-only adaptations:
  - NVIDIA#7162 (rebased) indexes optimizer metadata once in _get_param_id_to_sharded_metadata;
    _resolve_gtp_sharded_metadata, which this PR's tests call, is kept as a thin per-parameter
    view over that index;
    the pad-trimmed shard's gtp_pad_src backlink joins the dequantized-source hop there via
    gtp_entry_backlink, instead of the per-parameter lookup NVIDIA#7168 was written against.
  - configure_gtp_remat_from_recipe: dev (via NVIDIA#7293) already resolves the recipe default in
    resolve_gtp_pad_for_alignment; an explicit --gtp-remat-pad-for-alignment wins over it.
  - The flag is registered in _add_distributed_args, since dev derives the other GTP flags
    from the config dataclasses and has no hand-written --gtp-remat-* group.
  - dist_checkpointing/strategies/torch.py: the uneven-sharding error message uses
    get_torch_version outside the function that imports it locally; add a local import there
    (a module-level one is circular: megatron.core.utils imports dist_checkpointing).
  - Reconciliation with NVIDIA#7293 (on dev, not on main when NVIDIA#7168 was written): the checkpoint is
    logical, so a current save never mismatches; grant_shape_mismatch_for_gtp_padding is kept
    only as a reader for checkpoints written before the logical layout. Such a checkpoint is
    recoverable only at TP=1; logical shards carry gtp_tp_size and the grant refuses TP>1,
    where the old grid shifted every TP rank past 0 by pad_length. NVIDIA#7293's tests were adapted:
    the cross-degree round trip asserts that no waiver is needed, the grant-decision test
    writes its padded checkpoint by hand as a legacy artifact, and the "padded GTP save ->
    non-GTP load" case became an exact round trip instead of a hard failure.

Signed-off-by: xuwenc <xuwenc@nvidia.com>
xuwchen pushed a commit to xuwchen/Megatron-LM that referenced this pull request Oct 10, 2026
…7293)

Signed-off-by: Shiqing Fan <shiqingf@nvidia.com>
(cherry picked from commit 8349ade)
Signed-off-by: xuwenc <xuwenc@nvidia.com>

This branch was previously deployed

2 inactive deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Approved All necessary approvals have been made complexity: low nemotron

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feat] GTP+DCP

7 participants