关联 PR:https://gitcode.com/mindspore/hyper-parallel/pull/658
PR #658 为 Qwen3.5 dense、Qwen3.5-MoE 和 Qwen3-VL-MoE 补齐统一 Trainer 的真实训练能力,覆盖以下完整链路:
config.json
ModelSpec
data.type
.bin/.idx
PR 最终 squash 为一个业务提交。相对 PR 基线共修改 46 个生产文件;tests/、examples/、platform/ 和 trainer callbacks 无 diff,也不提交本机配置、日志或解析工具。
tests/
examples/
platform/
hyper_parallel/core/pipeline_parallel/scheduler.py
PipelineScheduleRuntime._inject_local_fsdp_actions
HSDPModule
hyper_parallel/core/pipeline_parallel/stage.py
SharedParameterInfo
_sync_shared_parameters
_init_shared_parameter_group
sync_shared_parameters_grad
get_last_stage_sens
execute_reduce_grad
to_empty
requires_grad
None
hyper_parallel/core/shard/_op_dispatch.py
_validate_inplace_partial_inputs
_restore_inplace_dtensor_result
add_/sub_
hyper_parallel/core/shard/ops/parallel_elementwise.py
_partial_signature
_contributes_to_partial_output
_zero_contribution
AddDistributedOp
SubDistributedOp
Partial + Replicate
Replicate - Partial
Inf*0=NaN
input/other
hyper_parallel/core/shard/ops/yaml/element_wise_ops_with_shape.yaml
Sub
SubExt
hyper_parallel/core/shard/ops/yaml/torch_element_wise.yaml
__rsub__
scalar - Partial
hyper_parallel/core/shard/ops/yaml/torch_element_wise_with_shape.yaml
sub
hyper_parallel/core/tensor_parallel/style.py
_src_data_rank_for_tensor
ColwiseParallel
RowwiseParallel
PrepareModuleOutput/InputOutput
src_data_rank=None
reduce_dtype
Replicate -> Shard
hyper_parallel/data/__init__.py
build_dataset
DATASET_REGISTRY
hyper_parallel/data/registry.py
DatasetRegistry.register/get/names
hyper_parallel/data/dummy.py
DummyDataset
build_dummy
train.seed + index
hyper_parallel/data/hf.py
TokenizedDataset
_load_raw
_maybe_truncate
build_hf_datasets/build_json_file
hyper_parallel/data/preset_pt.py
PresetPtDataset
_expand_batch
_split_pixel_block
_slice_position_ids
hyper_parallel/data/vl_dummy.py
DummyVLDataset
build_vl_dummy
hyper_parallel/data/megatron/__init__.py
data.type=megatron
hyper_parallel/data/megatron/builder.py
_parse_blend
_looks_like_blend
build_megatron
hyper_parallel/data/megatron/blendable_dataset.py
_build_blend_indices
BlendableDataset
hyper_parallel/data/megatron/gpt_dataset.py
GPTDataset
<prefix>_cache/
hyper_parallel/data/megatron/indexed_dataset.py
_IndexReader
IndexedDataset/Builder
.bin
.idx
hyper_parallel/models/qwen3_5/__init__.py
_ckpt_config_kwargs
_resolve_overrides
_build_config
register_spec
layer_types
hyper_parallel/models/qwen3_5/checkpoint.py
_remap_simple_key
load_hf_qwen3_5_state_dict
hyper_parallel/models/qwen3_5/model.py
Qwen3_5SdpaCore/Attention/GatedDeltaNet
ForCausalLM.forward
StageModule
hyper_parallel/models/qwen3_5/parallelize.py
pipelining_qwen3_5
_apply_qwen3_5_pp_stage_tp
("dp_replicate","dp_shard")
hyper_parallel/models/qwen3_5/state_dict.py
Qwen3_5StateDictAdapter
hyper_parallel/models/qwen3_5_moe/__init__.py
_build/_build_vl
hyper_parallel/models/qwen3_5_moe/checkpoint.py
load_hf_qwen3_5_moe_vl_state_dict
hyper_parallel/models/qwen3_5_moe/model.py
ForCausalLM
hyper_parallel/models/qwen3_5_moe/model_vl.py
hyper_parallel/models/qwen3_5_moe/mtp.py
Qwen3_5MoeMTP
mtp_loss
mtp.*
mtp_loss_weight=0
hyper_parallel/models/qwen3_5_moe/parallelize.py
_should_reduce
dp_shard=-1
hyper_parallel/models/qwen3_5_moe/state_dict.py
Qwen3_5MoeStateDictAdapter.load/save
model_config.vl
hyper_parallel/models/qwen3_vl_moe/__init__.py
_build_vl
hyper_parallel/models/qwen3_vl_moe/checkpoint.py
_remap_key
load_hf_qwen3_vl_moe_state_dict
(E,H,2I)/(E,I,H)
(E,2I,H)/(E,H,I)
hyper_parallel/models/qwen3_vl_moe/model.py
hyper_parallel/models/qwen3_vl_moe/parallelize.py
_validate_vl_tp_cp_heads
_build_qwen3_vl_moe_pp_schedule
hyper_parallel/models/qwen3_vl_moe/state_dict.py
Qwen3VLMoeStateDictAdapter
text_config
hyper_parallel/models/qwen3_vl_vision/__init__.py
hyper_parallel/models/qwen3_vl_vision/model.py
hyper_parallel/models/spec/model_spec.py
ModelSpec.tp_load_transform_fn
hyper_parallel/trainer/base.py
_validate_pp_runtime_options
_pp_normalize_grads
dp_size/(n_valid*tp_loss_repeats)
hyper_parallel/trainer/config.py
DataConfig
AcceleratorConfig
MixedPrecisionConfig
OptimizerConfig
max_grad_norm<=0
hyper_parallel/trainer/llm_trainer.py
cp*tp
hyper_parallel/trainer/parallel_dims.py
_validate_*
_register_data_flatten_aliases
_register_loss_flatten_alias
build_mesh
dp_replicate>1, dp_shard=1
dp_shard
ep→fsdp→dp→loss
hyper_parallel/trainer/vl_trainer.py
_vl_collate
scripts/train_lm.py
setdefault(HYPER_PARALLEL_PLATFORM=torch)
scripts/train_vl.py
trainer/parallel_dims.py::build_mesh -> models/*/parallelize.py::_resolve_*_dp/fsdp_mesh -> _build_fsdp_kwargs (只按最后一个 shard 轴判断参数可除性) -> trainer/base.py::_set_pp_stage_modules / _pp_average_plain_dp_grads
dp
fully_shard
dp_replicate
core/pipeline_parallel/scheduler.py::_inject_local_fsdp_actions -> stage.py::execute_reduce_grad -> trainer/base.py::_build_pipelined_model -> model-specific _fsdp_wrap_stage / pipeline_*_for_trainer
1/tp
shard ops YAML -> SubDistributedOp / AddDistributedOp -> OpDispatcher in-place safety + DTensor identity -> PrepareModuleOutput reduction dtype
checkpoint.py key/layout transform -> state_dict.py config/namespace selection -> ModelSpec.tp_load_transform_fn -> 已 parallelize 的 rank-local parameter
这四处必须配套;只改其中一处会导致 expert 轴错误、层数读取错误或 full checkpoint tensor 与 TP local parameter shape 不匹配。公共 vision package、VL model 的 visual/DeepStack 边界和 parallelize hooks同样必须配套,才能在 TP/CP/PP 前后 gather、注入并恢复正确 layout。
新增同步语义曾使若干函数越过代码检查门限。没有加入 suppression 或白名单,而是按职责边界做等价拆分:MoE reducer 参数谓词、VL TP+CP 约束、VL PP schedule、Trainer PP runtime options、ParallelDims 校验与 alias 注册。AST/行为矩阵确认条件、短路顺序、异常文本、schedule 分支和 alias 注册顺序不变;最终 production diff 按远端 Gate 同口径 CCN<20 复验零告警,本轮关键修复函数另按 CCN<=15、NLOC<=100 通过。
CCN<20
CCN<=15
NLOC<=100
0.00203276
0.00417256
0.00489401
PP2+FSDP2
VPP2+FSDP2
0.00147199
PP2+TP2+FSDP2
PP2+FSDP2/1F1B
0.00242819
4.9e-9
0.00794458
PP+EP
param_dtype=bfloat16
reduce/output_dtype=float32
关联 PR:https://gitcode.com/mindspore/hyper-parallel/pull/658
1. 这个 PR 做了什么
PR #658 为 Qwen3.5 dense、Qwen3.5-MoE 和 Qwen3-VL-MoE 补齐统一 Trainer 的真实训练能力,覆盖以下完整链路:
config.json构建实际模型几何,并完成 HF state-dict 导入/导出和 TP rank-local load transform。ModelSpec把模型构造、并行化、pipeline split 和 checkpoint transform 接入 Trainer。data.typeregistry,支持 dummy、VL dummy、HF/JSON、preset tensor 和 Megatron.bin/.idx/blend。PR 最终 squash 为一个业务提交。相对 PR 基线共修改 46 个生产文件;
tests/、examples/、platform/和 trainer callbacks 无 diff,也不提交本机配置、日志或解析工具。2. Core:8 个文件
hyper_parallel/core/pipeline_parallel/scheduler.pyPipelineScheduleRuntime._inject_local_fsdp_actionsHSDPModule时注入 unshard/reshard/reduce-grad action;实际 PP stage 根常是普通 Module、FSDP units 在子树中。改为遍历 stage 子树发现任意 HSDPModule,避免漏调度嵌套 FSDP 参数生命周期。hyper_parallel/core/pipeline_parallel/stage.pySharedParameterInfo、_sync_shared_parameters、_init_shared_parameter_group、sync_shared_parameters_grad、get_last_stage_sens、execute_reduce_gradto_empty会替换 Parameter,旧 shared info 持有 stale object;改为 owner+name 动态取 live parameter,meta 阶段延后 broadcast。tied stages 覆盖完整 PP mesh 时复用 PP group,避免 PP+FSDP 重复 world new_group。共享端requires_grad来自同一 tied/frozen 配置:全组 frozen 时统一跳过;仍需梯度但本 rank 的 grad 为None时,以同 shape/dtype/device 零值参加 collective,避免另一端阻塞。FSDP boundary 的 reduced grad 是 DTensor,因此只归约匹配的 local shard,等待 async handle 后写回原 layout。get_last_stage_sens保持通用 PP 的 unit sens,不读取 Trainer 私有状态;execute_reduce_grad遍历、去重并完成普通 stage 根下全部 HSDP roots,避免最后一个 reduce-scatter 延迟到下一 step。hyper_parallel/core/shard/_op_dispatch.py_validate_inplace_partial_inputs、_restore_inplace_dtensor_result、bypass dispatchadd_/sub_可能把 DTensor accumulator 返回成 local tensor。现在 mixed Partial signature 在 mutation 前 fail-fast,并始终为 Torch in-place 返回原 DTensor wrapper。hyper_parallel/core/shard/ops/parallel_elementwise.py_partial_signature、_contributes_to_partial_output、_zero_contribution、AddDistributedOp、SubDistributedOpPartial + Replicate原实现只用“所有 Partial 轴首 rank”判断,二维不同 Partial 轴会丢 shard;Sub 复用 Add 语义时Replicate - Partial非首 rank 符号错误。改为逐输入、逐输出 Partial 轴决定贡献;非贡献值构造保留 autograd edge 的严格零,并避免Inf*0=NaN;kwargs 先按input/other语义规范化;in-place 不同 Partial signature 明确拒绝;新增独立减法实现。hyper_parallel/core/shard/ops/yaml/element_wise_ops_with_shape.yamlSub、SubExtregistrySubDistributedOp。hyper_parallel/core/shard/ops/yaml/torch_element_wise.yaml__rsub__registrySubDistributedOp,使scalar - Partial正确。hyper_parallel/core/shard/ops/yaml/torch_element_wise_with_shape.yamlsubregistrySubDistributedOp。hyper_parallel/core/tensor_parallel/style.py_src_data_rank_for_tensor、ColwiseParallel、RowwiseParallel、PrepareModuleOutput/InputOutputsrc_data_rank=None。新增可选reduce_dtype以 FP32 完成 Partial reduction;最终修复其作用域,只在源 placements 含 Partial 且发生 reduction 时 cast,普通Replicate -> Shard保持原 dtype。3. Data:11 个文件
hyper_parallel/data/__init__.pybuild_dataset、DATASET_REGISTRY和内置 dataset 导出hyper_parallel/data/registry.pyDatasetRegistry.register/get/names、build_datasethyper_parallel/data/dummy.pyDummyDataset、build_dummytrain.seed + index确定性生成,容量覆盖全部训练 steps。hyper_parallel/data/hf.pyTokenizedDataset、_load_raw、_maybe_truncate、build_hf_datasets/build_json_filehyper_parallel/data/preset_pt.pyPresetPtDataset、_expand_batch、_split_pixel_block、_slice_position_idshyper_parallel/data/vl_dummy.pyDummyVLDataset、build_vl_dummyhyper_parallel/data/megatron/__init__.pydata.type=megatron。hyper_parallel/data/megatron/builder.py_parse_blend、_looks_like_blend、build_megatron.bin/.idxprefix 和加权多源语料;统一 suffix、seed、pad/EOD/mmap 配置,并生成足够训练样本。hyper_parallel/data/megatron/blendable_dataset.py_build_blend_indices、BlendableDatasethyper_parallel/data/megatron/gpt_dataset.pyGPTDataset<prefix>_cache/规则。hyper_parallel/data/megatron/indexed_dataset.py_IndexReader、IndexedDataset/Builder.bin/.idxwire-format 读写和越界/格式校验;大体积.bin使用 mmap/零拷贝,.idx元数据一次读入 RAM,示例只使用通用占位路径。4. Qwen3.5 dense:5 个文件
hyper_parallel/models/qwen3_5/__init__.py_ckpt_config_kwargs、_resolve_overrides、_build_config、register_specconfig.json合并 text/rope/tied-embedding 配置,层数缩减时同步处理layer_types,并注册 TP load transform 和 PP splitter。hyper_parallel/models/qwen3_5/checkpoint.py_remap_simple_key、load_hf_qwen3_5_state_dicthyper_parallel/models/qwen3_5/model.pyQwen3_5SdpaCore/Attention/GatedDeltaNet、mask/position helper、ForCausalLM.forward、StageModulehyper_parallel/models/qwen3_5/parallelize.pypipelining_qwen3_5、_apply_qwen3_5_pp_stage_tp、stage FSDP wrapper("dp_replicate","dp_shard")二维 mesh;参数整除只看实际 shard 轴。HSDP+CP 无法同时表达两个同步域时提前报错;PP+replicated-DP 保留 plain stage 交给 Trainer。dense PP+TP 原先关闭 full-model grad hooks 后没有在 stage 重挂:plain stage 现在安装 replicated-param hook,FSDP stage 则在 materialize/load 后通过 lazy post-FSDP reducer 同步,二者互斥且 VPP 每个本地 stage 都覆盖。hyper_parallel/models/qwen3_5/state_dict.pyQwen3_5StateDictAdapter5. Qwen3.5-MoE 与 Qwen3.5-MoE-VL:7 个文件
hyper_parallel/models/qwen3_5_moe/__init__.py_build/_build_vl、register_speclayer_types,增加 VL 分支和受控 MTP 开关,并注册模型入口。hyper_parallel/models/qwen3_5_moe/checkpoint.pyload_hf_qwen3_5_moe_vl_state_dicthyper_parallel/models/qwen3_5_moe/model.pyForCausalLM、StageModulehyper_parallel/models/qwen3_5_moe/model_vl.pyhyper_parallel/models/qwen3_5_moe/mtp.pyQwen3_5MoeMTP、mtp_lossmtp.*但原模型不消费;新增 next-2-token module,默认mtp_loss_weight=0,显式启用才进入总 loss;未覆盖的 TP/CP/PP 组合 fail-fast。hyper_parallel/models/qwen3_5_moe/parallelize.py_should_reduce、grad reducers、DP/HSDP/PP mesh resolver、visual FSDP、pipeline splitterdp_shard=-1从真实 mesh 解析,参数整除只看 shard 轴;HSDP+CP fail-fast;PP+HSDP 返回 plain stage由 Trainer 完整 DP reducer 同步。reducer 参数过滤复合谓词拆为 helper,保持短路顺序不变并消除复杂度越界。PP+EP 尚缺参数分类 stage reducer,现明确 fail-fast,避免可启动但 replicated 参数跨 EP 分叉。hyper_parallel/models/qwen3_5_moe/state_dict.pyQwen3_5MoeStateDictAdapter.load/savemodel_config.vl分流 VL loader,传递 text/vision depth 与 MTP 开关,VL 导出保留目标 namespace和 packed layout。6. Qwen3-VL-MoE、公共 Vision 与 ModelSpec:8 个文件
hyper_parallel/models/qwen3_vl_moe/__init__.py_build_vl、register_spechyper_parallel/models/qwen3_vl_moe/checkpoint.py_remap_key、load_hf_qwen3_vl_moe_state_dict(E,H,2I)/(E,I,H),runtime 使用(E,2I,H)/(E,H,I);加载时 transpose 到 runtime 布局,避免 grouped-MM 与 TP slicing 切错轴。hyper_parallel/models/qwen3_vl_moe/model.pyhyper_parallel/models/qwen3_vl_moe/parallelize.py_validate_vl_tp_cp_heads、TP/CP/EP hooks、_build_qwen3_vl_moe_pp_schedule、pipeline splitterdp_shard=-1从 mesh 解析,参数整除只看 shard 轴;PP+replicated-DP 保持 plain stage;HSDP+CP、PP+TP/EP、ragged VL PP 等当前不安全组合明确拒绝。最终把 TP+CP head 校验和 PP/VPP schedule 选择分别抽成 helper,异常文本、schedule 分支和参数对象均不变。hyper_parallel/models/qwen3_vl_moe/state_dict.pyQwen3VLMoeStateDictAdaptertext_config,不能依赖隐式顶层代理;显式区分 text-only/full-VL config并维持正确 HF namespace。hyper_parallel/models/qwen3_vl_vision/__init__.pyhyper_parallel/models/qwen3_vl_vision/model.pyhyper_parallel/models/spec/model_spec.pyModelSpec.tp_load_transform_fn7. Trainer 与启动脚本:7 个文件
hyper_parallel/trainer/base.py_validate_pp_runtime_options、_pp_normalize_grads、materialize/load、train step、PP loss/grad/clipdp_size/(n_valid*tp_loss_repeats),再进入 clip/optimizer;TP divisor消除 last-stage local replicated loss 的重复 backward sensitivity。loss aggregation、effective batch、AC 和 HF export 校验抽为单独 helper,校验优先级与异常文本保持。hyper_parallel/trainer/config.pyDataConfig、AcceleratorConfig、MixedPrecisionConfig、OptimizerConfigmax_grad_norm<=0语义。hyper_parallel/trainer/llm_trainer.pycp*tp整除 padding、mask/position ids和有效 token 数。hyper_parallel/trainer/parallel_dims.py_validate_*helpers、mesh specs、_register_data_flatten_aliases、_register_loss_flatten_alias、build_meshdp_replicate>1, dp_shard=1时 shard 轴被折叠:始终物化 size-1dp_shard,形成外层 replicate all-reduce、内层 no-op shard 的显式二维 HSDP topology。degree/dispatcher/product/EP/PP/Ulysses 校验及ep→fsdp→dp→lossalias 注册拆为职责单一 helper,保持校验顺序、异常文本、幂等判断和 alias 顺序。hyper_parallel/trainer/vl_trainer.py_vl_collate和 grid/position helperscripts/train_lm.pysetdefault(HYPER_PARALLEL_PLATFORM=torch),同时尊重用户显式覆盖。scripts/train_vl.py8. 关键跨文件因果关系
8.1 HSDP mesh 与 Trainer 归约域
dp,fully_shard无法区分外层dp_replicateall-reduce 与内层dp_shardreduce-scatter。dp_shard=-1必须从实际 mesh 解析。8.2 PP + nested FSDP + tied parameters
dp_size/(n_valid*tp_loss_repeats)梯度归一化,再 clip/step。直接使用 PP 不受 Trainer token-mean 策略影响;直接组合 TP 且把 replicated loss materialize 为 local tensor时,调用方需自行提供1/tpsensitivity。8.3 Partial Add/Sub 与 dtype
reduce_dtype只作用于真实 Partial reduction,不把普通 reshard输出意外提升到 FP32。8.4 VL checkpoint、vision 与 TP local load
这四处必须配套;只改其中一处会导致 expert 轴错误、层数读取错误或 full checkpoint tensor 与 TP local parameter shape 不匹配。公共 vision package、VL model 的 visual/DeepStack 边界和 parallelize hooks同样必须配套,才能在 TP/CP/PP 前后 gather、注入并恢复正确 layout。
8.5 复杂度治理为何需要配套修改多个文件
新增同步语义曾使若干函数越过代码检查门限。没有加入 suppression 或白名单,而是按职责边界做等价拆分:MoE reducer 参数谓词、VL TP+CP 约束、VL PP schedule、Trainer PP runtime options、ParallelDims 校验与 alias 注册。AST/行为矩阵确认条件、短路顺序、异常文本、schedule 分支和 alias 注册顺序不变;最终 production diff 按远端 Gate 同口径
CCN<20复验零告警,本轮关键修复函数另按CCN<=15、NLOC<=100通过。9. 验证摘要与边界
0.00203276;Qwen3.5-MoE 11/11,最大误差0.00417256;Qwen3-VL-MoE 14/14,最大误差0.00489401。最终 Trainer-owned scaling 下 densePP2+FSDP2与VPP2+FSDP2最大误差均为0.00147199,densePP2+TP2+FSDP2为0.00203276(step 2),VLPP2+FSDP2/1F1B为0.00242819(step 7)。4.9e-9。逐组合的卡数、step1/step20 loss、最大误差和启动步骤见 PR 描述。0.00794458;最终 Trainer-owned scaling 后未纳入通过矩阵,也不作为本 PR 的数值保证。Qwen3.5-MoEPP+EP当前明确 fail-fast。param_dtype=bfloat16、reduce/output_dtype=float32;BF16 output 不纳入该 PP 行的通过矩阵。