Modele i platformy AI

Jedynym przewodnikiem, którego potrzebujesz, aby dostosować Llama 3 lub dowolny inny model open-source

mm
Dodaj Unite.AI do preferowanych źródeł w Google

Dostosowywanie dużych modeli językowych (LLM) takich jak Llama 3 polega na adaptacji wstępnie wytrenowanego modelu do konkretnych zadań przy użyciu zestawu danych specyficznych dla danego zadania. Proces ten wykorzystuje wiedzę wstępnie wytrenowanego modelu, co sprawia, że jest on wydajny i ekonomiczny w porównaniu z treningiem od podstaw. W tym przewodniku przeprowadzimy Cię przez kroki dostosowywania Llama 3 przy użyciu QLoRA (Quantized LoRA), metody efektywnej pod względem parametrów, która minimalizuje użycie pamięci i koszty obliczeniowe.

Przegląd dostosowywania

Dostosowywanie obejmuje kilka kluczowych kroków:

  1. Wybór wstępnie wytrenowanego modelu: Wybierz model bazowy, który odpowiada Twojej pożądanej architekturze.
  2. Zbieranie odpowiedniego zestawu danych: Zbierz i przetwórz zestaw danych specyficzny dla Twojego zadania.
  3. Dostosowywanie: Dostosuj model przy użyciu zestawu danych, aby poprawić jego wydajność w konkretnych zadaniach.
  4. Ocena: Ocenić dostosowany model przy użyciu zarówno jakościowych, jak i ilościowych mierników.

Pojęcia i techniki

Dostosowywanie dużych modeli językowych

Dostosowywanie dużych modeli językowych

Pełne dostosowywanie

Pełne dostosowywanie aktualizuje wszystkie parametry modelu, czyniąc go specyficznym dla nowego zadania. Ta metoda wymaga znacznych zasobów obliczeniowych i jest często niepraktyczna dla bardzo dużych modeli.

Dostosowywanie efektywne pod względem parametrów (PEFT)

PEFT aktualizuje tylko podzbiór parametrów modelu, redukując wymagania pamięciowe i koszty obliczeniowe. Ta technika zapobiega katastrofalnemu zapomnieniu i utrzymuje ogólną wiedzę modelu.

Niska adaptacja rangi (LoRA) i kwantyzowana LoRA (QLoRA)

LoRA dostosowuje tylko kilka macierzy o niskiej randze, podczas gdy QLoRA kwantyzuje te macierze, aby dalej zmniejszyć ślad pamięciowy.

Metody dostosowywania

  1. Pełne dostosowywanie: Obejmuje trening wszystkich parametrów modelu na zestawie danych specyficznym dla zadania. Chociaż ta metoda może być bardzo skuteczna, jest również obliczeniowo kosztowna i wymaga znacznej ilości pamięci.
  2. Dostosowywanie efektywne pod względem parametrów (PEFT): PEFT aktualizuje tylko podzbiór parametrów modelu, co sprawia, że jest ono bardziej efektywne pod względem pamięci. Techniki takie jak niska adaptacja rangi (LoRA) i kwantyzowana LoRA (QLoRA) należą do tej kategorii.

Co to jest LoRA?

Porównanie metod dostosowywania: QLORA ulepsza LoRA z kwantyzacją 4-bitową i optymalizatorami stronicowanymi do zarządzania skokami pamięci

Porównanie metod dostosowywania: QLORA ulepsza LoRA z kwantyzacją 4-bitową i optymalizatorami stronicowanymi do zarządzania skokami pamięci

LoRA to ulepszona metoda dostosowywania, w której zamiast dostosowywania wszystkich wag modelu wstępnie wytrenowanego, dostosowuje się dwie mniejsze macierze, które przybliżają większą macierz. Te macierze stanowią adapter LoRA. Ten dostosowany adapter jest następnie ładowany do modelu wstępnie wytrenowanego i wykorzystywany do inferencji.

Kluczowe zalety LoRA:

  • Wydajność pamięciowa: LoRA redukuje ślad pamięciowy, dostosowując tylko małe macierze zamiast całego modelu.
  • Ponowne użycie: Oryginalny model pozostaje niezmieniony, a wiele adapterów LoRA może być z nim używanych, co ułatwia obsługę wielu zadań przy niższych wymaganiach pamięciowych.

Co to jest kwantyzowana LoRA (QLoRA)?

QLoRA idzie o krok dalej, kwantyzując wagi adapterów LoRA do niższej precyzji (np. 4-bitowej zamiast 8-bitowej). To dalej redukuje użycie pamięci i wymagania przechowywania, utrzymując porównywalny poziom skuteczności.

Kluczowe zalety QLoRA:

  • Jeszcze większa wydajność pamięciowa: Kwantyzując wagi, QLoRA znacznie redukuje wymagania pamięciowe i przechowywania modelu.
  • Utrzymywanie wydajności: Pomimo zmniejszonej precyzji, QLoRA utrzymuje poziom wydajności zbliżony do modeli pełnej precyzji.

Dostosowywanie zadaniowe

Podczas dostosowywania parametry modelu są dostosowywane na podstawie nowego zestawu danych, co pomaga mu lepiej zrozumieć i generować treści istotne dla konkretnego zadania. Ten proces zachowuje ogólną wiedzę językową zdobytą podczas wstępnego treningu, dostosowując model do nuansów docelowego obszaru.

Dostosowywanie w praktyce

Pełne dostosowywanie vs. PEFT

  • Pełne dostosowywanie: Obejmuje trening całego modelu, co może być obliczeniowo kosztowne i wymaga znacznej ilości pamięci.
  • PEFT (LoRA i QLoRA): Dostosowuje tylko podzbiór parametrów, redukując wymagania pamięciowe i zapobiegając katastrofalnemu zapomnieniu, co czyni ją bardziej efektywną alternatywą.

Kroki implementacyjne

  1. Konfiguracja środowiska: Zainstaluj niezbędne biblioteki i skonfiguruj środowisko obliczeniowe.
  2. Ładowanie i przetwarzanie zestawu danych: Ładuj zestaw danych i przetwórz go w format przyjazny dla modelu.
  3. Ładowanie wstępnie wytrenowanego modelu: Ładuj model bazowy z konfiguracjami kwantyzacji, jeśli używasz QLoRA.
  4. Tokenizacja: Tokenizuj zestaw danych, aby przygotować go do treningu.
  5. Trening: Dostosuj model przy użyciu przygotowanego zestawu danych.
  6. Ocena: Ocenić wydajność modelu w konkretnych zadaniach przy użyciu jakościowych i ilościowych mierników.

Krok po kroku przewodnik po dostosowaniu LLM

Skonfiguruj środowisko

Będziemy używać notesu Jupyter do tego samouczka. Platformy takie jak Kaggle, które oferują bezpłatne użycie GPU, lub Google Colab są idealne do uruchamiania tych eksperymentów.

1. Zainstaluj wymagane biblioteki

Upewnij się, że masz zainstalowane niezbędne biblioteki:

!pip install -qqq -U bitsandbytes transformers peft accelerate datasets scipy einops evaluate trl rouge_score

2. Importuj biblioteki i skonfiguruj środowisko

import os
import torch
from datasets import load_dataset
from transformers import (
AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig, TrainingArguments,
pipeline, HfArgumentParser
)
from trl import ORPOConfig, ORPOTrainer, setup_chat_format, SFTTrainer
from tqdm import tqdm
import gc
import pandas as pd
import numpy as np
from huggingface_hub import interpreter_login

# Wyłącz logowanie Weights and Biases
os.environ['WANDB_DISABLED'] = "true"
interpreter_login()

3. Ładuj zestaw danych

Będziemy używać zestawu danych DialogSum do tego samouczka:

dataset_name = "neil-code/dialogsum-test"
dataset = load_dataset(dataset_name)

4. Utwórz konfigurację BitsAndBytes

Aby załadować model w formacie 4-bitowym:

compute_dtype = getattr(torch, "float16")
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type='nf4',
bnb_4bit_compute_dtype=compute_dtype,
bnb_4bit_use_double_quant=False,
)

5. Ładuj wstępnie wytrenowany model

Użyjemy modelu Microsoft (MSFT ) Phi-2 do tego samouczka:

model_name = 'microsoft/phi-2'
device_map = {"": 0}
original_model = AutoModelForCausalLM.from_pretrained(
model_name,
device_map=device_map,
quantization_config=bnb_config,
trust_remote_code=True,
use_auth_token=True
)

6. Tokenizacja

Skonfiguruj tokenizator:

tokenizer = AutoTokenizer.from_pretrained(
model_name,
trust_remote_code=True,
padding_side="left",
add_eos_token=True,
add_bos_token=True,
use_fast=False
)
tokenizer.pad_token = tokenizer.eos_token

Dostosowywanie Llama 3 lub innych modeli

Podczas dostosowywania modeli takich jak Llama 3 lub innych modeli open-source, istnieją specyficzne rozważania i dostosowania wymagane, aby zapewnić optymalną wydajność. Oto szczegółowe kroki i spostrzeżenia, jak podejść do tego dla różnych modeli, w tym Llama 3, GPT-3 i Mistral.

5.1 Używanie Llama 3

Wybór modelu:

  • Upewnij się, że masz poprawny identyfikator modelu z hubu modeli Hugging Face. Na przykład model Llama 3 może być identyfikowany jako meta-llama/Meta-Llama-3-8B na Hugging Face.
  • Upewnij się, że masz dostęp i zaloguj się do swojego konta Hugging Face, jeśli jest to wymagane dla modeli takich jak Llama 3.

Tokenizacja:

  • Użyj odpowiedniego tokenizatora dla Llama 3, upewniając się, że jest on kompatybilny z modelem i obsługuje wymagane funkcje, takie jak padding i specjalne tokeny.

Pamięć i obliczenia:

  • Dostosowywanie dużych modeli takich jak Llama 3 wymaga znacznych zasobów obliczeniowych. Upewnij się, że Twoje środowisko, takie jak potężna konfiguracja GPU, może obsłużyć wymagania pamięciowe i obliczeniowe.

Przykład:

model_name = 'meta-llama/Meta-Llama-3-8B'
device_map = {"": 0}
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.float16,
bnb_4bit_use_double_quant=True,
)
original_model = AutoModelForCausalLM.from_pretrained(
model_name,
device_map=device_map,
quantization_config=bnb_config,
trust_remote_code=True,
use_auth_token=True
)

5.2 Używanie innych popularnych modeli (np. GPT-3, Mistral)

Wybór modelu:

  • Dla modeli takich jak GPT-3 i Mistral upewnij się, że używasz poprawnej nazwy modelu i identyfikatora z hubu modeli Hugging Face lub innych źródeł.

Tokenizacja:

  • Podobnie jak w przypadku Llama 3, upewnij się, że tokenizator jest poprawnie skonfigurowany i kompatybilny z modelem.

Pamięć i obliczenia:

  • Każdy model może mieć różne wymagania pamięciowe. Dostosuj swoje środowisko odpowiednio.

Przykład dla GPT-3:

model_name = 'openai/gpt-3'
device_map = {"": 0}
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.float16,
bnb_4bit_use_double_quant=True,
)
original_model = AutoModelForCausalLM.from_pretrained(
model_name,
device_map=device_map,
quantization_config=bnb_config,
trust_remote_code=True,
use_auth_token=True
)

7. Przetestuj model z inferencją zero-shot

Ocenić model bazowy z przykładowym wejściem:

from transformers import set_seed

set_seed(42)
index = 10
prompt = dataset['test'][index]['dialogue']
formatted_prompt = f"Instruct: Summarize the following conversation.\n{prompt}\nOutput:\n"

# Wygeneruj wyjście
def gen(model, prompt, max_length):
inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
outputs = model.generate(**inputs, max_length=max_length)
return tokenizer.batch_decode(outputs, skip_special_tokens=True)

res = gen(original_model, formatted_prompt, 100)
output = res[0].split('Output:\n')[1]

print(f'INPUT PROMPT:\n{formatted_prompt}')
print(f'MODEL GENERATION - ZERO SHOT:\n{output}')

8. Przetwórz zestaw danych

Zamień pary dialogów-podsumowań w prompty:

def create_prompt_formats(sample):
blurb = "Below is an instruction that describes a task. Write a response that appropriately completes the request."
instruction = "### Instruct: Summarize the below conversation."
input_context = sample['dialogue']
response = f"### Output:\n{sample['summary']}"
end = "### End"

parts = [blurb, instruction, input_context, response, end]
formatted_prompt = "\n\n".join(parts)
sample["text"] = formatted_prompt
return sample

dataset = dataset.map(create_prompt_formats)

9. Przygotuj model do treningu QLoRA

Przygotuj model do dostosowywania efektywnego pod względem parametrów:

original_model = prepare_model_for_kbit_training(original_model)

Hyperparametry i ich wpływ

Hyperparametry odgrywają kluczową rolę w optymalizacji wydajności modelu. Oto kilka kluczowych hyperparametrów do rozważenia:

  1. Stawka uczenia: Kontroluje szybkość, z jaką model aktualizuje swoje parametry. Wysoka stawka uczenia może prowadzić do szybszego zbieżności, ale może również przekroczyć optymalne rozwiązanie. Niska stawka uczenia zapewnia stabilną zbieżność, ale może wymagać więcej epok.
  2. Rozmiar partii: Liczba próbek przetwarzanych przed aktualizacją parametrów modelu. Większe rozmiary partii mogą poprawić stabilność, ale wymagają więcej pamięci. Mniejsze rozmiary partii mogą prowadzić do większego szumu w procesie treningu.
  3. Kroki akumulacji gradientu: Ten parametr pomaga symulować większe rozmiary partii, akumulując gradienty przez wiele kroków przed aktualizacją parametrów.
  4. Liczba epok: Liczba razy, gdy cały zestaw danych jest przetwarzany przez model. Więcej epok może poprawić wydajność, ale może również prowadzić do przeuczenia, jeśli nie zarządzane prawidłowo.
  5. Wygaszanie wag: Technika regularizacji, która zapobiega przeuczeniu, karząc duże wagi.
  6. Planowanie stawki uczenia: Dostosowuje stawkę uczenia podczas treningu, aby poprawić wydajność i zbieżność.

Dostosuj konfigurację treningu, dostosowując hyperparametry takie jak stawka uczenia, rozmiar partii i kroki akumulacji gradientu, w zależności od konkretnych wymagań modelu i zadania.

Przykładowa konfiguracja treningu

orpo_args = ORPOConfig(
learning_rate=8e-6,
lr_scheduler_type="linear",
max_length=1024,
max_prompt_length=512,
beta=0.1,
per_device_train_batch_size=2,
per_device_eval_batch_size=2,
gradient_accumulation_steps=4,
optim="paged_adamw_8bit",
num_train_epochs=1,
evaluation_strategy="steps",
eval_steps=0.2,
logging_steps=1,
warmup_steps=10,
report_to="wandb",
output_dir="./results/",
)

10. Trenuj model

Skonfiguruj trenera i rozpocznij trening:

trainer = ORPOTrainer(
model=original_model,
args=orpo_args,
train_dataset=train_dataset,
eval_dataset=eval_dataset,
tokenizer=tokenizer,
)
trainer.train()
trainer.save_model("fine-tuned-llama-3")

Ocena dostosowanego modelu

Po treningu ocenić wydajność modelu przy użyciu jakościowych i ilościowych metod.

1. Ocena ludzka

Porównaj wygenerowane podsumowania z napisanymi przez ludzi, aby ocenić jakość.

2. Ocena ilościowa

Użyj mierników takich jak ROUGE, aby ocenić wydajność:

from rouge_score import rouge_scorer

scorer = rouge_scorer.RougeScorer(['rouge1', 'rouge2', 'rougeL'], use_stemmer=True)
scores = scorer.score(reference_summary, generated_summary)
print(scores)

Typowe wyzwania i rozwiązania

1. Ograniczenia pamięci

Używanie QLoRA pomaga złagodzić problemy z pamięcią, kwantyzując wagi modelu do 4-bit. Upewnij się, że masz wystarczającą pamięć GPU, aby obsłużyć swój rozmiar partii i rozmiar modelu.

2. Przeuczenie

Monitoruj metryki walidacyjne, aby zapobiec przeuczeniu. Użyj technik takich jak wczesne zatrzymanie i wygaszanie wag.

3. Wolny trening

Optymalizuj szybkość treningu, dostosowując rozmiar partii, stawkę uczenia i kroki akumulacji gradientu.

4. Jakość danych

Upewnij się, że Twój zestaw danych jest czysty i dobrze przetworzony. Zła jakość danych może znacznie wpłynąć na wydajność modelu.

Podsumowanie

Dostosowywanie dużych modeli językowych przy użyciu QLoRA jest wydajnym sposobem adaptacji dużych modeli wstępnie wytrenowanych do konkretnych zadań z redukowanymi kosztami obliczeniowymi. Śledząc ten przewodnik, możesz dostosować PHI, Llama 3 lub dowolny inny model open-source, aby osiągnąć wysoką wydajność w swoich konkretnych zadaniach.

Przez ostatnie pięć lat zanurzałem się w fascynującym świecie Machine Learning i Deep Learning. Moja pasja i ekspertyza doprowadziły mnie do udziału w ponad 50 różnorodnych projektach inżynierii oprogramowania, ze szczególnym uwzględnieniem AI/ML. Moja nieustanna ciekawość również skierowała mnie w stronę Natural Language Processing, dziedziny, którą chcę dalej eksplorować.