@@ -53,7 +53,9 @@ def get_input_data_sharding(config, mesh):
5353 return nn .logical_to_mesh_sharding (P (* config .input_data_sharding_logical_axes ), mesh , config .logical_axis_rules )
5454
5555
56- def get_functional_train_with_signature (train_step , data_sharding , state_mesh_shardings , model , config , params_shardings = None ):
56+ def get_functional_train_with_signature (
57+ train_step , data_sharding , state_mesh_shardings , model , config , params_shardings = None
58+ ):
5759 """Get the shardings (both state and data) for `train_step`."""
5860 functional_train = functools .partial (train_step , model , config , state_mesh_shardings , params_shardings )
5961 functional_train .__name__ = "train_step"
@@ -97,14 +99,14 @@ def get_shaped_batch(config):
9799
98100def should_prevent_cse_in_remat (config ):
99101 """Determines whether to prevent common subexpression elimination (CSE) in remat.
100-
102+
101103 CSE should not be prevented when:
102104 1. Layers are being scanned (scan_layers=True), OR
103105 2. Gradient accumulation is enabled (gradient_accumulation_steps > 1) on GPU hardware
104-
106+
105107 Args:
106108 config: Configuration object with scan_layers, gradient_accumulation_steps, and hardware
107-
109+
108110 Returns:
109111 bool: True if CSE should be prevented, False otherwise
110112 """
@@ -961,6 +963,7 @@ def setup_training_state(model, data_iterator, tx, config, rng, mesh, checkpoint
961963 is_training ,
962964 )
963965
966+
964967def unbox_logicallypartioned (boxed_pytree ):
965968 """Unboxes the flax.LogicallyPartitioned pieces
966969 Args:
@@ -975,23 +978,24 @@ def unbox_logicallypartioned(boxed_pytree):
975978 is_leaf = lambda k : isinstance (k , nn .spmd .LogicallyPartitioned ),
976979 )
977980
981+
978982def add_data_to_sharding (mesh , path , aval , sharding ):
979983 """Adds 'data' dimension to sharding spec if compatible and not already present.
980-
984+
981985 This function attempts to add data parallelism to a sharding specification by finding
982986 a dimension that is divisible by the 'data' mesh axis size and doesn't conflict with
983987 existing partitioning (e.g., tensor parallelism).
984988 This function is mainly used to add data parallelism to the optimizer state for Zero-1 style sharding.
985-
989+
986990 Args:
987991 mesh: The device mesh
988992 path: JAX tree path to the value being sharded
989993 aval: Abstract value with shape information
990994 sharding: Current NamedSharding to potentially augment
991-
995+
992996 Returns:
993997 NamedSharding: Updated sharding with 'data' dimension added, or original if unchanged
994-
998+
995999 Raises:
9961000 AssertionError: If sharding is not NamedSharding or shape cannot be sharded
9971001 """
@@ -1000,10 +1004,12 @@ def add_data_to_sharding(mesh, path, aval, sharding):
10001004 try :
10011005 sharded_shape = sharding .shard_shape (aval .shape )
10021006 except Exception as e :
1003- raise AssertionError (f"Could not shard value { jax .tree_util .keystr (path )} of shape={ aval .shape } with { sharding = } " ) from e
1007+ raise AssertionError (
1008+ f"Could not shard value { jax .tree_util .keystr (path )} of shape={ aval .shape } with { sharding = } "
1009+ ) from e
10041010 pspec = sharding .spec
10051011
1006- if ' data' in jax .tree .leaves (pspec ):
1012+ if " data" in jax .tree .leaves (pspec ):
10071013 return sharding
10081014
10091015 for idx , (size , partition ) in enumerate (zip (sharded_shape , pspec )):
@@ -1013,25 +1019,26 @@ def add_data_to_sharding(mesh, path, aval, sharding):
10131019 if isinstance (partition , str ):
10141020 partition = (partition ,)
10151021
1016- if size % mesh .shape [' data' ] == 0 and (partition is None or ' tensor' not in partition ):
1017- added_component = (' data' ,) + partition
1018- new_pspec = jax .sharding .PartitionSpec (* (pspec [:idx ] + (added_component ,) + pspec [idx + 1 :]))
1022+ if size % mesh .shape [" data" ] == 0 and (partition is None or " tensor" not in partition ):
1023+ added_component = (" data" ,) + partition
1024+ new_pspec = jax .sharding .PartitionSpec (* (pspec [:idx ] + (added_component ,) + pspec [idx + 1 :]))
10191025 new_sharding = jax .sharding .NamedSharding (sharding .mesh , new_pspec )
10201026 return new_sharding
10211027 return sharding
10221028
1029+
10231030def maybe_update_params_sharding_with_opt (config , state_mesh_shardings ):
10241031 """Updates parameter sharding configuration when optimizer state sharding is enabled.
1025-
1032+
10261033 When shard_optimizer_over_data is enabled (Zero-1 style sharding), this function
10271034 extracts the optimizer state shardings from the Adam optimizer's first moment (mu)
10281035 and merges them with the parameter shardings. This ensures parameter sharding is
10291036 consistent with how the optimizer state is distributed across the compute mesh.
1030-
1037+
10311038 Args:
10321039 config: Configuration object with shard_optimizer_over_data flag
10331040 state_mesh_shardings: Train state mesh shardings containing params and opt_state
1034-
1041+
10351042 Returns:
10361043 A tuple of (prev_params_shardings, updated_state_mesh_shardings):
10371044 - prev_params_shardings: Original parameter shardings before the update
@@ -1042,17 +1049,22 @@ def maybe_update_params_sharding_with_opt(config, state_mesh_shardings):
10421049 if config .shard_optimizer_over_data :
10431050 if isinstance (state_mesh_shardings .opt_state , optax .ScaleByAdamState ):
10441051 sharded_fp32_params = state_mesh_shardings .opt_state .mu
1045- elif isinstance (state_mesh_shardings .opt_state , tuple ) and isinstance (state_mesh_shardings .opt_state [0 ], optax .ScaleByAdamState ):
1052+ elif isinstance (state_mesh_shardings .opt_state , tuple ) and isinstance (
1053+ state_mesh_shardings .opt_state [0 ], optax .ScaleByAdamState
1054+ ):
10461055 sharded_fp32_params = state_mesh_shardings .opt_state [0 ].mu
10471056 else :
1048- raise NotImplementedError (f"Could not find optimizer state shardings from optimizer of type { type (state_mesh_shardings .opt_state )} " )
1057+ raise NotImplementedError (
1058+ f"Could not find optimizer state shardings from optimizer of type { type (state_mesh_shardings .opt_state )} "
1059+ )
10491060 if "params" not in sharded_fp32_params .keys ():
10501061 # When quantization=fp8 is enabled the sharded_fp32_params
10511062 # are not wrapped in `params`. Here we wrap them back.
10521063 sharded_fp32_params = {"params" : sharded_fp32_params }
10531064 state_mesh_shardings = state_mesh_shardings .replace (params = dict (prev_params_shardings , ** sharded_fp32_params ))
10541065 return prev_params_shardings , state_mesh_shardings
10551066
1067+
10561068def setup_initial_state (
10571069 model ,
10581070 data_iterator ,
@@ -1145,7 +1157,11 @@ def get_abstract_state(model, tx, config, rng, mesh, is_training=True):
11451157 if is_training and config .shard_optimizer_over_data :
11461158 # Add data to sharding for optimizer state
11471159 state_mesh_shardings = state_mesh_shardings .replace (
1148- opt_state = jax .tree .map_with_path (functools .partial (add_data_to_sharding , mesh ), unbox_logicallypartioned (abstract_state ).opt_state , state_mesh_shardings .opt_state )
1160+ opt_state = jax .tree .map_with_path (
1161+ functools .partial (add_data_to_sharding , mesh ),
1162+ unbox_logicallypartioned (abstract_state ).opt_state ,
1163+ state_mesh_shardings .opt_state ,
1164+ )
11491165 )
11501166 if is_training and config .optimizer_memory_host_offload :
11511167 opt_state = jax .tree_util .tree_map (lambda x : x .with_memory_kind (kind = "pinned_host" ), state_mesh_shardings .opt_state )
0 commit comments