@@ -2005,7 +2005,7 @@ def _convert_param_to_dtensor_param(
20052005 # We overwrite the original DTensor's distributed configuration.
20062006 param_tensor = param
20072007 if isinstance (param , DTensor ):
2008- param_tensor = param .to_local ()
2008+ param_tensor = param ._local_tensor
20092009 # Convert the parameter to a DTensor.
20102010 new_param = torch .nn .Parameter (
20112011 DTensor .from_local (
@@ -2025,19 +2025,44 @@ def _convert_param_to_dtensor_param(
20252025 return new_param
20262026
20272027
2028+ class _ToLocalIdentity (torch .autograd .Function ):
2029+ """Extract the local tensor from a DTensor, preserving object identity.
2030+
2031+ Unlike DTensor.to_local(), this returns the exact same _local_tensor
2032+ object so that FSDP2's in-place attribute updates (e.g. after all-gather)
2033+ remain visible through any reference stored elsewhere (e.g. in ctx).
2034+ """
2035+
2036+ @staticmethod
2037+ def forward (ctx , dtensor_param : DTensor ) -> torch .Tensor :
2038+ ctx .device_mesh = dtensor_param .device_mesh
2039+ ctx .placements = dtensor_param .placements
2040+ ctx .set_materialize_grads (False )
2041+ return dtensor_param ._local_tensor
2042+
2043+ @staticmethod
2044+ def backward (ctx , grad_local ):
2045+ if grad_local is None :
2046+ return None
2047+ return DTensor .from_local (
2048+ grad_local ,
2049+ device_mesh = ctx .device_mesh ,
2050+ placements = ctx .placements ,
2051+ run_check = False ,
2052+ )
2053+
2054+
20282055def _extract_trainable_tensor_from_dtensor (dtensor_param : DTensor ) -> torch .Tensor :
20292056 """
20302057 Retrieves the local Tensor from a trainable DTensor Parameter.
20312058
2032- Calls DTensor.to_local() and sets `requires_grad_(DTensor.requires_grad)`,
2033- to inherit `requires_grad` from the DTensor parameter. This is necessary
2034- because DTensor.from_local(Tensor) (in `_convert_param_to_dtensor_param`)
2035- resets the `requires_grad` attribute in the local Tensor, and consequently
2036- deactivates gradient computation / differentiation in TransformerEngine .
2059+ Uses _ToLocalIdentity to preserve object identity between the returned
2060+ tensor and DTensor._local_tensor, ensuring FSDP2's in-place updates
2061+ remain visible. Sets `requires_grad_(DTensor.requires_grad)` to inherit
2062+ `requires_grad` from the DTensor parameter, since DTensor.from_local()
2063+ resets it on the local Tensor .
20372064 """
2038- # Extract the local compute Tensor.
2039- compute_param = dtensor_param .to_local ()
2040- # Set requires_grad on local Tensor based on DTensor.
2065+ compute_param = _ToLocalIdentity .apply (dtensor_param )
20412066 compute_param .requires_grad_ (dtensor_param .requires_grad )
20422067 return compute_param
20432068
0 commit comments