Model Merging
يدمج دمج النماذج أوزان نماذج ضُبطت بدقة انطلاقًا من نموذج أساسي واحد في نموذج واحد، دون كلفة استدلال إضافية. يتناول حساب المتوسط والحسابات على المهام.
يجمع دمج النماذج أوزان نموذجين مدرّبين أو أكثر في نموذج واحد، عادةً عبر حساب متوسط معلماتها أو جمعها، بحيث يحتفظ الناتج بقدرات كل نموذج من دون تشغيل شبكات متعددة أو إعادة التدريب على جميع بياناتها. تنجح هذه العملية عندما تتشارك النماذج البنية نفسها، وفي معظم الأساليب، نقطة بدء مشتركة مدرّبة مسبقًا: إذ لا يبتعد كل نموذج إلا مسافة قصيرة في فضاء الأوزان أثناء الضبط الدقيق، لذلك تظل أوزان النماذج متطابقة معلمةً بمعلمة. ويُستخدم الدمج على نطاق واسع لبناء نماذج لغوية كبيرة (LLMs) مفتوحة المصدر، ودمج محوّلات LoRA أو نقاط تحقق Stable Diffusion، كما أنشأت Llama 3 من Meta نماذجها بعد التدريب عبر حساب متوسط نماذج جرى الحصول عليها ببيانات أو معلمات فائقة مختلفة في كل مرحلة.
آلية عمل دمج النماذج#
تختلف أساليب الدمج في العناصر التي تجمعها وطريقة حل التعارضات بين النماذج:
- خلطات النماذج: حساب متوسط أوزان النماذج التي ضُبطت بدقة انطلاقًا من النموذج الأساسي نفسه باستخدام معلمات فائقة مختلفة. حققت خلطة جشعة من نماذج ViT-G المضبوطة بدقة دقةً من المرتبة الأولى بلغت 90.94% على ImageNet، وكانت نتيجة متقدمة على أحدث المستويات آنذاك.
- متوسط الأوزان العشوائي: يحسب متوسط نقاط التحقق المحفوظة في مراحل مختلفة من عملية تدريب واحدة، ما يميل إلى الاستقرار في منطقة أوسع وأكثر تسطحًا من سطح الخسارة.
- حساب المهام: يطرح الأوزان الأساسية من كل نموذج مضبوط بدقة لاستخراج متجه مهمة، ثم يضيف متجهات مهام مضروبة في معاملات قياس إلى الأوزان الأساسية لدمج المهارات، أو يطرح أحد المتجهات لإزالة سلوك ما.
- TIES-Merging: يحدّ من التداخل بين متجهات المهام عبر ثلاث خطوات: يعيد ضبط المعلمات التي لم تتغير إلا قليلًا أثناء الضبط الدقيق، ويحدد إشارة لكل معلمة، ثم يدمج القيم المتوافقة مع تلك الإشارة فقط.
- DARE: يحذف عشوائيًا معظم قيم كل متجه مهمة ويعيد قياس القيم المتبقية قبل الدمج، ما يزيل التغييرات الزائدة مع الحفاظ على قدرة كل مهمة.
يُعد حساب المتوسط على امتداد عملية تدريب واحدة جزءًا من التدريب الاعتيادي أيضًا. يحتفظ تدريب Ultralytics YOLO26 بمتوسط متحرك أسي (EMA) لأوزان النموذج إلى جانب الأوزان الجاري تحسينها، مع معدل اضمحلال يرتفع تدريجيًا إلى 0.9999 مع تقدم التدريب، وتحتوي نقاط التحقق last.pt وbest.pt التي يحفظها على هذا النموذج المحسوب متوسط أوزانه.
تشترك أساليب متجهات المهام في بنية واحدة: يُعبَّر عن كل نموذج مضبوط بدقة بوصفه الفرق بينه وبين النموذج الأساسي، ثم تُنقّى الفروق وتُدمج، ويُضاف الناتج مجددًا إلى النموذج الأساسي:
تطبّق أدوات مفتوحة المصدر مثل mergekit هذه الأساليب على نماذج LLM، إلى جانب الاستيفاء الكروي (SLERP) بين نموذجين.
أهمية نقطة البدء المشتركة#
يمكن إعادة ترتيب الوحدات المخفية في الشبكة العصبية من دون تغيير العمليات التي تنفذها الشبكة، لذلك نادرًا ما تخزّن شبكتان دُرّبتا بتهيئتين عشوائيتين مختلفتين الميزة نفسها في الموضع نفسه، ويؤدي حساب متوسطهما إلى مزج أوزان غير مترابطة. أما النماذج التي ضُبطت بدقة انطلاقًا من نموذج أساسي واحد، فتحافظ على ترتيب النموذج الأساسي وتظل ضمن المنطقة نفسها منخفضة الخسارة، لذا يظل متوسطها فعّالًا. يدرّب هذا المثال مصنّفًا صغيرًا باستخدام PyTorch على أرقام مكتوبة بخط اليد، ثم يضبط نسختين منه بدقة على نصفين مختلفين من بيانات التدريب المتبقية، ويقارن دمجهما بدمج نموذجين دُرّبا انطلاقًا من تهيئتين منفصلتين:
import copy
import torch
from sklearn.datasets import load_digits
from torch import nn
torch.manual_seed(0)
X, y = load_digits(return_X_y=True)
order = torch.randperm(len(X))
X, y = torch.tensor(X / 16, dtype=torch.float32)[order], torch.tensor(y)[order]
def mlp():
"""Return a small classifier for 8x8 digit images."""
return nn.Sequential(nn.Linear(64, 64), nn.ReLU(), nn.Linear(64, 64), nn.ReLU(), nn.Linear(64, 10))
def train(model, rows, steps):
"""Train a model with SGD on the given rows and return it."""
optimizer = torch.optim.SGD(model.parameters(), lr=0.1, momentum=0.9)
for _ in range(steps):
optimizer.zero_grad()
nn.functional.cross_entropy(model(X[rows]), y[rows]).backward()
optimizer.step()
return model
base = train(mlp(), slice(0, 300), 400) # shared pretrained starting point
halves = (slice(300, 900), slice(900, 1500)) # two different fine-tuning datasets
for name, (a, b) in [
("fine-tuned from one base", [train(copy.deepcopy(base), rows, 100) for rows in halves]),
("trained from separate inits", [train(mlp(), rows, 400) for rows in halves]),
]:
# Merge: average every weight tensor of the two models
merged = copy.deepcopy(a)
merged.load_state_dict({k: (a.state_dict()[k] + b.state_dict()[k]) / 2 for k in a.state_dict()})
accuracy = [(m(X[1500:]).argmax(1) == y[1500:]).float().mean().item() for m in (a, b, merged)]
print(f"{name}: {accuracy[0]:.3f} and {accuracy[1]:.3f}, merged {accuracy[2]:.3f}")من بين الأرقام الـ297 المحجوزة للاختبار، حقق النموذجان المضبوطان بدقة انطلاقًا من نموذج أساسي واحد درجتَي 0.956 و0.946، وبلغت درجة متوسطهما 0.970، وهي أعلى من درجة أي منهما لأنه يجمع ما تعلمه كل نموذج من نصف البيانات المخصص له. أما النموذجان المدرّبان انطلاقًا من تهيئتين منفصلتين، فحققا درجتَي 0.946 و0.956، وانخفضت درجة متوسطهما إلى 0.808. يدمج Git Re-Basin النماذج المدرّبة بصورة مستقلة عبر إعادة ترتيب الوحدات المخفية في أحد النموذجين أولًا لتتوافق مع وحدات النموذج الآخر.
دمج النماذج ومصطلحات ذات صلة#
- تجميعة النماذج: تحتفظ بكل نموذج وتجمع مخرجات النماذج، لذلك يزداد استهلاك الذاكرة وزمن الاستدلال بزيادة عدد النماذج. أما النموذج المدمج، فيتمتع بحجم نموذج واحد وسرعته.
- تقطير المعرفة: يدرّب نموذجًا جديدًا طالبًا لمحاكاة معلم واحد أو أكثر، ما يتطلب بيانات تدريب وقدرة حوسبة. أما الدمج فهو عملية حسابية مباشرة على الأوزان الموجودة.
- التدريب متعدد المهام: يدرّب نموذجًا واحدًا على بيانات جميع المهام معًا، وعادةً ما يحدد مستوى الدقة الذي يسعى الدمج إلى بلوغه من دون الوصول إلى تلك البيانات.
- التعلم الاتحادي: يحسب متوسط أوزان النماذج المدرّبة على أجهزة منفصلة في كل جولة. تبدأ جميع الأجهزة العميلة في كل جولة من النموذج العالمي نفسه، أي نقطة البدء المشتركة التي تجعل حساب المتوسط فعالًا.










