# Modules\_to\_save vs unload() in peft

**URL:** </static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fmodules-to-save-vs-unload-in-peft%2F156513%3E%5C
**Category:** Beginners\
**Created:** [May 23, 2025, 1:37pm UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fmodules-to-save-vs-unload-in-peft%2F156513 "2025-05-23T13:37:36Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![zpzpcici](https://avatars.discourse-cdn.com/v4/letter/z/b5ac83/32.png) [@zpzpcici](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Fu%2Fzpzpcici)%5C
**Post date:** [May 23, 2025, 1:37pm UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fmodules-to-save-vs-unload-in-peft%2F156513%2F1 "2025-05-23T13:37:36Z")

</div>

Recently, I need to use the `peft` library for LoRA fine-tuning, and at the same time, I want to fine-tune certain layers of my base model directly such as `lm_head`.  
I would like to save the parameters of my fine-tuned base\_model. While using `modules_to_save=["lm_head"]` in `LoraConfig` is a convenient approach, it results in high GPU memory usage. Alternatively, explicitly setting `requires_grad=True` for `lm_head` and saving it after training using `unload()`and `model.save_pretrained ("xxx")`leads to lower memory consumption. What are the differences between these two approaches in terms of saving the model?

---

<div class="post-metadata">

**Author:** ![John6666](https://sea2.discourse-cdn.com/hellohellohello/user_avatar/discuss.huggingface.co/john6666/32/27664_2.png) [@John6666](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Fu%2FJohn6666)%5C
**Post date:** [May 23, 2025, 3:45pm UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fmodules-to-save-vs-unload-in-peft%2F156513%2F2 "2025-05-23T15:45:03Z")

</div>

In theory, there doesn’t seem to be much difference in the results, but the behavior may differ significantly in practice.  
I think `save_pretrained()` is most likely to be well maintained.

> [@What is the proper way to add LoRa adapters and keep some layers trainable?](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fwhat-is-the-proper-way-to-add-lora-adapters-and-keep-some-layers-trainable%2F138112)%3A
>
> Hello everyone! Could someone explain why if I add LoRa adapters to a diffusion model using add\_adapter method the model layers, which I would like to keep trainable (mentioned in the config parameter modules\_to\_save), actually are not trainable? But they are trainable if I use get\_peft\_model method. Is it a bug or I misunderstand something? diffusers 0.32.1 peft 0.14.0 from diffusers import AutoencoderKL fro…

> <https://github.com/huggingface/peft/issues/2494>
>
> \*\*Summary:\*\*
> 
> When using \`peft.LoraConfig\` with \`modules\_to\_save=\["proj\_out"\]\`, …the parameters inside \`proj\_out\` (which are \`requires\_grad=True\` before adapter addition) are unexpectedly frozen (\`requires\_grad=False\`) after calling \`add\_adapter()\`.
> 
> This seems to contradict the intended functionality of \`modules\_to\_save\`, which should preserve the training status of specified modules.
> 
> \---
> 
> \*\*Environment:\*\*
> \- \`peft==0.15.1\` (latest)
> \- \`transformers\`, \`diffusers\` up-to-date
> \- Model: \[\`THUDM/CogVideoX-5b-I2V\`\](https://huggingface.co/THUDM/CogVideoX-5b-I2V)
> \- Python 3.10
> \- Torch 2.6.0+cu118
> 
> \---
> 
> \*\*Code to Reproduce:\*\*
> 
> \`\`\`python
> from diffusers.models import CogVideoXTransformer3DModel
> import torch
> from peft import LoraConfig
> 
> pretrained\_model\_name\_or\_path = "THUDM/CogVideoX-5b-I2V"
> 
> transformer = CogVideoXTransformer3DModel.from\_pretrained(
> pretrained\_model\_name\_or\_path,
> subfolder="transformer",
> torch\_dtype=torch.bfloat16,
> )
> 
> print("before LoRA")
> print(transformer.proj\_out.weight.requires\_grad) # True
> print(transformer.proj\_out.bias.requires\_grad) # True
> 
> transformer\_lora\_config = LoraConfig(
> r=4,
> lora\_alpha=4,
> init\_lora\_weights=True,
> target\_modules=\["to\_k", "to\_q", "to\_v", "to\_out.0"\],
> modules\_to\_save=\["proj\_out"\]
> )
> transformer.add\_adapter(transformer\_lora\_config)
> 
> print("after LoRA")
> print(transformer.proj\_out.weight.requires\_grad) # ❌ False (unexpected)
> print(transformer.proj\_out.bias.requires\_grad) # ❌ False (unexpected)
> \`\`\`
> 
> \---
> 
> \*\*Expected behavior:\*\*
> 
> After calling \`add\_adapter()\`, since \`"proj\_out"\` is explicitly listed in \`modules\_to\_save\`, both \`.weight\` and \`.bias\` of \`transformer.proj\_out\` should \*\*remain trainable\*\*, i.e., \`requires\_grad=True\`.
> 
> \---
> 
> \*\*Observed behavior:\*\*
> 
> Both \`.weight\` and \`.bias\` of \`proj\_out\` become \`requires\_grad=False\`, even though \`"proj\_out"\` appears exactly in \`named\_parameters()\` before the adapter is added.

> [@Missing trainable parameters in a loaded LoRA model](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fmissing-trainable-parameters-in-a-loaded-lora-model%2F45816)%3A
>
> I followed [this blog post](https://huggingface.co/blog/peft) for saving and loading a PEFT model. I defined my model as model = AutoModelForSequenceClassification.from\_pretrained('roberta-base', return\_dict=True) peft\_config = LoraConfig(task\_type="SEQ\_CLS", inference\_mode=False, r=8, lora\_alpha=16, lora\_dropout=0.1) model = get\_peft\_model(model, peft\_config) model.print\_trainable\_parameters() I saved it with save\_path = './test\_save' model.save\_pretrained(save\_path) and load it with config = PeftConfig.from\_pretrained(save\_…
