PEFT 文件
模型合併
並獲得增強的文件體驗
開始使用
模型合併
為每個任務訓練一個模型可能成本高昂、佔用儲存空間,並且模型無法學習新資訊以提高其效能。多工學習透過訓練一個模型來學習多個任務,可以克服其中一些限制,但它的訓練成本很高,並且為其設計資料集也具有挑戰性。模型合併透過將多個預訓練模型組合成一個模型,提供了一種解決這些挑戰的方案,使其具有每個獨立模型的組合能力,而無需任何額外訓練。
PEFT 提供了幾種模型合併方法,例如線性或 SVD 組合。本指南重點介紹兩種更高效地合併 LoRA 介面卡的方法,透過消除冗餘引數
- TIES - TrIm, Elect, and Merge (TIES) 是一種三步模型合併方法。首先,修剪冗餘引數,然後將衝突的符號解析為聚合向量,最後將符號與聚合符號相同的引數進行平均。此方法考慮了某些值(冗餘和符號不一致)可能會降低合併模型效能的情況。
- DARE - Drop And REscale 是一種可用於準備其他模型合併方法(如 TIES)的方法。它透過根據丟棄率隨機丟棄引數並重新縮放剩餘引數來工作。這有助於減少多個模型之間的冗餘和潛在干擾引數的數量。
模型使用 add_weighted_adapter() 方法合併,並且在 combination_type
引數中指定具體的模型合併方法。
合併方法
透過 TIES 和 DARE,透過將 combination_type
和 density
設定為保留自各個模型的權重的某個值來啟用合併。例如,讓我們合併三個微調的 TinyLlama/TinyLlama-1.1B-intermediate-step-1431k-3T 模型:tinyllama_lora_nobots、tinyllama_lora_sql 和 tinyllama_lora_adcopy。
當您嘗試使用 TIES 合併完全訓練好的模型時,您應該注意每個模型可能已新增到嵌入層中但不是原始檢查點詞彙表一部分的任何特殊令牌。這可能會導致問題,因為每個模型可能已將特殊令牌新增到相同的嵌入位置。如果是這種情況,您應該使用 resize_token_embeddings
方法來避免在相同的嵌入索引處合併特殊令牌。
如果您只合並從相同基礎模型訓練的 LoRA 介面卡,則不應該出現此問題。
載入基礎模型並可以使用 load_adapter() 方法載入併為每個介面卡分配名稱
from peft import PeftConfig, PeftModel
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
config = PeftConfig.from_pretrained("smangrul/tinyllama_lora_norobots")
model = AutoModelForCausalLM.from_pretrained(config.base_model_name_or_path, load_in_4bit=True, device_map="auto").eval()
tokenizer = AutoTokenizer.from_pretrained("smangrul/tinyllama_lora_norobots")
model.config.vocab_size = 32005
model.resize_token_embeddings(32005)
model = PeftModel.from_pretrained(model, "smangrul/tinyllama_lora_norobots", adapter_name="norobots")
_ = model.load_adapter("smangrul/tinyllama_lora_sql", adapter_name="sql")
_ = model.load_adapter("smangrul/tinyllama_lora_adcopy", adapter_name="adcopy")
使用 add_weighted_adapter() 方法設定介面卡、權重、adapter_name
、combination_type
和 density
。
大於 1.0
的權重值通常會產生更好的結果,因為它們能保持正確的比例。權重的良好預設起始值是將所有值設定為 1.0
。
adapters = ["norobots", "adcopy", "sql"]
weights = [2.0, 1.0, 1.0]
adapter_name = "merge"
density = 0.2
model.add_weighted_adapter(adapters, weights, adapter_name, combination_type="ties", density=density)
使用 set_adapter() 方法將新合併的模型設定為活動模型。
model.set_adapter("merge")
現在你可以使用合併後的模型作為指令微調模型來撰寫廣告文案或 SQL 查詢!
messages = [
{"role": "user", "content": "Write an essay about Generative AI."},
]
text = tokenizer.apply_chat_template(messages, add_generation_prompt=True, tokenize=False)
inputs = tokenizer(text, return_tensors="pt")
inputs = {k: v.to("cuda") for k, v in inputs.items()}
outputs = model.generate(**inputs, max_new_tokens=256, do_sample=True, top_p=0.95, temperature=0.2, repetition_penalty=1.2, eos_token_id=tokenizer.eos_token_id)
print(tokenizer.decode(outputs[0]))
合併 (IA)³ 模型
(IA)³ 模型支援介面卡的線性合併。要合併 (IA)³ 模型中的介面卡,請使用 IA3Model
類中的 add_weighted_adapter
方法。此方法類似於 LoraModel
中使用的 add_weighted_adapter
方法,主要區別在於缺少 combination_type
引數。例如,要將三個 (IA)³ 介面卡合併到 PEFT 模型中,您可以按如下方式進行
adapters = ["adapter1", "adapter2", "adapter3"]
weights = [0.4, 0.3, 0.3]
adapter_name = "merge"
model.add_weighted_adapter(adapters, weights, adapter_name)
建議權重總和為 1.0 以保持模型規模。然後可以使用 set_adapter
方法將合併後的模型設定為活動模型
model.set_adapter("merge")