PEFT documentation

دمج النماذج

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v0.21.0).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

دمج النماذج

قد يكون تدريب نموذج لكل مهمة مكلفًا، ويستهلك مساحة تخزين كبيرة، كما أن هذه النماذج غير قادرة على تعلم معلومات جديدة لتحسين أدائها. يمكن لتعلم المهام المتعددة التغلب على بعض هذه القيود من خلال تدريب نموذج ليتعلم عدة مهام، لكن تدريبه مكلف وتصميم مجموعة بيانات له أمر صعب. يقدم دمج النماذج حلاً لهذه التحديات من خلال دمج عدة نماذج مُسبقة التدريب في نموذج واحد، مما يمنحه القدرات المجمعة لكل نموذج فردي دون أي تدريب إضافي.

توفر PEFT عدة طرق لدمج النماذج، مثل الجمع الخطي أو الجمع باستخدام التحليل القيمي المفرد (SVD). يركّز هذا الدليل على طريقتين أكثر كفاءةً لدمج محوِّلات LoRA من خلال إزالة المعاملات الزائدة:

  • TIES - TrIm, Elect, and Merge (TIES) is a three-step method for merging models. First, redundant parameters are trimmed, then conflicting signs are resolved into an aggregated vector, and finally the parameters whose signs are the same as the aggregate sign are averaged. This method takes into account that some values (redundant and sign disagreement) can degrade performance in the merged model.
  • 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، يجب أن تكون على دراية بأي رموز خاصة قد أضافها كل نموذج إلى طبقة التضمين (embedding layer) والتي لا تُشكّل جزءاً من قاموس نقطة الحفظ (checkpoint) الأصلية. قد يتسبب ذلك في مشكلة لأن كل نموذج قد أضاف رمزاً خاصاً إلى موضع التضمين نفسه. في هذه الحالة، يجب عليك استخدام طريقة 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")

اضبط المُكيّفات والأوزان وadapter_name وcombination_type وdensity باستخدام طريقة add_weighted_adapter().

TIES
DARE

عادةً ما تُنتج قيم الأوزان الأكبر من 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!

instruct
نسخة الإعلان
SQL
device = torch.accelerator.current_accelerator().type if hasattr(torch, "accelerator") else "cuda"
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(device) 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)³، استخدم طريقة add_weighted_adapter من فئة IA3Model. هذه الطريقة مشابهة لطريقة add_weighted_adapter المستخدمة في LoraModel، مع الفارق الرئيسي المتمثل في غياب معامل 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")
Update on GitHub