fix(qwen2_5_omni): put the thinker prefix inside the peft prefix on lora saves - #3672
Conversation
…ora saves Fixes NVIDIA-NeMo#3655. Same bug NVIDIA-NeMo#3630 fixes for qwen3_omni_moe: on peft saves the adapter prepended "thinker." to every key, including ones already carrying the "base_model.model." outer prefix, so the exported adapter had keys HF PEFT can't attach. It also broke imports of correctly named external adapters, which passed through from_hf unchanged. The thinker namespace now goes inside the peft prefix on save, from_hf strips it from either position and drops talker/token2wav keys in either position too, and old malformed saves still resume through the leading-strip fallback. The adapter also overrides map_peft_target_module_to_hf so adapter_config.json target_modules carry the thinker namespace, keeping peft's suffix matching off the talker's structurally identical submodules. Signed-off-by: stanley1208 <stanley.mei08@gmail.com>
|
/ok to test 0ec219f |
yuhezhang-ai
left a comment
There was a problem hiding this comment.
Reviewed the prefix conversion, metadata target mapping, and legacy loading paths; no blocking findings.
Validation: all 17 focused adapter tests passed. An additional tiny-model CPU check using Transformers 5.15.1 and PEFT 0.19.1 exercised native Checkpointer.save_model and real PeftModel.from_pretrained: all eight adapter tensors loaded exactly, bulk and single-tensor exports agreed, and no adapters were injected into talker/token2wav. Reloaded text logits matched exactly; merged logits differed by at most 5.96e-8. Checkpointer.load_model restored both current and legacy malformed checkpoint names exactly. CI is green on this revision.
This is a suitable incremental fix toward #3867. Please carry the real Qwen2.5 Omni consumer regression into that shared suite as a follow-up.
…family Adding qwen2_5_omni to the reload suite turned up two problems in its map_peft_target_module_to_hf, both already fixed on its qwen3_omni_moe sibling. The signature was missing v4_compatible. addons.py:566 always passes it, so every PEFT save raised TypeError while writing adapter_config.json. The base class has taken that argument since NVIDIA-NeMo#3866; the override landed a week later in NVIDIA-NeMo#3672 without it, and nothing noticed because this family had no coverage. It also added the thinker. namespace unconditionally, while to_hf and convert_single_tensor_to_hf both check _uses_thinker_prefix first. On a thinker-only base that leaves adapter_config.json pointing at modules the receiving model does not have. Same defect as the one found in review on NVIDIA-NeMo#3945, which this family never had applied to it. The tiny fixture needed three rounds of shrinking: the talker and token2wav sub-configs are not coerced from dicts, and the talker carries its own sizes as well as a nested text_config. Left alone the reload target built 6.6B parameters in five minutes; it is now 1.4M in two seconds. Verified it bites: restoring the old hook fails four of the seven cases. Signed-off-by: stanley1208 <stanley.mei08@gmail.com>
Fixes #3655. same bug #3630 fixes for qwen3_omni_moe, just in this adapter.
when you train a lora and save it, every weight gets a name. this adapter added
thinker.to the start of every name, but peft names must start withbase_model.model.. withthinker.in front, hf peft doesn't recognize any of the names, so the saved adapter can't be used. loading adapters made outside automodel failed for the same reason.what changed:
thinker.now goes in the right spot, afterbase_model.model.instead of before it. loading understands both the new and the old naming, so existing saves still workadded cpu tests for all of the above.