Skip to content
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
4692f0c
apply all changes from m4 dist ckpt update
yaoyu-33 Nov 5, 2025
f38a3bf
pass tp_group param
dimapihtar Nov 6, 2025
092b397
fix tp_group usage
dimapihtar Nov 6, 2025
3677324
fix tp_group usage
dimapihtar Nov 6, 2025
2505e40
remove debug assertions
dimapihtar Nov 6, 2025
2aa92c5
fix style
dimapihtar Nov 6, 2025
27ad0fa
pass tp_param to state_dict
dimapihtar Nov 6, 2025
bf5052d
add tp_group to state_dict
dimapihtar Nov 6, 2025
47a787a
pass tp_group param to sharded_state_dict
dimapihtar Nov 6, 2025
c011b28
pass tp_group to sharded_state_dict
dimapihtar Nov 6, 2025
f6aab54
pass tp_group to sharded_state_dict
dimapihtar Nov 6, 2025
1927f96
fix training/checkpointing
yaoyu-33 Nov 6, 2025
32f0bd1
add warning for additional non-used kwargs
yaoyu-33 Nov 6, 2025
ddd3fca
update fallback logic
yaoyu-33 Nov 6, 2025
8808957
lint
yaoyu-33 Nov 6, 2025
7d92f3c
fix dp cp bug
yaoyu-33 Nov 6, 2025
bb47881
lint
yaoyu-33 Nov 6, 2025
d479753
fix gated delta net's sharded state dict
yaoyu-33 Nov 6, 2025
e4efd2c
remove tp_group arg from sharded_state_dict
dimapihtar Nov 6, 2025
4ebb3ab
set self.tp_group
dimapihtar Nov 6, 2025
2ec2d18
pass tp_group & pp_group to get_rng_state
dimapihtar Nov 7, 2025
0880e9c
minor fix
dimapihtar Nov 7, 2025
df31e36
remove extra tp_group arg
dimapihtar Nov 7, 2025
029bba7
remove extra tp_group arg
dimapihtar Nov 7, 2025
cf7b543
fix code style
dimapihtar Nov 7, 2025
656b91c
fix code style
dimapihtar Nov 7, 2025
672c5ad
set te_group properly
dimapihtar Nov 7, 2025
fcb950a
fix tp_group fallback
yaoyu-33 Nov 7, 2025
c67d12e
fix bug
yaoyu-33 Nov 10, 2025
05c2d8a
Merge branch 'dev' into yuya/m4_dist_ckpt_dev
yaoyu-33 Nov 11, 2025
e1da770
Merge branch 'dev' into yuya/m4_dist_ckpt_dev
yaoyu-33 Nov 11, 2025
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
54 changes: 48 additions & 6 deletions megatron/core/extensions/transformer_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
from megatron.core.transformer.mlp import MLP
from megatron.core.transformer.transformer_config import TransformerConfig
from megatron.core.transformer.utils import (
ensure_metadata_has_dp_cp_group,
is_layer_window_attention,
make_sharded_tensors_for_checkpoint,
)
Expand Down Expand Up @@ -420,6 +421,9 @@ def __init__(
# duplicated across TP ranks
setattr(param, "sequence_parallel", self.config.sequence_parallel)

tp_group = get_tensor_model_parallel_group_if_none(tp_group, is_expert=is_expert)
self._tp_group = tp_group

def forward(self, x):
"""Forward."""
_is_first_microbatch = (
Expand All @@ -444,7 +448,14 @@ def sharded_state_dict(self, prefix="", sharded_offsets=(), metadata=None):
self.parallel_mode is None
), "TELinear sharded_state_dict can only be used with duplicated parallel mode"
state_dict = self.state_dict(prefix="", keep_vars=True)
return make_sharded_tensors_for_checkpoint(state_dict, prefix, None, sharded_offsets)
return make_sharded_tensors_for_checkpoint(
state_dict,
prefix,
None,
sharded_offsets,
tp_group=self._tp_group,
dp_cp_group=metadata["dp_cp_group"],
)

def backward_dw(self):
"""Compute weight gradients during the backward pass if delay_wgrad_compute is enabled."""
Expand Down Expand Up @@ -492,6 +503,7 @@ def __init__(

# TODO: For backward compatibility, remove in v0.15.
tp_group = get_tensor_model_parallel_group_if_none(tp_group, is_expert=is_expert)
self._tp_group = tp_group

# TE returns a zero length Tensor when bias=False and
# return_bias=True, but we prefer None. So in that case we
Expand Down Expand Up @@ -625,9 +637,15 @@ def forward(self, x):

def sharded_state_dict(self, prefix="", sharded_offsets=(), metadata=None):
"""Sharding along axis 0, bias sharded"""
metadata = ensure_metadata_has_dp_cp_group(metadata)
state_dict = self.state_dict(prefix="", keep_vars=True)
return make_sharded_tensors_for_checkpoint(
state_dict, prefix, {"weight": 0, "bias": 0}, sharded_offsets
state_dict,
prefix,
{"weight": 0, "bias": 0},
sharded_offsets,
tp_group=self._tp_group,
dp_cp_group=metadata["dp_cp_group"],
)

def __repr__(self):
Expand Down Expand Up @@ -670,6 +688,7 @@ def __init__(
if gather_output:
raise ValueError("Transformer Engine linear layers do not support gather_output = True")
tp_group = get_tensor_model_parallel_group_if_none(tp_group, is_expert=is_expert)
self._tp_group = tp_group
world_size = get_pg_size(tp_group)
rank = get_pg_rank(tp_group)

Expand Down Expand Up @@ -720,7 +739,12 @@ def sharded_state_dict(self, prefix="", sharded_offsets=(), metadata=None):
"""Sharding along axis 0, bias sharded"""
state_dict = self.state_dict(prefix="", keep_vars=True)
return make_sharded_tensors_for_checkpoint(
state_dict, prefix, {"weight": 0, "bias": 0}, sharded_offsets
state_dict,
prefix,
{"weight": 0, "bias": 0},
sharded_offsets,
tp_group=self._tp_group,
dp_cp_group=metadata["dp_cp_group"],
)

def __repr__(self):
Expand Down Expand Up @@ -764,6 +788,7 @@ def __init__(
"Transformer Engine linear layers do not support input_is_parallel = False"
)
tp_group = get_tensor_model_parallel_group_if_none(tp_group, is_expert=is_expert)
self._tp_group = tp_group

super().__init__(
input_size=input_size,
Expand Down Expand Up @@ -814,7 +839,12 @@ def sharded_state_dict(self, prefix="", sharded_offsets=(), metadata=None):
"""Sharding along axis 1, bias not sharded"""
state_dict = self.state_dict(prefix="", keep_vars=True)
return make_sharded_tensors_for_checkpoint(
state_dict, prefix, {"weight": 1}, sharded_offsets
state_dict,
prefix,
{"weight": 1},
sharded_offsets,
tp_group=self._tp_group,
dp_cp_group=metadata["dp_cp_group"],
)

def __repr__(self):
Expand Down Expand Up @@ -901,6 +931,7 @@ def __init__(
assert hasattr(
pg_collection, "hcp"
), "TEDotProductAttention pg_collection must have hierarchical cp pg"
self._tp_group = pg_collection.tp

if is_te_min_version("0.10.0"):
extra_kwargs["attention_type"] = attention_type
Expand Down Expand Up @@ -1078,7 +1109,12 @@ def sharded_state_dict(
else:
state_dict = {}
return make_sharded_tensors_for_checkpoint(
state_dict, prefix, {'softmax_offset': 0}, sharded_offsets
state_dict,
prefix,
{'softmax_offset': 0},
sharded_offsets,
tp_group=self._tp_group,
dp_cp_group=metadata["dp_cp_group"],
)


Expand Down Expand Up @@ -1138,6 +1174,7 @@ def __init__(
# The comms between TP and EP group is explicitly handled by MoE token dispatcher.
# So we disable comms by making TE agnostic of model parallel.
tp_group = get_tensor_model_parallel_group_if_none(tp_group, is_expert=is_expert)
self._tp_group = tp_group
tp_size = get_pg_size(tp_group)

self.explicit_expert_comm = is_expert and (tp_size > 1 or self.expert_parallel)
Expand Down Expand Up @@ -1372,7 +1409,12 @@ def _sharded_state_dict_grouped(
(ep_axis, global_expert_idx, num_global_experts),
)
sub_sd = make_sharded_tensors_for_checkpoint(
state_dict, '', tp_axis_map, new_sharded_offsets
state_dict,
'',
tp_axis_map,
new_sharded_offsets,
tp_group=self._tp_group,
dp_cp_group=metadata["dp_cp_group"],
)
# Remove expert layers indexing from sharded keys
replace_prefix_for_sharding(sub_sd, f"{gemm_idx}.", expert_prefix)
Expand Down
4 changes: 3 additions & 1 deletion megatron/core/models/bert/bert_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from megatron.core.models.common.embeddings.language_model_embedding import LanguageModelEmbedding
from megatron.core.models.common.embeddings.rotary_pos_embedding import RotaryEmbedding
from megatron.core.models.common.language_module.language_module import LanguageModule
from megatron.core.process_groups_config import ProcessGroupCollection
from megatron.core.transformer.dot_product_attention import (
DotProductAttention as MCoreDotProductAttention,
)
Expand Down Expand Up @@ -73,9 +74,10 @@ def __init__(
seq_len_interpolation_factor: Optional[float] = None,
add_binary_head=True,
return_embeddings=False,
pg_collection: Optional[ProcessGroupCollection] = None,
vp_stage: Optional[int] = None,
):
super(BertModel, self).__init__(config=config)
super(BertModel, self).__init__(config=config, pg_collection=pg_collection)

if has_config_logger_enabled(config):
log_config_to_disk(config, locals(), prefix=type(self).__name__)
Expand Down
19 changes: 17 additions & 2 deletions megatron/core/models/common/language_module/language_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@
from megatron.core.transformer.enums import AttnBackend
from megatron.core.transformer.module import MegatronModule
from megatron.core.transformer.transformer_config import TransformerConfig
from megatron.core.utils import is_te_min_version, make_tp_sharded_tensor_for_checkpoint
from megatron.core.transformer.utils import ensure_metadata_has_dp_cp_group
from megatron.core.utils import (
get_tensor_model_parallel_group_if_none,
is_te_min_version,
make_tp_sharded_tensor_for_checkpoint,
)


class LanguageModule(MegatronModule):
Expand All @@ -44,6 +49,7 @@ def __init__(
pg_collection = ProcessGroupCollection.use_mpu_process_groups()
self.pg_collection = pg_collection
self.cp_group = pg_collection.cp
self.tp_group = get_tensor_model_parallel_group_if_none(pg_collection.tp)
self.pp_group = pg_collection.pp
assert hasattr(self.pg_collection, 'embd'), (
"pg_collection must have a embd. In previous version, it used default "
Expand Down Expand Up @@ -277,6 +283,10 @@ def sharded_state_dict(
ShardedStateDict: sharded state dict for the LanguageModel
"""
assert not sharded_offsets, "Unexpected sharded offsets"

# Guard for cases metadata is not provided
metadata = ensure_metadata_has_dp_cp_group(metadata)

sharded_state_dict = super().sharded_state_dict(prefix, sharded_offsets, metadata)

first_stage_word_emb_key = f'{prefix}embedding.word_embeddings.weight'
Expand All @@ -285,7 +295,7 @@ def sharded_state_dict(

if self.share_embeddings_and_output_weights:
self.tie_embeddings_and_output_weights_state_dict(
sharded_state_dict, output_layer_weight_key, first_stage_word_emb_key
sharded_state_dict, output_layer_weight_key, first_stage_word_emb_key, metadata
)
elif self.post_process:
# Make sure the output layer follows the embeddings padding logic
Expand All @@ -302,6 +312,7 @@ def tie_embeddings_and_output_weights_state_dict(
sharded_state_dict: ShardedStateDict,
output_layer_weight_key: str,
first_stage_word_emb_key: str,
metadata: Optional[dict] = None,
) -> None:
"""Ties the embedding and output weights in a given sharded state dict.

Expand All @@ -311,9 +322,11 @@ def tie_embeddings_and_output_weights_state_dict(
This entry will be replaced with a tied version
first_stage_word_emb_key (str): this must be the same as the
ShardedTensor.key of the first stage word embeddings.
metadata (Optional[Dict]): metadata controlling sharded state dict creation.

Returns: None, acts in-place
"""
metadata = ensure_metadata_has_dp_cp_group(metadata)
if not self.post_process:
# No output layer
assert output_layer_weight_key not in sharded_state_dict, sharded_state_dict.keys()
Expand Down Expand Up @@ -346,4 +359,6 @@ def tie_embeddings_and_output_weights_state_dict(
key=first_stage_word_emb_key,
replica_id=last_stage_word_emb_replica_id,
allow_shape_mismatch=True,
tp_group=self.tp_group,
dp_cp_group=metadata['dp_cp_group'],
)
8 changes: 7 additions & 1 deletion megatron/core/models/gpt/gpt_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,12 @@ def sharded_state_dict(
if self.mtp_process and not self.pre_process:
emb_weight_key = f'{prefix}embedding.word_embeddings.weight'
emb_weight = self.embedding.word_embeddings.weight
tie_word_embeddings_state_dict(sharded_state_dict, emb_weight, emb_weight_key)
tie_word_embeddings_state_dict(
sharded_state_dict,
emb_weight,
emb_weight_key,
tp_group=self.tp_group,
dp_cp_group=metadata['dp_cp_group'],
)

return sharded_state_dict
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def __init__(
pin_cpu_grads: bool = True,
pin_cpu_params: bool = True,
overlap_cpu_optimizer_d2h_h2d: bool = True,
**kwargs
**kwargs,
):
super(HybridDeviceOptimizer, self).__init__(
params,
Expand Down
12 changes: 10 additions & 2 deletions megatron/core/post_training/modelopt/layers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.

import logging
from typing import Callable, List, Optional

import torch
Expand All @@ -10,6 +11,8 @@
from megatron.core.transformer.transformer_layer import TransformerLayer
from megatron.core.transformer.utils import make_sharded_tensors_for_checkpoint

logger = logging.getLogger(__name__)

try:
import transformer_engine as te

Expand Down Expand Up @@ -116,6 +119,7 @@ def __init__(
tp_group: Optional[torch.distributed.ProcessGroup] = None,
):
self.config = config
self.tp_group = tp_group

self._return_bias = skip_bias_add and bias

Expand Down Expand Up @@ -153,7 +157,11 @@ def sharded_state_dict(self, prefix="", sharded_offsets=(), metadata=None):
if v.ndim == 0:
state_dict[k] = v.view(1)
sharded_state_dict = make_sharded_tensors_for_checkpoint(
state_dict, prefix, sharded_offsets=sharded_offsets
state_dict,
prefix,
sharded_offsets=sharded_offsets,
tp_group=self.tp_group,
dp_cp_group=metadata['dp_cp_group'],
)
return sharded_state_dict

Expand Down Expand Up @@ -229,7 +237,7 @@ def _report_quantize_tensor_info(self):
if not isinstance(v, torch.Tensor):
continue
original_dtype, original_shape = self._original_tensor_info.get(k, ("-", "-"))
print(
logger.info(
"{:<64} {:<16} {:<32} {:<16} {:<32}".format(
k, original_dtype, original_shape, str(v.dtype), str(v.shape)
)
Expand Down
18 changes: 15 additions & 3 deletions megatron/core/ssm/gated_delta_net.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from megatron.core.transformer.module import MegatronModule
from megatron.core.transformer.spec_utils import ModuleSpec, build_module
from megatron.core.transformer.utils import (
ensure_metadata_has_dp_cp_group,
make_sharded_tensors_for_checkpoint,
sharded_state_dict_default,
)
Expand Down Expand Up @@ -411,8 +412,11 @@ def _torch_compiled_gated_norm(self, x, gate):
y = y.to(x_dtype)
return y

def sharded_state_dict(self, prefix="", sharded_offsets=(), metadata=None):
def sharded_state_dict(self, prefix="", sharded_offsets=(), metadata=None, tp_group=None):
"""Provide a sharded state dictionary for distributed checkpointing."""
# Guard for cases metadata is not provided
metadata = ensure_metadata_has_dp_cp_group(metadata)

sharded_state_dict = {}
# Parameters
self._save_to_state_dict(sharded_state_dict, "", keep_vars=True)
Expand All @@ -424,8 +428,11 @@ def sharded_state_dict(self, prefix="", sharded_offsets=(), metadata=None):
"dt_bias": 0,
}, # parameters sharded across TP
sharded_offsets=sharded_offsets,
tp_group=(tp_group if tp_group is not None else self.pg_collection.tp),
dp_cp_group=metadata['dp_cp_group'],
)
# Submodules
tp_group = tp_group if tp_group is not None else self.pg_collection.tp
for name, module in self.named_children():
if name == "conv1d":
# Add TP sharding for Conv1d
Expand All @@ -434,11 +441,16 @@ def sharded_state_dict(self, prefix="", sharded_offsets=(), metadata=None):
if self.conv_bias:
tp_sharding_map[f"bias"] = 0
module_sharded_sd = make_sharded_tensors_for_checkpoint(
module_sd, f"{prefix}{name}.", tp_sharding_map, sharded_offsets
module_sd,
f"{prefix}{name}.",
tp_sharding_map,
sharded_offsets,
tp_group=tp_group,
dp_cp_group=metadata['dp_cp_group'],
)
else:
module_sharded_sd = sharded_state_dict_default(
module, f"{prefix}{name}.", sharded_offsets, metadata
module, f"{prefix}{name}.", sharded_offsets, metadata, tp_group=tp_group
)

sharded_state_dict.update(module_sharded_sd)
Expand Down
7 changes: 6 additions & 1 deletion megatron/core/ssm/mamba_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ def __init__(
assert pg_collection is not None, "pg_collection must be provided for MambaStack"

self.pp_group = pg_collection.pp
self.tp_group = pg_collection.tp

# Required for pipeline parallel schedules
self.input_tensor = None
Expand Down Expand Up @@ -417,7 +418,11 @@ def sharded_state_dict(
if not module is self.layers:
sharded_state_dict.update(
sharded_state_dict_default(
module, f'{prefix}{name}.', sharded_offsets, metadata
module,
f'{prefix}{name}.',
sharded_offsets,
metadata,
tp_group=self.tp_group,
)
)

Expand Down
Loading
Loading