fix(kimi_k25): map lm_head to model.language_model.lm_head - #3632
Conversation
…-level key
KimiK25VLStateDictAdapter.from_hf renamed language_model.lm_head.* to
lm_head.*, which matches no parameter of KimiK25VLForConditionalGeneration
(the head lives at model.language_model.lm_head.*).
The base-model load runs set_model_state_dict(strict=False),
so the mismatch is only a warning
("missing=['model.language_model.lm_head.weight'] unexpected=['lm_head.weight']")
and the head keeps its random init: every K2.5 fine-tune through this path
trains against an uninitialised output head.
Apply the same "model." + key rule the adapter already uses for the other
language_model.* keys. With the fix the warning is gone and step-0 SFT loss
on chat data is 2.18 (a random head gives ~ln(163840) ≈ 12).
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Aarni Koskela <akx@iki.fi>
|
I think the FQN correction itself is valid, but the current root-cause statement ("the head was left at random init on every load since #1132") does not appear to be accurate. I tested this with the actual Kimi-K2.5 checkpoint:
The reason is that the multi-rank DCP path builds its HF state dict from tensors that alias the final model storage. DCP writes the checkpoint into the real I can reproduce an actual regression at
That commit routes the single-rank case through the full-state path, where checkpoint tensors no longer alias model storage and the incorrect FQN is silently ignored by Could you clarify the topology used for the reported step-0 loss and whether 2.18 was true same-input base/head A/B? If it was a normal multi-rank run, this mapping change should not affect the loaded head or loss. I suggest reframing this as fixing the Kimi adapter contract and the single-rank full-state regression introduced by #3574. It would also be good to add a regression test through the single-device |
What does this PR do ?
Fixes the Kimi-K2.5 state-dict adapter mapping
language_model.lm_head.*to a top-levellm_head.*key that no parameter has, which left the output head at random init on every load throughNeMoAutoModelForCausalLM/KimiK25VLForConditionalGeneration.Changelog
kimi_k25_vl/state_dict_adapter.py:from_hfmapslanguage_model.lm_head.*tomodel.language_model.lm_head.*(the model's actual FQN), using the same"model." + key rule the adapter already applies to the otherlanguage_model.*` keys.Background: loading
moonshotai/Kimi-K2.5loggedCheckpoint key mismatch ... missing=['model.language_model.lm_head.weight'] unexpected=['lm_head.weight']and continued, because the base-model load usesset_model_state_dict(strict=False). Training then runs against an uninitialised head with a plausible-looking loss curve. With this fix the warning is gone and step-0 SFT loss on chat data is 2.18 (a random head gives ~ln(163840) ≈ 12).Before your PR is "Ready for review"
Pre checks:
Additional Information