core.distributed.fsdp.src.megatron_fsdp.experimental.optimizer#
Optimizer adapter for the minimal Megatron-FSDP path.
Module Contents#
Functions#
Allocate optimizer state so a DCP load has DTensors to fill. |
|
Attach FSDP-aware step hooks to an optimizer instance. |
Data#
API#
- core.distributed.fsdp.src.megatron_fsdp.experimental.optimizer.__all__#
[‘fully_shard_optimizer’, ‘init_optimizer_state’]
- core.distributed.fsdp.src.megatron_fsdp.experimental.optimizer.init_optimizer_state(optimizer: torch.optim.Optimizer) None#
Allocate optimizer state so a DCP load has DTensors to fill.
- Func:
~torch.distributed.checkpoint.state_dict.get_optimizer_state_dictinitializes empty optimizer state via torch’s_init_optim_state, but that assigns a parameter-dtype gradient. A Megatron-FSDP sharded parameter advertises the FSDP gradient dtype throughgrad_dtype, which differs from the (main-weight) parameter dtype under mixed precision, and rejects a mismatched gradient. So initialize the state here with agrad_dtype-matched zero gradient; the subsequent load overwrites it. This is a no-op once the state exists (for example after a training step).
TODO: this function becomes unnecessary once torch’s
_init_optim_statehonors a parameter’sgrad_dtypewhen it allocates the placeholder gradient (torch.zeros_like(param)intorch/distributed/checkpoint/state_dict.py); an upstream issue is being filed.- Parameters:
optimizer – Optimizer whose (possibly empty) state should be materialized.
- core.distributed.fsdp.src.megatron_fsdp.experimental.optimizer.fully_shard_optimizer(
- optimizer: torch.optim.Optimizer,
- *,
- precision_aware: bool = False,
Attach FSDP-aware step hooks to an optimizer instance.
The adapted optimizer preserves its existing parameter groups, temporarily casts gradients around optimizer steps for FSDP sharded parameters whose data dtype differs from their grad dtype unless the optimizer is precision aware, and refreshes compute weights after each optimizer step.
Alternatives considered: - Monkey-patching optimizer methods directly on the instance. This is more invasive and harder to compose than hooks. - Generating an FSDP-specific subclass per
torch.optim.Optimizer. This adds extra class-generation machinery, but would let us instrumentzero_gradand__init__as well asstepif needed. - Casting frommain_grad.dtypetomain_weight.dtypeafter the last microbatch and casting back before the first microbatch. This should be done from a root post-backward callback if needed later, so users do not need to callfully_shard_optimizeron an existingtorch.optim.Optimizer. - Letting the user setmain_weightandmain_gradto the same dtype. This is enough for an FSDP2 drop-in replacement path and lets optimizers stay unaware of FSDP precision handling.- Parameters:
optimizer – Optimizer instance to adapt in place.
precision_aware – Whether the optimizer accepts FSDP’s mixed-precision gradients without temporary casting.