Tutorial Unsloth: Fine-Tuning LLM yang Cepat dan Hemat Memori

# Fine-Tuning LLM Secara Efisien dengan Unsloth Dahulu, melakukan fine-tuning model bahasa besar membutuhkan server multi-GPU yang mahal dan waktu tunggu berjam-jam. Unsloth mengubah persamaan itu de...

By Ruby Abdullah · · tutorial
UnslothLLMFine-TuningLoRAQLoRAPython

Fine-Tuning LLM Secara Efisien dengan Unsloth

Dahulu, melakukan fine-tuning model bahasa besar membutuhkan server multi-GPU yang mahal dan waktu tunggu berjam-jam. Unsloth mengubah persamaan itu dengan menulis ulang bagian-bagian paling berat dari loop pelatihan, sehingga Anda dapat melakukan fine-tuning model seperti Llama, Mistral, Qwen, Gemma, dan Phi sekitar dua kali lebih cepat dengan kebutuhan VRAM yang jauh lebih rendah. Dalam tutorial ini kita akan menelusuri alur kerja yang lengkap dan realistis: memasang Unsloth, memuat model 4-bit, menambahkan adapter LoRA, menyiapkan dataset, melatih dengan SFTTrainer dari Hugging Face, menjalankan inferensi, dan mengekspor hasilnya untuk kebutuhan produksi.

Apa Itu Unsloth dan Mengapa Lebih Cepat

Unsloth adalah pustaka sumber terbuka yang mempercepat supervised fine-tuning (SFT) pada model bahasa berbasis transformer. Ini bukan algoritma pelatihan baru dan tidak mengubah matematika model Anda. Sebaliknya, Unsloth mengganti beberapa operasi yang menentukan performa dengan implementasi tulisan tangan yang melakukan pekerjaan yang sama secara lebih efisien.

Peningkatan kecepatan berasal dari beberapa keputusan rekayasa yang konkret:

  • Kernel Triton kustom. Operasi seperti embedding RoPE, RMSNorm, fungsi loss cross-entropy, dan perkalian matriks LoRA diimplementasikan ulang sebagai kernel Triton yang menyatu (fused). Menyatukan beberapa langkah ke dalam satu kernel menghindari pembacaan dan penulisan berulang ke memori GPU, yang biasanya menjadi hambatan sebenarnya.
  • Autograd manual. Alih-alih sepenuhnya mengandalkan grafik diferensiasi otomatis PyTorch, Unsloth menyediakan backward pass yang diturunkan secara manual untuk operasi yang dikelolanya. Hal ini menghapus tensor antara yang biasanya tetap disimpan PyTorch, sehingga menurunkan puncak penggunaan memori.
  • Desain yang sadar memori. Unsloth mengintegrasikan kuantisasi 4-bit (QLoRA) dan strategi gradient checkpointing kustom sehingga urutan panjang dan model yang lebih besar dapat muat di satu GPU konsumen.

Satu hal yang perlu ditegaskan: ini adalah implementasi ulang yang persis, bukan pendekatan aproksimasi. Unsloth tidak menukar akurasi demi kecepatan. Kurva loss yang Anda peroleh seharusnya cocok dengan menjalankan Hugging Face plus PEFT standar, hanya saja dihasilkan lebih cepat dan dengan jejak memori yang lebih kecil.

Apa yang Didukung Unsloth

Unsloth menyasar fine-tuning LoRA dan QLoRA untuk keluarga model bobot terbuka yang populer:

  • Llama (3, 3.1, 3.2, dan turunannya)
  • Mistral dan Mixtral
  • Qwen (2 dan 2.5)
  • Gemma (1 dan 2)
  • Phi (3 dan 3.5)

Pustaka ini bekerja pada satu GPU NVIDIA, termasuk T4 gratis yang ditawarkan di Google Colab. Full fine-tuning untuk setiap parameter umumnya berada di luar kekuatan utamanya; pustaka ini dibangun di sekitar metode yang hemat parameter.

Pemasangan

Untuk sebagian besar lingkungan terbaru, satu perintah pip sudah cukup:

pip install unsloth

Unsloth bergantung pada build PyTorch yang mendukung CUDA, transformers, trl, peft, accelerate, dan bitsandbytes. Jika Anda berada di mesin baru, pasang dulu build PyTorch yang sesuai dengan versi CUDA Anda, lalu pasang Unsloth:

# Contoh untuk CUDA 12.1 (sesuaikan dengan lingkungan Anda)

pip install torch --index-url https://download.pytorch.org/whl/cu121

pip install unsloth

Untuk mengambil perbaikan terbaru langsung dari repositori:

pip install "unsloth[colab-new] @ git+https://github.com/unslothai/unsloth.git"

Anda dapat memverifikasi pemasangan dan memeriksa GPU dengan:

import torch

from unsloth import FastLanguageModel

print("CUDA tersedia:", torch.cuda.isavailable())

print("Perangkat:", torch.cuda.getdevicename(0) if torch.cuda.isavailable() else "CPU")

Memuat Model 4-Bit

Titik masuk untuk hampir segalanya adalah FastLanguageModel.frompretrained. Memuat dalam 4-bit (QLoRA) adalah yang menjaga VRAM tetap rendah. Di sini kita memuat model instruct kecil yang muat dengan nyaman pada satu GPU.

from unsloth import FastLanguageModel

import torch

maxseqlength = 2048 # Panjang konteks yang ingin Anda latih

dtype = None # None membuat Unsloth deteksi otomatis (bf16 di Ampere+, fp16 selain itu)

loadin4bit = True # QLoRA 4-bit; set False untuk LoRA 16-bit jika VRAM mencukupi

model, tokenizer = FastLanguageModel.frompretrained(

modelname="unsloth/llama-3.2-3b-instruct-bnb-4bit",

maxseqlength=maxseqlength,

dtype=dtype,

loadin4bit=loadin4bit,

)

Beberapa catatan mengenai argumen ini:

  • maxseqlength mengontrol seberapa panjang contoh pelatihan Anda. Unsloth mendukung konteks panjang melalui kernelnya, tetapi urutan yang lebih panjang menghabiskan lebih banyak memori, jadi pilihlah nilai terkecil yang masih mencakup data Anda.
  • Nama model unsloth/...-bnb-4bit adalah salinan pra-kuantisasi yang dihosting oleh tim Unsloth. Model ini terunduh lebih cepat dan melewati langkah kuantisasi saat berjalan. Anda juga dapat memberikan ID model Hugging Face standar apa pun.
  • Membiarkan dtype=None adalah default yang aman; Unsloth akan memilih bfloat16 pada GPU yang mendukungnya.

Menambahkan Adapter LoRA

Kita tidak memperbarui semua bobot model. Sebaliknya, kita memasang matriks LoRA kecil yang dapat dilatih dan membekukan sisanya. getpeftmodel menghubungkan semua ini.

model = FastLanguageModel.getpeftmodel(

model,

r=16, # Rank LoRA: lebih tinggi = kapasitas lebih besar, memori lebih besar

targetmodules=[

"qproj", "kproj", "vproj", "oproj",

"gateproj", "upproj", "downproj",

],

loraalpha=16, # Faktor skala; pilihan umum adalah alpha == r

loradropout=0, # 0 sudah dioptimalkan dan bekerja baik dalam praktik

bias="none", # "none" adalah pengaturan yang dioptimalkan dan direkomendasikan

usegradientcheckpointing="unsloth", # Lihat tips memori di bawah

randomstate=3407,

userslora=False, # Rank-stabilized LoRA, opsional

loftqconfig=None,

)

Penjelasan pilihan utama:

  • r (rank) adalah tombol kapasitas utama. Nilai 8, 16, 32, dan 64 umum digunakan. Untuk sebagian besar tugas mengikuti instruksi, 16 adalah titik awal yang masuk akal.
  • targetmodules mendaftar lapisan linear mana yang menerima adapter. Menyertakan proyeksi atensi maupun proyeksi MLP (seperti di atas) adalah konfigurasi tipikal yang berkinerja baik.
  • usegradientcheckpointing="unsloth" mengaktifkan implementasi checkpointing milik Unsloth sendiri, yang lebih hemat memori dibanding versi generik PyTorch dan merupakan flag terpenting untuk memuat urutan yang panjang.

Menyiapkan Dataset

Misalkan kita menginginkan model yang menjawab pertanyaan tentang layanan konsultasi data perusahaan kita. Kita akan menggunakan dataset Q&A kustom kecil dalam format instruksi Alpaca, lalu mengonversinya dengan chat template model agar token spesial menjadi benar.

Format Gaya Alpaca

from datasets import loaddataset

Dataset ilustratif kecil. Dalam praktik, muat dataset JSON/CSV/Hub Anda sendiri.

raw = loaddataset("yahma/alpaca-cleaned", split="train[:2000]")

alpacaprompt = """Berikut adalah instruksi yang menjelaskan sebuah tugas, disertai input yang memberi konteks tambahan. Tulis respons yang menyelesaikan permintaan dengan tepat.

Instruksi:

{}

Input:

{}

Respons:

{}"""

EOSTOKEN = tokenizer.eostoken # Penting: tanpa EOS model tidak pernah belajar berhenti

def formatalpaca(examples):

texts = []

for instruction, inp, output in zip(

examples["instruction"], examples["input"], examples["output"]

):

text = alpacaprompt.format(instruction, inp, output) + EOSTOKEN

texts.append(text)

return {"text": texts}

dataset = raw.map(formatalpaca, batched=True)

Bug dataset yang paling umum adalah lupa menambahkan EOSTOKEN. Tanpa itu, model terus menghasilkan teks melewati jawaban dan tidak pernah memproduksi token berhenti.

Format dengan Chat Template

Jika data Anda berbentuk percakapan, jalur yang lebih bersih adalah menggunakan struktur gaya ShareGPT dan menerapkan chat template model. Unsloth menyediakan helper untuk ini.

from unsloth.chattemplates import getchattemplate

tokenizer = getchattemplate(

tokenizer,

chattemplate="llama-3.1", # Cocokkan template dengan model dasar Anda

)

def formatchat(examples):

convos = examples["conversations"] # daftar giliran {"role", "content"}

texts = [

tokenizer.applychattemplate(c, tokenize=False, addgenerationprompt=False)

for c in convos

]

return {"text": texts}

dataset = chatdataset.map(formatchat, batched=True)

Untuk data yang datang sebagai kolom instruksi/output terpisah, tosharegpt dapat menggabungkannya ke dalam struktur percakapan sebelum Anda menerapkan template. Prinsipnya sama: hasilkan satu field text per contoh yang berisi string terformat lengkap dan benar menurut tokenizer.

Pelatihan dengan SFTTrainer

Unsloth terintegrasi langsung dengan SFTTrainer dari Hugging Face TRL. Tidak ada yang aneh di sini; Anda cukup memberikan model Unsloth dan dataset terformat ke trainer standar.

from trl import SFTTrainer

from transformers import TrainingArguments

from unsloth import isbfloat16supported

trainer = SFTTrainer(

model=model,

tokenizer=tokenizer,

traindataset=dataset,

datasettextfield="text",

maxseqlength=maxseqlength,

datasetnumproc=2,

packing=False, # Set True untuk memadatkan urutan pendek demi throughput ekstra

args=TrainingArguments(

perdevicetrainbatchsize=2,

gradientaccumulationsteps=4, # Ukuran batch efektif = 2 4 = 8

warmupsteps=5,

maxsteps=60, # Gunakan numtrainepochs untuk pelatihan penuh

learningrate=2e-4,

fp16=not isbfloat16supported(),

bf16=isbfloat16supported(),

loggingsteps=1,

optim="adamw8bit", # Optimizer 8-bit menghemat memori

weightdecay=0.01,

lrschedulertype="linear",

seed=3407,

outputdir="outputs",

reportto="none",

),

)

trainerstats = trainer.train()

Catatan mengenai konfigurasi:

  • gradientaccumulationsteps memungkinkan Anda menyimulasikan ukuran batch yang lebih besar tanpa biaya memori. Ukuran batch efektif adalah perdevicetrainbatchsize gradientaccumulationsteps.
  • optim="adamw8bit" menggunakan optimizer 8-bit dari bitsandbytes, yang kira-kira memangkas separuh memori state optimizer dengan dampak kualitas yang dapat diabaikan.
  • Gunakan maxsteps untuk eksperimen cepat dan beralih ke numtrainepochs saat Anda melatih secara serius.
  • Learning rate 2e-4 adalah default yang wajar untuk LoRA; turunkan ke 1e-4 jika loss tidak stabil.

Memantau Memori

Unsloth mencetak ringkasan memori dan kecepatan selama pelatihan. Anda juga dapat memeriksanya secara manual:

gpustats = torch.cuda.getdeviceproperties(0)

startmem = round(torch.cuda.maxmemoryreserved() / 1024 / 1024 / 1024, 2)

print(f"GPU: {gpustats.name}, total memori: {round(gpustats.totalmemory/1024/1024/1024,2)} GB")

print(f"Memori tercadang sebelum/sesudah pelatihan: {startmem} GB")

Tips Memori dan VRAM

Membuat satu sesi pelatihan muat di GPU sederhana sebagian besar bergantung pada segelintir tuas:

  • Gunakan 4-bit (loadin4bit=True). Ini adalah penghematan tunggal terbesar dan menjadi alasan utama memilih Unsloth.
  • Set usegradientcheckpointing="unsloth". Ini menukar sedikit komputasi demi pengurangan besar pada memori aktivasi dan mengungguli checkpointing generik.
  • Jaga maxseqlength tetap ketat. Memori berskala dengan panjang urutan. Jika 90 persen contoh Anda di bawah 1024 token, jangan set batasnya ke 4096.
  • Turunkan ukuran batch, naikkan gradient accumulation. Ini menjaga ukuran batch efektif tetap konstan sambil mengurangi puncak memori.
  • Pilih adamw8bit. Optimizer 8-bit secara nyata mengurangi memori state optimizer.
  • Aktifkan packing=True untuk banyak contoh pendek. Packing menyambung urutan pendek untuk mengisi jendela konteks, meningkatkan throughput, meski sedikit mengubah perhitungan loss.

Pada Colab T4 gratis (16 GB) Anda dapat dengan nyaman melakukan fine-tuning model kelas 3B dalam 4-bit dan bahkan beberapa model 7B/8B dengan maxseqlength serta ukuran batch yang konservatif.

Menjalankan Inferensi

Setelah pelatihan, alihkan model ke mode inferensi yang dioptimalkan Unsloth, yang mengaktifkan jalur generasi cepat bawaan.

FastLanguageModel.forinference(model)  # Generasi ~2x lebih cepat

messages = [

{"role": "user", "content": "Layanan apa yang biasanya ditawarkan perusahaan konsultasi data?"},

]

inputs = tokenizer.applychattemplate(

messages,

tokenize=True,

addgenerationprompt=True,

returntensors="pt",

).to("cuda")

outputs = model.generate(

inputids=inputs,

maxnewtokens=256,

usecache=True,

temperature=0.7,

topp=0.9,

)

print(tokenizer.batchdecode(outputs, skipspecialtokens=True)[0])

Untuk keluaran streaming token demi token, gunakan TextStreamer:

from transformers import TextStreamer

streamer = TextStreamer(tokenizer, skipprompt=True)

= model.generate(inputids=inputs, streamer=streamer, maxnewtokens=256)

Menyimpan dan Mengekspor Model

Unsloth mendukung tiga target penyimpanan praktis tergantung bagaimana Anda berniat melakukan deployment.

Hanya Adapter LoRA

Artefak terkecil. Ia hanya menyimpan bobot adapter yang dilatih dan harus dimuat di atas model dasar nanti.

model.savepretrained("loramodel")

tokenizer.savepretrained("loramodel")

Untuk mengunggah ke Hugging Face Hub:

model.pushtohub("nama-pengguna-anda/loramodel", token="hf...")

Model 16-Bit Tergabung

Menggabungkan bobot LoRA kembali ke model dasar dan menyimpan checkpoint 16-bit mandiri. Inilah format yang diharapkan sebagian besar tumpukan penyajian (vLLM, TGI, Transformers biasa).

model.savepretrainedmerged(

"merged16bitmodel",

tokenizer,

savemethod="merged16bit",

)

Anda juga dapat menyimpan model 4-bit tergabung dengan savemethod="merged4bit" ketika ukuran disk dan unduhan lebih penting dibanding presisi.

GGUF untuk llama.cpp dan Ollama

Untuk menjalankan model di llama.cpp, Ollama, atau LM Studio, ekspor ke GGUF dengan kuantisasi pilihan Anda.

# Kuantisasi tunggal (q4km adalah keseimbangan ukuran/kualitas yang baik)

model.savepretrainedgguf("ggufmodel", tokenizer, quantizationmethod="q4km")

Beberapa kuantisasi sekaligus

model.savepretrainedgguf(

"ggufmodel",

tokenizer,

quantizationmethod=["q4km", "q80", "f16"],

)

Setelah diekspor, Anda dapat mendaftarkan file GGUF ke Ollama menggunakan Modelfile sederhana:

# Modelfile

FROM ./ggufmodel/unsloth.Q4KM.gguf

Lalu bangun dan jalankan:

ollama create my-finetune -f Modelfile

ollama run my-finetune

Menggunakan Unsloth di Colab Gratis

Unsloth populer sebagian karena dapat berjalan di Colab T4 gratis. Alur kerjanya identik dengan yang di atas. Dua pengingat praktis:

  • Sematkan versi di bagian atas notebook agar restart runtime tidak menarik dependensi yang tidak kompatibel.
  • Simpan adapter Anda ke Google Drive atau Hub sebelum sesi kehabisan waktu; sesi Colab gratis tidak persisten.

from google.colab import drive

drive.mount("/content/drive")

model.savepretrained("/content/drive/MyDrive/loramodel")

Praktik Terbaik

  • Mulai kecil dan iterasi. Jalankan 60 langkah terlebih dahulu untuk memastikan pipeline bekerja dari ujung ke ujung sebelum meluncurkan tugas berjam-jam.
  • Cocokkan chat template dengan model dasar. Template Llama pada model Qwen menghasilkan prompt yang cacat dan hasil yang buruk.
  • Selalu tambahkan token EOS dalam format gaya Alpaca agar model belajar berhenti.
  • Lacak kurva loss. Sesi LoRA yang sehat menunjukkan loss yang menurun stabil; loss yang datar atau meledak biasanya menandakan masalah learning rate atau format.
  • Validasi secara kualitatif. Loss kuantitatif tidaklah cukup; ambil sampel beberapa prompt dan baca keluarannya sebelum deployment.
  • Sisihkan set evaluasi kecil untuk mendeteksi overfitting, terutama dengan dataset kecil dan rank tinggi.

Kesalahan Umum

  • Lupa EOSTOKEN. Kesalahan paling sering; model berbicara tanpa henti saat inferensi.
  • Learning rate terlalu tinggi. LoRA menoleransi laju lebih tinggi dibanding full fine-tuning, tetapi 1e-3 ke atas sering membuat pelatihan tidak stabil. Tetaplah di sekitar 2e-4.
  • maxseqlength terlalu besar. Menetapkannya jauh di atas panjang data sebenarnya memboroskan memori dan dapat menyebabkan error out-of-memory tanpa manfaat.
  • Dtype atau CUDA tidak cocok. Build PyTorch yang tidak cocok dengan driver CUDA Anda adalah penyebab umum kegagalan saat pemasangan.
  • Mengharapkan perilaku full fine-tuning. Unsloth dioptimalkan untuk LoRA/QLoRA. Jika Anda perlu memperbarui setiap parameter di klaster besar, ini bukan alat yang tepat.
  • Melewatkan mode inferensi. Lupa FastLanguageModel.forinference(model) membuat generasi tetap berjalan di jalur pelatihan yang lebih lambat.

Kesimpulan dan Poin Penting

Unsloth membuat fine-tuning LLM dapat diakses pada perangkat keras yang sebelumnya terlalu kecil untuk tugas ini, tanpa meminta Anda berkompromi pada kualitas keluaran. Dengan mengimplementasikan ulang bagian-bagian mahal dari loop pelatihan sebagai kernel Triton yang menyatu beserta backward pass tulisan tangan, ia memberikan pelatihan sekitar 2x lebih cepat dan VRAM yang jauh lebih rendah sambil menghasilkan hasil yang sama dengan sesi PEFT standar.

Hal-hal pokok yang perlu diingat:

  • Unsloth mempercepat fine-tuning LoRA dan QLoRA untuk keluarga Llama, Mistral, Qwen, Gemma, dan Phi pada satu GPU.
  • Muat model 4-bit dengan FastLanguageModel.frompretrained, pasang adapter dengan getpeftmodel, dan latih dengan SFTTrainer Hugging Face yang sudah familier.
  • Penghematan memori terbesar datang dari pemuatan 4-bit, usegradientcheckpointing="unsloth", maxseqlength yang ketat, dan optimizer 8-bit.
  • Simpan sesuai kebutuhan deployment Anda: adapter LoRA untuk portabilitas, model 16-bit tergabung untuk penyajian standar, atau GGUF untuk llama.cpp dan Ollama.
  • Ia berjalan di Colab gratis, menjadikannya cara yang sangat baik untuk mempelajari fine-tuning sebelum berkomitmen pada infrastruktur yang lebih besar.

Dengan alur kerja ini Anda dapat mengambil model instruct kecil, mengadaptasikannya ke dataset Q&A kustom, dan mengirimkan artefak siap deployment hanya dalam satu sore.

Artikel Terkait

Tutorial Axolotl: Fine-Tuning LLM Berbasis Konfigurasi YAML

Fine-Tuning LLM Berbasis Konfigurasi dengan Axolotl Kebanyakan proyek fine-tuning dimulai dengan cara yang sama: seseora...

Fireworks AI: Platform Inference Super Cepat buat Open LLM dan Model Multimodal

Fireworks AI: Platform Inference Super Cepat buat Open LLM dan Model Multimodal Halo temen-temen, di tutorial kali ini a...

Together AI: Panduan Lengkap Inference dan Fine-Tuning Model Open Source dengan Satu API

Together AI: Panduan Lengkap Inference dan Fine-Tuning Model Open Source dengan Satu API Halo temen-temen! Kali ini aku ...

Tutorial TRL: Post-Training LLM dengan SFT, DPO, dan Reward Modeling

Post-Training LLM dengan TRL: SFT, Reward Modeling, dan DPO Setelah sebuah base language model selesai dipretraining, mo...