Fine-tuning model besar tanpa biaya meledak: parameter-efficient fine-tuning dengan LoRA dan QLoRA, kuantisasi untuk hemat memori, langkah praktis fine-tune LoRA di GPU consumer, serta gambaran RLHF dan DPO untuk menyelaraskan perilaku model

Setelah di episode 13 kita memahami arsitektur transformer dan fine-tuning dasar, muncul kenyataan pahit: fine-tuning penuh model 7B+ membutuhkan GPU kelas server — berpuluh GB VRAM, biaya puluhan juta per bulan, dan memakan waktu berhari-hari. Pada 2026, hampir tidak ada tim yang melakukan full fine-tuning untuk produksi; hampir semuanya memakai parameter-efficient fine-tuning (PEFT).
PEFT mengubah permainan: alih-alih melatih miliaran parameter, kalian melatih sebagian kecil parameter tambahan (kadang kurang dari 1%) dan memperoleh hasil yang sebanding. Episode ini membangun keterampilan LoRA/QLoRA yang akan kalian pakai hampir setiap hari sebagai MLE modern — termasuk memilih GPU yang tepat dan memahami kapan RLHF/DPO diperlukan.
Full fine-tuning memperbarui semua bobot model. Dampaknya:
Inilah alasan teknik PEFT lahir dan langsung menjadi standar industri.
LoRA (Hu et al., 2021) berangkat dari observasi penting: perubahan bobot saat fine-tuning memiliki rank rendah — hanya sedikit arah yang benar-benar berguna. Alih-alih memperbarui matriks bobot W (misal 4096×4096), LoRA menambahkan dua matriks kecil A dan B yang hasil kalinya B×A mendekati perubahan W:
h = W·x + (B·A)·x
└─────┘
adaptasi LoRA, rank rMatriks A (r×k) dan B (d×r) berukuran kecil — dengan r=8..64, jumlah parameter terlatih turun drastis. Bobot asli W dibekukan (tidak dilatih), hanya A dan B yang berubah.
from peft import LoraConfig, get_peft_model
from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5-1.5B")
lora_config = LoraConfig(
r=16, # rank adaptasi
lora_alpha=32, # skala: alpha/r
target_modules=["q_proj", "k_proj", "v_proj", "o_proj"],
lora_dropout=0.05,
bias="none",
)
peft_model = get_peft_model(model, lora_config)
print(f"trainable: {peft_model.num_parameters(only_trainable=True):,} parameter")Kelebihan terbesar LoRA: adapter yang dihasilkan kecil (ratusan KB hingga beberapa MB, bukan puluhan GB). Model dasar yang sama bisa dipakai untuk banyak tugas — cukup tukar adapter — tanpa duplikasi bobot.
QLoRA menggabungkan LoRA dengan kuantisasi 4-bit: bobot model dasar dikompresi ke 4-bit, sementara adapter LoRA tetap dilatih dalam presisi normal. Ini menurunkan kebutuhan memori hingga ~4x, sehingga model 7B bisa di-fine-tune di GPU consumer 16-24GB:
from transformers import BitsAndBytesConfig, AutoModelForCausalLM
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype="bfloat16",
)
model = AutoModelForCausalLM.from_pretrained(
"Qwen/Qwen2.5-7B",
quantization_config=bnb_config,
device_map="auto",
)
peft_model = get_peft_model(model, lora_config)| Teknik | VRAM dibutuhkan (7B) | Hasil |
|---|---|---|
| Full fine-tune | ~60GB+ | Kualitas maksimal, mahal |
| LoRA | ~20-30GB | Mendekati full, adapter kecil |
| QLoRA | ~8-12GB | Hampir setara LoRA, GPU consumer OK |
Berikut alur utuh yang bisa kalian jalankan — dari dataset ke adapter:
from datasets import load_dataset
from transformers import AutoTokenizer, TrainingArguments
from trl import SFTTrainer
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-1.5B")
dataset = load_dataset("json", data_files="data/support_tickets.json")["train"]
trainer = SFTTrainer(
model=peft_model,
train_dataset=dataset,
args=TrainingArguments(
output_dir="./lora-out",
per_device_train_batch_size=4,
gradient_accumulation_steps=4,
learning_rate=2e-4,
num_train_epochs=3,
logging_steps=50,
),
)
trainer.train()
peft_model.save_pretrained("./lora-adapter") # simpan adapter sajafrom peft import PeftModel
base = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5-1.5B")
model = PeftModel.from_pretrained(base, "./lora-adapter")Model dasar + adapter adalah kombinasi yang di-deploy — di episode 15 kita akan menyajikannya lewat vLLM.
Kuantisasi menghemat memori dengan mengorbankan presisi. Aturan yang harus selalu dipakai: ukur dampaknya, jangan asumsikan. Sebelum mengadopsi QLoRA atau model 4-bit, bandingkan metrik (misal accuracy atau perplexity) model berkuantisasi vs presisi penuh pada eval set kalian. Untuk banyak tugas, perbedaannya kecil; untuk tugas presisi tinggi (misal matematika), bisa signifikan.
Fine-tuning supervised mengajarkan format & pengetahuan; alignment mengajarkan perilaku — menjawab sesuai preferensi manusia, tidak berbahaya, dan mengikuti instruksi.
from trl import DPOTrainer, DPOConfig
dpo_dataset = load_dataset("json", data_files="data/preferences.json")["train"]
dpo_args = DPOConfig(output_dir="./dpo-out", beta=0.1, per_device_train_batch_size=2)
dpo_trainer = DPOTrainer(
model=model, args=dpo_args, train_dataset=dpo_dataset, tokenizer=tokenizer
)
dpo_trainer.train()Untuk tahun 2026, alur produksi yang umum: SFT → DPO. SFT memberi kemampuan tugas, DPO menyelaraskan jawaban dengan preferensi. RLHF penuh biasanya hanya untuk tim dengan resource besar.
Warning
Data alignment (preferensi manusia) adalah aset paling mahal dan paling mudah "bocor". Pastikan data preferensi di-review untuk bias, di-versioning ketat, dan tidak mengandung data pribadi. Model yang diselaraskan dengan data berkualitas buruk akan menghasilkan kebijakan yang buruk — dan kesalahan ini hampir mustahil diperbaiki dengan prompt.
| Pitfall | Dampak | Pencegahan |
|---|---|---|
| Memilih rank LoRA terlalu besar | Overfit, adapter membesar | Mulai r=8..32, naik bertahap |
| Lupa alpha scaling | Perilaku adaptasi melenceng | alpha ≈ 2×r sebagai titik awal |
| Adapter & base mismatch | Inference error | Simpan model id base di adapter config |
| Kuantisasi tanpa evaluasi | Kualitas turun tak terdeteksi | Bandingkan metrik sebelum/sesudah |
| Data SFT jelek, lalu berharap DPO memperbaiki | Perilaku tetap buruk | Kualitas data sebelum alignment |
Pada episode 14 ini, kalian telah menguasai fine-tuning yang efisien:
Di episode 15 selanjutnya kita akan membahas Serving LLMs (vLLM/TGI) — PagedAttention, continuous batching, OpenAI-compatible API, dan cara menyajikan model LLM lokal dengan throughput dan memori yang efisien. Sampai jumpa di episode 15!