Skip to content

Draft [2/N] Megatron FSDP: Introduce Megatron-FSDP2 with per-module fully_shard() API - #4849

Draft
shjwudp wants to merge 68 commits into
NVIDIA:mainfrom
shjwudp:mfsdp_refactor_main_stage2
Draft

Draft [2/N] Megatron FSDP: Introduce Megatron-FSDP2 with per-module fully_shard() API#4849
shjwudp wants to merge 68 commits into
NVIDIA:mainfrom
shjwudp:mfsdp_refactor_main_stage2

Conversation

@shjwudp

@shjwudp shjwudp commented May 18, 2026

Copy link
Copy Markdown
Contributor

What does this PR do ?

Part-1 link: #4435

Summary

Introduce Megatron-FSDP2 — a refactored per-module sharding implementation (fully_shard_v2) with FSDP2-compatible API, communication-compute overlap, activation recompute support, and a pooled memory allocator for Megatron Core.

Key Features

  • fully_shard() API: FSDP2-compatible wrapping interface that converts modules to FSDPModule dynamically, groups parameters into ParameterGroups with flat DataParallelBuffers, and installs forward/backward hooks for the unshard → forward → reshard → backward → reduce lifecycle.
  • Communication-compute overlap (two streams):
    • Unshard prefetch (ag_stream): all-gathers parameters for the next module while the current module computes forward.
    • Async reduce-grad (rs_stream): reduce-scatters gradients while later modules compute backward. Sliding drain rule keeps ≤ 2 gradient buffers live at any time.
  • Activation recompute support: Derived backward_module tracking + persistent unshard_done_events prevent redundant all-gathers and premature resharding during gradient checkpointing recompute passes.
  • TracePoolAllocator: Three-phase (trace → plan → optimized) pooled memory allocator using greedy left-edge interval coloring. Eliminates per-call torch.empty overhead with a static pool replayed across micro-batches.
  • Four sharding strategies: no_shard, optim (ZeRO-1), optim_grads (ZeRO-2), optim_grads_params (ZeRO-3), with uneven DTensor and distributed checkpoint support.

Files Changed (27 files, +5,014 / −9)

Area Files Description
v2/ package __init__.py, fully_shard.py, fsdp_module.py, hooks.py, param_group.py, dp_buffer.py, allocator.py, utils.py, mixed_precision.py, design.md, README.md Core implementation and design docs
Integration mcore_fsdp_adapter.py, src/megatron_fsdp/__init__.py, megatron_fsdp.py, distributed_data_parallel_config.py Adapter supporting legacy and v2 paths
Example examples/megatron_fsdp/fsdp_toy.py Standalone training example
Tests tests/.../v2/test_allocator.py, test_param_group.py, test_mcore_fully_shard_api.py, test_checkpoint_online_convert.py Unit and integration tests

Experimental Results — Per-Module Sharding Rewrite

Verification was performed comparing the refactored implementation against the baseline.

Metric Baseline Megatron-FSDP2 Change
Performance (TFLOPs) 496.78 513.90 Slight improvement, within expected fluctuation range
Memory (GB) 48.30 47.15 Memory usage reduction
Convergence Comparable to baseline; observed difference ≈ 0.01, likely attributable to changes in parameter grouping
The refactored implementation achieves performance parity or better, modest memory savings, and convergence comparable to the baseline.

W&B link: https://wandb.ai/nvidia/megatron-fsdp/reports/M-FSDP-Rewrite-Convergence-Test-llama3-8b---VmlldzoxNjgzNTg3OQ

⚠️ For major changes (either in lines of code or in its impact), please make sure to first share a design doc with the team. If you're unsure what's the best way to do so, contact the @mcore-oncall.

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:

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 the @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.

For MRs into `dev` branch The proposed review process for `dev` branch is under active discussion.

MRs are mergable after one approval by either eharper@nvidia.com or zijiey@nvidia.com.

Autumn1998 and others added 30 commits April 21, 2026 16:07
Preserve the Megatron-FSDP fully_shard optimizer contract by wiring main-gradient access into the DTensor-backed path and copying optimizer-updated main weights back into model-weight buffers after optimizer.step().

This squash also folds in the review fixes needed for the debug branch changes:
- allocate gradient reduce buffers on demand during reduce-scatter
- align ParameterGroup.reduce_grad with the fully_shard caller
- propagate NaN-check flags to every FSDP module
- validate unsharded parameters across all parameter groups
- drop leftover post-backward debug code and guard optional grad checks

Documentation for this merge is captured in this commit message per request.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Move fully_shard_v2.py, param_group.py, dp_buffer.py, allocator.py to
  megatron/core/distributed/fsdp/src/megatron_fsdp/fully_shard_rewrite/
- Reference uneven_dtensor from parent module instead of copying
- Fix test imports in test_param_group.py and test_allocator.py
- Add __init__.py with exports
- Add README.md documentation
- Rename fully_shard_v2 to fully_shard_rewrite in fsdp_toy.py and adapter
- Add extensive docstrings to fully_shard.py and param_group.py
- Fix ParameterGroup call: pass mesh=mesh instead of params[0]._dtype
…_rewrite

- Add _FSDPRootContext with dedicated CUDA streams for all-gather and
  reduce-scatter to enable computation-communication overlap
- Implement unshard prefetch that pipelines parameter loading to the
  next module in forward/backward execution order
- Enable async reduce-scatter overlapped with backward pass
- Plumb mixed precision policy (main_params_dtype, main_grads_dtype)
  from adapter layer through to ParameterGroup gradient buffers
- Simplify dp_buffer.reduce_grad to always accumulate reduced shards
  synchronously into persistent buffer for gradient accumulation
- Fix no_sync property (nullcontext() -> nullcontext)
- Add --use-fsdp-fully-shard-api training argument
Fix multiple correctness bugs in the unshard-prefetch and reduce-scatter overlap
implementation for fully_shard_rewrite:

- Fix `_init_fsdp_state` to pass `enable_unshard_prefetch`/`enable_async_reduce_grad`
  to child FSDP modules (was calling without required args, causing TypeError).
- Fix `reduce_grad_buckets` from positional list to `Dict[id(module)]` mapping, fixing
  incorrect bucket index lookup that used `forward_order.index(self)`.
- Fix async reduce_grad path: remove premature `event.wait()` + `release_grad_buffer()`
  after recording event, replacing with deferred sliding drain (2-module lag).
- Fix `_post_backward_final_callback` to skip modules already handled via
  `post_backward_issued` flag and drain remaining buckets correctly.
- Fix `_scale_gradients` to operate on `dist_grad._local_tensor` instead of
  `main_grad_buffer.data`.
- Fix `_copy_main_weights_to_model_weights` to zero main grads afterward to
  avoid stale gradients.
- Fix `param_group.py`: include `"optim"` in `shard_grads` condition, fix
  gradient buffer dtype selection, fix `_init_dist_params` for `no_shard` and
  missing buffers, fix `release_grad_buffer` to drop `main_grad` views (prevent
  memory leak with TE gradient-accumulation-fusion).
- Fix `allocator.py`: change `param_group_id` from `int` to `ParamGroupIdx`,
  fix `free` to delete bucket after freeing storage, add `_free_storage` safety
  helper, remove `_resize_` in `allocate` that incorrectly truncated reused buckets.
- Add `grad_added_to_main_grad` flag support for TE gradient-accumulation-fusion.
- Wire `enable_unshard_prefetch`/`enable_async_reduce_grad` config flags through
  `mcore_fsdp_adapter.py`.
- Extract `ParamGroupIdx`, `RegisterFSDPBackwardFunction`, `_replace_module_parameter`
  into new `utils.py`.
- Add comprehensive `design_overlap.md` documenting the full overlap architecture.
…lap path

Bug fixes:

- Add stream.wait_stream(current_stream) in unshard() before launching
  async all-gather on ag_stream, ensuring main-stream writes to parameter
  data complete before the NCCL all-gather reads them.  This was the root
  cause of convergence divergence in the computation-communication overlap
  path where stale or partially-written parameter shards were gathered.
- Fix shard_grads in _init_buffers() to exclude "optim" strategy: ZeRO-1
  should shard optimizer states only, not distribute the gradient buffer.

New:

- Implement stop_communication() for the fully_shard path (was raising
  NotImplementedError): waits on ag_stream and rs_stream to bring all
  communication into the main CUDA stream before the optimizer step.
- Add NVTX ranges (MFSDP unshard/reshard/reduce_grad) for profiling.

Memory:

- Free original full-parameter storage via _free_storage() after copying
  data into weight buffers during _init_buffers(), reducing peak memory.

Docs:

- Rename design_overlap.md → design.md and expand to cover stream
  barriers, NVTX profiling, memory optimization, stop_communication().
- Fix README.md: correct file tree, sharding strategy table (optim row
  was incorrectly marked as sharding weights/grads), add ZeRO analogues.
- Remove stale FIXME comment, polish code comments and docstrings.
This patchset resolves multiple convergence-critical correctness bugs
discovered during Llama3-8B convergence testing with the rewrite
(`fully_shard_rewrite`) Megatron-FSDP path, and adds diagnostic
tooling to prevent future regressions.

## Correctness Fixes (Convergence Critical)

### dist_param attribute propagation (mcore_fsdp_adapter.py)
Copy `is_embedding_parameter`, `is_embedding_or_output_parameter`,
`sequence_parallel`, `partition_dim`, `partition_stride`,
`_tensor_parallel_mode`, and other metadata from original parameters
to the FSDP DTensor dist_params.  The optimizer param-group builder
relies on these attributes; missing them causes parameters to be
assigned to wrong optimizer groups (wrong weight-decay / LR
multipliers), leading directly to convergence divergence.

### Zero-numel DTensor grads cause silent FusedAdam corruption (param_group.py)
When a parameter's local shard has numel=0 on a DP rank, creating a
DTensor with an empty local tensor and passing it to fused
multi-tensor optimizers (e.g. TE FusedAdam) silently corrupts updates
for neighboring non-empty parameters in the same group.  The optimizer
runs without error — only convergence divergence reveals the bug.
Fix: skip DTensor creation when `grad_data.numel() == 0`, record
`None` instead.  Also guard `_scale_gradients` with `dist_grad is None`.
Documented in design.md § Pitfall and README § Gotchas.

### FusedAdam master_weights always disabled (optimizer/__init__.py)
Remove the `use_precision_aware_optimizer` gate; FusedAdam's internal
master_weights are redundant with Megatron-FSDP's main-weight buffers
and cause correctness issues with 1D DTensor parameters.  Always
disable them.

### Fragment bin-packing in dp_buffer (dp_buffer.py)
Replace ad-hoc leftover-fragment placement with a proper bin-packing
algorithm that fills chunk_size_factor-sized alignment grids.  This
fixes buffer layout edge cases where misaligned fragments caused
overlaps or out-of-bounds accesses.

### Reduce-scatter output aliasing (dp_buffer.py)
Use a separate output tensor in `reduce_scatter_tensor` instead of
slicing the full input buffer directly.  Aliasing the input can cause
the collective to overwrite its own input, silently corrupting
gradients.

### Inverted async reduce wait condition (fully_shard.py)
`_wait_for_previous_async_reduce_grad` returned early when
`enable_async_reduce_grad=True`, opposite of the intended behavior
(the legacy code waited only in the async path).  This prevented
waiting for in-flight reduce events, causing premature grad-buffer
release.  Fix: invert condition to `if not ctx.enable_async_reduce_grad`.

### Meta-device init DP-rank parameter sync (fully_shard.py)
After materializing meta parameters with `reset_parameters()`, each DP
rank may have different random values (due to divergent RNG states).
Broadcast full parameters from DP rank 0 within the DP-CP mesh
*before* FSDP param groups create DTensors, so every rank's shard is
a correct slice of the same full parameter.  Also fix `broadcast_params`
in adapter: changed from `not_implemented_op` to `noop` (the training
loop calls it under `--data-parallel-random-init`; the init-time
broadcast above covers the sync).

### Meta-device init RNG tracker forking (fully_shard.py)
The legacy path wraps `reset_parameters()` with `ResetParametersContext`
which forks the model-parallel RNG tracker for non-TE modules when
TE >= 0.9.0 is present.  Without this fork, TP ranks consume different
RNG sequences during init, producing inconsistent values for
TP-duplicated parameters (LayerNorm weights, biases).  Add equivalent
forking in `_materialize_meta_module`.

### post_backward_issued guard (fully_shard.py)
Use `getattr(module, "post_backward_issued", False)` to avoid
AttributeError when the attribute is missing.

## New Features

### Gradient scaling factor & ReduceOp (fully_shard.py, dp_buffer.py,
mcore_fsdp_adapter.py)
Support `calculate_per_token_loss`, `average_in_collective`, and
default (1/dp_world_size) scaling.  Use `_make_nccl_premul_sum` for
FP32/FP16 and manual pre-scaling for BF16.

### Stream synchronization (mcore_fsdp_adapter.py)
Implement `finish_grad_sync` and `synchronize_param_gather` for the
rewrite path (formerly no-ops), synchronizing `rs_stream` and
`ag_stream` with the main CUDA stream.

### grad_added_to_main_grad handling (fully_shard.py)
When TE gradient-accumulation-fusion writes directly to `main_grad`,
discard the dummy `.grad` tensor instead of zeroing/overwriting
`main_grad`.

## Debug / Diagnostic Tooling

### per-param norm logging (fully_shard.py, megatron_fsdp.py,
training.py, config)
New `--log-per-param-norm` config flag logs per-parameter L2 norms
for both params and grads, globally reduced across DP ranks.

### Parameter group diagnostics (fully_shard.py)
`_log_parameter_groups()` prints compact buffer-layout summaries
with memory metrics.  `check_all_fsdp_buffers()` validates no
local-slice overlaps in any FSDP buffer at runtime.

### Logging callbacks wired to adapter (mcore_fsdp_adapter.py)
`log_per_param_norms`, `compute_per_param_norms`, `log_parameter_groups`
are now accessible from the `FullyShardedDataParallel` wrapper.

## Documentation
- design.md: new "Pitfall: Zero-Numel Gradient Shards" section
- README.md: new "Gotchas / Pitfalls" section
refactor(mfsdp): simplify mixed precision policy defaults
…ergence fixes

Squashed from mfsdp_refactor_main_ep (12 commits up to 00adbef):

- Activation recompute / gradient checkpointing:
  Add backward-phase coordination via _FSDPRootContext with derived
  backward_module tracking and persistent unshard_done_events. Prevents
  redundant all-gathers and premature resharding during recompute.
  (930843c, ca847c1)

- TracePoolAllocator:
  Three-phase bucket allocator (trace/plan/optimized) using greedy
  left-edge interval coloring. Eliminates per-call torch.empty overhead
  by pre-allocating a static pool with cursor-based replay across
  micro-batches. (5410f39, a21041b, e8d434e)

- Bucket allocators for weight/grad buffers:
  StorageFreeingBucketAllocator and TemporaryBucketAllocator manage
  pooled memory for unsharded parameter and gradient buffers.
  (5032b6c)

- Convergence fixes:
  Fix zero-numel gradient shard handling to prevent fused optimizer
  corruption. Add loss detach for E2E correctness. Fix ND parallel
  setting bug in unit tests. (8cfffdb, adaf543, 4ffa3d6, a91e3da)

- Docs: design.md, gap analysis, and allocator documentation. (00adbef, dee8bd4)
- Add Apache 2.0 Copyright headers to 10 new files, update year to 2026
- Replace print() with logging: logger.warning for validation,
  logger.info for param/grad norms, logger.debug for trace dumps
- Add missing docstrings: Bucket, phase, ParamGroupIdx,
  make_uneven_dtensor, get_state_dict
- Remove unused Optional import from allocator.py
- Remove misleading # TODO from fully_shard.py mp_policy param
- Revert megatron/core/optimizer/__init__.py
- isort clean
Autumn1998 and others added 9 commits May 19, 2026 00:41
## Overview
Adds full checkpoint save/load support for Megatron FSDP v2
(use_megatron_fsdp_v2, formerly use_fully_shard_api), including
model + optimizer state, cross-setting resharding, and online
conversion from MFSDP v1 and ND-parallel (torch_dist) formats.

## Core changes

### checkpoint.py — Path A save/load and post-processing
- _apply_mcore_postprocess: unified post-processing (FP8 cleanup,
  SwiGLU/GDN split, expert key remapping) on model state dict;
  optimizer keys kept canonical for DistributedOptimizer compat
- _build_dtensor_optim_sd: wraps FusedAdam plain-tensor states as
  DTensors using model param mesh/placements (required for DCP)
- _propagate_chunk_metadata_to_state_dict: copies chunk metadata
  from model params to state dict DTensors (zero collectives)
- _split_dtensor_v2: unified split supporting both DTensor and
  plain tensor inputs; uses chunk metadata for uneven sharding
- _get_fsdp_slice_from_dtensor: derives FSDP slice from
  __create_chunk_list__ metadata (handles uneven sharding)
- MegatronFSDPStateful: handles optimizer=None gracefully

### uneven_dtensor.py — chunk metadata and split utilities
- split_dtensor: general DTensor split with locally-derived
  chunk metadata (one collective upfront, zero per split)
- compute_split_offsets_and_sizes, copy_chunk_metadata,
  get_fsdp_slice_from_uneven_dtensor: moved from checkpoint.py
- make_uneven_dtensor: accepts chunk_metadata/copy_chunk_meta_from
  params; handles 0-numel edge case

### checkpointing.py — training loop integration
- _is_megatron_fsdp_v2: detects v2 models (FSDPModule or
  FullyShardedDataParallel wrapper)
- preprocess_fsdp_dtensor_state_dict: v2 path delegates to
  _apply_mcore_postprocess; v1 path preserved for baseline
- load_checkpoint: auto-detect checkpoint format for
  fsdp_dtensor/torch_dist before building skeleton
- _load_torch_dist_into_megatron_fsdp_v2: loads torch_dist
  checkpoint (model weights) into v2 skeleton via key mapping
- optimizer state wrapping deferred to caller (save_checkpoint /
  _load_base_checkpoint after raw_optimizer_state_dict capture)
- opt_param_scheduler preserved in checkpoint metadata

### distrib_optimizer.py — expert key handling
- _param_name: skips handle_experts_in_state_dict for v2
  (keeps global expert indices; applied later in post-process)

### arguments.py — rename and auto-set
- --use-fully-shard-api renamed to --use-megatron-fsdp-v2
- use_megatron_fsdp_v2=True auto-sets use_megatron_fsdp=True

### Config dataclasses
- use_fully_shard_api -> use_megatron_fsdp_v2 in two config files

## Test suite (test_mcore_checkpoint.py)
- Single parametrized test_checkpoint_online_convert with
  (source_type, source_configs, target_configs) covering:
  - V2 round-trip: 2 cases (optim_grads_params, optim_grads)
  - V2 cross-setting: 2 cases (strategy A -> strategy B and reverse)
  - V1 -> V2: 3 cases (different sharding strategies)
  - ND-parallel -> V2: 2 cases (dp_reshardable, fully_reshardable)
- All use train_step() + save_checkpoint() (native MCore APIs)
- Model weights verified with exact match; optimizer verified
  for FSDP source types (V1/V2) via gather-to-full-tensor

## Design doc (mcore_fsdp_checkpoint_design.md)
- Updated function table, feature support matrix, dual-dict
  pattern (Section 5.11), and save/load flow diagrams
@shjwudp shjwudp changed the title [2/N] Megatron FSDP: Introduce Megatron-FSDP2 with per-module fully_shard() API Draft [2/N] Megatron FSDP: Introduce Megatron-FSDP2 with per-module fully_shard() API May 20, 2026
shjwudp and others added 17 commits May 23, 2026 17:39
**load_torch_dist_into_fsdp_v2 — 5-phase pipeline:**
- Phase 1: _preprocess_and_verify_v2_state_dict — shadow dict for DCP load
  (DTensors share storage with original plain tensors), verifies chunk metadata
- Phase 2: _build_torch_dist_to_v2_map — key matching with debug logging
- Phase 3: DCP load of mapped state dict
- Phase 4: _load_expert_params_from_torch_dist — expert flatten→individual split
- Phase 5: strictness verification (raises or warns via --strict flag)

**Code consolidation:**
- _split_fused_params_v2 merges handle_swiglu/gdn_in_state_dict_v2 (~130→75 lines)
- _maybe_wrap_as_uneven_dtensor shared by two wrapping functions
- Merged double iteration in preprocessing, simplified apply_mcore_postprocess

**Bug fixes:**
- _match_gdn_key missing dtensor arg (TypeError in GDN optimizer path)
- _load_expert_params_from_torch_dist: tuple unpack mismatch, multi-chunk
  copy overwrite, module. prefix mismatch in optim_matched, td_flat_key
  construction with removeprefix('module.'), debug print cleanup

**Dead code removal:**
- save_checkpoint/load_checkpoint from __all__, _get_tp_world_size,
  _intersection, _offset_slice, _expert_param_local_key, unused imports

**checkpointing.py:** strict param threaded through call chain

**Design doc:** updated function table, section references, normalization table
… develop/mfsdp-refactor-main-stage2

# Conflicts:
#	megatron/core/distributed/fsdp/src/megatron_fsdp/v2/param_group.py
Introduce NVFP4 primary-weights support in Megatron FSDP v2.

### Core: NVFP4 storage handling

- **BufferIndex.compact(factor, compact_shapes)**: Proportionally scale all
  indices for packed storage (factor=0.5 for NVFP4 2:1 packing). All buffers
  build with logical shapes + shared chunk_size_factor; only model_weight
  and transpose_weight buffers are compacted. Preserves proportional
  item-offset mapping across buffers.

- **get_param_storage_shapes()**: Return packed shapes for NVFP4 (last dim
  halved), logical shapes otherwise. Drives compact and DTensor creation.

- **FullyShardNVFP4Policy**: NVFP4 policy with enabled/recipe, wired
  through FullyShardMixedPrecisionPolicy and mcore_fsdp_adapter.

- **fp4_param_gather**: Added to DistributedDataParallelConfig, mirrors
  fp8_param_gather.

### Mixed precision NVFP4 path

- quantize_main_weights_to_nvfp4: Convert fp32 main shards to packed NVFP4
  model-weight shards using TE quantize_master_weights.
- post_unshard: Calls post_all_gather_processing for NVFP4 params.
- is_nvfp4_param, get_nvfp4_raw_data, model_init_context NVFP4 support.

### Checkpoint refactor

- Generic fused-layer matching (_match_fused_key) replaces hardcoded
  expert-key patterns. Supports regular fused layers, GroupedMLP, and
  SequentialMLP experts.
- Phase 4 slicing in load_torch_dist_into_fsdp_v2 uses DTensor shards to
  avoid OOM on large fused tensors.
- _find_param_in_map: While-loop strips multiple module. prefixes,
  fixing optimizer state dict lookups for double-wrapped models.
- Metadata propagation: _propagate_chunk_metadata_to_state_dict at save
  time; _apply_mcore_postprocess validates __create_chunk_list__ on all
  DTensors.
- Removed tautological assert in _match_fused_key debug logging.

### API renames

- _get_item_offset → _get_item_global_range
- _get_item_slice_in_shard → _get_item_self_range
- Merged _get_item_local_index/_get_item_local_shard_index →
  _get_item_local_range with as_shard kwarg
- fetch_unsharded_buffer → fetch_buffer
- only_shard → as_shard kwarg on get_item

### Documentation

- Added nvfp4_design.md: Full NVFP4 design including storage shape
  distinction, compact pattern, chunk_size_factor rationale, checkpoint
  flow, and BufferIndex API reference (summon_full_params marked planned).
- Updated mcore_fsdp_checkpoint_design.md for Phase 4 generic slicing.
- Updated README.md sharding strategy status (only optim_grads_params).

### Tests

- NVFP4 checkpoint round-trip test (v2_rt_nvfp4_optim_grads_params).
- NVFP4 E2E test in test_mcore_nd_parallel.
- Skipped no_shard/optim/optim_grads tests (not yet supported).
- Reduced layer dimensions in test_param_group for faster UT runs.

### Fixes

- _match_fused_key: Delete tautological assert after add_to_set.
- checkpointing.py: Recursive v2 detection, metadata propagation for
  fsdp_dtensor saves, reject dp_reshardable for v2.
- dp_buffer.py: init_buffers remove dead model_weight_shapes variable.
- fsdp_module.py: Gradient dtype cast replaces failing assert.
- utils.py: Fix torch._C._get_accelerator crash on CPU.
fix(mfsdp): support fsdp v2 zero-1 and zero-2
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.

2 participants