Connect with us

Kunstig intelligens

Den eneste vejledning, du har brug for til at finjustere Llama 3 eller enhver anden open source-model

mm
FINE TUNING OPEN SOURCE LLM PYTHON GUIDE

Finjustering af store sprogmodeller (LLM’er) som Llama 3 indebærer at tilpasse en forudtrænet model til bestemte opgaver ved hjælp af en domænespecifik dataset. Dette proces udnytter modellens forudgående viden, hvilket gør det effektivt og omkostningseffektivt i forhold til at træne fra scratch. I denne vejledning vil vi gå gennem trinnene til at finjustere Llama 3 ved hjælp af QLoRA (Quantized LoRA), en parameter-effektiv metode, der minimiserer hukommelsesbrug og beregningsomkostninger.

Overblik over finjustering

Finjustering indebærer flere nøgletrin:

  1. Valg af forudtrænet model: Vælg en basismodel, der er i overensstemmelse med din ønskede arkitektur.
  2. Indsamling af relevant dataset: Indsamle og forarbejd en dataset, der er specifik for din opgave.
  3. Finjustering: Tilpas modellen ved hjælp af datasettet for at forbedre dens præstation på bestemte opgaver.
  4. Evaluering: Vurder den finjusterede modells præstation ved hjælp af både kvalitative og kvantitative metrikker.

Koncepter og teknikker

Finjustering af store sprogmodeller

Finjustering af store sprogmodeller

Full finjustering

Full finjustering opdaterer alle modellens parametre, hvilket gør den specifik for den nye opgave. Denne metode kræver betydelige beregningsressourcer og er ofte upraktisk for meget store modeller.

Parameter-effektiv finjustering (PEFT)

PEFT opdaterer kun en undermængde af modellens parametre, hvilket reducerer hukommelseskrav og beregningsomkostninger. Denne teknik forhindrer katastrofalt glemsomhed og opretholder modellens generelle viden.

Low-Rank Adaptation (LoRA) og Quantized LoRA (QLoRA)

LoRA finjusterer kun få lav-rangs matricer, mens QLoRA kvantiserer disse matricer for at reducere hukommelsesaftrykket yderligere.

Finjusteringsmetoder

  1. Full finjustering: Dette indebærer træning af alle modellens parametre på den opgave-specifikke dataset. Selvom denne metode kan være meget effektiv, er den også beregningskrævende og kræver betydelig hukommelse.
  2. Parameter-effektiv finjustering (PEFT): PEFT opdaterer kun en undermængde af modellens parametre, hvilket gør den mere hukommelseffektiv. Teknikker som Low-Rank Adaptation (LoRA) og Quantized LoRA (QLoRA) falder ind under denne kategori.

Hvad er LoRA?

Sammenligning af finjusteringsmetoder: QLORA forbedrer LoRA med 4-bit præcision og paginerede optimizatorer til hukommelsesspidsstyring

Sammenligning af finjusteringsmetoder: QLORA forbedrer LoRA med 4-bit præcision og paginerede optimizatorer til hukommelsesspidsstyring

LoRA er en forbedret finjusteringsmetode, hvor man i stedet for at finjustere alle vægtene i den forudtrænede model, finjusterer to mindre matricer, der approksimerer den større matrix. Disse matricer udgør LoRA-adapteren. Denne finjusterede adapter indlæses herefter i den forudtrænede model og bruges til inferens.

Nøglefordele ved LoRA:

  • Hukommelseeffektivitet: LoRA reducerer hukommelsesaftrykket ved at finjustere kun små matricer i stedet for hele modellen.
  • Gensbrug: Den originale model forbliver uændret, og multiple LoRA-adaptere kan bruges med den, hvilket faciliterer håndtering af multiple opgaver med lavere hukommelseskrav.

Hvad er Quantized LoRA (QLoRA)?

QLoRA tager LoRA et skridt videre ved at kvantificere vægtene af LoRA-adapterne til lavere præcision (f.eks. 4-bit i stedet for 8-bit). Dette reducerer hukommelsesbrug og lagringskrav yderligere, mens det opretholder en sammenlignelig niveau af effektivitet.

Nøglefordele ved QLoRA:

  • Endnu større hukommelseeffektivitet: Ved at kvantificere vægtene reducerer QLoRA modellens hukommelses- og lagringskrav betydeligt.
  • Opretholder præstation: Trods den reducerede præcision opretholder QLoRA præstationsniveauer tæt på det fuldpræcisionsmodellen.

Opgave-specifik tilpasning

Under finjustering justeres modellens parametre baseret på den nye dataset, hvilket hjælper den med at bedre forstå og generere indhold, der er relevant for den specifikke opgave. Denne proces opretholder den generelle sprogkundskab, der er erhvervet under forudtræning, mens den tilpasser modellen til nuancerne i måldomænet.

Finjustering i praksis

Full finjustering vs. PEFT

  • Full finjustering: Dette indebærer træning af hele modellen, hvilket kan være beregningskrævende og kræver betydelig hukommelse.
  • PEFT (LoRA og QLoRA): PEFT finjusterer kun en undermængde af parametre, hvilket gør den mere hukommelseffektiv og forhindrer katastrofalt glemsomhed, hvilket gør den til en mere effektiv alternativ.

Implementeringstrin

  1. Konfigurer miljø: Installer nødvendige biblioteker og konfigurer beregningsmiljøet.
  2. Indlæs og forarbejd dataset: Indlæs datasettet og forarbejd det i en format, der er egnet for modellen.
  3. Indlæs forudtrænet model: Indlæs basismodellen med kvantiseringskonfigurationer, hvis QLoRA bruges.
  4. Tokenisering: Tokeniser datasettet for at forberede det til træning.
  5. Træning: Finjuster modellen ved hjælp af det forberedte dataset.
  6. Evaluering: Evaluér modellens præstation på bestemte opgaver ved hjælp af både kvalitative og kvantitative metrikker.

Trin-for-trin vejledning til finjustering af LLM

Konfiguration af miljø

Vi vil bruge en Jupyter-notebook til denne vejledning. Platforme som Kaggle, der tilbyder gratis GPU-brug, eller Google Colab er ideelle til at køre disse eksperimenter.

1. Installer nødvendige biblioteker

Først sikre, at du har de nødvendige biblioteker installeret:

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

2. Importér biblioteker og konfigurer miljø


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

# Deaktiver Weights and Biases logging
os.environ['WANDB_DISABLED'] = "true"
interpreter_login()

3. Indlæs dataset

Vi vil bruge DialogSum-datasettet til denne vejledning:

Forarbejd datasettet i overensstemmelse med modellens krav, herunder anvendelse af passende skabeloner og sikring af, at dataformatet er egnet til finjustering​ (Hugging Face)​​ (DataCamp)​.


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

Inspektér datasetstrukturen:


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

4. Opret BitsAndBytes-konfiguration

For at indlæse modellen i 4-bit format:


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. Indlæs forudtrænet model

Brug Microsofts Phi-2-model til denne vejledning:


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. Tokenisering

Konfigurer tokenisatoren:


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

Finjustering af Llama 3 eller andre modeller

Når du finjusterer modeller som Llama 3 eller andre state-of-the-art open-source LLM’er, er der bestemte overvejelser og tilpasninger, der kræves for at sikre optimal præstation. Her er de detaljerede trin og indsigt i, hvordan du kan tilpasse disse modeller til bestemte opgaver, herunder Llama 3, GPT-3 og Mistral.

5.1 Brug af Llama 3

Modelvalg:

  • Sikre, at du har den korrekte modelidentifikator fra Hugging Face-modelhubben. F.eks. kan Llama 3-modellen være identificeret som meta-llama/Meta-Llama-3-8B på Hugging Face.
  • Sikre, at du har adgang til og logger ind på din Hugging Face-konto, hvis det er nødvendigt for modeller som Llama 3​ (Hugging Face)​​

Tokenisering:

  • Brug den passende tokenisator til Llama 3, sikre, at den er kompatibel med modellen og understøtter nødvendige funktioner som padding og specieltegn.

Hukommelse og beregning:

  • Finjustering af store modeller som Llama 3 kræver betydelige beregningsressourcer. Sikre, at dit miljø, såsom en kraftfuld GPU-opstilling, kan håndtere hukommelses- og beregningskravene. Sikre, at miljøet kan håndtere hukommelseskravene, som kan reduceres ved at bruge teknikker som QLoRA til at reducere hukommelsesaftrykket​ (Hugging Face Forums)

Eksempel:

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
)

Tokenisering:

Afhængigt af den specifikke brugsanvisning og modellens krav, sikre, at tokenisatoren matcher modellen og er konfigureret korrekt.

Llama 3-tokenisatoreksempel:


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

GPT-3 og Mistral-tokenisatoreksempel:


tokenizer = AutoTokenizer.from_pretrained(
model_name,
use_fast=True
)

7. Test modellen med zero-shot-inferens

Evaluér den basismodel med en eksempelindtastning:

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"

# Generér output
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. Forarbejd dataset

Konverter dialog-summaripar til prompts:


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)

Tokeniser det formaterede dataset:


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. Forbered modellen til QLoRA

Forbered modellen til parameter-effektiv finjustering:


original_model = prepare_model_for_kbit_training(original_model)

Hyperparametre og deres indvirkning

Hyperparametre spiller en afgørende rolle i at optimere modellens præstation. Her er nogle nøglehyperparametre at overveje:

  1. Læringsrate: Kontrollerer, hvor hurtigt modellen opdaterer sine parametre. En høj læringsrate kan føre til hurtigere konvergens, men kan også overskyde den optimale løsning. En lav læringsrate sikrer stabil konvergens, men kan kræve flere epocher.
  2. Batch-størrelse: Antallet af eksempler, der behandles, før modellen opdaterer sine parametre. Større batch-størrelser kan forbedre stabiliteten, men kræver mere hukommelse. Mindre batch-størrelser kan føre til mere støj i træningsprocessen.
  3. Gradient-akkumuleringstrin: Dette parameter hjælper med at simulere større batch-størrelser ved at akkumulere gradienter over flere trin, før der udføres en parameteropdatering.
  4. Antal epocher: Antallet af gange, hele datasettet passerer gennem modellen. Flere epocher kan forbedre præstationen, men kan også føre til overfitning, hvis det ikke håndteres korrekt.
  5. Vægtfordampning: En reguleringsteknik til at forhindre overfitning ved at straffe store vægte.
  6. Læringsrateskæder: Justerer læringsraten under træning for at forbedre præstationen og konvergens.

Tilpas træningskonfigurationen ved at justere hyperparametre som læringsrate, batch-størrelse og gradient-akkumuleringsstrin baseret på modellens og opgavens specifikke krav. F.eks. kan Llama 3-modeller kræve forskellige læringsrater i forhold til mindre modeller​ (Weights & Biases)​​ (GitHub)

Eksempel på træningskonfiguration

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. Træn modellen

Konfigurer træneren og start træning:

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")

Evaluering af den finjusterede model

Efter træning, evaluér modellens præstation ved hjælp af både kvalitative og kvantitative metoder.

1. Menneskelig evaluering

Sammenlign de genererede summarier med menneskeskrevne summarier for at vurderere kvaliteten.

2. Kvantitativ evaluering

Brug metrikker som ROUGE til at vurderere præstation:


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)

Almindelige udfordringer og løsninger

1. Hukommelsesbegrænsninger

Brug af QLoRA hjælper med at mindske hukommelsesproblemer ved at kvantificere modellens vægte til 4-bit. Sikre, at du har nok GPU-hukommelse til at håndtere din batch-størrelse og modellens størrelse.

2. Overfitning

Overvåg valideringsmetrikker for at forhindre overfitning. Brug teknikker som tidlig stopning og vægtfordampning.

3. Langsom træning

Optimer træningshastighed ved at justere batch-størrelse, læringsrate og brug af gradient-akkumuleringsstrin.

4. Datakvalitet

Sikre, at dit dataset er rent og godt forarbejdet. Dårlig datakvalitet kan have en betydelig indvirkning på modellens præstation.

Konklusion

Finjustering af LLM’er ved hjælp af QLoRA er en effektiv måde at tilpasse store forudtrænede modeller til bestemte opgaver med reducerede beregningsomkostninger. Ved at følge denne vejledning kan du finjustere PHI, Llama 3 eller andre open-source-modeller til at opnå høj præstation på dine specifikke opgaver.

Jeg har brugt de sidste fem år på at dykke ned i den fascinerende verden af Machine Learning og Deep Learning. Min passion og ekspertise har ført til, at jeg har bidraget til over 50 forskellige software-udviklingsprojekter, med særlig fokus på AI/ML. Min vedvarende nysgerrighed har også ført mig i retning af Natural Language Processing, et felt jeg er ivrig efter at udforske yderligere.