Connect with us

Jedyny przewodnik, którego potrzebujesz do dokształcenia Llama 3 lub innego modelu open source

Sztuczna inteligencja

Jedyny przewodnik, którego potrzebujesz do dokształcenia Llama 3 lub innego modelu open source

mm
FINE TUNING OPEN SOURCE LLM PYTHON GUIDE

Dokształcanie dużych modeli językowych (LLM) jak Llama 3 obejmuje adaptację wstępnie wytrenowanego modelu do konkretnych zadań przy użyciu zbioru danych specyficznych dla danej dziedziny. 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 przejdziemy przez kroki dokształcania 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 dokształcania

Dokształcanie obejmuje kilka kluczowych kroków:

  1. Wybór wstępnie wytrenowanego modelu: Wybierz model bazowy, który jest zgodny z Twoją pożądaną architekturą.
  2. Zbieranie odpowiedniego zbioru danych: Zbierz i przetwórz zbiór danych specyficzny dla Twojego zadania.
  3. Dokształcanie: Przystosuj model przy użyciu zbioru danych, aby poprawić jego wydajność w konkretnych zadaniach.
  4. Ocena: Ocenić dokształcony model przy użyciu zarówno jakościowych, jak i ilościowych miar.

Pojęcia i techniki

Dokształcanie dużych modeli językowych

Dokształcanie dużych modeli językowych

Pełne dokształcanie

Pełne dokształcanie 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.

Dokształcanie 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 rangowa adaptacja (LoRA) i kwantyzowana LoRA (QLoRA)

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

Metody dokształcania

  1. Pełne dokształcanie: Obejmuje trening wszystkich parametrów modelu na zadaniowym zbiorze danych. Chociaż ta metoda może być bardzo skuteczna, jest również obliczeniowo droga i wymaga znacznej ilości pamięci.
  2. Dokształcanie 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 rangowa adaptacja (LoRA) i kwantyzowana LoRA (QLoRA) należą do tej kategorii.

Czym jest LoRA?

Porównanie metod dokształcania: QLORA ulepsza LoRA z kwantyzacją 4-bitową i zoptymalizowanymi optymalizatorami do zarządzania skokami pamięci

Porównanie metod dokształcania: QLORA ulepsza LoRA z kwantyzacją 4-bitową i zoptymalizowanymi optymalizatorami do zarządzania skokami pamięci

LoRA jest ulepszoną metodą dokształcania, w której zamiast dokształcania wszystkich wag wstępnie wytrenowanego modelu, dokształca się dwie mniejsze macierze, które przybliżają większą macierz. Te macierze stanowią adapter LoRA. Ten dokształcony adapter jest następnie ładowany do wstępnie wytrenowanego modelu i używany do inferencji.

Kluczowe zalety LoRA:

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

Czym jest kwantyzowana LoRA (QLoRA)?

QLoRA idzie o krok dalej niż LoRA, 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.
  • Utrzymanie wydajności: Pomimo redukcji precyzji, QLoRA utrzymuje poziomy wydajności zbliżone do modeli pełnej precyzji.

Dostosowanie do zadania

Podczas dokształcania parametry modelu są dostosowywane na podstawie nowego zbioru danych, co pomaga mu lepiej zrozumieć i generować treści istotne dla konkretnego zadania. Proces ten zachowuje ogólną wiedzę językową uzyskaną podczas wstępnego treningu, dostosowując model do niuansów docelowego obszaru.

Dokształcanie w praktyce

Pełne dokształcanie vs. PEFT

  • Pełne dokształcanie: Obejmuje trening całego modelu, co może być obliczeniowo drogie i wymagać znacznej ilości pamięci.
  • Dokształcanie efektywne pod względem parametrów (LoRA i QLoRA): Dokształca tylko podzbiór parametrów, redukując wymagania pamięciowe i zapobiegając katastrofalnemu zapomnieniu, co czyni je bardziej efektywną alternatywą.

Kroki implementacji

  1. Konfiguracja środowiska: Zainstaluj niezbędne biblioteki i skonfiguruj środowisko obliczeniowe.
  2. Ładowanie i przetwarzanie zbioru danych: Ładuj zbiór danych i przetwórz go w sposób odpowiedni dla modelu.
  3. Ładowanie wstępnie wytrenowanego modelu: Ładuj model bazowy z konfiguracjami kwantyzacji, jeśli używasz QLoRA.
  4. Tokenizacja: Tokenizuj zbiór danych, aby przygotować go do treningu.
  5. Trening: Dokształcaj model przy użyciu przygotowanego zbioru danych.
  6. Ocena: Ocenić wydajność modelu na konkretnych zadaniach przy użyciu jakościowych i ilościowych miar.

Krok po kroku przewodnik po dokształcaniu LLM

Ustawienie środowiska

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

Najpierw 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 zbiór danych

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

Przetwórz zbiór danych zgodnie z wymaganiami modelu, w tym zastosowaniem odpowiednich szablonów i upewnieniem się, że format danych jest odpowiedni do dokształcania​ (Hugging Face)​​ (DataCamp)​.

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

Zbadaj strukturę zbioru danych:

print(dataset['test'][0])

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 Phi-2 firmy Microsoft 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

Dokształcanie Llama 3 lub innych modeli

Podczas dokształcania modeli takich jak Llama 3 lub innych modeli open source, istnieją specyficzne rozważania i dostosowania wymagane do zapewnienia optymalnej wydajności. 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ę, aby zażądać dostępu i zalogować się do swojego konta Hugging Face, jeśli jest to wymagane dla modeli takich jak Llama 3​ (Hugging Face)​​

Tokenizacja:

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

Pamięć i obliczenia:

  • Dokształcanie 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. Upewnij się, że środowisko może obsłużyć wymagania pamięciowe, które mogą być złagodzone przez użycie technik takich jak QLoRA, aby zmniejszyć ślad pamięciowy​ (Hugging Face Forums)

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
)

Tokenizacja:

W zależności od konkretnego przypadku użycia i wymagań modelu, upewnij się, że konfiguracja tokenizatora jest poprawna i nie zawiera zbędnych ustawień. Na przykład, use_fast=True jest zalecane dla lepszej wydajności​ (Hugging Face)​​ (Weights & Biases)​.

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

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 poprawnego nazwy i identyfikatora modelu z hubu modeli Hugging Face lub innych źródeł.

Tokenizacja:

  • Podobnie jak w przypadku Llama 3, upewnij się, że tokenizator jest poprawnie skonfigurowany i zgodny 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
)

Przykład dla Mistral:

model_name = 'mistral-7B'
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
)

Zagadnienia z tokenizacją: Każdy model może mieć unikalne wymagania dotyczące tokenizacji. Upewnij się, że tokenizator jest zgodny z modelem i poprawnie skonfigurowany.

Przykład tokenizatora Llama 3:

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

Przykład tokenizatora GPT-3 i Mistral:

tokenizer = AutoTokenizer.from_pretrained(
model_name,
use_fast=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"

# Generuj 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 zbiór danych

Przekonwertuj pary dialogów i podsumowań w przykładowe dane wejściowe:

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)

Zatokenizuj sformatowany zbiór danych:

def preprocess_batch(batch, tokenizer, max_length):
return tokenizer(batch["text"], max_length=max_length, truncation=True)

max_length = 1024
train_dataset = dataset["train"].map(lambda batch: preprocess_batch(batch, tokenizer, max_length), batched=True)
eval_dataset = dataset["validation"].map(lambda batch: preprocess_batch(batch, tokenizer, max_length), batched=True)

9. Przygotuj model do QLoRA

Przygotuj model do dokształcania efektywnego pod względem parametrów:

original_model = prepare_model_for_kbit_training(original_model)

Parametry i ich wpływ

Parametry mają kluczowe znaczenie w optymalizacji wydajności Twojego modelu. Oto kilka kluczowych parametrów do rozważenia:

  1. Szybkość uczenia: Kontroluje szybkość, z jaką model aktualizuje swoje parametry. Wysoka szybkość uczenia może prowadzić do szybszego zbieżności, ale może również przekroczyć optymalne rozwiązanie. Niska szybkość 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 wykonaniem aktualizacji parametrów.
  4. Liczba epok: Liczba razy, gdy cały zbiór danych jest przetwarzany przez model. Więcej epok może poprawić wydajność, ale może również prowadzić do przeuczenia, jeśli nie zostanie odpowiednio zarządzane.
  5. Wygaszanie: Technika regularizacji, która zapobiega przeuczeniu, karząc duże wagi.
  6. Planista szybkości uczenia: Dostosowuje szybkość uczenia podczas treningu, aby poprawić wydajność i zbieżność.

Dostosuj konfigurację treningu, dostosowując parametry takie jak szybkość uczenia, rozmiar partii i kroki akumulacji gradientu, w zależności od konkretnych wymagań modelu i zadania. Na przykład, modele Llama 3 mogą wymagać innych szybkości uczenia w porównaniu z mniejszymi modelami​ (Weights & Biases)​​ (GitHub)

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 dokształconego modelu

Po treningu, ocenić wydajność modelu przy użyciu zarówno jakościowych, jak i ilościowych metod.

1. Ocena ludzka

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

2. Ocena ilościowa

Użyj miar 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.

3. Wolny trening

Optymalizuj szybkość treningu, dostosowując rozmiar partii, szybkość uczenia i używając kroków akumulacji gradientu.

4. Jakość danych

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

Podsumowanie

Dokształcanie dużych modeli językowych przy użyciu QLoRA jest efektywnym sposobem na adaptację dużych wstępnie wytrenowanych modeli do konkretnych zadań z redukowanymi kosztami obliczeniowymi. Śledząc ten przewodnik, możesz dokształcić PHI, Llama 3 lub inny model open source, aby osiągnąć wysoką wydajność w Twoich konkretnych zadaniach.

Spędziłem ostatnie pięć lat, zanurzając się w fascynującym świecie Machine Learning i Deep Learning. Moja pasja i ekspertyza doprowadziły mnie do udziału w ponad 50 różnych 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ę bardziej zbadać.