Fix action embedder MLP initialization after FSDP checkpoint load - #5
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Action Embedder MLP Initialization Fix
Problem
When fine-tuning the action-conditioned DiT
(
ActionConditionedMinimalV1LVGDiT/ActionChunkConditionedMinimalV1LVGDiT)from the pre-trained Cosmos-Predict2.5 base checkpoint, the two action
embedder MLPs (
action_embedder_B_Dandaction_embedder_B_3D) end up withall-zero weights and biases, making action conditioning non-functional.
Root cause
Mlpmodules aftersuper().__init__(). These modules do not exist in the pre-trained basecheckpoint.
metadevice forFSDP and then loads the base checkpoint with
strict=False.action_embedderkeys, thoseparameters are silently skipped during loading and materialized as
all-zero tensors.
Consequences
actions.
following actions" comes from the conditioning frames, not from the action
signal.
Solution
After checkpoint loading in the trainer, detect whether all action embedder
weight matrices on
model.netare exactly zero. If so, apply standardnn.LinearKaiming uniform initialization directly on the local tensorstorage (bypassing DTensor dispatch), copy the new weights into
model.net_emavia the existing EMA updater, and synchronize across ranks.Decision logic
The re-init is gated so it runs only in the scenarios where it is safe and
desired:
iterationDistributed-training handling
The fix handles both FSDP-sharded and non-FSDP distributed runs:
model.fsdp_device_mesh is not None):every rank re-initializes its own local shard via
.to_local(), copiesnet -> net_emavia the existing EMA updater, and then callsbroadcast_dtensor_model_states(...)to synchronize replica groups.net -> net_ema, thendistributed.sync_model_states(...)broadcasts toall other ranks.
Verification
Diagnostic logging is added to the trainer to report the action embedder
weight norms at four phases:
POST-CKPT-LOAD,POST-REINIT,PRE-FIRST-STEP, andPOST-STEP-{1, 2, 5, 10, 50, 100}. Expected behavior:0.000000.POST-CKPT-LOADis0.000000;POST-REINITis nonzero and matches the standard Kaiming uniform scale;subsequent
POST-STEP-Nsnapshots show the weights evolving undergradient descent.
re-init and training continues with the trained weights unchanged.
Files changed
cosmos_predict2/_src/predict2/action/networks/action_conditioned_minimal_v1_lvg_dit.pyMlp.init_weights(): applies Kaiming uniform initializationdirectly on the local tensor storage via
.to_local()when theparameter is a DTensor, so it works correctly for DTensor-sharded
parameters where
reset_parameters()can be silently intercepted bythe DTensor dispatch layer.
reinitialize_action_embedders()to bothActionConditionedMinimalV1LVGDiTandActionChunkConditionedMinimalV1LVGDiT: iterates over both actionembedder MLPs, calls
init_weights()on each, and logs the resultinglocal weight norms.
cosmos_predict2/_src/imaginaire/trainer.py_reinitialize_action_embedders_if_needed(model, iteration)implementing the gated re-init logic described above.
_log_action_embedder_state(model, phase)that walksmodel.named_parameters()and reports norm, min, max, and gradientnorm for every
action_embedderparameter (using.to_local()forDTensor-backed parameters).
ImaginaireTrainer.train():POST-CKPT-LOADdiagnostic after
checkpointer.load(...), followed by the_reinitialize_action_embedders_if_needed(...)call, thenPOST-REINITandPRE-FIRST-STEPdiagnostics, andPOST-STEP-Ndiagnostics inside the training loop.
broadcast_dtensor_model_statesfromcosmos_predict2._src.predict2.utils.dtensor_helper.