mindspore-ai / mindspore-ai/hyper-parallel
[Bug] !823 HSDP 融合 all-reduce 在 reduce_dtype=None 时 output_buffer dtype mismatch(融合 buffer fp32 vs reduce bf16)
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 53
- Forks
- 63
- Avg merge
- 23h 45m
- Merged PRs (30d)
- 63
Description
该问题是怎么引起的?
!823(493b018 feat(mindspore): HSDP backward RS/AR overlap for comm_fusion=False,2026-06-15 17:08 合入 master)新增了 AllReduceParamGroup 融合 all-reduce 路径。该路径在 reduce_dtype is None 时,对 None 的解释前后不一致:
| 位置 | 对 reduce_dtype=None 的处理 |
结果 dtype |
|---|---|---|
AllReduceParamGroup.allocate_fused_buffer(param_group.py:725);compute_aligned_layout(param_group.py:708,用 ms.Tensor([], dtype=None).itemsize 算 element_size) |
ms.mint.empty(dtype=None) → MindSpore 默认 |
fp32 |
reduce_scatter_grad(param.py,reduce_dtype = dtype or grad.dtype) |
None or grad.dtype |
bf16 |
于是融合 buffer 被分配成 fp32,而归约要用 bf16,reduce_scatter_grad 里 output_buffer.dtype != reduce_dtype 的一致性校验(param.py:814)失败。
reduce_dtype=None 来源:参数的 reduce_dtype 属性为 None(语义为“按梯度原生 dtype 归约、不升 fp32”),对应训练配置 accumulate_allreduce_grads_in_fp32: False。经 state.py:269 self._reduce_dtype = next(iter(reduce_dtypes)) 传到上述两处。
非融合路径不受影响:state.py:474-483(output_buffer=None)由 reduce_scatter_grad 自行按 grad.dtype 分配 buffer,dtype 自洽;只有 !823 的融合组路径(state.py:485-507)会触发。
这是 !823 引入的回归——该融合路径在 15984d1(!821,更新前 HEAD)中并不存在(git merge-base --is-ancestor d3a5855 15984d1 为否)。
重现步骤
环境:
- MindSpore 2.10.0 / Ascend 910B2 / aarch64
- hyper-parallel
16e69a6(含!823) - 模型:DeepSeek-V3(MLA),mindformers,PYNATIVE(
--mode 1)
触发配置要点:
params_dtype: bfloat16+compute_dtype: bfloat16accumulate_allreduce_grads_in_fp32: False(⇒ 参数reduce_dtype=None)- 走到
!823的AllReduceParamGroup融合 all-reduce 组路径(state.py:485-507)
观测到的具体布局:8 卡,tensor_parallel: 2 + sequence_parallel: true + pipeline_parallel: 2(FSDP dp_shard=2)。反向梯度 reduce-scatter 时首个 step 崩溃。pipeline_parallel_interleave_num 取 1 或 2 均一致触发(与 PP interleave 无关)。
根因为代码层面对
None的两种解释不一致,与具体并行拓扑无关,阅读param_group.py/param.py即可确认。
报错信息
ValueError: output_buffer dtype mismatch: expected BFloat16, got Float32
调用栈(全程在 hyper-parallel):
hyper_parallel/core/pipeline_parallel/scheduler.py:802 _exec_step
hyper_parallel/core/pipeline_parallel/scheduler.py:233 _exec_fsdp_reduce_grad
hyper_parallel/core/pipeline_parallel/stage.py:504 execute_reduce_grad
hyper_parallel/platform/mindspore/fully_shard/state.py:674 post_backward
hyper_parallel/platform/mindspore/fully_shard/state.py:501 _issue_reduce_scatter_for_current_module
hyper_parallel/platform/mindspore/fully_shard/param.py:814 reduce_scatter_grad
ValueError: output_buffer dtype mismatch: expected BFloat16, got Float32
建议修复:在 AllReduceParamGroup 中把 None 的 reduce_dtype 解析为参数原生 dtype(已传入的 orig_dtypes[0]),令 allocate_fused_buffer / compute_aligned_layout 与 reduce_scatter_grad 的 None or grad.dtype 语义对齐,例如:
# AllReduceParamGroup.__init__
self.reduce_dtype = reduce_dtype if reduce_dtype is not None else (orig_dtypes[0] if orig_dtypes else None)
影响:任何 accumulate_allreduce_grads_in_fp32: False(reduce_dtype=None)且命中 !823 融合 all-reduce 组路径的动态图 FSDP 训练,首个反向归约即崩。
相关:与 #215 属同一主题(bf16 场景 reduced grad fp32 与 bf16 目标不一致),但崩溃点、触发条件、所在路径均不同——#215 在 !823 之前的非融合写回路径(apply_reduced_grad,param.py:920),本 issue 在 !823 今天新合入的融合路径(reduce_scatter_grad 的融合 buffer 分配,param.py:814,由 reduce_dtype=None 触发)。
schema_version: 1
source: gitcode
gitcode_repo: mindspore/hyper-parallel
gitcode_issue: 217
source_url: https://gitcode.com/mindspore/hyper-parallel/issues/217
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with AllReduceParamGroup.allocate_fused_buffer and compute_aligned_layout in param_group.py, then compare their reduce_dtype handling with reduce_scatter_grad in param.py and the fused path in state.py:485-507. Run the provided bfloat16 FSDP reproduction with accumulate_allreduce_grads_in_fp32 disabled. Done means the fused buffer uses the native gradient dtype and the reduce-scatter no longer raises a dtype mismatch.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- distributed-systems, machine-learning
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100