모델 병합
더 많은 작업
- Model Merging; 모델 병합
- 같은 사전 학습 모델에서 갈라져 나온 여러 미세조정 모델의 가중치를 산술적으로 합쳐, 추가 학습 없이 하나의 모델로 만드는 기법
모델 병합(model merging, 모델 머징)은 여러 신경망의 매개변수를 가중치 공간에서 직접 결합해 새 모델 하나를 만드는 기법이다. 출력 단계에서 여러 모델의 예측을 합치는 앙상블과 달리, 결과는 원래 모델 하나와 크기와 추론 비용이 같다. 학습 데이터에 접근하지 않고도, GPU 없이 CPU만으로도 할 수 있어서 공개 대형 언어 모델 생태계에서 미세조정 모델의 능력을 조합하는 수단으로 쓰였다.
단순 평균에서 출발해, 미세조정으로 생긴 변화량(작업 벡터)을 더하고 빼는 작업 산술(Task Arithmetic), 변화량끼리의 간섭을 줄이는 TIES와 DARE, 구면 보간인 SLERP, 병합 비율을 진화 알고리즘으로 찾는 방법이 차례로 나왔다. 공개 도구로는 아르시(Arcee)의 mergekit이 있다.[1]
서로 무관하게 학습한 두 신경망의 가중치를 평균하면 보통 성능이 무너진다. 은닉 유닛의 순서를 바꿔도 같은 함수가 되는 순열 대칭성 때문에, 같은 기능을 하는 유닛이 두 모델에서 다른 위치에 있기 때문이다. 깃 리베이슨(Git Re-Basin)은 한 모델의 유닛 순서를 다른 모델에 맞춰 정렬하면 독립적으로 학습한 모델끼리도 병합할 수 있음을 보였다.[2]
같은 사전 학습 모델에서 미세조정한 모델끼리는 사정이 다르다. 사전 학습 가중치라는 같은 출발점에서 조금씩만 움직였으므로, 손실이 낮은 하나의 분지(basin) 안에 함께 있는 경우가 많다.[3] 두 가중치를 잇는 직선 위에서 손실이 높아지지 않는 성질을 선형 모드 연결성(linear mode connectivity)이라 한다.[4] 그래서 LLM 병합은 거의 항상 같은 기반 모델, 같은 구조, 같은 토크나이저를 전제로 한다.
기반 모델 가중치를 , 미세조정 모델 의 가중치를 라 하고, 작업 벡터(task vector)를 로 둔다.
모델 수프(model soup)는 하이퍼파라미터만 달리해 같은 모델을 여러 번 미세조정한 결과를 평균했다. 이 방법으로 JFT로 사전 학습한 ViT-G의 ImageNet top-1 정확도를 90.94%로 올려 당시 최고 기록을 세웠고, 앙상블과 달리 추론 비용이 늘지 않았다.[3] 피셔 병합(Fisher merging)은 각 매개변수의 중요도를 피셔 정보로 재서 가중 평균한다.[5] 업스테이지는 SOLAR 10.7B를 만들 때, 서로 다른 데이터로 학습한 SFT 모델끼리, DPO 모델끼리 가중치를 단순 평균해 각각의 장점을 살린 모델을 얻었다.[6]
작업 벡터를 그냥 더하면 두 가지 간섭이 생긴다. 미세조정 중 조금만 바뀐 중복 매개변수가 잡음이 되고, 같은 매개변수를 한 모델은 올리고 다른 모델은 내려 서로 상쇄한다. TIES(TRIM, ELECT SIGN & MERGE)는 세 단계로 이를 줄인다.[8]
- 다듬기(Trim): 작업 벡터마다 크기 상위 만 남기고 나머지를 0으로 만든다.
- 부호 선출(Elect): 매개변수마다 모델들의 값 합의 부호, 즉 크기 합이 큰 쪽의 부호를 정한다.
- 분리 병합(Disjoint merge): 선출된 부호와 부호가 같은 모델의 값만 평균한다. 0인 값은 평균에서 뺀다.
검증 세트가 없을 때의 기본 설정으로 논문은 상위 20%만 남기고 을 제시했다.[8]
DARE(Drop And REscale)는 작업 벡터(논문 용어로 델타 매개변수)의 원소를 비율 로 무작위로 0으로 만들고, 남은 원소를 배 키워 기댓값을 유지한다.[9]
SFT로 생긴 델타 값은 대개 0.002 이내로 작고 중복이 심해, 90%나 99%를 지워도 능력이 유지되었다. 이렇게 희소하게 만든 작업 벡터를 작업 산술이나 TIES로 합치면 간섭이 줄어든다. 다만 델타가 큰 경우에는 통하지 않았다. 코드 데이터 5천억 토큰을 더 학습한 코드 라마 계열은 라마 2 기준 델타가 커서, 10%만 지워도 HumanEval 성능이 0으로 떨어졌다.[9]
구면 선형 보간(Spherical Linear Interpolation, SLERP)은 두 모델 사이를 직선 대신 초구면의 대원호를 따라 보간한다. 두 가중치 벡터 사이 각도를 라 하면 다음과 같다.
선형 보간은 두 벡터의 사이각이 클수록 중간점의 노름이 줄어드는데, SLERP는 노름 변화를 줄인다. 두 모델만 합칠 수 있고, 텐서마다 따로 적용하며, 두 벡터가 거의 평행하면 선형 보간으로 대신한다. mergekit에서는 이면 기반 모델, 이면 다른 모델이 된다.[10]
세 기법의 핵심을 PyTorch로 쓰면 다음과 같다(PyTorch 2.5에서 실행 확인).
import torch
def ties_merge(base, models, density=0.2, lam=1.0):
merged = {}
for k in base:
tvs = torch.stack([m[k] - base[k] for m in models]) # 작업 벡터 [N, ...]
# 1) Trim: 모델마다 크기 상위 density 비율만 남긴다
flat = tvs.abs().flatten(1)
kth = max(1, int(flat.shape[1] * density))
thresh = flat.topk(kth, dim=1).values[:, -1].view(-1, *[1] * (tvs.dim() - 1))
tvs = torch.where(tvs.abs() >= thresh, tvs, torch.zeros_like(tvs))
# 2) Elect: 원소별 합의 부호
sign = torch.sign(tvs.sum(dim=0))
# 3) Disjoint merge: 부호가 같은 값만 평균
agree = (torch.sign(tvs) == sign) & (tvs != 0)
merged[k] = base[k] + lam * (tvs * agree).sum(0) / agree.sum(0).clamp(min=1)
return merged
def dare(delta, p=0.9):
keep = (torch.rand_like(delta) >= p).float()
return delta * keep / (1 - p) # 남은 값은 1/(1-p)배
def slerp(t, a, b, eps=1e-8):
a_n, b_n = a / (a.norm() + eps), b / (b.norm() + eps)
dot = (a_n * b_n).sum().clamp(-1.0, 1.0)
if dot.abs() > 0.9995: # 거의 평행하면 선형 보간
return (1 - t) * a + t * b
omega = torch.arccos(dot)
return (torch.sin((1 - t) * omega) * a + torch.sin(t * omega) * b) / torch.sin(omega)
사카나 AI(Sakana AI)는 어떤 모델을 어떤 비율로, 어느 층을 어떤 순서로 합칠지를 진화 알고리즘으로 찾았다. 가중치 공간의 병합 비율뿐 아니라 층을 쌓는 순서(데이터 흐름 공간)까지 탐색해, 일본어 모델과 수학 모델을 합친 일본어 수학 LLM이 따로 학습하지 않았는데도 일본어 벤치마크에서 더 큰 모델들을 앞섰다고 보고했다. 논문은 2025년 1월 《네이처 머신 인텔리전스》에 실렸다.[11]
| 기법 | 모델 수 | 기반 모델 필요 | 주요 매개변수 | 언제 쓰나 |
|---|---|---|---|---|
| 가중치 평균(linear) | 2개 이상 | 아니요 | 모델별 가중치 | 같은 실행의 체크포인트, 하이퍼파라미터만 다른 모델 |
| SLERP | 2개 | 예 | 성격이 다른 두 모델 사이를 부드럽게 보간 | |
| 작업 산술 | 1개 이상 | 예 | , 모델별 가중치 | 능력 더하기, 행동 지우기 |
| TIES | 2개 이상 | 예 | 밀도(남길 비율), | 여러 모델을 한꺼번에 합칠 때 간섭 줄이기 |
| DARE(+TIES) | 2개 이상 | 예 | 밀도 , | SFT 델타가 작은 모델끼리 |
| 진화적 병합 | 여러 개 | 경우에 따라 | 탐색 공간, 평가 데이터 | 병합 비율을 자동으로 찾을 때. 평가 비용이 듦 |
mergekit은 아르시가 공개한 병합 도구로, 텐서를 필요할 때만 불러오는 방식이라 CPU만으로도, VRAM 8GB 정도로도 큰 모델을 병합할 수 있다. 라이선스는 LGPL-3.0이다.[12] 논문은 오픈 소스 커뮤니티가 이미 수천 개 모델을 이 도구로 병합했다고 밝혔다.[1] 지원 방법은 linear, slerp, nuslerp, multislerp, karcher, task_arithmetic, ties, dare_linear, dare_ties, della, breadcrumbs, sce, model_stock, nearswap, arcee_fusion, passthrough 등이다.[12]
설정은 YAML로 쓴다. 다음은 저장소 예제를 바탕으로 한 TIES 병합 설정이다.[12]
models:
- model: psmathur/orca_mini_v3_13b
parameters:
density: [1, 0.7, 0.1] # 층 위치에 따라 남길 비율을 바꾸는 기울기 지정
weight: 1.0
- model: garage-bAInd/Platypus2-13B
parameters:
density: 0.5
weight: [0, 0.3, 0.7, 1]
- model: WizardLM/WizardMath-13B-V1.0
parameters:
density: 0.33
weight:
- filter: mlp # MLP 텐서에만 다른 가중치
value: 0.5
- value: 0
merge_method: ties
base_model: TheBloke/Llama-2-13B-fp16
parameters:
normalize: true
dtype: float16
mergekit-yaml config.yml ./merged-model --cuda
passthrough 방식은 여러 모델의 층을 잘라 이어 붙여 더 깊은 모델을 만드는 데 쓰인다(흔히 프랑켄머지라 부른다). 업스테이지의 깊이 확장(depth up-scaling)은 32층 모델 두 벌에서 한쪽은 마지막 8층, 다른 쪽은 처음 8층을 빼고 이어 48층 모델을 만든 뒤, 성능이 떨어진 것을 계속 사전 학습으로 회복시켰다. 논문은 커뮤니티에서도 같은 방식의 확장이 동시에 개발되었다고 적었다.[6]
- 같은 계보 전제: 구조, 토크나이저, 기반 모델이 같아야 한다. 어휘가 다르면 mergekit도 토크나이저 정렬 설정을 요구한다.[12]
- 예측하기 어려움: 어떤 조합과 비율이 좋은지 이론적 지침이 약해 평가를 반복해야 한다. 진화적 병합은 이 탐색을 자동화하지만 평가 비용이 든다.
- 평가 문제: 병합 비율을 특정 벤치마크 점수로 고르면 그 벤치마크에 과적합하기 쉽다. 원래 모델들이 평가 데이터로 오염되었다면 병합 모델도 물려받는다. 벤치마크 오염 참고.
- 라이선스: 병합 모델은 원래 모델들의 라이선스 조건을 모두 따져야 한다.
- LoRA 어댑터 병합: LoRA 어댑터 여러 개를 합치는 것도 같은 원리로 할 수 있다. PEFT의
add_weighted_adapter는combination_type으로 linear, ties, dare_linear, dare_ties 등을 지원한다.[13]
- ↑ 1.0 1.1 Charles Goddard 외, 〈Arcee's MergeKit: A Toolkit for Merging Large Language Models〉, 2024. arXiv:2403.13257
- ↑ Samuel K. Ainsworth, Jonathan Hayase, Siddhartha Srinivasa, 〈Git Re-Basin: Merging Models modulo Permutation Symmetries〉, 2022. arXiv:2209.04836
- ↑ 3.0 3.1 Mitchell Wortsman 외, 〈Model soups: averaging weights of multiple fine-tuned models improves accuracy without increasing inference time〉, ICML 2022. arXiv:2203.05482
- ↑ Jonathan Frankle 외, 〈Linear Mode Connectivity and the Lottery Ticket Hypothesis〉, ICML 2020. arXiv:1912.05671
- ↑ Michael Matena, Colin Raffel, 〈Merging Models with Fisher-Weighted Averaging〉, 2021. arXiv:2111.09832
- ↑ 6.0 6.1 Dahyun Kim 외, 〈SOLAR 10.7B: Scaling Large Language Models with Simple yet Effective Depth Up-Scaling〉, 2023. arXiv:2312.15166
- ↑ 7.0 7.1 Gabriel Ilharco 외, 〈Editing Models with Task Arithmetic〉, ICLR 2023. arXiv:2212.04089
- ↑ 8.0 8.1 Prateek Yadav 외, 〈TIES-Merging: Resolving Interference When Merging Models〉, NeurIPS 2023. arXiv:2306.01708
- ↑ 9.0 9.1 Le Yu 외, 〈Language Models are Super Mario: Absorbing Abilities from Homologous Models as a Free Lunch〉, ICML 2024. arXiv:2311.03099
- ↑ Merge Method Guide, mergekit 저장소(2026년 10월 확인).
- ↑ Takuya Akiba 외, 〈Evolutionary Optimization of Model Merging Recipes〉, 《Nature Machine Intelligence》, 2025. arXiv:2403.13187
- ↑ 12.0 12.1 12.2 12.3 mergekit README, 아르시(2026년 10월 확인, PyPI 최신 배포판 0.1.4).
- ↑ peft/tuners/lora/model.py, 허깅 페이스 PEFT v0.21.2.