Tutorial Lengkap Fine-tuning LLM dengan LoRA dan PEFT
Fine-tuning Large Language Models (LLM) secara tradisional membutuhkan GPU memory yang sangat besar dan waktu yang lama. LoRA (Low-Rank Adaptation) dan PEFT (Parameter-Efficient Fine-Tuning) memungkinkan Anda melakukan fine-tuning dengan resource yang jauh lebih kecil sambil mempertahankan performa yang kompetitif.
Apa itu LoRA dan PEFT?
LoRA (Low-Rank Adaptation)
LoRA adalah teknik yang menambahkan trainable low-rank matrices ke layer-layer model yang di-freeze. Daripada mengupdate semua parameter model:
- Freeze semua weights original model
- Inject trainable rank decomposition matrices (A dan B)
- Hanya train matrices baru ini (< 1% dari total parameters)
- Memory efficient: ~10x lebih kecil dari full fine-tuning
- Faster training: Training lebih cepat
- No inference latency: Weights bisa di-merge
- Task switching: Swap LoRA adapters untuk tasks berbeda
PEFT (Parameter-Efficient Fine-Tuning)
PEFT adalah library dari Hugging Face yang menyediakan berbagai metode fine-tuning efisien:
- LoRA: Low-rank adaptation
- QLoRA: LoRA dengan quantization
- Prefix Tuning: Prepend trainable tokens
- Prompt Tuning: Learn soft prompts
- IA3: Infused Adapter by Inhibiting and Amplifying
Instalasi
# Install packages
pip install transformers datasets accelerate peft bitsandbytes
pip install trl # Untuk training utilities
pip install wandb # Optional: experiment tracking
Untuk QLoRA (4-bit quantization)
pip install bitsandbytes>=0.41.0
Verify GPU
python -c "import torch; print(torch.cuda.isavailable())"
Quick Start: Fine-tune dengan LoRA
1. Basic LoRA Fine-tuning
from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments
from peft import LoraConfig, getpeftmodel, TaskType
from datasets import loaddataset
from trl import SFTTrainer
Load base model dan tokenizer
modelname = "meta-llama/Llama-2-7b-hf" # Atau model lain
tokenizer = AutoTokenizer.frompretrained(modelname)
tokenizer.padtoken = tokenizer.eostoken
model = AutoModelForCausalLM.frompretrained(
modelname,
torchdtype="auto",
devicemap="auto"
)
Konfigurasi LoRA
loraconfig = LoraConfig(
r=8, # Rank of the update matrices
loraalpha=32, # Scaling factor
targetmodules=["qproj", "vproj"], # Modules to apply LoRA
loradropout=0.05,
bias="none",
tasktype=TaskType.CAUSALLM
)
Apply LoRA ke model
model = getpeftmodel(model, loraconfig)
model.printtrainableparameters()
Output: trainable params: 4,194,304 || all params: 6,742,609,920 || trainable%: 0.06%
Load dataset
dataset = loaddataset("timdettmers/openassistant-guanaco", split="train")
Training arguments
trainingargs = TrainingArguments(
outputdir="./lora-output",
numtrainepochs=3,
perdevicetrainbatchsize=4,
gradientaccumulationsteps=4,
learningrate=2e-4,
fp16=True,
loggingsteps=10,
savestrategy="epoch",
warmupratio=0.03,
)
Trainer
trainer = SFTTrainer(
model=model,
args=trainingargs,
traindataset=dataset,
tokenizer=tokenizer,
datasettextfield="text",
maxseqlength=512,
)
Train
trainer.train()
Save LoRA weights
model.savepretrained("./lora-adapter")
2. LoRA Config Parameters
from peft import LoraConfig
config = LoraConfig(
# Core parameters
r=8, # Rank: dimensi dari low-rank matrices
# Lebih tinggi = lebih ekspresif tapi lebih banyak params
# Typical: 4, 8, 16, 32, 64
loraalpha=32, # Scaling factor
# Rule: alpha = 2 r untuk hasil optimal
# Scaling = alpha / r
# Target modules (varies by model architecture)