AI-modeller och plattformar

Den enda guiden du behöver för att finjustera Llama 3 eller någon annan öppen källkodsmodell

mm
Lägg till Unite.AI bland dina föredragna källor på Google

Finjustering av stora språkmodeller (LLM) som Llama 3 innebär att anpassa en förtränad modell till specifika uppgifter med hjälp av en domänspecifik dataset. Denna process utnyttjar modellens förkunskap, vilket gör den effektiv och kostnadseffektiv jämfört med att träna från scratch. I den här guiden kommer vi att gå igenom stegen för att finjustera Llama 3 med hjälp av QLoRA (Quantized LoRA), en parameter-effektiv metod som minimerar minnesanvändning och beräkningskostnader.

Översikt av finjustering

Finjustering innebär flera viktiga steg:

  1. Urval av en förtränad modell: Välj en basmodell som överensstämmer med din önskade arkitektur.
  2. Insamling av en relevant dataset: Samla in och förbehandla en dataset som är specifik för din uppgift.
  3. Finjustering: Anpassa modellen med hjälp av datasetet för att förbättra dess prestanda på specifika uppgifter.
  4. Utvardering: Utvärdera den finjusterade modellen med hjälp av både kvalitativa och kvantitativa mått.

Begrepp och tekniker

Finjustering av stora språkmodeller

Finjustering av stora språkmodeller

Fullständig finjustering

Fullständig finjustering uppdaterar alla modellens parametrar, vilket gör den specifik för den nya uppgiften. Denna metod kräver betydande beräkningsresurser och är ofta opraktisk för mycket stora modeller.

Parameter-effektiv finjustering (PEFT)

PEFT uppdaterar endast en delmängd av modellens parametrar, vilket minskar minneskraven och beräkningskostnaderna. Denna teknik förhindrar katastrofalt glömska och bibehåller modellens allmänna kunskap.

Låg-rank-adaptation (LoRA) och kvantiserad LoRA (QLoRA)

LoRA finjusterar endast ett fåtal låg-rank-matriser, medan QLoRA kvantiserar dessa matriser för att ytterligare minska minnesavtrycket.

Finjusteringsmetoder

  1. Fullständig finjustering: Detta innebär att träna alla modellens parametrar på den uppgiftsspecifika dataseten. Medan denna metod kan vara mycket effektiv, är den också beräkningsmässigt dyrt och kräver betydande minnesresurser.
  2. Parameter-effektiv finjustering (PEFT): PEFT uppdaterar endast en delmängd av modellens parametrar, vilket gör den mer minneseffektiv. Tekniker som Låg-rank-adaptation (LoRA) och kvantiserad LoRA (QLoRA) faller inom denna kategori.

Vad är LoRA?

Jämförelse av finjusteringsmetoder: QLORA förbättrar LoRA med 4-bitars precision och sidordnade optimerare för minneshantering

Jämförelse av finjusteringsmetoder: QLORA förbättrar LoRA med 4-bitars precision och sidordnade optimerare för minneshantering

LoRA är en förbättrad finjusteringsmetod där, istället för att finjustera alla vikterna i den förtränade modellen, två mindre matriser som approximerar den större matrisen finjusteras. Dessa matriser utgör LoRA-adaptern. Denna finjusterade adapter läses sedan in i den förtränade modellen och används för inferens.

Nyckelfördelar med LoRA:

  • Minneseffektivitet: LoRA minskar minnesavtrycket genom att finjustera endast små matriser istället för hela modellen.
  • Återanvändbarhet: Den ursprungliga modellen förblir oförändrad, och flera LoRA-adapter kan användas med den, vilket underlättar hantering av flera uppgifter med lägre minneskrav.

Vad är kvantiserad LoRA (QLoRA)?

QLoRA tar LoRA ett steg längre genom att kvantisera vikterna i LoRA-adapterna till lägre precision (t.ex. 4-bitars istället för 8-bitars). Detta minskar ytterligare minnesanvändning och lagringskrav medan det bibehåller en jämförbar nivå av effektivitet.

Nyckelfördelar med QLoRA:

  • Ännu större minneseffektivitet: Genom att kvantisera vikterna minskar QLoRA modellens minnes- och lagringskrav avsevärt.
  • Bibehåller prestanda: Trots den reducerade precisionen bibehåller QLoRA prestandanivåer nära fullprecisionsmodeller.

Uppgiftsspecifik anpassning

Under finjustering justeras modellens parametrar baserat på den nya dataseten, vilket hjälper den att bättre förstå och generera innehåll relevant för den specifika uppgiften. Denna process behåller den allmänna språkkunskapen som erhållits under förträning medan den anpassar modellen till nyanserna i måldomänen.

Finjustering i praktiken

Fullständig finjustering vs. PEFT

  • Fullständig finjustering: Innebär att träna hela modellen, vilket kan vara beräkningsmässigt dyrt och kräver betydande minnesresurser.
  • PEFT (LoRA och QLoRA): Finjusterar endast en delmängd av parametrarna, vilket minskar minneskraven och förhindrar katastrofalt glömska, vilket gör det till en mer effektiv alternativ.

Implementeringssteg

  1. Konfigurera miljön: Installera nödvändiga bibliotek och konfigurera beräkningsmiljön.
  2. Ladda och förbehandla dataset: Ladda datasetet och förbehandla det till ett format som är lämpligt för modellen.
  3. Ladda förtränad modell: Ladda basmodellen med kvantiseringskonfigurationer om QLoRA används.
  4. Tokenisering: Tokenisera datasetet för att förbereda det för träning.
  5. Träning: Finjustera modellen med det förberedda datasetet.
  6. Utvardering: Utvärdera modellens prestanda på specifika uppgifter med hjälp av kvalitativa och kvantitativa mått.

Steg-för-steg-guide till finjustering av LLM

Konfigurera miljön

Vi kommer att använda en Jupyter-anteckningsbok för den här guiden. Plattformar som Kaggle, som erbjuder gratis GPU-användning, eller Google Colab är idealiska för att köra dessa experiment.

1. Installera nödvändiga bibliotek

Först, se till att du har de nödvändiga biblioteken installerade:

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

2. Importera bibliotek och konfigurera miljön

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

# Inaktivera Weights and Biases-loggning
os.environ['WANDB_DISABLED'] = "true"
interpreter_login()

3. Ladda dataset

Vi kommer att använda DialogSum-datasetet för den här guiden:
Förbehandla datasetet enligt modellens krav, inklusive tillämpning av lämpliga mallar och säkerställande av att dataformatet är lämpligt för finjustering​ (Hugging Face)​​ (DataCamp)​.

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

Inspektera datasetstrukturen:

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

4. Skapa BitsAndBytes-konfiguration

För att ladda modellen i 4-bitarsformat:

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. Ladda förtränad modell

Använd Microsofts Phi-2-modell för den här guiden:

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

Konfigurera tokenisatorn:

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 av Llama 3 eller andra modeller

När du finjusterar modeller som Llama 3 eller andra state-of-the-art-öppen-källkods-LLM, finns det specifika överväganden och justeringar som krävs för att säkerställa optimal prestanda. Här är detaljerade steg och insikter om hur man närmar sig detta för olika modeller, inklusive Llama 3, GPT-3 och Mistral.

5.1 Användning av Llama 3

Modellval:

  • Säkerställ att du har den korrekta modellidentifieraren från Hugging Face-modellhubben. Till exempel kan Llama 3-modellen identifieras som meta-llama/Meta-Llama-3-8B på Hugging Face.
  • Säkerställ att du begär åtkomst och loggar in på ditt Hugging Face-konto om det krävs för modeller som Llama 3​ (Hugging Face)​​

Tokenisering:

  • Använd den lämpliga tokenisatorn för Llama 3, säkerställ att den är kompatibel med modellen och stöder krävda funktioner som padding och specialtecken.

Minne och beräkning:

  • Finjustering av stora modeller som Llama 3 kräver betydande beräkningsresurser. Säkerställ att din miljö, såsom en kraftfull GPU-uppsättning, kan hantera minnes- och bearbetningskraven. Säkerställ att miljön kan hantera minneskraven, som kan mildras genom att använda tekniker som QLoRA för att minska minnesavtrycket​ (Hugging Face Forums)

Exempel:

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:

Beroende på det specifika användningsfallet och modellkraven, säkerställ att tokenisatorn är korrekt konfigurerad utan redundanta inställningar. Till exempel är use_fast=True rekommenderat för bättre prestanda​ (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 Användning av andra populära modeller (t.ex. GPT-3, Mistral)

Modellval:

  • För modeller som GPT-3 och Mistral, säkerställ att du använder den korrekta modellnamnet och identifieraren från Hugging Face-modellhubben eller andra källor.

Tokenisering:

  • Liknande Llama 3, se till att tokenisatorn är korrekt konfigurerad och kompatibel med modellen.

Minne och beräkning:

  • Varje modell kan ha olika minneskrav. Justera din miljökonfiguration enligt behov.

Exempel för 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
)

Exempel för 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
)

Tokeniseringsöverväganden: Varje modell kan ha unika tokeniseringskrav. Säkerställ att tokenisatorn matchar modellen och är korrekt konfigurerad.

Llama 3-tokeniseringsexempel:

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 och Mistral-tokeniseringsexempel:

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

7. Testa modellen med nollskottsinferens

Utvardera basmodellen med ett exempelinput:

from transformers import set_seed

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

<p># Generera 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)</p>

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

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

8. Förbehandla dataset

Konvertera dialog-summa-par till prompt:

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)

Tokenisera det formaterade datasetet:

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. Förbered modellen för QLoRA

Förbered modellen för parameter-effektiv finjustering:

original_model = prepare_model_for_kbit_training(original_model)

Hyperparametrar och deras påverkan

Hyperparametrar spelar en avgörande roll för att optimera modellens prestanda. Här är några viktiga hyperparametrar att överväga:

  1. Inlärningshastighet: Kontrollerar hur snabbt modellen uppdaterar sina parametrar. En hög inlärningshastighet kan leda till snabbare konvergens men kan också överskrida den optimala lösningen. En låg inlärningshastighet säkerställer stadig konvergens men kan kräva fler epoker.
  2. Batchstorlek: Antalet prover som bearbetas innan modellen uppdaterar sina parametrar. Större batchstorlekar kan förbättra stabiliteten men kräver mer minne. Mindre batchstorlekar kan leda till mer brus i träningsprocessen.
  3. Gradientackumuleringssteg: Denna parameter hjälper till att simulera större batchstorlekar genom att ackumulera gradienter över flera steg innan en parameteruppdatering utförs.
  4. Antal epoker: Antalet gånger som hela datasetet passerar genom modellen. Fler epoker kan förbättra prestandan men kan också leda till överanpassning om det inte hanteras korrekt.
  5. Viktförfall: Regleringsteknik för att förhindra överanpassning genom att bestraffa stora vikter.
  6. Inlärningshastighetsschema: Justerar inlärningshastigheten under träningsprocessen för att förbättra prestandan och konvergensen.

Anpassa träningskonfigurationen genom att justera hyperparametrar som inlärningshastighet, batchstorlek och gradientackumuleringssteg baserat på den specifika modellen och uppgiftens krav. Till exempel kan Llama 3-modeller kräva olika inlärningshastigheter jämfört med mindre modeller​ (Weights & Biases)​​ (GitHub)

Exempel 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äna modellen

Konfigurera tränaren och starta träningsprocessen:

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

Utvardering av den finjusterade modellen

Efter träningsprocessen utvärdera modellens prestanda med hjälp av både kvalitativa och kvantitativa metoder.

1. Mänsklig utvardering

Jämför de genererade sammanfattningarna med mänskligt skrivna för att bedöma kvaliteten.

2. Kvantitativ utvardering

Använd mått som ROUGE för att bedöma prestandan:

from rouge_score import rouge_scorer

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

Vanliga utmaningar och lösningar

1. Minnesbegränsningar

Användning av QLoRA hjälper till att mildra minnesproblem genom att kvantisera modellvikter till 4-bitars. Säkerställ att du har tillräckligt med GPU-minne för att hantera din batchstorlek och modellstorlek.

2. Överanpassning

Övervaka valideringsmått för att förhindra överanpassning. Använd tekniker som tidig stoppning och viktförfall.

3. Långsam träningsprocess

Optimera träningshastigheten genom att justera batchstorlek, inlärningshastighet och använda gradientackumuleringssteg.

4. Datakvalitet

Säkerställ att din dataset är ren och väl förbehandlad. Dålig datakvalitet kan påverka modellens prestanda avsevärt.

Slutsats

Finjustering av LLM med QLoRA är ett effektivt sätt att anpassa stora förtränade modeller till specifika uppgifter med reducerade beräkningskostnader. Genom att följa den här guiden kan du finjustera PHI, Llama 3 eller någon annan öppen källkodsmodell för att uppnå hög prestanda på dina specifika uppgifter.

Jag har tillbringat de senaste fem åren med att dyka djupt in i den fascinerande världen av Maskinlärning och Djupinlärning. Min passion och expertis har lett mig till att bidra till över 50 olika mjukvaruprojekt, med särskild fokus på AI/ML. Min pågående nyfikenhet har också lett mig mot Naturlig Språkbehandling, ett område som jag är angelägen om att utforska vidare.