Skip to content

FIX: inject_adapter incorrectly propagates inference_mode to active adapters#3290

Open
kiritozc wants to merge 2 commits into
huggingface:mainfrom
kiritozc:fix/inject-adapter-inference-mode-propagation
Open

FIX: inject_adapter incorrectly propagates inference_mode to active adapters#3290
kiritozc wants to merge 2 commits into
huggingface:mainfrom
kiritozc:fix/inject-adapter-inference-mode-propagation

Conversation

@kiritozc

Copy link
Copy Markdown

Description

When injecting a new adapter via inject_adapter, the housekeeping section calls:

self.set_adapter(self.active_adapters, inference_mode=peft_config.inference_mode)

Here peft_config belongs to the newly injected adapter, but self.active_adapters points to the existing active adapter(s). When the new adapter has inference_mode=True (e.g. during save_pretrained with path_initial_model_for_weight_conversion in PiSSA/OLoRA/CorDA workflows), this erroneously freezes the already-active training adapter, causing grad_norm to become 0 and training to effectively stop.

Fix

Only propagate inference_mode when the new adapter IS the active adapter (first-time injection). For subsequent adapters, set_adapter is called without inference_mode, preserving the existing active adapter's trainability state. The new adapter's own inference_mode is still correctly handled by the existing code below.

Tests

  • Added test_inject_adapter_inference_mode_does_not_freeze_active_adapter — a regression test covering LoraConfig, LoHaConfig, LoKrConfig, IA3Config, OFTConfig, BOFTConfig
  • Two existing xfailing tests (switch_inference_mode and add_adapter) remain as xfail since they require decoupling active adapter selection from requires_grad in set_adapter

Related

…ctive adapters

When injecting a new adapter via inject_adapter, the housekeeping section
called set_adapter(self.active_adapters, inference_mode=peft_config.inference_mode).
Here peft_config belongs to the newly injected adapter, but self.active_adapters
points to the existing active adapter(s). When the new adapter has
inference_mode=True (e.g. during save_pretrained with
path_initial_model_for_weight_conversion in PiSSA/OLoRA/CorDA workflows),
this erroneously freezes the already-active training adapter, causing
grad_norm to become 0 and training to effectively stop.

The fix only propagates inference_mode when the new adapter IS the active
adapter (first-time injection). For subsequent adapters, set_adapter is
called without inference_mode, preserving the existing active adapter's
trainability state. The new adapter's own inference_mode is still correctly
handled by the existing code that follows.

This was a regression introduced in commit 13fa0ae (PR huggingface#2765).

A regression test is added that verifies adding an adapter with
inference_mode=True does not freeze the existing active adapter.

@BenjaminBossan BenjaminBossan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for fixing this edge case. This fix looks good but I have two small comments regarding the test, please check.

Comment thread tests/test_custom_models.py Outdated
params_with_grad = [n for n, p in model.named_parameters() if p.requires_grad]
assert all(not p.requires_grad for p in model.parameters())

@pytest.mark.parametrize("config_cls", [LoraConfig, LoHaConfig, LoKrConfig, IA3Config, OFTConfig, BOFTConfig])

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OFT is failing to initialize with the given arguments. But I think for this test, just checking LoRA is enough (like in the previous tests).

Comment thread tests/test_custom_models.py Outdated
# Regression test for a bug where adding a second adapter with inference_mode=True would incorrectly freeze
# the already-active training adapter. This happened because inject_adapter propagated the new adapter's
# inference_mode to set_adapter for the existing active adapters.
# See PR #XXXX

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update the comment.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, I've addressed both review comments:

Please take another look. Thanks!

@HuggingFaceDocBuilderDev

Copy link
Copy Markdown

The docs for this PR live here. All of your documentation changes will be reflected on that endpoint. The docs are available until 30 days after the last update.

@BenjaminBossan BenjaminBossan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of tests are failing now. I think this is because they baked in the previous assumption and thus may require updating. Could you please take a look?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants