You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Three independent bugs in the NNX path, surfaced by running DeepSeek-V3 with
multi-token prediction.
mtp_loss was silently 0. mtp_losses/mtp_acceptance subclass nnx.Intermediate and
nnx type filters match by isinstance, so the generic nnx.pop(model,
nnx.Intermediate) in loss_fn consumed them before the dedicated pop ran. That pop
then returned empty and calculate_mtp_loss fell through to its 0.0 default. Pop
the subclasses first. Linen is unaffected; it keys mutable collections by name.
qwix quantization crashed with "roll requires ndarray, got NoneType". NNX modules
are stateful, so quantize_model must run a real forward pass, but only tokens,
positions and segment ids were passed and the MTP block reads the decoder targets
unconditionally. Pass dummy targets, restoring the semantics of the
is_initializing() guard the NNX port left commented out. Linen never traces a
forward during quantization, so it never hit this.
DeepSeek params were left replicated, tripping assert_params_sufficiently_sharded
once the crash above was fixed. _create_scanned_layers records each stack's axis
name in nnx.PARTITION_NAME ("dense_layers"/"moe_layers"), but the scan-axis
round-trip hardcoded the literal "layers". The name never matched, so the fallback
stripped a real logical axis instead of the scan axis and a bogus "layers" was
inserted: ('embed','dense_layers','mlp') became ('dense_layers','layers','mlp').
'embed' is the only carrier of fsdp, hence P(None, ...). This is neither an MTP
nor a qwix bug: it corrupts on every forward for multi-stack models, but is
normally invisible because the sharding snapshot is taken before the first train
step. qwix makes it fatal only because it quantizes inside model construction,
within the traced snapshot. Resolve the axis name per-variable from
nnx.PARTITION_NAME, and raise on inconsistent metadata rather than blindly
stripping an axis, as flax's own nnx.spmd.remove_axis does.
Verified on deepseek3-tiny (v6e-8) with sharding_tolerance untouched: nnx+mtp and
nnx+mtp+qwix now both report mtp_loss 1.224, matching the Linen reference. The
sharding metadata round-trip goes from 29 of 32 params corrupted to 0. gpt3-52k,
gpt3-52k+qwix, gemma2-2b and deepseek3-tiny with scan_layers=false all train clean.
Add regression tests for all three. multi_token_prediction_test.py drives the real
loss_fn and asserts a non-zero MTP loss; quantizations_nnx_mtp_test.py quantizes an
MTP model through qwix without crashing; maxtext_utils_nnx_test.py checks the
scan-axis helpers keep the real logical axis. Each fails on the pre-fix code.
0 commit comments