huggingface / huggingface/peft
Four of the five diffusers-style tuner docstring examples (LoHa, LoKr, OFT, MiSS) fail as written
- 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 (editable install from `src/`, upstream `main` at `a4c223f3`)
- transformers 5.8.1
- accelerate 1.13.0
- diffusers 0.37.1
- torch 2.12.0+cu130
- Python 3.10.20
- Linux-7.0.0-30-generic-x86_64-with-glibc2.39
Three of the four failures are version-independent: they raise inside `__init__` of the config dataclass, before any model or checkpoint is touched. The MiSS failure needs a pipeline loaded, but reproduces on any SD 1.5-shaped checkpoint.
### Who can help?
@BenjaminBossan
### Reproduction
Five PEFT methods carry an `Example:` block in `model.py` that adapts a `StableDiffusionPipeline`: LoHa, LoKr, OFT, MiSS and HRA. All five reach the API reference via `[[autodoc]]` (`loha.md:90`, `lokr.md:64`, `oft.md:98`, `miss.md:102`, `hra.md:40`), so they are what a reader copies off the docs site. Four cannot run, each for a different reason.
| method | result |
|---|---|
| LoHa | `TypeError: LoHaConfig.__init__() got an unexpected keyword argument 'lora_alpha'` |
| LoKr | `TypeError: LoKrConfig.__init__() got an unexpected keyword argument 'lora_alpha'` |
| OFT | `ValueError: You can only specify either r (8) or oft_block_size (32), but not both simultaneously, because r x oft_block_size == in_features.` |
| MiSS | `TypeError: Target module Conv2d(64, 64, kernel_size=(1, 1), stride=(1, 1)) is not supported. Currently, only torch.nn.Linear (optionally quantized) is supported.` |
| HRA | runs |
To reproduce, copy the `Example:` block out of any of the four `model.py` files and run it. LoHa, LoKr and OFT fail at the first config, before the pipeline is fetched:
```py
>>> from peft import LoHaConfig
>>> LoHaConfig(task_type="SEQ_2_SEQ_LM", r=8, lora_alpha=32, target_modules=["k_proj"])
TypeError: LoHaConfig.__init__() got an unexpected keyword argument 'lora_alpha'
```
**LoHa, LoKr — `lora_alpha` is not a field on either config.** `src/peft/tuners/loha/model.py`, `src/peft/tuners/lokr/model.py`, two call sites each. The field is `alpha`; `git log -S lora_alpha` on both config files is empty. Copied from a LoRA block and never adjusted — broken since `7a5f17f3` (#956) and `884b1ac3` (#978). `tests/test_stablediffusion.py` passes `"alpha": 32` here, so this is a rename rather than a deletion.
**OFT — `r=8` collides with the default `oft_block_size=32`.** `OFTConfig` defaults to `r=0`, `oft_block_size=32`, and `oft/config.py` enforces an exclusive-or:
```py
if not (self.r != 0) ^ (self.oft_block_size != 0):
raise ValueError(...)
```
A value-only check despite the message naming `in_features`, so the example raises on any checkpoint. The example predates the check — `da17ac0f` (#1160) versus `2a807359` (#1996). The tests pair them as `"r": 1, "oft_block_size": 0`.
**MiSS — targets modules MiSS cannot adapt.** `src/peft/tuners/miss/model.py` targets `proj_in` and `proj_out`, which are `Conv2d` in SD 1.5. MiSS supports `Linear` only, unlike HRA's `HRAConv2d`. The block is a verbatim copy of HRA's — only the class names differ — and it arrived with Bone in `13fb29f0` (#2172, 2024-11-05), whose layer had no `Conv2d` support either;
`bb4fb50e` (#2604) renamed Bone to MiSS and carried it across unchanged. So it has never run. It is also the only one of the five untested in `tests/test_stablediffusion.py`.
**Smaller finding: all five construct the tuner class directly.**
```py
>>> model.text_encoder = LoHaModel(model.text_encoder, config_te, "default")
```
This does not raise, which is the problem: `BaseTuner.__getattr__` forwards to the wrapped module, so `save_pretrained` resolves to `PreTrainedModel.save_pretrained` and silently writes a base-model checkpoint rather than an adapter. You asked for `get_peft_model` in the #3254 review; #3657 covers `lora`, `hira` and `beft` — these five are the rest.
### Expected behavior
All five examples should run as written, and each adapted sub-module should be a `PeftModel` whose `save_pretrained` writes an adapter.
**Proposed scope.** One PR, docstrings only: rename the keyword in LoHa and LoKr, add `oft_block_size=0` in OFT, replace MiSS's Stable Diffusion example with a causal-LM one, and switch all five to `get_peft_model`. Batched across the five methods rather than split per file, per `AGENTS.md`. No runtime change. The acceptance test is executable — all five run, each adapted sub-module returns a `PeftModel`.
**On MiSS I now think the example should be dropped rather than made to run.** Restricting its unet targets to the `Linear` subset would work, but nothing about the method suggests a Stable Diffusion example was ever intended: the paper is framed entirely around LLMs, `examples/miss_finetuning` fine-tunes `AutoModelForCausalLM`, and the reference implementation
at `Joluck/MiSS` has no mention of `Conv2d`, diffusion or a unet. MiSS is also the only one of the five with no `Conv2d` layer at all. The other `Linear`-only methods already have a house pattern — `vera`, `shira` and `ln_tuning` each carry a short causal-LM example built with `get_peft_model` — so I would give MiSS one of those. Happy to keep an SD example instead if you would rather.
Would a PR be welcome? I will wait for your go-ahead before coding.
*AI assistance: I used Claude Code to help audit and draft this. I ran every command myself and can defend the change end-to-end.*
Contributor guide
Research direction
Start with the Example blocks in the five tuner model.py files, especially src/peft/tuners/loha/model.py, src/peft/tuners/lokr/model.py, and src/peft/tuners/miss/model.py, and compare their configs with tests/test_stablediffusion.py. Run each example and verify that all five complete, adapted sub-modules are PeftModel instances, and save_pretrained writes an adapter checkpoint.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, pytorch
- Domain
- documentation
- Issue type
- Documentation
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100