mindspore-ai / mindspore-ai/hyper-parallel

[Bug] !823 HSDP 融合 all-reduce 在 reduce_dtype=None 时 output_buffer dtype mismatch(融合 buffer fp32 vs reduce bf16)

Open
#255 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
53
Forks
63
Avg merge
23h 45m
Merged PRs (30d)
63

Description

该问题是怎么引起的?

!823493b018 feat(mindspore): HSDP backward RS/AR overlap for comm_fusion=False2026-06-15 17:08 合入 master)新增了 AllReduceParamGroup 融合 all-reduce 路径。该路径在 reduce_dtype is None 时,对 None 的解释前后不一致:

位置 reduce_dtype=None 的处理 结果 dtype
AllReduceParamGroup.allocate_fused_bufferparam_group.py:725);compute_aligned_layoutparam_group.py:708,用 ms.Tensor([], dtype=None).itemsize 算 element_size) ms.mint.empty(dtype=None) → MindSpore 默认 fp32
reduce_scatter_gradparam.pyreduce_dtype = dtype or grad.dtype None or grad.dtype bf16

于是融合 buffer 被分配成 fp32,而归约要用 bf16,reduce_scatter_gradoutput_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-483output_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: bfloat16
  • accumulate_allreduce_grads_in_fp32: False(⇒ 参数 reduce_dtype=None
  • 走到 !823AllReduceParamGroup 融合 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 中把 Nonereduce_dtype 解析为参数原生 dtype(已传入的 orig_dtypes[0]),令 allocate_fused_buffer / compute_aligned_layoutreduce_scatter_gradNone 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: Falsereduce_dtype=None)且命中 !823 融合 all-reduce 组路径的动态图 FSDP 训练,首个反向归约即崩。

相关:与 #215 属同一主题(bf16 场景 reduced grad fp32 与 bf16 目标不一致),但崩溃点、触发条件、所在路径均不同——#215 在 !823 之前的非融合写回路径(apply_reduced_gradparam.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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with AllReduceParamGroup in param_group.py, especially allocate_fused_buffer and compute_aligned_layout, then compare their reduce_dtype handling with reduce_scatter_grad in param.py and the fused path in state.py:485-507. Reproduce with bfloat16 parameters and accumulate_allreduce_grads_in_fp32: False. Done means the fused buffer and reduce-scatter use the native gradient dtype without the reported output_buffer mismatch.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend, distributed-systems
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.