mindspore-ai / mindspore-ai/hyper-parallel
[Bug] distribute_module 复制路径在 MindSpore 下丢失 param.name 导致参数重名冲突
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 53
- Forks
- 63
- Avg merge
- 23h 45m
- Merged PRs (30d)
- 63
Description
问题简述 (Summary)
在 MindSpore 后端下,distribute_module 的复制路径(_replicate_submodule_params_buffers)
用 module_prefix + 局部 key 拼出新参数名,而没有沿用参数自身已经全局限定的 param.name。
对叶子模块调用 distribute_module 时 module_prefix 为空,新参数名退化为裸局部 key
(如 "weight")。由于 MindSpore 要求参数名全局唯一,当多个叶子模块都走这条复制路径时,
第二个就会报 its name 'weight' already exists。
使用场景 (Use case)
pynative 模式下用 distribute_module 做张量并行 / 专家并行。两种常见写法都会触发:
- 复制类 ParallelStyle(如对 LayerNorm / 路由 gate 的
NoParallel/SequenceParallel)
传partition_fn=None,让distribute_module把所有参数复制成 DTensor; - 分片类 style 的
partition_fn只覆盖了部分参数,其余参数交给内置 replicate pass。
在一个有多个叶子线性/嵌入/归一化层的真实模型(例如 DeepSeek-V3)上,TP/EP 初始化阶段必现。
根因 (Root cause)
hyper_parallel/core/dtensor/dtensor.py 的 _replicate_submodule_params_buffers:
param_name = f"{module_prefix}.{key}" if module_prefix else key
new_param = _distribute_module_new_parameter(param_name, dt, requires_grad)
module_prefix 来自 cells_and_names(),是相对于传入 distribute_module 的那个模块的路径。
当 distribute_module 直接作用在叶子模块上时,其根的 module_prefix == "",于是
param_name 退化为裸局部 key("weight")。
_distribute_module_new_parameter 在 MindSpore 分支用该名字构造 Parameter(dtensor, name=param_name, ...):
if platform.platform_type == PlatformType.MINDSPORE:
return platform.Parameter(dtensor, name=key, requires_grad=requires_grad)
PyTorch 的 Parameter 不依赖全局名字(靠 module 属性槽位 + 层级识别),所以无碍;
但 MindSpore 的 Parameter.name 必须全局唯一,多个叶子都被重命名为 "weight" → 冲突。
备注:同样的裸 key 问题也存在于自带的
ColwiseParallel/RowwiseParallel的
_partition_linear_fn/_partition_embedding_fn(_distribute_module_new_parameter(key, ...)),
在 MindSpore 多 leaf TP 下同样会重名冲突。
错误栈 (Error)
ValueError: The value [Tensor(shape=[64640, 3584], dtype=Float32, value=...)] ,
its name 'weight' already exists. Please set a unique name for the parameter.
File ".../hyper_parallel/core/dtensor/dtensor.py", in _replicate_submodule_params_buffers
new_param = _distribute_module_new_parameter(param_name, dt, requires_grad)
(出现在第二个被复制的叶子模块上;第一个叶子把 "weight" 占用后,第二个再注册同名即报错。)
期望行为 (Expected)
复制(以及分片)重建参数时,MindSpore 下应沿用参数自身已限定的 param.name,
而不是用相对 module_prefix 重新拼。PyTorch 无 name 时再退回构造名。
建议修复 (Suggested fix)
_replicate_submodule_params_buffers 优先取 param.name:
param_name = getattr(param, "name", None) or (
f"{module_prefix}.{key}" if module_prefix else key
)
new_param = _distribute_module_new_parameter(param_name, dt, requires_grad)
ColwiseParallel / RowwiseParallel 的 _partition_*_fn 同理改用 param.name。
环境 (Environment)
- hyper_parallel: master @
0c28158 - MindSpore: 2.10.0
- 硬件: Ascend 910B
- 模型: DeepSeek-V3(pynative,TP / EP)
schema_version: 1
source: gitcode
gitcode_repo: mindspore/hyper-parallel
gitcode_issue: 224
source_url: https://gitcode.com/mindspore/hyper-parallel/issues/224
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 in hyper_parallel/core/dtensor/dtensor.py by reading _replicate_submodule_params_buffers and _distribute_module_new_parameter, then inspect the _partition_linear_fn and _partition_embedding_fn paths mentioned in the issue. Reproduce distribution on multiple MindSpore leaf modules and verify that replicated and partitioned parameters retain unique fully qualified names without the 'weight' collision.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- distributed-systems
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 70/100