Model Merging
Слияние моделей объединяет веса моделей, дообученных на одной базовой модели, в единую модель без дополнительных затрат на инференс. Разбираем усреднение и арифметику задач.
Слияние моделей объединяет веса двух или более обученных моделей в одну, обычно усредняя или складывая их параметры. В результате модель сохраняет способности каждой из исходных моделей, но ей не нужно запускать несколько сетей или переобучаться на всех их данных. Этот подход работает, если у моделей одна архитектура и, для большинства методов, общее предварительно обученное начальное состояние: дообучение сдвигает каждую копию лишь на небольшое расстояние в пространстве весов, поэтому веса моделей по-прежнему совпадают параметр за параметром. Слияние широко используют для создания открытых больших языковых моделей (LLMs), объединения адаптеров LoRA или контрольных точек Stable Diffusion, а Meta при постобучении Llama 3 усредняла модели, полученные с разными данными или гиперпараметрами на каждом этапе.
Как работает слияние моделей#
Методы слияния различаются тем, что именно они объединяют и как разрешают конфликты между моделями:
- Супы моделей: усредняют веса моделей, дообученных от одной и той же базовой модели с разными гиперпараметрами. Жадный суп из дообученных моделей ViT-G достиг точности top-1 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 объединяет независимо обученные модели, сначала переставляя скрытые нейроны одной модели так, чтобы они соответствовали нейронам другой.
Слияние моделей и смежные понятия#
- Ансамбль моделей: сохраняет все модели и объединяет их результаты, поэтому потребление памяти и задержка инференса растут с количеством моделей. Объединённая модель по размеру и скорости соответствует одной модели.
- Дистилляция знаний: обучает новую модель-ученика имитировать одну или несколько моделей-учителей, для чего нужны обучающие данные и вычислительные ресурсы. Слияние — это непосредственная арифметическая операция над уже существующими весами.
- Обучение с несколькими задачами: обучает одну модель сразу на данных всех задач и обычно задаёт уровень точности, которого пытается достичь слияние без доступа к этим данным.
- Федеративное обучение: на каждом раунде усредняет веса моделей, обученных на отдельных устройствах. Каждый раунд начинается с одной глобальной модели для всех клиентов — общего начального состояния, благодаря которому усреднение работает.










