With Ulysses context parallelism and FlashAttention input_layout="TND", Hyper Parallel attaches a 4-D tensor_map to the softmax_max/softmax_sum outputs, while the MindSpore kernel returns 3-D local tensors. The resulting DTensor has inconsistent metadata:
local tensor shape rank: 3
layout.tensor_map rank: 4
This becomes a runtime failure on the latest r1.0.0 branch (b36bf6006bd224a6b720f9a10dd73086b8b7b92a).
max-attention-logit monitoring enabled, which queries the DTensor layout of softmax_max
The first forward step fails when converting the local softmax shape back to its global shape:
File "mindformers/pynative/layers/flash_attention.py", line 56, in _local_head_slice
full_shape = tuple(int(d) for d in layout.get_global_shape(local_shape))
File "hyper_parallel/core/dtensor/layout.py", line 687, in get_global_shape
return self._mesh.get_global_shape(slice_shape, self._tensor_map)
File "hyper_parallel/core/dtensor/device_mesh.py", line 1291, in get_global_shape
raise ValueError(
ValueError: Length of slice_shape (3) must match the length of tensor_map (4).
The same training case runs for multiple steps with the earlier Hyper Parallel commit 65d7e501, but fails at step 0 with b36bf600.
Root cause and regression history
MindSpore defines the FlashAttention outputs as follows:
Non-TND: softmax_max/softmax_sum shape is (B, N, S, 8).
TND: softmax_max/softmax_sum shape is (T, N, 8).
Therefore, the TND softmax outputs are 3-D.
However, _build_softmax_tensor_map() currently initializes a fixed four-element map and also returns four elements for TND:
This optimization is reasonable, but it exposes the pre-existing invalid TND softmax layout instead of implicitly rebuilding it. The resulting 3-D local tensor plus 4-D layout causes the failure above.
Expected behavior
For TND input, softmax_max and softmax_sum should receive a 3-D tensor map matching (T, N, 8):
The Ulysses head sharding carried by query_tm[1] should remain intact, and len(output.layout.tensor_map) should equal len(output.to_local().shape).
Additional context
Suggested fix and validation:
Make _build_softmax_tensor_map() return three elements for TND softmax outputs and four elements for non-TND layouts.
Update the existing TND unit tests, which currently assert a 4-D softmax tensor map.
Add a test that wraps an actual or representative 3-D TND softmax output through wrap_output(), then verifies that local rank and tensor-map rank match.
Add an 8-rank Ulysses smoke test that executes at least one FlashAttention forward/backward step.
Checklist
🐛 Describe the bug
Summary
With Ulysses context parallelism and FlashAttention
input_layout="TND", Hyper Parallel attaches a 4-Dtensor_mapto thesoftmax_max/softmax_sumoutputs, while the MindSpore kernel returns 3-D local tensors. The resulting DTensor has inconsistent metadata:This becomes a runtime failure on the latest
r1.0.0branch (b36bf6006bd224a6b720f9a10dd73086b8b7b92a).Reproduction
Environment and parallel configuration:
r1.0.0@b36bf6006bd224a6b720f9a10dd73086b8b7b92a2.10.0138f97c02b60f7ad5e759e900224d934b1601d01context_parallel_method: ulyssesinput_layout="TND"softmax_maxThe first forward step fails when converting the local softmax shape back to its global shape:
The same training case runs for multiple steps with the earlier Hyper Parallel commit
65d7e501, but fails at step 0 withb36bf600.Root cause and regression history
MindSpore defines the FlashAttention outputs as follows:
softmax_max/softmax_sumshape is(B, N, S, 8).softmax_max/softmax_sumshape is(T, N, 8).Therefore, the TND softmax outputs are 3-D.
However,
_build_softmax_tensor_map()currently initializes a fixed four-element map and also returns four elements for TND:softmax_tm = [-1, -1, -1, -1] if input_layout_str == "TND": softmax_tm[0] = query_tm[0] softmax_tm[1] = query_tm[1] return tuple(softmax_tm)This produces a map equivalent to
(T_map, N_map, -1, -1)for a real(T, N, 8)tensor.The incorrect 4-D inference existed before the observed regression, but the old output wrapping path masked it. Previously,
wrap_output()called:DTensor.from_local()rebuilt the layout usinglen(local_tensor.shape), so a 3-D kernel output was wrapped with a newly constructed 3-D layout.Commit
ec7cdac9a5b17de3a56e5244080b7578f384b2bf(fix: align dtensor dispatch layout handling) changed output wrapping to reuse the inferred Layout directly:This optimization is reasonable, but it exposes the pre-existing invalid TND softmax layout instead of implicitly rebuilding it. The resulting 3-D local tensor plus 4-D layout causes the failure above.
Expected behavior
For TND input,
softmax_maxandsoftmax_sumshould receive a 3-D tensor map matching(T, N, 8):if input_layout_str == "TND": return ( query_tm[0] if len(query_tm) > 0 else -1, query_tm[1] if len(query_tm) > 1 else -1, -1, )The Ulysses head sharding carried by
query_tm[1]should remain intact, andlen(output.layout.tensor_map)should equallen(output.to_local().shape).Additional context
Suggested fix and validation:
_build_softmax_tensor_map()return three elements for TND softmax outputs and four elements for non-TND layouts.wrap_output(), then verifies that local rank and tensor-map rank match.Relevant commits:
r1.0.0: https://gitcode.com/mindspore/hyper-parallel/commit/b36bf6006bd224a6b720f9a10dd73086b8b7b92aEnvironment info