core.distributed.fsdp.src.megatron_fsdp.experimental.owner_planning#
Pure parameter layout and owner-compute packing logic for MFSDP v2’s all-Flat layout.
ParameterLayoutdescribes how a single parameter’s flat element range is split across the DP group under MFSDP v2’s all-Flatlayout.ParameterLayout.from_groupbuilds{tensor_index: layout}for eligible parameters in anFsdpParameterGroup, keyed by each parameter’s index within the group.assign_owner_workbalances owner-compute work across owner ranks using a caller-supplied cost function.GroupOwnerLayout.from_groupbuilds a data structure capturing the per-group owner layout upon the above.OwnerGatherPlan.pack/OwnerScatterPlan.packtake theGroupOwnerLayoutplus this rank’s data and build the flat P2P send/recv buffers,OwnerGatherPlan.reconstruct_fullstitches gathered shards back into the full flat tensor on the owner, andOwnerScatterPlan.unpackextracts this rank’s flat result shards from the received buffers.
Module Contents#
Classes#
How a single parameter’s flat element range splits across the DP group. |
|
Owner layout for one |
|
Metadata and send buffers for the owner-gather P2P step of a set of parameters. |
|
Metadata and send buffers for the owner-scatter P2P step of a set of parameters. |
Functions#
Whether the given tensor has dimensionality ≥2. |
|
Cost function matching the Newton-Schulz orthogonalization compute estimate for the given number of Newton-Schulz iterations/steps. |
|
Assign one owner rank to each parameter, keyed by tensor index. |
API#
- core.distributed.fsdp.src.megatron_fsdp.experimental.owner_planning.select_ge_2d_params(param: torch.Tensor) bool#
Whether the given tensor has dimensionality ≥2.
- class core.distributed.fsdp.src.megatron_fsdp.experimental.owner_planning.ParameterLayout#
How a single parameter’s flat element range splits across the DP group.
MFSDP v2’s all-
Flatlayout gives each rank one contiguous global element range per parameter, in rank order, so rankrholds[offset, offset + count)whereoffsetis the sum of the previous ranks’ counts. A rank withcount == 0holds no elements of this parameter... attribute:: full_shape
The parameter’s global shape.
.. attribute:: flat_counts
Per-rank element count;
0means the rank holds no elements.- full_shape: torch.Size#
None
- flat_counts: tuple[int, ...]#
None
- __post_init__() None#
- classmethod from_group(
- group: core.distributed.fsdp.src.megatron_fsdp.experimental.parameter_group.FsdpParameterGroup,
- *,
- eligible_fn: collections.abc.Callable[[torch.Tensor], bool] | None = None,
Build
{tensor_index: layout}for eligible parameters in anFsdpParameterGroup.Keys are the parameters’ indices within
group.fsdp_parameters(their tensor indices in the DBuffer layout). Parameters not selected byeligible_fnare absent from the returned dict.- Parameters:
group – The FSDP parameter group whose DBuffer layout describes the parameter placements.
eligible_fn – Predicate selecting which parameters participate in owner-compute orthogonalization. Takes a parameter tensor as input and return whether the parameter is supposed to be included. When
None, defaults to matching ≥2D tensors (param.ndim >= 2).
- property dp_size: int#
Number of ranks in the DP group for this parameter.
- full_numel() int#
Return the total number of elements in the full (unsharded) parameter.
- rank_offset(rank: int) int#
Return the starting offset of
rank’s shard within the flat parameter.
- rank_numel(rank: int) int#
Return the number of elements
rankholds.
- owner_candidates() tuple[int, ...]#
Return the ranks that hold a non-empty shard of this parameter.
- is_boundary() bool#
True if more than one rank holds a non-empty shard of this parameter.
- core.distributed.fsdp.src.megatron_fsdp.experimental.owner_planning.ns_cost_fn(
- num_ns_steps: int,
Cost function matching the Newton-Schulz orthogonalization compute estimate for the given number of Newton-Schulz iterations/steps.
numel * (min(rows, cols) * num_steps + 1)under the DBuffer’s leading-dim view ((shape[0], shape[1:].numel())).
- core.distributed.fsdp.src.megatron_fsdp.experimental.owner_planning.assign_owner_work(
- layouts: dict[int, core.distributed.fsdp.src.megatron_fsdp.experimental.owner_planning.ParameterLayout],
- cost_fn: collections.abc.Callable[[core.distributed.fsdp.src.megatron_fsdp.experimental.owner_planning.ParameterLayout], float] | None = None,
Assign one owner rank to each parameter, keyed by tensor index.
Non-boundary parameters are assigned to their original rank (the only rank holding their elements, so no communication is needed) and their cost counts toward that rank’s running total cost. Boundary parameters are processed in descending cost order and each is greedily given to its eligible rank with the smallest running cost total.
- Parameters:
layouts – Parameter layouts keyed by each parameter’s tensor index in its
FsdpParameterGroup.cost_fn – Callable that returns a positive cost estimate for a given parameter layout. The greedy balancer minimizes the maximum running cost total across ranks, so the cost should reflect the relative compute weight of owning each parameter (e.g., an orthogonalization cost estimate). When
None, defaults to a compute estimate for orthogonalization via Newton-Schulz with 5 iterations/steps.
- Returns:
Mapping from tensor index to owner rank.
- class core.distributed.fsdp.src.megatron_fsdp.experimental.owner_planning.GroupOwnerLayout#
Owner layout for one
FsdpParameterGroup: its params and their owner ranks.The layouts and assignments are step-independent in the general case, so the owner layout may be cached across optimizer steps.
The
tensor_indexused here refers to the parameter’s/tensor’s index in theFsdpParameterGroup... attribute:: group
The FSDP parameter group the layouts and owners refer to.
.. attribute:: layouts
{tensor_index: layout}for the participating parameters... attribute:: owners
{tensor_index: owner_rank}with an entry for every participating parameter. Ranks are indices into the group’s mesh.- group: core.distributed.fsdp.src.megatron_fsdp.experimental.parameter_group.FsdpParameterGroup#
None
- layouts: dict[int, core.distributed.fsdp.src.megatron_fsdp.experimental.owner_planning.ParameterLayout]#
None
- owners: dict[int, int]#
None
- classmethod from_group(
- group: core.distributed.fsdp.src.megatron_fsdp.experimental.parameter_group.FsdpParameterGroup,
- *,
- cost_fn: collections.abc.Callable[[core.distributed.fsdp.src.megatron_fsdp.experimental.owner_planning.ParameterLayout], float] | None = None,
- eligible_fn: collections.abc.Callable[[torch.Tensor], bool] | None = None,
Build the owner layout for one group.
- Parameters:
group – The FSDP parameter group whose DBuffer layout describes the parameter placements.
cost_fn – Cost estimate per parameter layout used to balance owner assignments across ranks. When
None, defaults to a compute estimate for orthogonalization via Newton-Schulz with 5 iterations/steps. See alsoassign_owner_work.eligible_fn – Predicate selecting which parameters participate in owner-compute orthogonalization. When
None, defaults to matching ≥2D tensors. See alsoParameterLayout.from_group.
- property mesh: torch.distributed.device_mesh.DeviceMesh#
Device mesh of the group.
- class core.distributed.fsdp.src.megatron_fsdp.experimental.owner_planning.OwnerGatherPlan#
Metadata and send buffers for the owner-gather P2P step of a set of parameters.
The owner keeps its own shard locally (no self-send), so it only receives from the other shard-holding ranks.
reconstruct_fullreconstructs each owned tensor by concatenating the per-rank shards in rank order (i.e., global element order).Example:
# We are also using some pseudocode here for brevity. # Assume: torch.distributed.get_world_size() == 2 torch.distributed.get_rank() == 0 # We're observing from rank 0 param_0: torch.Tensor param_1: torch.Tensor # Params are in this order as observed by MFSDP. model.param_groups == [{"params": [param_0, param_1]}] # Both params are owned by rank 1 (was previously determined using `GroupOwnerLayout`). param_0.owner == 1 param_1.owner == 1 param_0.shape == (6, 4) # Global shape. param_1.shape == (4, 4) # Global shape. param_0.local_shard.shape == (3, 4) # Rank 0 has shard indexed by `[0:3, ...]`. param_1.local_shard.shape == (2, 4) # Rank 0 has shard indexed by `[0:2, ...]`. param_0.local_shard.numel == 12 param_1.local_shard.numel == 8 owner_gather_plan.send_buffers == {1: tensor(20)} # 12 + 8 = 20 elements # `owner_gather_plan.send_buffers[1]` represents the following in its packed flat buffer: # +--------------------+-------------------+ # | param_0 (12 elems) | param_1 (8 elems) | # +--------------------+-------------------+ # byte order: --> # Rank 0 owns nothing owner_gather_plan.recv_sizes == {} owner_gather_plan.own_shards == {} owner_gather_plan.recv_offsets == {} # --- # Same settings as above, now observing from rank 1 (the owner): torch.distributed.get_rank() == 1 param_0.local_shard.shape == (3, 4) # Rank 1 has shard indexed by `[3:6, ...]`. param_1.local_shard.shape == (2, 4) # Rank 1 has shard indexed by `[2:4, ...]`. send_buffers = {} # Rank 1 owns everything. recv_sizes = {0: 20} # 12 + 8 = 20 elements from rank 0 # Rank 1's own shards, flattened (views): own_shards = {0: param_0.local_shard.view(-1), 1: param_1.local_shard.view(-1)} recv_offsets = { (0, 0): 0, # `param_0` (tensor index 0) from rank 0: offset 0 (1, 0): 12, # `param_1` (tensor index 1) from rank 0: offset 12 }
.. attribute:: send_buffers
Per-destination-owner flat send buffer (this rank’s shards for that owner’s params, in tensor-index order). Only owners with non-zero send size appear.
.. attribute:: recv_sizes
Per-source-rank element count this rank (as an owner) receives. Only sources with non-zero total size appear.
.. attribute:: own_shards
This rank’s flat local shard per owned parameter, keyed by tensor index (used directly in reconstruction, not communicated).
.. attribute:: recv_offsets
Per
(tensor_index, src_rank), the flat offset of this param’s shard inside the recv buffer received fromsrc_rank. Only contains tuples for whichsrc_rankholds elements.- layouts: dict[int, core.distributed.fsdp.src.megatron_fsdp.experimental.owner_planning.ParameterLayout]#
None
- this_rank: int#
None
- send_buffers: dict[int, torch.Tensor]#
None
- recv_sizes: dict[int, int]#
None
- own_shards: dict[int, torch.Tensor]#
None
- recv_offsets: dict[tuple[int, int], int]#
None
- classmethod pack(
- plan: core.distributed.fsdp.src.megatron_fsdp.experimental.owner_planning.GroupOwnerLayout,
- local_shards: dict[int, torch.Tensor],
Pack this rank’s local shards into per-owner P2P send buffers.
- Parameters:
plan – The group’s owner layout.
local_shards – This rank’s local shard per parameter, only required for every parameter it holds elements of. Shards may be passed in any shape.
- reconstruct_full(
- param_index: int,
- recv_buffers: dict[int, torch.Tensor],
Reconstruct the full flat tensor for one owned parameter from its per-rank shards.
Concatenates the per-rank shards in rank order (i.e., global element order). Results can be
viewed into the desired shape. For a parameter only this rank holds elements of, the own flat shard is returned directly.- Parameters:
param_index – Tensor index of the parameter (a key of the
layoutsdict passed topack).recv_buffers – Per-source-rank received buffer (only sources that sent).
- class core.distributed.fsdp.src.megatron_fsdp.experimental.owner_planning.OwnerScatterPlan#
Metadata and send buffers for the owner-scatter P2P step of a set of parameters.
The owner keeps its own result shard (applied directly), so it only sends to the other shard-holding ranks.
.. attribute:: send_buffers
Per-destination-rank flat send buffer (this owner’s result shards for the params it owns, in tensor-index order). Only destinations with non-zero send size appear.
.. attribute:: recv_sizes
Per-owner-rank element count this rank (as a destination) receives. Only owners with non-zero total size appear.
.. attribute:: recv_offsets
Per
(tensor_index, owner_rank), the flat offset of this param’s result shard inside the recv buffer received fromowner_rank. Only contains tuples for which this rank holds elements.- layouts: dict[int, core.distributed.fsdp.src.megatron_fsdp.experimental.owner_planning.ParameterLayout]#
None
- this_rank: int#
None
- send_buffers: dict[int, torch.Tensor]#
None
- recv_sizes: dict[int, int]#
None
- recv_offsets: dict[tuple[int, int], int]#
None
- classmethod pack(
- plan: core.distributed.fsdp.src.megatron_fsdp.experimental.owner_planning.GroupOwnerLayout,
- full_results: dict[int, torch.Tensor],
Pack this owner rank’s full results into per-destination P2P send buffers.
- Parameters:
plan – The group’s owner layout.
full_results – Full result tensor per parameter this rank owns. Tensors may be passed in any shape.
- unpack(
- recv_buffers: dict[int, torch.Tensor],
Extract this rank’s local flat result shards from the per-owner recv buffers.
- Parameters:
recv_buffers – Per-owner-rank received buffer (only owners that sent).
- Returns:
Mapping from tensor index to this rank’s local flat result shard, for parameters this rank holds elements of but does NOT own.