1 介紹
- PEFT (Parameter-Efficient Fine Tuning) 方法在微調時凍結預訓練模型參數,并在其上添加少量可訓練的參數(稱為適配器)
- 這些適配器被訓練用來學習特定任務的信息。
- 這種方法已被證明在內存效率和計算使用上非常高效,同時能產生與完全微調模型相當的結果。
- 使用PEFT訓練的適配器通常比完整模型小一個數量級,這使得分享、存儲和加載它們變得非常方便。
- 例如,一個OPTForCausalLM模型的適配器權重在Hub上的存儲只有約6MB
- 相比之下,完整的模型權重可以達到約700MB。
2 加載 PEFT適配器
2.1 直接from_pretrained加載
- 若要從?Transformers 加載和使用 PEFT 適配器模型,請確保 Hub 存儲庫或本地目錄包含 adapter_config.json 文件和適配器權重
- 然后,可以使用 AutoModel類加載 PEFT 適配器模型
from transformers import AutoModelForCausalLM, AutoTokenizerpeft_model_id = "ybelkada/opt-350m-lora"
model = AutoModelForCausalLM.from_pretrained(peft_model_id)
2.2 load_adapter加載
from transformers import AutoModelForCausalLMmodel_id = "facebook/opt-350m"
peft_model_id = "ybelkada/opt-350m-lora"model = AutoModelForCausalLM.from_pretrained(model_id)
model.load_adapter(peft_model_id)
?2.3 以8位/4位加載
- bitsandbytes 集成支持 8 位和 4 位精度數據類型,這對于加載大型模型非常有用,因為它節省了內存
- 在 from_pretrained() 中添加 load_in_8bit 或 load_in_4bit 參數,并設置 device_map="auto" 以有效地將模型分配到你的硬件
from transformers import AutoModelForCausalLM, AutoTokenizerpeft_model_id = "ybelkada/opt-350m-lora"
model = AutoModelForCausalLM.from_pretrained(peft_model_id, device_map="auto", load_in_8bit=True)
3 添加適配器?
from transformers import AutoModelForCausalLM
from peft import LoraConfigmodel_id = "facebook/opt-350m"
model = AutoModelForCausalLM.from_pretrained(model_id)
#加載這個模型lora_config = LoraConfig(target_modules=["q_proj", "k_proj"],init_lora_weights=False
)
'''
target_modules 參數指定了將 LoRA 適配器應用于模型的哪些部分這里是 "q_proj"(查詢投影)和 "k_proj"(鍵投影)init_lora_weights 設置為 False,意味著在初始化時不加載 LoRA 權重
'''model.add_adapter(lora_config, adapter_name="adapter_1")
#使用 add_adapter 方法將之前配置的 LoRA 適配器添加到模型中,適配器命名為 "adapter_1"model.add_adapter(lora_config, adapter_name="adapter_2")
# 附加具有相同配置的新適配器"adapter_2"
4 設置使用哪個適配器
# 使用 adapter_1
model.set_adapter("adapter_1")
output = model.generate(**inputs)
print(tokenizer.decode(output_disabled[0], skip_special_tokens=True))# 使用 adapter_2
model.set_adapter("adapter_2")
output_enabled = model.generate(**inputs)
print(tokenizer.decode(output_enabled[0], skip_special_tokens=True))
5 啟用和禁用適配器
一旦向模型添加了適配器,可以啟用或禁用適配器模塊
from transformers import AutoModelForCausalLM, OPTForCausalLM, AutoTokenizer
from peft import PeftConfigmodel_id = "facebook/opt-350m"
adapter_model_id = "ybelkada/opt-350m-lora"tokenizer = AutoTokenizer.from_pretrained(model_id)
text = "Hello"
inputs = tokenizer(text, return_tensors="pt")
#加載分詞器和初始化輸入model = AutoModelForCausalLM.from_pretrained(model_id)
peft_config = PeftConfig.from_pretrained(adapter_model_id)
'''
加載了預訓練的基礎模型 facebook/opt-350m 和適配器的配置。PeftConfig.from_pretrained 方法用于加載預定義的適配器配置。
'''peft_config.init_lora_weights = False
model.add_adapter(peft_config)
'''
在添加適配器前,設置 init_lora_weights = False 指明在初始化時不使用預訓練的 LoRA 權重,
而是使用隨機權重。然后將適配器添加到模型中。
'''model.enable_adapters()
output1 = model.generate(**inputs)
#啟用適配器,然后使用啟用了適配器的模型生成文本model.disable_adapters()
output2 = model.generate(**inputs)
#禁用適配器后,再次生成文本以查看不使用適配器時模型的輸出表現tokenizer.decode(output1[0])
'''
'</s>Hello------------------'
'''tokenizer.decode(output2[0])
'''
"</s>Hello, I'm a newbie to this sub. I'm looking for a good place to"
'''
6 訓練PEFT適配器
6.1 舉例:添加lora適配器
6.1.1?定義你的適配器配置
from peft import LoraConfigpeft_config = LoraConfig(lora_alpha=16,lora_dropout=0.1,r=64,bias="none",task_type="CAUSAL_LM",
)
lora_alpha=16
:指定 LoRA 層的縮放因子。lora_dropout=0.1
:設置在 LoRA 層中使用的 dropout 比率,以避免過擬合。r=64
:設置每個 LoRA 層的秩,即低秩矩陣的維度。bias="none"
:指定不在 LoRA 層中使用偏置項。task_type="CAUSAL_LM"
:設定這個 LoRA 配置是為了因果語言模型任務。
6.1.2 將適配器添加到模型
model.add_adapter(peft_config)
6.1.3將模型傳遞給 Trainer以進行訓練
from transformers import Trainer
trainer = Trainer(model=model, ...)
trainer.train()