Modele i platformy AI
Jedynym przewodnikiem, którego potrzebujesz, aby dostosować Llama 3 lub dowolny inny model open-source
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:
- Wybór wstępnie wytrenowanego modelu: Wybierz model bazowy, który odpowiada Twojej pożądanej architekturze.
- Zbieranie odpowiedniego zestawu danych: Zbierz i przetwórz zestaw danych specyficzny dla Twojego zadania.
- Dostosowywanie: Dostosuj model przy użyciu zestawu danych, aby poprawić jego wydajność w konkretnych zadaniach.
- Ocena: Ocenić dostosowany model przy użyciu zarówno jakościowych, jak i ilościowych mierników.
Pojęcia i techniki
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
- 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.
- 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
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
- Konfiguracja środowiska: Zainstaluj niezbędne biblioteki i skonfiguruj środowisko obliczeniowe.
- Ładowanie i przetwarzanie zestawu danych: Ładuj zestaw danych i przetwórz go w format przyjazny dla modelu.
- Ładowanie wstępnie wytrenowanego modelu: Ładuj model bazowy z konfiguracjami kwantyzacji, jeśli używasz QLoRA.
- Tokenizacja: Tokenizuj zestaw danych, aby przygotować go do treningu.
- Trening: Dostosuj model przy użyciu przygotowanego zestawu danych.
- 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-8Bna 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:
- 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.
- 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.
- Kroki akumulacji gradientu: Ten parametr pomaga symulować większe rozmiary partii, akumulując gradienty przez wiele kroków przed aktualizacją parametrów.
- 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.
- Wygaszanie wag: Technika regularizacji, która zapobiega przeuczeniu, karząc duże wagi.
- 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.













