fix(fsdp): resolve fp32 master-weight compute dtype per parameter (#3328)
* fix(fsdp): resolve fp32 master-weight compute dtype per parameter Custom MoE models (e.g. Qwen3.5/3.6-MoE) never record `_hf_compute_dtype`, so every parameter falls to the compute-dtype fallback in `_make_compute_dtype_fn`. The fallback keyed on a module-global `storage_is_uniform` flag, which a single native-bf16 sibling (`shared_expert_gate`) flips false -- misclassifying the layer's fp32 master weights as fp32 compute. With #3255's `cast_forward_inputs=False`, the misclassified fp32 unit no longer casts its bf16 input and the forward crashes (`bf16 @ fp32`). Resolve the fallback per parameter: unhinted fp32 storage under a lower-precision policy is an fp32 master weight and computes in the policy dtype; any other storage keeps its own dtype. A single bf16 sibling no longer forces the layer's fp32 master weights into fp32 compute. The `(storage, compute)` grouping still keeps each FSDP unit storage-uniform, so `_init_mp_dtypes` is unaffected. Fixes #3327 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Signed-off-by: NancyFyong <88076188+NancyFyong@users.noreply.github.com> * fix(qwen3_5_moe): pin _fp32_params compute, build shared_expert_gate in dtype Follow-up to the per-parameter compute-dtype fallback (#3328). Two gaps that the resolver change exposes on Qwen3.5-MoE: - The MoE parallelizer keys the fp32 compute pin on `_keep_in_fp32_modules_strict`, which the model never set, so the SSM-gating A_log/dt_bias fell to the policy dtype (bf16) instead of fp32. Add the strict entry, matching the inkling/kimi_k3 siblings. - `shared_expert_gate` was built at the `initialize_linear_module` default (bf16) even under fp32 master-weight storage, making it the lone bf16 sibling the #3327 fallback has to tolerate. Build it in `config.dtype`. Add a compute-contract regression test for the mixed-storage, no-HF-hint layout (fp32 masters + a genuinely-bf16 shared_expert_gate + the fp32 holder): ordinary weights and the gate compute bf16; only the pinned A_log/dt_bias stay fp32. Fixes #3327 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Signed-off-by: NancyFyong <88076188+NancyFyong@users.noreply.github.com> * fix(qwen3_next): pin _fp32_params fp32 compute via strict contract Qwen3-Next uses the same intrinsic-fp32 `_fp32_params` holder but declared it only in `_keep_in_fp32_modules`. The MoE parallelizer keys the fp32 compute pin on `_keep_in_fp32_modules_strict`, so under the generalized fallback its A_log/dt_bias would compute in bf16. Add the strict entry, matching Qwen3.5-MoE. Add a model-owned assertion guarding the strict declaration on every model with the holder, so a future model that forgets the contract fails a test rather than silently dropping to bf16. Fixes #3327 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Signed-off-by: NancyFyong <88076188+NancyFyong@users.noreply.github.com> --------- Signed-off-by: NancyFyong <88076188+NancyFyong@users.noreply.github.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: Alexandros Koumparoulis <153118171+akoumpa@users.noreply.github.com>
N
NancyFyong committed
eca4a8e1cdb7f808d9faf3a3a025bdc490c5e5e1
Parent: c2b929f
Committed by GitHub <noreply@github.com>
on 8/4/2026, 3:39:50 AM