huggingface / huggingface/peft

LN Tuning: KeyError on forward/merge when the active adapter does not target all adapted layers

Open
#3,574 9 comments 0 reactions 1 assignee Claimed by @BenjaminBossan View on GitHub
Dominant language
Python
Stars
21.7k
Forks
2.5k
Avg merge
4d 12h
Merged PRs (30d)
59

Description

### System Info

peft 0.20.1.dev0 (main, b60f055), torch 2.13.0, Python 3.11, macOS (CPU)

### Who can help?

@BenjaminBossan @githubnemo

### Information

- [ ] The official example scripts
- [x] My own modified scripts

### Tasks

- [ ] An officially supported task in the `examples` folder
- [x] My own task or dataset

### Reproduction

```python
import torch, torch.nn as nn
from peft import LNTuningConfig, get_peft_model

class MLP(nn.Module):
def __init__(self):
super().__init__()
self.lin0 = nn.Linear(10, 20); self.relu = nn.ReLU(); self.lin1 = nn.Linear(20, 10)
def forward(self, x):
return self.lin1(self.relu(self.lin0(x)))

model = get_peft_model(MLP(), LNTuningConfig(target_modules=["lin0", "lin1"]), adapter_name="first")
model.add_adapter("second", LNTuningConfig(target_modules=["lin0"]))
model.set_adapter("second")
model(torch.randn(4, 10)) # KeyError: 'second'
```

Full traceback ends:

```
File ".../peft/tuners/ln_tuning/layer.py", line 120, in forward
result = self.ln_tuning_layers[active_adapter](x, *args, **kwargs)
File ".../torch/nn/modules/container.py", line 555, in __getitem__
KeyError: 'second'
```

`model.merge_adapter()` in the same state also raises `KeyError: 'second'` (from `merge`, which indexes `adapter_names[0]` without a membership check).

### Expected behavior

When multiple LN Tuning adapters target different modules, activating one adapter should work like every other PEFT method: layers not targeted by the active adapter fall back to their base layer instead of raising a KeyError (e.g. LoRA does `if active_adapter not in self.lora_A.keys(): continue`; IA³ has the same membership guard). The existing test `test_requires_grad_lntuning_different_targets` already sets up this exact configuration — it just never calls forward, so the crash was never caught.

I have a fix ready (membership filter + base-layer fallback in `forward`/`merge`, with regression tests that fail on main and pass with the fix; the LN Tuning test selection passes 231/231). Per the contribution guidelines I'll wait for a maintainer go-ahead here before opening the PR. AI assistance was used in finding and preparing this; I have reviewed and run everything.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.