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 следует учитывать, какие специальные токены каждая модель могла добавить в слой эмбеддингов, если они не входят в словарь исходного контрольной точки. Это может вызвать проблему, поскольку каждая модель могла добавить специальный токен в одну и ту же позицию эмбеддинга. В этом случае используйте метод 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