PEFT documentation
LoRA
LoRA
LoRA adalah salah satu metode PEFT yang paling populer dan merupakan titik awal yang baik jika Anda baru mulai menggunakan PEFT. Metode ini awalnya dikembangkan untuk model bahasa besar, tetapi menjadi metode pelatihan yang sangat populer untuk model difusi karena efisiensi dan efektivitasnya.
Low-Rank Adaptation (LoRA) adalah metode PEFT yang menguraikan matriks besar menjadi dua matriks ber-rank rendah yang lebih kecil. Hal ini secara drastis mengurangi jumlah parameter yang perlu dihaluskan.
Abstrak dari makalah tersebut adalah:
Paradigma penting dalam pemrosesan bahasa alami terdiri dari pra-pelatihan berskala besar pada data domain umum dan adaptasi ke tugas atau domain tertentu. Seiring dengan pra-pelatihan model yang semakin besar, fine-tuning penuh, yang melatih ulang semua parameter model, menjadi semakin tidak layak. Menggunakan GPT-3 175B sebagai contoh — mendeploykan instance independen dari model yang telah di-fine-tune, masing-masing dengan 175B parameter, sangat mahal. Kami mengusulkan Low-Rank Adaptation, atau LoRA, yang membekukan bobot model pra-terlatih dan menyuntikkan matriks dekomposisi rank yang dapat dilatih ke setiap lapisan arsitektur Transformer, sehingga sangat mengurangi jumlah parameter yang dapat dilatih untuk tugas downstream. Dibandingkan dengan GPT-3 175B yang di-fine-tune dengan Adam, LoRA dapat mengurangi jumlah parameter yang dapat dilatih hingga 10.000 kali dan kebutuhan memori GPU hingga 3 kali. LoRA menghasilkan kualitas model yang setara atau lebih baik daripada fine-tuning pada RoBERTa, DeBERTa, GPT-2, dan GPT-3, meskipun memiliki lebih sedikit parameter yang dapat dilatih, throughput pelatihan yang lebih tinggi, dan, berbeda dengan adapters, tidak ada latensi inferensi tambahan. Kami juga menyediakan investigasi empiris mengenai rank-deficiency dalam adaptasi model bahasa, yang memberikan wawasan tentang efektivitas LoRA. Kami merilis paket yang memfasilitasi integrasi LoRA dengan model PyTorch dan menyediakan implementasi serta checkpoint model kami untuk RoBERTa, DeBERTa, dan GPT-2 di this https URL.
LoRA merepresentasikan pembaruan bobot dengan dua matriks yang lebih kecil (disebut matriks pembaruan) melalui dekomposisi rank rendah. Matriks-matriks baru ini dapat dilatih untuk beradaptasi dengan data baru sambil menjaga jumlah total parameter tetap rendah. Matriks bobot asli tetap dibekukan dan tidak menerima pembaruan lebih lanjut. Untuk menghasilkan hasil akhir, bobot asli dan bobot adaptif tambahan digabungkan. Anda juga dapat menggabungkan bobot adapter dengan model dasar untuk menghilangkan latensi inferensi.

Pendekatan ini memiliki sejumlah keuntungan:
- LoRA membuat finetuning lebih efisien dengan mengurangi secara drastis jumlah parameter yang dapat dilatih.
- Bobot pretrained asli tetap dibekukan, yang berarti Anda dapat memiliki beberapa model LoRA yang ringan dan portabel untuk berbagai tugas turunan yang dibangun di atasnya.
- LoRA bersifat ortogonal terhadap metode parameter-efisien lainnya dan dapat dikombinasikan dengan banyak di antaranya.
- Kinerja model yang ditala ulang menggunakan LoRA sebanding dengan kinerja model yang ditala ulang secara penuh.
Pada prinsipnya, LoRA dapat diterapkan pada subset matriks bobot mana pun dalam jaringan saraf untuk mengurangi jumlah parameter yang dapat dilatih. Namun, untuk kesederhanaan dan efisiensi parameter yang lebih lanjut, LoRA biasanya hanya diterapkan pada blok perhatian dalam model Transformer - mungkin juga layak menargetkan lapisan lainnya. Jumlah parameter yang dapat dilatih dalam model LoRA yang dihasilkan bergantung pada ukuran matriks pembaruan, yang terutama ditentukan oleh rank r dan bentuk matriks bobot asli.
Anda dapat menginisialisasi matriks ber-rank rendah dengan mempertimbangkan berbagai kasus penggunaan - kesadaran tugas (CorDA, EVA, Astra), konvergensi yang lebih cepat (PiSSA), mitigasi kuantisasi (LoftQ) - hanya untuk menyebut beberapa kasus penggunaan. Baca tentang inisialisasi yang berbeda di bawah. Inisialisasi default adalah agar LoRA menjadi no-op, untuk secara bertahap mempelajari perilaku baru tanpa banyak mengganggu model yang ada.
Penggunaan
Ukuran matriks pembaruan ber-rank rendah ditentukan oleh rank atau r. Rank yang lebih tinggi berarti model memiliki lebih banyak parameter untuk dilatih, tetapi juga berarti model memiliki kapasitas belajar yang lebih besar. Pada contoh berikut, Anda akan menargetkan matriks query dan value dari blok perhatian. Parameter penting lainnya yang perlu diatur adalah lora_alpha (faktor penskalaan), bias (apakah none, all atau hanya parameter bias LoRA yang harus dilatih), dan modules_to_save (modul di luar lapisan LoRA yang akan dilatih dan disimpan). Semua parameter ini - dan lainnya - dapat ditemukan di LoraConfig.
from peft import LoraConfig, get_peft_model
config = LoraConfig(
r=16,
lora_alpha=16,
target_modules=["query", "value"],
lora_dropout=0.1,
bias="none",
modules_to_save=["classifier"],
)
model = get_peft_model(model, config)
model.print_healthcheck()Ikhtisar benchmark
Inisialisasi
Inisialisasi bobot LoRA dikendalikan oleh parameter init_lora_weights di LoraConfig. Secara default, PEFT menginisialisasi bobot LoRA dengan Kaiming-uniform untuk bobot A dan nol untuk bobot B, yang menghasilkan transformasi identitas (sama seperti implementasi referensi).
Untuk lapisan transformers.Conv1D, seperti proyeksi GPT-2, gunakan fan_in_fan_out=True karena bobotnya disimpan sebagai (in_features, out_features) alih-alih tata letak nn.Linear. Inisialisator berbasis bobot yang didukung menggunakan tata letak Linear untuk dekomposisi dan memulihkan tata letak penyimpanan saat memperbarui bobot dasar. Penskalaan "stable" dari LoRA-GA juga menggunakan dimensi keluaran terlepas dari tata letak penyimpanan.
Anda juga dapat meneruskan init_lora_weights="gaussian". Sesuai namanya, ini menginisialisasi bobot A dengan distribusi Gaussian dan nol untuk bobot B (inilah cara Diffusers menginisialisasi bobot LoRA).
from peft import LoraConfig
config = LoraConfig(init_lora_weights="gaussian", ...)Tersedia juga opsi untuk mengatur init_lora_weights=False yang berguna untuk debugging dan pengujian. Ini seharusnya satu-satunya kali Anda menggunakan opsi ini. Saat memilih opsi ini, bobot LoRA diinisialisasi sedemikian rupa sehingga tidak menghasilkan transformasi identitas.
from peft import LoraConfig
config = LoraConfig(init_lora_weights=False, ...)Normalized Low-Rank Adaptation (NoRA) menormalisasi matriks down-projection LoRA. PEFT menerapkan normalisasi ini hanya saat inisialisasi melalui init_lora_weights="nora" di LoraConfig: ia menormalisasi kolom dari bobot LoRA A yang diinisialisasi secara acak dan menginisialisasi bobot LoRA B ke nol. Kedua matriks tetap dapat dilatih, dan bobot dasar dibiarkan tidak berubah.
Untuk lapisan linear, pembaruan bobot adapter adalah $\Delta W = sBA$, di mana memiliki bentuk (r, in_features), memiliki bentuk (out_features, r), dan adalah faktor penskalaan LoRA. NoRA dimulai dari bobot A acak yang dibuat oleh lapisan linear LoRA dan menormalisasi setiap kolom di sepanjang dimensi rank:
Karena B bernilai nol, pembaran bobot adapter adalah nol sebelum pelatihan. Dengan bias="none" dan lora_bias=False, adapter pada awalnya mempertahankan keluaran model dasar. NoRA tidak memerlukan dataset kalibrasi atau dekomposisi bobot.
Untuk NoRA, pengaturan yang direkomendasikan adalah
lora_alphasama denganr(rasio alpha/rank 1:1), misalnya,r=8, lora_alpha=8. Denganuse_rslora=Falsebawaan, ini mempertahankan faktor penskalaan 1; mengaktifkan rank-stabilized LoRA mengubahnya menjadilora_alpha / sqrt(r).
Contoh berikut menerapkan NoRA pada dua lapisan linear dalam model PyTorch kecil:
from torch import nn
from peft import LoraConfig, get_peft_model
model = nn.Sequential(
nn.Linear(32, 32),
nn.ReLU(),
nn.Linear(32, 16),
)
config = LoraConfig(
r=8,
lora_alpha=8,
target_modules=["0", "2"],
init_lora_weights="nora",
bias="none",
lora_bias=False,
use_rslora=False,
)
model = get_peft_model(model, config)
model.print_healthcheck()Untuk model Transformers, atur target_modules ke nama-nama lapisan linear yang ingin Anda adaptasi, seperti ["q_proj", "v_proj"] ketika nama-nama tersebut ada dalam model.
NoRA menggunakan konfigurasi, pelatihan, penyimpanan, dan API pemuatan LoRA yang sudah ada, sehingga tidak ada kelas NoraConfig atau NoraModel yang terpisah. Untuk API konfigurasi dan model yang dibagikan, lihat LoraConfig dan LoraModel.
NoRA mendukung modul target torch.nn.Linear atau nn.Parameter yang diteruskan secara langsung dengan target_parameters. Tidak didukung untuk embeddings, lapisan conv, dan sebagainya.
PiSSA menginisialisasi adapter LoRA menggunakan nilai-nilai singular utama dan vektor-vektor singular. Modifikasi sederhana ini memungkinkan PiSSA untuk konvergen lebih cepat daripada LoRA dan pada akhirnya mencapai kinerja yang lebih unggul. Selain itu, PiSSA mengurangi error kuantisasi dibandingkan dengan QLoRA, yang menghasilkan peningkatan lebih lanjut.
Konfigurasikan metode inisialisasi menjadi “pissa”, yang mungkin memerlukan beberapa menit untuk mengeksekusi SVD pada model terlatih:
from peft import LoraConfig
config = LoraConfig(init_lora_weights="pissa", ...)Sebagai alternatif, jalankan SVD cepat, yang hanya membutuhkan beberapa detik. Jumlah iterasi menentukan keseimbangan antara kesalahan dan waktu komputasi:
lora_config = LoraConfig(init_lora_weights="pissa_niter_[number of iters]", ...)Untuk instruksi terperinci tentang penggunaan PiSSA, silakan ikuti instruksi ini.
MiCA (Minor Component Adaptation) adalah pelengkap bagi PiSSA: alih-alih menginisialisasi dari komponen singular utama, MiCA menggunakan komponen minor. Secara konkret, dengan W = U Σ V^T, MiCA menetapkan B = U[:, -r:] (vektor singular kiri r yang terkait dengan nilai singular terkecil) dan A = 0. Selama pelatihan, hanya A yang diperbarui; B dibekukan. Intuisinya adalah bahwa arah singular minor sebagian besar tidak digunakan oleh tugas pra-pelatihan, sehingga menawarkan subruang yang lebih “plastis” untuk menyuntikkan pengetahuan baru sambil mempertahankan kemampuan pra-pelatihan.
Karena A == 0 saat inisialisasi, kontribusi adapter B · A == 0 dan keluaran model dipertahankan persis pada langkah 0 — tidak diperlukan pengurangan residual pada bobot dasar (berbeda dengan PiSSA). Karena hanya A yang dapat dilatih, jumlah parameter yang dapat dilatih untuk r yang sama kira-kira setengah dari LoRA.
from peft import LoraConfig
config = LoraConfig(init_lora_weights="mica", r=16, target_modules=["q_proj", "v_proj"], ...)MiCA saat ini mendukung modul target nn.Linear dan nn.Embedding. Rank yang dipilih harus memenuhi r <= min(in_features, out_features) untuk lapisan linear dan r <= min(num_embeddings, embedding_dim) untuk lapisan embedding. Untuk penggunaan yang lebih rinci, lihat instruksi ini.
MiCA terutama ditujukan untuk pra-pelatihan lanjutan / pra-pelatihan adaptif domain. Dalam pengaturan tersebut, gunakan model dasar, bukan checkpoint yang telah disetel untuk instruksi atau obrolan, untuk inisialisasi SVD dan pelatihan MiCA. Setelah pelatihan, gabungkan adapter ke dalam bobot model dasar dan gunakan model dasar yang telah diadaptasi tersebut sebagai titik awal untuk penyetelan instruksi/obrolan berikutnya.
CorDA membangun adapter LoRA yang sadar tugas dari dekomposisi bobot yang diorientasikan oleh konteks tugas hilir yang akan dipelajari (mode pratinjau instruksi, IPM) atau pengetahuan dunia yang harus dipertahankan (mode pengetahuan terpelihara, KPM). KPM tidak hanya mencapai kinerja yang lebih baik daripada LoRA pada tugas fine-tuning, tetapi juga memitigasi pelupaan katastrofik dari pengetahuan dunia yang telah dilatih sebelumnya. Ketika mempertahankan pengetahuan yang telah dilatih sebelumnya bukan menjadi perhatian, IPM lebih diutamakan karena dapat mempercepat konvergensi lebih lanjut dan meningkatkan kinerja fine-tuning.
Anda perlu mengatur metode inisialisasi menjadi “corda”, dan menentukan mode IPM atau KPM serta dataset untuk mengumpulkan matriks kovarians.
@torch.no_grad()
def run_model():
# Assume `model` and `dataset` is in context...
model.eval()
for batch in dataset:
model(**batch)
corda_config = CordaConfig(
corda_method="kpm",
)
lora_config = LoraConfig(
init_lora_weights="corda",
corda_config=corda_config,
)
preprocess_corda(model, lora_config, run_model=run_model)
peft_model = get_peft_model(model, lora_config)Untuk instruksi terperinci tentang penggunaan CorDA, silakan ikuti instruksi ini.
Astra membangun adapter LoRA yang sadar tugas dari vektor eigen ekor dari matriks kovariansi dari aktivasi output modul, yang diperkirakan dari dataset kalibrasi kecil dari tugas hilir. Bobot pralatih diproyeksikan ke subruang yang direntangkan oleh vektor eigen ekor untuk menginisialisasi adapter, yang membatasi pembaruan ke subruang aktivasi yang paling relevan untuk tugas hilir dan mempercepat konvergensi.
Anda perlu mengatur metode inisialisasi menjadi “astra”, secara eksplisit mengatur target_modules, dan menyediakan dataset kalibrasi untuk mengumpulkan matriks kovarians.
@torch.no_grad()
def run_model():
# Assume `model` and `dataset` is in context...
model.eval()
for batch in dataset:
model(**batch)
from peft.tuners.lora import AstraConfig, preprocess_astra
astra_config = AstraConfig()
lora_config = LoraConfig(
init_lora_weights="astra",
target_modules=["q_proj", "v_proj"],
astra_config=astra_config,
)
preprocess_astra(model, lora_config, run_model=run_model)
peft_model = get_peft_model(model, lora_config)Untuk instruksi terperinci tentang penggunaan Astra, silakan ikuti instruksi ini.
OLoRA menggunakan dekomposisi QR untuk menginisialisasi adapter LoRA. OLoRA menerjemahkan bobot dasar model dengan faktor dekomposisi QR mereka, yaitu, memodifikasi bobot sebelum melakukan pelatihan apa pun pada bobot tersebut. Pendekatan ini secara signifikan meningkatkan stabilitas, mempercepat kecepatan konvergensi, dan pada akhirnya mencapai kinerja yang lebih unggul.
Anda hanya perlu meneruskan satu opsi tambahan untuk menggunakan OLoRA:
from peft import LoraConfig
config = LoraConfig(init_lora_weights="olora", ...)Untuk penggunaan yang lebih lanjut, silakan merujuk ke dokumentasi kami.
EVA melakukan SVD pada aktivasi input dari setiap lapisan dan menggunakan vektor singular kanan untuk menginisialisasi bobot LoRA. Oleh karena itu, ini adalah skema inisialisasi yang didorong oleh data. Selain itu, EVA secara adaptif mengalokasikan rank di antara lapisan berdasarkan “rasio varians yang dijelaskan” - sebuah metrik yang diturunkan dari analisis SVD.
Anda dapat menggunakan EVA dengan mengatur init_lora_weights="eva" dan mendefinisikan EvaConfig di LoraConfig:
from peft import LoraConfig, EvaConfig
peft_config = LoraConfig(
init_lora_weights = "eva",
eva_config = EvaConfig(rho = 2.0),
...
)Parameter rho (≥ 1.0) menentukan seberapa banyak redistribusi yang diizinkan. Ketika rho=1.0 dan r=16, adapter LoRA dibatasi tepat pada 16 rank, sehingga mencegah terjadinya redistribusi. Nilai yang direkomendasikan untuk EVA dengan redistribusi adalah 2.0, yang berarti rank maksimum yang diizinkan untuk sebuah layer adalah 2r.
Disarankan untuk melakukan inisialisasi EVA pada akselerator (misalnya GPU CUDA, Intel XPU) karena jauh lebih cepat. Untuk mengoptimalkan jumlah memori yang tersedia untuk EVA, Anda dapat menggunakan flag low_cpu_mem_usage di get_peft_model():
peft_model = get_peft_model(model, peft_config, low_cpu_mem_usage=True)Lalu, panggil initialize_lora_eva_weights() untuk menginisialisasi bobot EVA (dalam kebanyakan kasus, dataloader yang digunakan untuk inisialisasi eva dapat sama dengan yang digunakan untuk finetuning):
initialize_lora_eva_weights(peft_model, dataloader)
EVA berfungsi langsung dengan bitsandbytes. Cukup inisialisasi model dengan quantization_config dan panggil initialize_lora_eva_weights() seperti biasa.
Untuk instruksi lebih lanjut tentang penggunaan EVA, silakan merujuk ke dokumentasi kami.
Saat melakukan kuantisasi model dasar untuk pelatihan QLoRA, pertimbangkan untuk menggunakan inisialisasi LoftQ, yang telah terbukti meningkatkan kinerja saat melatih model terkuantisasi. Idenya adalah bobot LoRA diinisialisasi sedemikian rupa sehingga error kuantisasi diminimalkan. Untuk menggunakan LoftQ, ikuti instruksi ini.
Pelajari lebih lanjut tentang cara kerja PEFT dengan kuantisasi dan cara menggunakan LoftQ dalam panduan Kuantisasi.
Cara lain untuk menginisialisasi LoraConfig adalah dengan metode rank-stabilized LoRA (rsLoRA). Arsitektur LoRA menskalakan setiap adapter selama setiap forward pass dengan skalar tetap yang ditetapkan saat inisialisasi dan bergantung pada rank r. Skalar tersebut diberikan oleh lora_alpha/r dalam implementasi asli, tetapi rsLoRA menggunakan lora_alpha/math.sqrt(r) yang menstabilkan adapter dan meningkatkan potensi kinerja dari penggunaan r yang lebih tinggi.
from peft import LoraConfig
config = LoraConfig(use_rslora=True, ...)LoRA-GA (Low-Rank Adaptation with Gradient Approximation) menginisialisasi bobot adapter dengan melakukan SVD pada gradien yang diperkirakan, sehingga bobotnya lebih selaras dengan full-finetuning untuk konvergensi yang lebih cepat.
Metode ini memerlukan fungsi inisialisasi untuk memperkirakan gradien sebelum memulai pelatihan yang sebenarnya:
from peft.tuners.lora import preprocess_loraga
def train_step():
"""Run forward and backward passes for gradient estimation."""
dataloader_iter = iter(grad_dataloader)
for _ in range(N):
batch = next(dataloader_iter)
batch = {k: v.to(device) for k, v in batch.items()}
outputs = model(**batch)
loss = outputs.loss
loss.backward()
preprocess_loraga(model, lora_config, train_step)Tips Penggunaan
Estimasi Gradien: LoRA-GA memerlukan fase estimasi gradien sebelum inisialisasi model. Gunakan
preprocess_loraga()dengan callbacktrain_stepuntuk menghitung gradien pada sejumlah kecil batch pelatihan (biasanya 64-128 batch).Strategi Inisialisasi: LoRA-GA mendukung empat strategi arah (
direction):"ArBr","A2rBr","ArB2r"(default), dan"random", serta empat strategi penskalaan (scale):"stable"(default),"weight_svd","gd_scale", dan"unit". Kombinasi default memberikan keseimbangan terbaik antara kecepatan konvergensi dan stabilitas.Modifikasi Bobot Dasar: Berbeda dengan LoRA standar, LoRA-GA memodifikasi bobot model dasar selama inisialisasi dengan mengurangi versi berskala dari aproksimasi peringkat rendah. Hal ini memungkinkan keselarasan yang lebih baik dengan gradien fine-tuning penuh. Karena bobot dasar dimodifikasi, gunakan
save_pretrained()dengan argumensave_embedding_layersatau berikanpath_initial_model_for_weight_conversion.Overhead Komputasi: Estimasi gradien menambahkan overhead kecil selama inisialisasi (biasanya 1-2 menit untuk 64 batch), tetapi ini cepat teramortisasi oleh konvergensi yang lebih cepat selama pelatihan.
Kompatibilitas: LoRA-GA memerlukan bobot presisi penuh dan tidak mendukung model terkuantisasi. Dapat dikombinasikan dengan varian LoRA lainnya seperti DoRA.
Pelatihan
Bagian ini menunjukkan cara menangani skenario pelatihan yang lebih kompleks, bukan sekadar menerapkan adapter ber-rank rendah pada model dan memberi umpan data.
Pelatihan bergaya QLoRA
Pengaturan LoRA bawaan di PEFT menambahkan bobot yang dapat dilatih ke lapisan query dan value dari setiap blok perhatian. Namun, QLoRA, yang menambahkan bobot yang dapat dilatih ke semua lapisan linear dari model transformer, dapat memberikan performa yang setara dengan model yang sepenuhnya ditala ulang. Untuk menerapkan LoRA ke semua lapisan linear, seperti pada QLoRA, atur target_modules="all-linear" (lebih mudah daripada menentukan modul individual berdasarkan nama yang dapat bervariasi tergantung pada arsitektur).
config = LoraConfig(target_modules="all-linear", ...)Untuk informasi lebih lanjut tentang cara menerapkan kuantisasi ke adapter PEFT, lihat panduan kuantisasi.
Replikasi Layer yang Efisien Memori dengan LoRA
Pendekatan yang digunakan untuk meningkatkan kinerja model adalah memperluas model dengan menduplikasi lapisan dalam model untuk membangun model yang lebih besar dari model pralatih berukuran tertentu. Misalnya, meningkatkan model 7B menjadi model 10B seperti yang dijelaskan dalam makalah SOLAR. PEFT LoRA mendukung jenis ekspansi ini dengan cara yang hemat memori, yang memungkinkan penyesuaian lanjutan menggunakan adapter LoRA yang dipasang pada lapisan setelah replikasi lapisan. Lapisan yang direplikasi tidak memerlukan memori tambahan karena mereka berbagi bobot dasar, sehingga satu-satunya memori tambahan yang diperlukan adalah memori untuk bobot adapter. Untuk menggunakan fitur ini, Anda akan membuat konfigurasi dengan argumen layer_replication.
config = LoraConfig(layer_replication=[[0,4], [2,5]], ...)Dengan asumsi model asli memiliki 5 lapisan [0, 1, 2 ,3, 4], ini akan membuat model dengan 7 lapisan yang disusun sebagai [0, 1, 2, 3, 2, 3, 4]. Hal ini mengikuti konvensi merge pass through mergekit di mana urutan lapisan yang ditentukan sebagai tuple mulai inklusif dan akhir eksklusif ditumpuk untuk membangun model akhir. Setiap lapisan dalam model akhir mendapatkan set adapter LoRA yang berbeda.
Fewshot-Metamath-OrcaVicuna-Mistral-10B adalah contoh model yang dilatih menggunakan metode ini pada Mistral-7B yang diperluas menjadi 10B. adapter_config.json menunjukkan contoh konfigurasi adapter LoRA yang menerapkan metode ini untuk fine-tuning.
Kontrol terperinci atas rank dan alpha (penyeskalan)
Secara default, semua lapisan yang ditargetkan dengan LoRA akan memiliki rank r yang sama dan lora_alpha yang sama (yang menentukan penskalaan LoRA), tergantung pada apa yang ditentukan dalam LoraConfig. Namun, dalam beberapa kasus, Anda mungkin ingin menunjukkan nilai yang berbeda untuk lapisan yang berbeda. Hal ini dimungkinkan dengan meneruskan argumen rank_pattern dan alpha_pattern ke LoraConfig. Argumen ini harus berupa kamus dengan kunci berupa nama lapisan dan nilai berupa nilai rank/alpha. Kunci dapat berupa regular expressions (regex). Semua lapisan LoRA yang tidak disebutkan secara eksplisit dalam rank_pattern dan alpha_pattern akan mengambil nilai default r dan lora_alpha.
Sebagai contoh, misalkan kita memiliki model dengan struktur berikut:
>>> print(model)
Outer(
(foo): Linear(...)
(module): Middle(
(foo): Linear(...)
(foobar): Linear(...)
(module): Inner(
(foo): Linear(...)
(barfoo): Linear(...)
)
)
)rank_pattern={"foo": 42}akan mencocokkan semua 3 lapisanfoo. Baikfoobarmaupunbarfootidak dicocokkan.rank_pattern={"^foo": 42}hanya akan mencocokkan lapisanfoodari model, tetapi tidak mencocokkanmodule.foomaupunmodule.module.foo. Hal ini karena^berarti “awal string” saat menggunakan ekspresi reguler, dan hanyafooyang diawali dengan"foo"; nama lapisan lainnya memiliki prefiks.rank_pattern={"^module.foo": 42}hanya cocok denganmodule.foo, tetapi tidak denganmodule.module.foo, karena alasan yang sama.rank_pattern={"module.foo": 42}cocok denganmodule.foodanmodule.module.foo, tetapi tidak denganfoo.rank_pattern={"^foo": 42, "^module.module.foo": 55}cocok denganfoodanmodule.module.foo, masing-masing, tetapi tidak denganmodule.foo.- Tidak perlu menandai
$untuk menandai akhir dari pencocokan, karena ini ditambahkan secara otomatis oleh PEFT.
Logika yang sama berlaku untuk alpha_pattern. Jika Anda ragu, jangan mencoba menggunakan ekspresi reguler yang rumit — cukup berikan nama lengkap untuk setiap modul dengan rank/alpha yang berbeda, didahului oleh prefiks ^, dan Anda seharusnya tidak akan mengalami masalah.
Deteksi modul target yang layak secara otomatis
peft.helpers.KappaTuneSelector mengimplementasikan strategi pemilihan target berbasis bilangan kondisi dari makalah KappaTune. Modul ini memindai setiap modul nn.Linear dan, untuk model di mana bobot ahli MoE disimpan sebagai tensor nn.Parameter 3D yang digabungkan (misalnya Llama-4, Qwen3-MoE), juga parameter-parameter tersebut, menghitung bilangan kondisi matriks κ = σ_max / σ_min untuk masing-masing, lalu memilih lapisan yang paling isotropik (κ terendah). Lapisan isotropik ini berfungsi sebagai kandidat ideal untuk fine-tuning, karena sifat entropi tingginya memungkinkan mereka menyerap informasi baru dengan lebih mudah, sementara lapisan yang terspesialisasi dan anisotropik dibiarkan utuh untuk memitigasi pelupaan katastrofik selama pembelajaran berkelanjutan.
Gunakan peft.helpers.find_kappa_target_modules() sebagai satu baris untuk mendapatkan target_modules optimal untuk LoraConfig:
from peft import LoraConfig, get_peft_model
from peft.helpers import find_kappa_target_modules
model = AutoModelForCausalLM.from_pretrained("mistralai/Mixtral-8x7B-Instruct-v0.1")
targets = find_kappa_target_modules(model, top_p=0.2)
config = LoraConfig(
target_modules=targets["target_modules"],
target_parameters=targets["target_parameters"] if stable_modules_dic["target_parameters"] else None,
r=64,
lora_alpha=32,
task_type="CAUSAL_LM",
)
peft_model = get_peft_model(model, config)Lihat contoh lengkap di sini.
Menargetkan nn.Parameter secara langsung
Secara umum, Anda sebaiknya menggunakan target_modules untuk menargetkan modul (misalnya nn.Linear). Namun, dalam beberapa situasi, hal ini tidak memungkinkan. Misalnya, pada banyak lapisan mixture of expert (MoE) di HF Transformers, nn.Parameter digunakan alih-alih nn.Linear. PEFT biasanya menimpa metode forward untuk LoRA, tetapi untuk nn.Parameter, tidak ada metode tersebut. Oleh karena itu, untuk menerapkan LoRA pada parameter tersebut, parameter itu perlu ditargetkan dengan target_parameters. Sebagai contoh, untuk Llama4, Anda dapat meneruskan: target_parameters=['feed_forward.experts.gate_up_proj', 'feed_forward.experts.down_proj].
Perlu diperhatikan bahwa saat menargetkan parameter ahli, PEFT dapat menambah overhead waktu eksekusi yang signifikan. Alasannya adalah PEFT selalu mematerialisasi kontribusi LoRA untuk setiap ahli meskipun hanya sejumlah kecil ahli yang diperlukan. Selama pelatihan, hal ini kurang relevan karena, sepanjang sekuens, biasanya sebagian besar ahli diaktifkan setidaknya sekali. Namun, selama inferensi, biasanya cache KV digunakan sehingga kita hanya perlu menghitung token terakhir, yang berarti hanya sejumlah kecil ahli yang diaktifkan. Oleh karena itu, penggunaan LoRA pada lapisan MoE dapat menyebabkan perlambatan yang signifikan pada waktu inferensi. Rekomendasinya adalah menggabungkan bobot (model.merge_adapter() atau model = model.merge_and_unload()). Hal ini menghilangkan overhead PEFT.
Investigasi yang lebih rinci mengenai masalah ini dapat ditemukan pada pull request tentang optimasi MoE ini.
Catatan
- Saat ini, argumen ini memungkinkan penargetan
nn.Parameter2-dimensi atau 3-dimensi. Diasumsikan bahwa untuk parameter 3-dimensi, dimensi ke-0 adalah dimensi ahli (expert). - Beberapa adapter LoRA (ditambahkan melalui
model.add_adapterataumodel.load_adapter) yang menggunakantarget_parametersdidukung, tetapi semuanya harus menargetkan set parameter yang sama.
Parameter pakar MoE dan vLLM
Beberapa model MoE di Transformers menyimpan bobot pakar sebagai tensor nn.Parameter (sering kali 3D), bukan modul nn.Linear.
Untuk menerapkan LoRA ke pakar-pakar tersebut, gunakan target_parameters dan atur rank per lapisan dengan rank_pattern:
num_experts = getattr(model.config, "num_local_experts", None) or model.config.num_experts
effective_r = max(1, r // num_experts)
config = LoraConfig(
r=r,
lora_alpha=32,
target_modules=["q_proj", "v_proj"],
target_parameters=[
# Mixtral / Qwen3-MoE / GPT-OSS
"mlp.experts.gate_up_proj",
"mlp.experts.down_proj",
# Llama4
# "feed_forward.experts.gate_up_proj",
# "feed_forward.experts.down_proj",
],
rank_pattern={
"experts.gate_up_proj": effective_r,
"experts.down_proj": effective_r,
},
)Hal ini menjaga total anggaran parameter LoRA tetap serupa dengan lapisan padat (lihat LoRA Without Regret oleh Schulman dkk.). Modul non-ahli menggunakan rank default r.
Inferensi yang dipercepat dengan model yang telah dihaluskan dimungkinkan, misalnya, dengan vLLM yang mendukung lapisan ahli MoE yang digabungkan sejak v0.11.2.
Latih token secara efisien bersama LoRA
Adaptor PEFT LoRA mendukung penambahan token baru dengan parameter trainable_token_indices. Hal ini memungkinkan penyesuaian token lain bersamaan dengan fine-tuning lapisan tertentu. Hanya token yang ditentukan yang dilatih, sementara semua token lainnya tidak diubah. Metode ini menghemat memori dan tidak membuang konteks yang telah dipelajari dari embedding token yang ada, berbeda dengan melatih seluruh matriks embedding. Di balik layar, metode ini menggunakan lapisan dari TrainableTokensModel.
# for layer 'embed_tokens'
config = LoraConfig(trainable_token_indices=[idx_1, idx_2, ...], ...)
# specific embedding layer
config = LoraConfig(trainable_token_indices={'emb_tokens': [idx_1, idx_2, ...]}, ...)Pada potongan kode di bawah ini, kami menunjukkan cara menambahkan token baru ke model dan cara melatihnya bersama lapisan lain dalam model.
from transformers import AutoTokenizer, AutoModelForCausalLM
from peft import get_peft_model, LoraConfig
base_model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-v0.1")
tokenizer = AutoTokenizer.from_pretrained("mistralai/Mistral-7B-v0.1")
# we define our new tokens and add them to the tokenizer as special tokens
special_tokens = ['<|start_think|>', '<|stop_think|>']
tokenizer.add_special_tokens({'additional_special_tokens': special_tokens})
# make room for new tokens in the embedding matrix if it isn't big enough already
base_model.resize_token_embeddings(max(len(tokenizer), base_model.model.embed_tokens.num_embeddings))
# typical LoRA config with `trainable_token_indices` targeting embedding layer `embed_tokens`
# and specifically our new tokens we just added
lora_config = LoraConfig(
target_modules='all-linear',
trainable_token_indices={'embed_tokens': tokenizer.convert_tokens_to_ids(special_tokens)},
)
peft_model = get_peft_model(base_model, lora_config)
# proceed to train the model like normal
[...]Bobot token disimpan sebagai bagian dari state dict adapter bersama dengan bobot LoRA. Fine-tuning penuh dan penyimpanan matriks embedding akan menyimpan file yang jauh lebih besar.
Untuk memberikan gambaran seberapa banyak VRAM yang dapat dihemat, perbandingan sederhana dari contoh di atas dilakukan antara melatih matriks embedding secara penuh (modules_to_save=["embed_tokens"]), menggunakan LoRA untuk matriks embedding (target_modules=[..., "embed_tokens"], rank 32) dan token yang dapat dilatih (trainable_token_indices=[...], 6 token):
| Token yang Dapat Dilatih | LoRA | Fine-tuning Penuh | |
|---|---|---|---|
| VRAM | 15,562 MB | 15,581MB | ~16.500MB |
| Pengaruh | 6 token | semua token | semua token |
Pengikatan bobot
Banyak LM kausal menggunakan weight tying, di mana dua atau lebih bobot berbagi parameter dasar yang sama. Dalam kasus yang paling umum, bobot embedding input (embed_tokens) dan bobot proyeksi output (lm_head) berbagi tensor yang sama. Hal ini karena mengurangi jumlah parameter dan biasanya mempertahankan kualitas model.
Tidak selalu jelas bagaimana PEFT menangani bobot terikat ini ketika ditargetkan untuk fine-tuning. Untuk LoRA, ensure_weight_tying pada LoraConfig mengontrol apakah PEFT harus secara eksplisit menjaga pembaruan sisi adapter tetap terikat untuk lapisan-lapisan tersebut. Dalam praktiknya, hal ini dapat memengaruhi modules_to_save, target_modules, dan trainable_token_indices. Perhatikan bahwa logika ini sebagian bergantung pada konvensi dalam penamaan lapisan ("embed_tokens", "lm_head") dan kerja yang tepat tidak dapat dijamin jika konvensi tersebut tidak digunakan.
Tabel di bawah ini merangkum perilaku yang diharapkan.
modules_to_save
| Bobot model dasar terikat | ensure_weight_tying | Bentuk LoraConfig | Perilaku |
|---|---|---|---|
| Tidak | False | modules_to_save=["embed_tokens"] atau ["lm_head"] | Tambahkan ModulesToSaveWrapper hanya pada lapisan yang dipilih |
| Tidak | True | modules_to_save=["embed_tokens"] atau ["lm_head"] | Beri peringatan, lalu tambahkan ModulesToSaveWrapper hanya pada layer yang dipilih |
| Ya | False | modules_to_save=["embed_tokens"] atau ["lm_head"] | Perlakukan sebagai terpisah |
| Ya | True | modules_to_save=["embed_tokens"] atau ["lm_head"] | Bungkus lapisan yang terikat dan pertahankan bungkusnya tetap terikat |
| Tidak | False | modules_to_save=["embed_tokens", "lm_head"] | Perlakukan sebagai terpisah |
| Tidak | True | modules_to_save=["embed_tokens", "lm_head"] | Beri peringatan, lalu perlakukan sebagai terpisah |
| Ya | False | modules_to_save=["embed_tokens", "lm_head"] | Beri peringatan, lalu perlakukan sebagai terpisah |
| Ya | True | modules_to_save=["embed_tokens", "lm_head"] | Jaga agar ModulesToSaveWrapper tetap terhubung |
target_modules
| Bobot model dasar terikat | ensure_weight_tying | Bentuk LoraConfig | Perilaku |
|---|---|---|---|
| Tidak | False | target_modules=["embed_tokens"] atau ["lm_head"] | Tambahkan LoRA hanya pada lapisan yang dipilih |
| Tidak | True | target_modules=["embed_tokens"] atau ["lm_head"] | Beri peringatan, lalu tambahkan LoRA hanya pada lapisan yang dipilih |
| Ya | False | target_modules=["embed_tokens"] atau ["lm_head"] | Perlakukan sebagai terpisah |
| Ya | True | target_modules=["embed_tokens"] atau ["lm_head"] | Jaga adapter LoRA tetap terikat |
| Tidak | False | target_modules=["embed_tokens", "lm_head"] | Perlakukan sebagai terpisah |
| Tidak | True | target_modules=["embed_tokens", "lm_head"] | Beri peringatan, lalu perlakukan sebagai terpisah |
| Ya | False | target_modules=["embed_tokens", "lm_head"] | Beri peringatan, lalu perlakukan sebagai terpisah |
| Ya | True | target_modules=["embed_tokens", "lm_head"] | Jaga adapter LoRA tetap terikat |
trainable_token_indices
Untuk token yang dapat dilatih, terdapat komplikasi tambahan bahwa meskipun LM head dan embeddings diikat, sebagai pengguna saya mungkin ingin melakukan fine-tuning pada token yang berbeda di atasnya. Oleh karena itu, pada tabel contoh di bawah, kami membedakan antara fine-tuning token yang sama dan fine-tuning token yang berbeda.
| Bobot model dasar terikat | ensure_weight_tying | Bentuk LoraConfig | Perilaku |
|---|---|---|---|
| Tidak | False | trainable_token_indices=[1, 2, 3] | Token yang dapat dilatih hanya pada embedding |
| Tidak | True | trainable_token_indices=[1, 2, 3] | Peringatan, kemudian token yang dapat dilatih hanya pada embedding |
| Ya | False | trainable_token_indices=[1, 2, 3] | Token yang dapat dilatih |
| Ya | True | trainable_token_indices=[1, 2, 3] | Token yang dapat dilatih |
| Tidak | False | trainable_token_indices={"lm_head": [1, 2], "embed_tokens": [1, 2]} | Perlakukan sebagai terpisah |
| Tidak | True | trainable_token_indices={"lm_head": [1, 2], "embed_tokens": [1, 2]} | Beri peringatan, lalu perlakukan sebagai terpisah |
| Ya | False | trainable_token_indices={"lm_head": [1, 2], "embed_tokens": [1, 2]} | Token yang dapat dilatih |
| Ya | True | trainable_token_indices={"lm_head": [1, 2], "embed_tokens": [1, 2]} | Token yang dapat dilatih |
| Tidak | False | trainable_token_indices={"lm_head": [1, 2], "embed_tokens": [3, 4]} | Perlakukan sebagai terpisah |
| Tidak | True | trainable_token_indices={"lm_head": [1, 2], "embed_tokens": [3, 4]} | Beri peringatan, lalu perlakukan sebagai terpisah |
| Ya | False | trainable_token_indices={"lm_head": [1, 2], "embed_tokens": [3, 4]} | Perlakukan sebagai terpisah |
| Ya | True | trainable_token_indices={"lm_head": [1, 2], "embed_tokens": [3, 4]} | Error |
Bagi pengguna, ini berarti:
- Secara umum, jika Anda ingin melakukan fine-tuning pada bobot yang terikat dan ingin tetap mengikatnya, berikan
ensure_weight_tying=True. - Jika bobot model dasar Anda tidak terikat,
ensure_weight_tying=Truetidak dapat memaksa pengikatan dan hanya memberikan peringatan. - Untuk
trainable_token_indices, lapisan yang terikat harus menggunakan indeks token yang sama ketikaensure_weight_tying=True.
Optimizer
Pelatihan LoRA dapat secara opsional mencakup optimizer khusus. Saat ini, PEFT mendukung LoRA-FA, LoRA+, dan Riemannian-preconditioned LoRA.
Optimizer LoRA-FA
Pelatihan LoRA dapat menjadi lebih efektif dan efisien dengan menggunakan LoRA-FA, seperti yang dijelaskan dalam LoRA-FA. LoRA-FA mengurangi konsumsi memori aktivasi dengan mengunci matriks A dan hanya menyetel matriks B. Selama pelatihan, gradien dari B dioptimalkan untuk mengaproksimasi gradien penyetelan parameter penuh. Selain itu, konsumsi memori LoRA-FA tidak sensitif terhadap rank (karena menghapus aktivasi dari $A$), sehingga dapat meningkatkan kinerja dengan memperbesar lora rank tanpa meningkatkan konsumsi memori.
from peft import LoraConfig, get_peft_model
from peft.optimizers import create_lorafa_optimizer
from transformers import Trainer, get_cosine_schedule_with_warmup
base_model = AutoModelForCausalLM.from_pretrained("meta-llama/Meta-Llama-3-8B-Instruct")
config = LoraConfig(...)
model = get_peft_model(base_model, config)
optimizer = create_lorafa_optimizer(
model=model,
r=128,
lora_alpha=32,
lr=7e-5,
)
scheduler = get_cosine_schedule_with_warmup(
optimizer,
num_warmup_steps=100,
num_training_steps=1000,
)
trainer = Trainer(
...,
optimizers=(optimizer, scheduler),
)LoRA+ mengoptimalkan LoRA
Pelatihan LoRA dapat dioptimalkan menggunakan LoRA+, yang menggunakan tingkat pembelajaran berbeda untuk matriks adapter A dan B, yang terbukti meningkatkan kecepatan finetuning hingga 2x dan performa sebesar 1-2%.
from peft import LoraConfig, get_peft_model
from peft.optimizers import create_loraplus_optimizer
from transformers import Trainer
import bitsandbytes as bnb
base_model = ...
config = LoraConfig(...)
model = get_peft_model(base_model, config)
optimizer = create_loraplus_optimizer(
model=model,
optimizer_cls=bnb.optim.Adam8bit,
lr=5e-5,
loraplus_lr_ratio=16,
)
scheduler = None
...
trainer = Trainer(
...,
optimizers=(optimizer, scheduler),
)LoRA dengan preconditioning Riemannian
Pelatihan LoRA dapat ditingkatkan dengan preconditioner Riemannian, seperti yang dijelaskan dalam Riemannian Preconditioned LoRA. Pada setiap langkah optimizer, gradien dari matriks LoRA dan dikalikan dengan preconditioner yang menskalakan ulang gradien Euclidean menuju arah Riemannian (scaled-gradient) pada manifold matriks low-rank, yang memberikan kondisi yang lebih baik untuk pembaruan dan dapat meningkatkan konvergensi. Karena preconditioner berukuran $r \times r$, overhead memori dan waktu eksekusinya kecil relatif terhadap rank LoRA. create_riemannian_optimizer membungkus kelas optimizer dasar mana pun (misalnya torch.optim.AdamW atau torch.optim.SGD): parameter non-LoRA diperbarui oleh optimizer dasar tanpa perubahan, dan hanya nn.Linear-lapisan LoRA berbentuklora_A / lora_B) dipreconditioner.
from peft import LoraConfig, get_peft_model
from peft.optimizers import create_riemannian_optimizer
from transformers import Trainer, get_cosine_schedule_with_warmup
import torch
base_model = AutoModelForCausalLM.from_pretrained("meta-llama/Meta-Llama-3-8B-Instruct")
config = LoraConfig(...)
model = get_peft_model(base_model, config)
optimizer = create_riemannian_optimizer(
model=model,
optimizer_cls=torch.optim.AdamW,
lr=5e-5,
reg=1e-2,
)
scheduler = get_cosine_schedule_with_warmup(
optimizer,
num_warmup_steps=100,
num_training_steps=1000,
)
trainer = Trainer(
...,
optimizers=(optimizer, scheduler),
)reg adalah suku redaman yang ditambahkan ke diagonal matriks sebelum inversi; ia menstabilkan preconditioner ketika faktor LoRA (hampir) rank-deficient.
Pelatihan Pasca
Bagian ini menunjukkan metode pasca-pemrosesan potensial untuk adapter yang telah dilatih.
Menggabungkan bobot LoRA ke dalam model dasar
Meskipun LoRA jauh lebih kecil dan lebih cepat untuk dilatih, Anda mungkin mengalami masalah latensi selama inferensi karena model dasar dan adapter LoRA dimuat secara terpisah. Untuk menghilangkan latensi, gunakan fungsi merge_and_unload() untuk menggabungkan bobot adapter dengan model dasar. Hal ini memungkinkan Anda menggunakan model gabungan baru tersebut sebagai model mandiri. Fungsi merge_and_unload() tidak menyimpan bobot adapter di memori.
Berikut adalah diagram yang menjelaskan intuisi penggabungan adapter LoRA:

Kami menunjukkan di cuplikan di bawah cara menjalankannya menggunakan PEFT.
from transformers import AutoModelForCausalLM
from peft import PeftModel
base_model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-v0.1")
peft_model_id = "alignment-handbook/zephyr-7b-sft-lora"
model = PeftModel.from_pretrained(base_model, peft_model_id)
model = model.merge_and_unload()Penting untuk menugaskan model yang dikembalikan ke sebuah variabel dan menggunakannya, karena merge_and_unload() bukan operasi in-place. Jika Anda perlu menyimpan salinan bobot agar dapat membatalkan penggabungan adapter nanti atau menghapus dan memuat yang berbeda, Anda sebaiknya menggunakan fungsi merge_adapter() sebagai gantinya. Sekarang Anda memiliki opsi untuk menggunakan unmerge_adapter() untuk mengembalikan model dasar.
from transformers import AutoModelForCausalLM
from peft import PeftModel
base_model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-v0.1")
peft_model_id = "alignment-handbook/zephyr-7b-sft-lora"
model = PeftModel.from_pretrained(base_model, peft_model_id)
model.merge_adapter()
# unmerge the LoRA layers from the base model
model.unmerge_adapter()Pada model terkuantisasi, proses unmerging tidak bersifat eksak: merging akan mengkuantisasi ulang bobot dasar, dan siklus merge dan unmerge yang berulang dapat mengakumulasi error pembulatan. Lihat Merging adapters into quantized weights.
Jika beberapa adapter aktif dan hanya sebagian yang digabungkan, adapter yang tidak digabungkan akan secara diam-diam tidak diterapkan. Perilaku ini akan berubah di PEFT v1.0. Lihat Menggabungkan hanya sebagian dari adapter yang aktif.
Fungsi add_weighted_adapter() berguna untuk menggabungkan beberapa LoRA menjadi adapter baru berdasarkan skema pembobotan yang diberikan pengguna pada parameter weights. Di bawah ini adalah contoh end-to-end.
Pertama, muat model dasar:
from transformers import AutoModelForCausalLM
from peft import PeftModel
import torch
base_model = AutoModelForCausalLM.from_pretrained(
"mistralai/Mistral-7B-v0.1", dtype=torch.float16, device_map="auto"
)Lalu kami memuat adapter pertama:
peft_model_id = "alignment-handbook/zephyr-7b-sft-lora"
model = PeftModel.from_pretrained(base_model, peft_model_id, adapter_name="sft")Lalu muat adapter yang berbeda dan gabungkan dengan yang pertama:
weighted_adapter_name = "sft-dpo"
model.load_adapter("alignment-handbook/zephyr-7b-dpo-lora", adapter_name="dpo")
model.add_weighted_adapter(
adapters=["sft", "dpo"],
weights=[0.7, 0.3],
adapter_name=weighted_adapter_name,
combination_type="linear"
)
model.set_adapter(weighted_adapter_name)Terdapat beberapa metode yang didukung untuk
combination_type. Lihat dokumentasi untuk detail lebih lanjut. Perhatikan bahwa “svd” sebagaicombination_typetidak didukung saat menggunakantorch.float16atautorch.bfloat16sebagai tipe data.
Sekarang, lakukan inferensi:
device = torch.accelerator.current_accelerator().type if hasattr(torch, "accelerator") else "cuda"
tokenizer = AutoTokenizer.from_pretrained("mistralai/Mistral-7B-v0.1")
prompt = "Hey, are you conscious? Can you talk to me?"
inputs = tokenizer(prompt, return_tensors="pt")
inputs = {k: v.to(device) for k, v in inputs.items()}
with torch.no_grad():
generate_ids = model.generate(**inputs, max_length=30)
outputs = tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
print(outputs)Memulihkan kinerja model dasar melalui reduksi dimensi intruder
Paper LoRA vs Full Fine-tuning: An Illusion of Equivalence berargumen bahwa pelatihan LoRA memperkenalkan dimensi tambahan ke dalam bobot yang sangat sedikit kesamaannya dengan bobot yang sudah dipelajari dan menyebabkan lupa terhadap informasi yang sudah dipelajari. PEFT menerapkan mitigasi yang disarankan di peft.tuners.lora.intruders.reduce_intruder_dimension().
Mekanisme mitigasi ini akan mengambil model PEFT dengan LoRA yang dimuat dan membuat adapter baru yang dimodifikasi, yang dimuat berdampingan dengan adapter yang sudah ada dan kini menjadi adapter aktif.
Contoh penggunaan:
from peft.tuners.lora.intruders import reduce_intruder_dimension
peft_model = AutoPeftModelForCausalLM.from_pretrained('hubnemo/llama-3.2b-metamathqa-lora64')
reduce_intruder_dimension(
peft_model,
mitigation_lambda=0.75,
)
peft_model.generate(...)Ada beberapa hiperparameter yang dapat digunakan untuk menyetel efektivitas mitigasi, namun, seperti yang ditunjukkan pada Gambar 8 dari makalah tersebut, akan selalu ada trade-off antara akurasi tugas yang dipelajari oleh adapter dan hilangnya pengetahuan model dasar. Mitigasi akan menghapus informasi dari adapter untuk mengurangi dampak terhadap hilangnya pengetahuan sebelumnya, tetapi ini juga berarti bahwa beberapa informasi tentang tugas yang dipelajari oleh adapter juga hilang.
Meskipun nilai default diatur untuk memberikan keseimbangan yang baik antara kedua faktor tersebut, tidak dijamin bahwa nilai default tersebut akan berlaku untuk adapter, model, dan data Anda. Oleh karena itu, disarankan untuk menyiapkan benchmark guna mengukur efeknya.
Muat adapter
Adapters dapat dimuat ke model pretrained dengan load_adapter(), yang berguna untuk mencoba berbagai adapter yang bobotnya tidak digabungkan. Atur bobot adapter yang aktif dengan fungsi set_adapter().
from transformers import AutoModelForCausalLM
from peft import PeftModel
base_model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-v0.1")
peft_model_id = "alignment-handbook/zephyr-7b-sft-lora"
model = PeftModel.from_pretrained(base_model, peft_model_id)
# load different adapter
model.load_adapter("alignment-handbook/zephyr-7b-dpo-lora", adapter_name="dpo")
# set adapter as active
model.set_adapter("dpo")Untuk mengembalikan model dasar, Anda dapat menggunakan unload() untuk memuat ulang semua modul LoRA atau delete_adapter() untuk menghapus adapter sepenuhnya. unload() bukan operasi in-place, ingatlah untuk menugaskan model yang dikembalikan ke variabel dan menggunakannya.
# unload adapter
model = model.unload()
# delete adapter
model.delete_adapter("dpo")Paralelisme Tensor
LoRA mendukung Tensor Parallelism (TP) yang disediakan oleh Transformers. Ketika model dasar dimuat dengan tp_plan, PEFT secara otomatis mendeteksi konfigurasi TP dari setiap modul target dan menambahkan hook yang sesuai ke bobot adapter LoRA agar mereka berpartisipasi dengan benar dalam komputasi tensor-parallel.
Dukungan Tensor Parallelism untuk LoRA memerlukan
transformers >= 5.4.0. API Tensor Parallelism berbasis DTensor memerlukanpeft >= 0.21.1dantransformers >= 5.17.0.
Penggunaannya identik dengan alur kerja LoRA standar — cukup muat model dasar dengan tp_plan sebelum membungkusnya dengan PEFT:
from transformers import AutoModelForCausalLM
from peft import get_peft_model, LoraConfig
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.1-8B", tp_plan="auto")
lora_config = LoraConfig(r=16, target_modules=["q_proj", "v_proj"])
model = get_peft_model(model, lora_config)Menyimpan dan memuat bekerja seperti biasa melalui save_pretrained / from_pretrained. PEFT mengumpulkan bobot adapter yang terpecah kembali menjadi tensor penuh sebelum menyimpan, sehingga checkpoint bersifat portabel dan independen dari jumlah perangkat yang digunakan selama pelatihan.
Jika Anda menerapkan tensor parallelism tanpa rencana TP, misalnya dengan parallelize_module dari PyTorch, PEFT akan menentukan ukuran bobot LoRA dari nn.Linear yang di-shard sesuai dengan shard lokalnya jika device mesh bobot tersebut memiliki dimensi bernama "tp", dan sesuai dengan bentuk layer penuh jika tidak (seperti pada FSDP2). PEFT tidak menambahkan hook TP ke bobot LoRA ini atau mengumpulkannya saat menyimpan. Jika dimensi mesh TP Anda memiliki nama yang berbeda, tambahkan sebelum membuat model PEFT:
from peft.utils.integrations import TpMeshDimRegistry
TpMeshDimRegistry.register("tp_dim")Inferensi
Bagian ini menampilkan apa yang dapat Anda lakukan saat inferensi dengan LoRA, seperti memisahkan adapter.
LoRA yang Diaktifkan (aLoRA)
Activated LoRA (aLoRA) adalah arsitektur low rank adapter untuk LM kausal yang menggunakan ulang KV cache dari model dasar yang ada untuk inferensi yang lebih efisien. Pendekatan ini paling cocok untuk pipeline inferensi yang mengandalkan model dasar untuk sebagian besar tugas/generasi, tetapi menggunakan adapter aLoRA untuk melakukan tugas khusus dalam rantai tersebut. Misalnya, memeriksa atau mengoreksi output yang dihasilkan oleh model dasar. Dalam pengaturan ini, waktu inferensi dapat dipercepat hingga satu orde magnitudo atau lebih. Untuk informasi lebih lanjut tentang aLoRA dan banyak contoh kasus penggunaan, lihat paper aLoRA.
Teknik ini memindai kemunculan terakhir dari urutan pemanggilan (alora_invocation_tokens) pada setiap input (ini bisa sesingkat 1 token). Bobot adapter diaktifkan pada token yang dimulai dari awal urutan pemanggilan. Input apa pun setelah urutan pemanggilan juga diadaptasi, dan semua token yang dihasilkan akan menggunakan bobot yang telah diadaptasi. Bobot pada token sebelumnya dibiarkan tidak diadaptasi, sehingga cache untuk token-token tersebut dapat dipertukarkan dengan cache model dasar karena adanya causal attention mask pada LM kausal. Pemakaiannya sangat mirip dengan LoRA standar. Perbedaan utamanya adalah bahwa urutan pemanggilan harus ditentukan saat adapter dibuat:
from peft import LoraConfig
config = LoraConfig(alora_invocation_tokens=alora_invocation_tokens, task_type="CAUSAL_LM", ...)`alora_invocation_tokens` adalah daftar id token integer. Diberikan string invocation yang diinginkan, ini dapat diperoleh sebagai:
invocation_string = "placeholder"
alora_invocation_tokens = tokenizer.encode(invocation_string, add_special_tokens=False).Tokenizer adalah tokenizer dari model dasar. Gunakan add_special_tokens=False untuk menghindari penambahan token SOS/EOS dalam string pencarian kita (yang kemungkinan besar akan menyebabkan pencarian gagal).
Catatan
- aLoRA hanya didukung untuk tugas
task_type=CAUSAL_LMkarena fokusnya pada penggunaan ulang cache. - Karena bobot disesuaikan pada lebih sedikit token, aLoRA sering kali (tidak selalu) membutuhkan rank (
r) yang lebih tinggi daripada LoRA.r=32bisa menjadi titik awal yang baik. - Bobot aLoRA tidak dapat digabungkan ke dalam model dasar berdasarkan definisinya, karena bobot adapter diterapkan secara selektif ke subset token. Upaya untuk menggabungkannya akan menghasilkan error.
- Beam search belum didukung.
- Secara umum, tidak disarankan untuk menambahkan token baru ke tokenizer yang tidak ada di model dasar. Hal ini dapat mempersulit kasus penggunaan di mana model dasar dan model adapter beroperasi pada konteks yang tumpang tindih. Anda dapat menghindari masalah ini dengan menambahkan token yang dapat dilatih ke model dasar sebelum melatih adapter.
Pilihan urutan pemanggilan dan desain SFT
Anda harus menambahkan sekuens alora_invocation_tokens karena tidak ditambahkan secara otomatis. Kami merekomendasikan untuk mengaktifkan bobot adapter lebih awal (di awal prompting yang spesifik untuk adapter), tetapi setelah input panjang apa pun, untuk memaksimalkan kinerja model tanpa mengorbankan penggunaan ulang cache. Seperti pada model apa pun,
format harus konsisten antara pelatihan dan pengujian.
Pertimbangkan contoh berikut, di mana model dasar memiliki template chat, dan tujuannya adalah melatih adapter untuk menghasilkan output yang diinginkan.
- Opsi 1: Jika tidak ada prompt khusus tugas, yaitu inputnya adalah riwayat chat dengan prompt
assistant, maka promptassistantdari template chat (misalnya<|start_of_role|>assistant<|end_of_role|>) adalah pilihan yang alami untuk string pemanggilan. Lihat template chat model untuk menemukan prompt untuk model tersebut. - Opsi 2: Jika ada prompt khusus tugas untuk adapter yang menjelaskan tugas yang dipelajari adapter, dan prompt tersebut ditempatkan sebagai giliran
usertepat sebelum generasi, maka promptuserdari template chat (misalnya<|start_of_role|>user<|end_of_role|>) adalah pilihan yang alami untuk string pemanggilan.
Setelah menentukan string pemanggilan, dapatkan tokenizer model dan peroleh alora_invocation_tokens sebagai
alora_invocation_tokens = tokenizer.encode(invocation_string, add_special_tokens=False).Contoh setup inferensi ada di alora finetuning.
Jika menggunakan string kustom untuk string pemanggilan, pastikan bahwa awal dan akhir string adalah token khusus untuk menghindari masalah dengan tokenisasi di batas-batasnya.
Untuk memahami alasannya, bayangkan ‘a’, ‘b’, ‘c’, dan ‘ab’ adalah token dalam tokenizer Anda (nomor 1, 2, 3, 4 masing-masing). Misalkan alora_invocation_tokens = [2, 3]. Sekarang bayangkan string input Anda adalah “abc”. Karena “ab” adalah sebuah token, string ini akan ditokenisasi menjadi [4,3]. Akibatnya, alora_invocation_tokens akan gagal ditemukan, meskipun string “bc” ada di dalamnya. Namun, jika awal dan akhir string invokasi adalah token khusus, kasus kegagalan ini tidak akan pernah terjadi karena token khusus tidak pernah ditokenisasi menjadi token yang sama dengan karakter lain.
Menggunakan (dan menggunakan ulang) cache untuk generasi
Tujuan utama aLoRA adalah membuat KV cache dapat dipertukarkan antara model dasar dan model adapter aLoRA sebelum urutan pemanggilan karena nilai KV dasar dan yang diadaptasi tidak kompatibel. Secara spesifik, kunci dan nilai yang disimpan selama satu generasi model dapat digunakan dalam generasi berikutnya untuk menghindari operasi prefill yang mahal untuk token konteks. Saat berbagi cache antara model dasar dan adapter aLoRA, terdapat 2 pola utama:
- Model dasar telah menghasilkan sesuatu, dan kemudian adapter aLoRA dipanggil untuk melakukan generasi lanjutan. Misalnya, model dasar menjawab sebuah pertanyaan, dan aLoRA yang dilatih untuk mendeteksi halusinasi memeriksa respons dari model dasar.
- Sebuah adapter aLoRA telah menghasilkan sesuatu, dan model dasar atau adapter aLoRA lain dipanggil untuk melakukan generasi lanjutan yang memiliki tumpang tindih konteks parsial dengan aLoRA asli. Misalnya, pengguna memberikan kueri, dan aLoRA menulis ulang kueri tersebut agar lebih mandiri dan meningkatkan pengambilan dalam sistem RAG. Kemudian, dokumen diambil dan dimuat ke dalam konteks, aLoRA memeriksa apakah dokumen-dokumen ini relevan dengan pertanyaan, dan kemudian model dasar menghasilkan jawaban.
Untuk mendemonstrasikan perilaku di atas saat menggunakan caching, kami menggunakan DynamicCache dari transformers. Pastikan nilai cache yang diadaptasi tidak dicampur dengan nilai cache dasar. Secara khusus, diperlukan langkah tambahan untuk berbagi cache ketika ada tumpang tindih konteks parsial (pola 2).
Polakan 1: Model dasar diikuti oleh aLoRA Di sini, seluruh input dan hasil generasi dari model dasar dimasukkan ke dalam adapter aLoRA, bersama dengan urutan pemanggilan:
from transformers import DynamicCache
...
cache = DynamicCache()
inputs_base = tokenizer(prompt_base, return_tensors="pt")
# Generate from base model and save cache
with model_alora.disable_adapter():
output = model_alora.generate(inputs_base["input_ids"].to(device),attention_mask=inputs_base["attention_mask"].to(device),past_key_values = cache,return_dict_in_generate=True)
output_text_base = tokenizer.decode(output.sequences[0])
cache = output.past_key_values
# Generate with aLoRA adapter from cache
prompt_alora = output_text + INVOCATION_STRING
inputs_alora = tokenizer(prompt_alora, return_tensors="pt").to(device)
output = model_alora.generate(**inputs_alora, past_key_values=cache)
output_text_alora = tokenizer.decode(output[0])
# Note: cache is now tainted with adapter values and cannot be used in base model from here on!Polakan 2: generasi aLoRA diikuti oleh model dasar (atau aLoRA lain) dengan tumpang tindih konteks parsial Di sini, kami melakukan prefill konteks bersama menggunakan model dasar, lalu melakukan generasi.
from transformers import DynamicCache
import copy
...
cache = DynamicCache()
inputs_shared = tokenizer(prompt_shared, return_tensors="pt").to(device)
# Prefill from base model and save cache
with model_alora.disable_adapter():
with torch.no_grad():
model_alora(**inputs_shared, past_key_values=cache)
cache_copy = copy.deepcopy(cache)
# Generate from aLoRA using prefilled cache
prompt_alora = prompt_shared + INVOCATION_STRING
inputs_alora = tokenizer(prompt_alora, return_tensors="pt").to(device)
output = model_alora.generate(**inputs_alora, past_key_values=cache)
output_text_alora = tokenizer.decode(output[0])
# Generate from base model using saved cache not tainted by aLoRA KV values
prompt_base = prompt_shared
inputs_base = tokenizer(prompt_base, return_tensors="pt").to(device)
with model_alora.disable_adapter():
output = model_alora.generate(**inputs_base, past_key_values=cache_copy)
output_text_base = tokenizer.decode(output[0])Inferensi dengan adapter LoRA yang berbeda dalam batch yang sama
Biasanya, setiap batch inferensi harus menggunakan adapter yang sama dalam PEFT. Hal ini terkadang merepotkan, karena kita mungkin memiliki batch yang berisi sampel yang ditujukan untuk digunakan dengan adapter LoRA yang berbeda. Misalnya, kita bisa memiliki model dasar yang bekerja dengan baik dalam bahasa Inggris dan dua adapter LoRA lainnya, satu untuk bahasa Prancis dan satu untuk bahasa Jerman. Biasanya, kita harus memecah batch kita sehingga setiap batch hanya berisi sampel dari salah satu bahasa; kita tidak dapat menggabungkan bahasa yang berbeda dalam batch yang sama.
Untungnya, Anda dapat mencampur berbagai adapter LoRA dalam batch yang sama menggunakan argumen adapter_name. Di bawah ini, kami menunjukkan contoh bagaimana hal ini bekerja dalam praktiknya. Pertama, mari muat model dasar, English, dan dua adapter, French dan German, seperti ini:
from transformers import AutoTokenizer, AutoModelForCausalLM
from peft import PeftModel
model_id = ...
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(model_id)
# load the LoRA adapter for French
peft_model = PeftModel.from_pretrained(model, <path>, adapter_name="adapter_fr")
# next, load the LoRA adapter for German
peft_model.load_adapter(<path>, adapter_name="adapter_de")Sekarang, kita ingin menghasilkan teks pada sampel yang berisi ketiga bahasa: tiga sampel pertama dalam bahasa Inggris, tiga sampel berikutnya dalam bahasa Prancis, dan tiga sampel terakhir dalam bahasa Jerman. Kita dapat menggunakan argumen adapter_names untuk menentukan adapter mana yang akan digunakan untuk setiap sampel. Karena model dasar kita digunakan untuk bahasa Inggris, kita menggunakan string khusus "__base__" untuk sampel-sampel ini. Untuk tiga sampel berikutnya, kita menunjukkan nama adapter dari fine-tune LoRA Prancis, dalam hal ini "adapter_fr". Untuk tiga sampel terakhir, kita menunjukkan nama adapter dari fine-tune LoRA Jerman, dalam hal ini "adapter_de". Dengan cara ini, kita dapat menggunakan model dasar dan dua adapter dalam satu batch.
inputs = tokenizer(
[
"Hello, my dog is cute",
"Hello, my cat is awesome",
"Hello, my fish is great",
"Salut, mon chien est mignon",
"Salut, mon chat est génial",
"Salut, mon poisson est super",
"Hallo, mein Hund ist süß",
"Hallo, meine Katze ist toll",
"Hallo, mein Fisch ist großartig",
],
return_tensors="pt",
padding=True,
)
adapter_names = [
"__base__", "__base__", "__base__",
"adapter_fr", "adapter_fr", "adapter_fr",
"adapter_de", "adapter_de", "adapter_de",
]
output = peft_model.generate(**inputs, adapter_names=adapter_names, max_new_tokens=20)Perhatikan bahwa urutan tidak menjadi masalah di sini, yaitu sampel dalam batch tidak perlu dikelompokkan berdasarkan adapter seperti pada contoh di atas. Kami hanya perlu memastikan bahwa argumen adapter_names selaras dengan sampel.
Selain itu, pendekatan yang sama juga berfungsi dengan fitur modules_to_save, yang memungkinkan penyimpanan dan penggunaan ulang lapisan jaringan saraf tertentu, seperti kepala kustom untuk tugas klasifikasi, di antara berbagai adapter LoRA.
Catatan
Menggunakan fitur ini memiliki beberapa kekurangan, yaitu:
- Itu hanya berfungsi untuk inferensi, bukan untuk pelatihan.
- Menonaktifkan adapter menggunakan konteks
with model.disable_adapter()memiliki prioritas lebih tinggi daripadaadapter_names. - Anda tidak dapat meneruskan
adapter_namesketika beberapa bobot adapter telah digabungkan dengan bobot dasar menggunakan metodemerge_adapter. Silakan batalkan penggabungan semua adapter terlebih dahulu dengan memanggilmodel.unmerge_adapter(). Perhatikan bahwa penggabungan hanya sebagian dari adapter yang aktif memiliki catatan serupa di luaradapter_names. - Karena alasan yang jelas, ini tidak dapat digunakan setelah memanggil
merge_and_unload(), karena dalam kasus ini semua adapter LoRA akan digabungkan ke dalam bobot dasar. - Fitur ini saat ini tidak berfungsi dengan DoRA, jadi atur
use_dora=FalsediLoraConfigAnda jika Anda ingin menggunakannya. - Fitur
modules_to_savesaat ini hanya didukung untuk lapisan bertipeLinear,Embedding,Conv2d, danConv1d. - Terdapat overhead yang diharapkan untuk inferensi dengan
adapter_names, terutama jika jumlah adapter yang berbeda dalam batch sangat tinggi. Hal ini terjadi karena ukuran batch secara efektif berkurang menjadi jumlah sampel per adapter. Jika kinerja runtime adalah prioritas utama Anda, coba lakukan hal berikut:- Tingkatkan ukuran batch.
- Usahakan untuk menghindari adanya sejumlah besar adapter yang berbeda dalam batch yang sama, lebih baik gunakan batch yang homogen. Hal ini dapat dicapai dengan menampung sampel yang memiliki adapter yang sama dan hanya melakukan inferensi dengan sedikit adapter yang berbeda.
- Lihatlah implementasi alternatif seperti LoRAX, punica, atau S-LoRA, yang dirancang khusus untuk bekerja dengan sejumlah besar adapter yang berbeda.
Menggabungkan dan Menggunakan Ulang Adapter LoRA
Arrow
Arrow adalah algoritma routing modular yang dirancang untuk menggabungkan beberapa adapter LoRA spesifik tugas yang telah dilatih sebelumnya guna menyelesaikan tugas tertentu, serupa dengan Polytropon tetapi tanpa memerlukan fine-tuning. Alih-alih menggabungkan semua adapter secara naif, Arrow memperkenalkan mekanisme routing mixture-of-experts (MoE) berbasis token yang bebas gradien. Pada saat inferensi, algoritma ini pertama-tama menghitung prototipe untuk setiap LoRA dengan mengekstrak vektor singular kanan teratas dari dekomposisi SVD-nya. Setiap representasi token kemudian dibandingkan dengan prototipe tersebut melalui kemiripan kosinus untuk memperoleh koefisien routing. Token dialokasikan ke k adapter LoRA yang paling relevan, dengan koefisiennya dinormalisasi melalui softmax, dan outputnya digabungkan secara linear. Hal ini memungkinkan pemanfaatan ulang modul LoRA yang ada untuk tugas baru dan menghasilkan generalisasi zero-shot yang lebih kuat.
Di PEFT, Arrow diaktifkan melalui [`ArrowConfig]andcreate_arrow_model. You can also configure parameters such astop_k(the number of LoRA adapters combined per token),router_temperature(the softmax temperature applied to the routing coefficients), andrng_seed` (for reproducibility).
from peft import create_arrow_model, ArrowConfig
from transformers import AutoModelForCausalLM
# Loading the model
base_model = AutoModelForCausalLM.from_pretrained("microsoft/Phi-3-mini-4k-instruct")
# Creating the Arrow config
arrow_config = ArrowConfig(
top_k=3,
router_temperature=1.0,
rng_seed=42,
)
# The LoRA adapters below were trained on a clustered FLAN dataset.
# Task clustering was performed using the Model-Based Clustering (MBC) method,
# as described in the Arrow paper.
# While one could train a separate LoRA for each task and let Arrow route tokens among them,
# training LoRAs on clusters of tasks instead provides an indirect optimization for
# transfer across the multi-task dataset.
task_specific_adapter_paths = [
f"TahaBa/phi3-mini-clustered-flan/ts_expert_{i}" for i in range(10)
]
# Creating the Arrow model
model = create_arrow_model(
base_model=base_model,
task_specific_adapter_paths=task_specific_adapter_paths,
arrow_config=arrow_config,
)
# Now the forward path could be called on this model, like a normal PeftModel.Selain itu, Anda dapat menambahkan atau menghapus adapter setelah memanggil create_arrow_model—misalnya, untuk melakukan fine-tuning pada adapter baru atau membuang yang tidak diperlukan. Setelah adapter ditempatkan, Anda dapat mengaktifkan "arrow_router" untuk inferensi guna menggunakan Arrow. Perhatikan bahwa jika Anda menambahkan adapter LoRA baru setelah create_arrow_model dan ingin melakukan fine-tuning padanya, Anda harus secara eksplisit mengatur adapter baru tersebut sebagai aktif, karena "arrow_router" diaktifkan secara default di create_arrow_model.
from trl import SFTTrainer, SFTConfig
# Adding a new adapter and activating it
model.add_adapter(adapter_name='new_adapter')
model.set_adapter('new_adapter')
# Now the model could be trained along the `new_adapter`.
trainer = SFTTrainer(
model=model,
args=SFTConfig(...),
...
)
# Once the training is done, you can activate `arrow_router` and use it in inference
model.set_adapter('arrow_router') # Model is ready to be used at inference time nowGenKnowSub
GenKnowSub meningkatkan Arrow dengan memurnikan adapter LoRA yang spesifik tugas sebelum routing. Ide utamanya adalah mengurangi pengetahuan umum yang terenkodasi dalam ruang LoRA—berdasarkan prinsip pelupaan-via-negasi—sehingga adapter tugas menjadi lebih terisolasi dan berfokus pada sinyal yang relevan dengan tugas. Secara konkret, GenKnowSub memperkirakan subruang “umum” berdimensi rendah dari seperangkat adapter LoRA umum (bukan spesifik tugas) dan menghapus komponen ini dari pembaruan LoRA setiap adapter tugas sebelum routing per-token Arrow. Hal ini biasanya meningkatkan komposabilitas dan mengurangi interferensi saat menggabungkan banyak adapter tugas.
Di PEFT, aktifkan GenKnowSub dengan mengatur use_gks=True di ArrowConfig, dan menyediakan general_adapter_paths di create_arrow_model:
from peft import create_arrow_model, ArrowConfig
from transformers import AutoModelForCausalLM
# Loading the model
base_model = AutoModelForCausalLM.from_pretrained("microsoft/Phi-3-mini-4k-instruct")
# Creating the Arrow config
arrow_config = ArrowConfig(
top_k=3,
router_temperature=1.0,
use_gks=True,
rng_seed=42,
)
# Path to task-specific, trained on flan clustered dataset (as we explained before.)
task_specific_adapter_paths = [
f"TahaBa/phi3-mini-clustered-flan/ts_expert_{i}" for i in range(10)
]
# These general adapters are trained on English, German, and French Wikipedia dataset,
# with causal language modelling objective, each pair like: (507 token tsentence, 5 token completion), and the loss computed on the completion
general_adapter_paths = [
"TahaBa/phi3-mini-general-adapters/cluster0_batch16_prop1.0_langen/checkpoint-17",
"TahaBa/phi3-mini-general-adapters/cluster0_batch16_prop1.0_langfr/checkpoint-35",
"TahaBa/phi3-mini-general-adapters/cluster0_batch16_prop1.0_langger/checkpoint-17"
]
# Creating the Arrow model
model = create_arrow_model(
base_model=base_model,
task_specific_adapter_paths=task_specific_adapter_paths,
general_adapter_paths=general_adapter_paths,
arrow_config=arrow_config,
)
# Now the forward path could be called on this model, like a normal PeftModel.Untuk mengkodekan pengetahuan umum, GenKnowSub mengurangi rata-rata dari adapter umum yang diberikan dari setiap adapter khusus tugas sekali, sebelum routing dimulai. Selain itu, kemampuan untuk menambahkan atau menghapus adapter setelah memanggil create_arrow_model (seperti yang dijelaskan di bagian Arrow) masih didukung dalam kasus ini.
Hal-hal yang perlu diperhatikan saat menggunakan Arrow + GenKnowSub:
Semua adapter LoRA (khusus tugas dan umum) harus berbagi
rankdantarget_modulesyang sama.Setiap inkonsistensi dalam pengaturan ini akan memicu error di
create_arrow_model.Mendukung faktor penskalaan (
lora_alpha) yang berbeda di antara adapter tugas — Arrow menanganinya secara otomatis.Menggabungkan
"arrow_router"tidak didukung, karena perilaku routing dinamisnya.Pada
create_arrow_model, task adapter dimuat sebagaitask_idan general adapter sebagaigks_j(di manaidanjadalah indeks). Fungsi ini memastikan konsistensitarget_modules,rank, dan apakah adapter diterapkan pada lapisanLinearatauLinear4bit. Kemudian, modul"arrow_router"ditambahkan dan diaktifkan. Setiap kustomisasi proses ini memerlukan penggantian (override) padacreate_arrow_model.Implementasi ini kompatibel dengan kuantisasi 4-bit (melalui bitsandbytes):
from transformers import AutoModelForCausalLM, BitsAndBytesConfig import torch # Quantisation config bnb_config = BitsAndBytesConfig( load_in_4bit=True, bnb_4bit_quant_type="nf4", bnb_4bit_compute_dtype=torch.bfloat16, bnb_4bit_use_double_quant=False, ) # Loading the model base_model = AutoModelForCausalLM.from_pretrained( "microsoft/Phi-3-mini-4k-instruct", dtype=torch.bfloat16, device_map="auto", quantization_config=bnb_config, ) # Now call create_arrow_model() as we explained before.
API
LoraConfig
kelas peft.LoraConfig
< source >( task_type: Optional[Union[str, TaskType]] = Nonepeft_type: Optional[Union[str, PeftType]] = Noneauto_mapping: Optional[dict] = Nonepeft_version: Optional[str] = Nonebase_model_name_or_path: Optional[str] = Nonerevision: Optional[str] = Noneinference_mode: bool = Falser: int = 8target_modules: Optional[Union[list[str], str]] = Noneexclude_modules: Optional[Union[list[str], str]] = Nonelora_alpha: int = 8lora_dropout: float = 0.0fan_in_fan_out: bool = Falsebias: Literal['none', 'all', 'lora_only'] = 'none'use_rslora: bool = Falsemodules_to_save: Optional[list[str]] = Noneinit_lora_weights: bool | Literal['gaussian', 'eva', 'olora', 'pissa', 'pissa_niter_[number of iters]', 'corda', 'astra', 'loftq', 'orthogonal', 'mica', 'nora'] = Truelayers_to_transform: Optional[Union[list[int], int]] = Nonelayers_pattern: Optional[Union[list[str], str]] = Nonerank_pattern: Optional[dict] = <factory>alpha_pattern: Optional[dict] = <factory>megatron_config: Optional[dict] = Nonemegatron_core: Optional[str] = 'megatron.core'trainable_token_indices: Optional[Union[list[int], dict[str, list[int]]]] = Noneloftq_config: Union[LoftQConfig, dict] = <factory>eva_config: Optional[EvaConfig] = Nonecorda_config: Optional[CordaConfig] = Noneastra_config: Optional[AstraConfig] = Nonelora_ga_config: Optional[LoraGAConfig] = Noneuse_dora: bool = Falsevelora_config: Optional[Union[VeloraConfig, dict]] = Nonealora_invocation_tokens: Optional[list[int]] = Noneuse_qalora: bool = Falseqalora_group_size: int = 16monteclora_config: Optional[MontecloraConfig] = Nonelayer_replication: Optional[list[tuple[int, int]]] = Noneruntime_config: LoraRuntimeConfig = <factory>lora_bias: bool = Falsetarget_parameters: Optional[list[str]] = Noneuse_bdlora: Optional[BdLoraConfig] = Nonearrow_config: Optional[ArrowConfig] = Nonekasa_config: Optional[KasaConfig] = Noneensure_weight_tying: bool = False )
Parameter
- r (
int) — Dimensi perhatian Lora (“rank”). - target_modules (
Optional[Union[List[str], str]]) — Nama-nama modul yang akan diterapkan adapter-nya. Jika ini ditentukan, hanya modul dengan nama yang ditentukan yang akan diganti. Saat melewatkan string, pencocokan regex akan dilakukan. Saat melewatkan daftar string, pencocokan persis akan dilakukan atau diperiksa apakah nama modul diakhiri dengan salah satu string yang dilewatkan. Jika ini ditentukan sebagai ‘all-linear’, maka semua modul linear/Conv1D akan dipilih (jika modelnya adalah PreTrainedModel, lapisan output dikecualikan). Jika ini tidak ditentukan, modul akan dipilih sesuai dengan arsitektur model. Jika arsitekturnya tidak diketahui, error akan dilempar — dalam kasus ini, Anda harus menentukan modul target secara manual. Untuk menghindari penargetan modul apa pun (karena Anda ingin menerapkantarget_parameters), aturtarget_modules=[]. - exclude_modules (
Optional[Union[List[str], str]]) — Nama-nama modul yang tidak akan diterapkan adapter. Saat melewatkan string, pencocokan regex akan dilakukan. Saat melewatkan daftar string, pencocokan persis akan dilakukan atau diperiksa apakah nama modul berakhiran dengan salah satu string yang dilewatkan. - lora_alpha (
int) — Parameter alpha untuk penskalaan Lora. - lora_dropout (
float) — Probabilitas dropout untuk lapisan Lora. - fan_in_fan_out (
bool) — Atur ini ke True jika layer yang akan diganti menyimpan bobot seperti (fan_in, fan_out). Misalnya, gpt-2 menggunakanConv1Dyang menyimpan bobot seperti (fan_in, fan_out) sehingga ini harus diatur keTrue. - bias (
str) — Jenis bias untuk LoRA. Bisa berupa ‘none’, ‘all’, atau ‘lora_only’. Jika ‘all’ atau ‘lora_only’, bias yang sesuai akan diperbarui selama pelatihan. Perhatikan bahwa ini berarti, bahkan saat adapter dinonaktifkan, model tidak akan menghasilkan output yang sama seperti model dasar tanpa adaptasi. - use_rslora (
bool) — Jika diatur ke True, menggunakan Rank-Stabilized LoRA yang mengatur faktor penskalaan adapter menjadilora_alpha/math.sqrt(r), karena terbukti bekerja lebih baik. Jika tidak, akan menggunakan nilai default aslilora_alpha/r. - modules_to_save (
List[str]) — Daftar modul selain lapisan adapter yang akan diatur sebagai dapat dilatih dan disimpan dalam checkpoint akhir. - init_lora_weights (
bool|Literal["gaussian", "eva", "olora", "pissa", "pissa_niter_[number of iters]", "corda", "astra", "loftq", "orthogonal", "mica", "nora"]) — Cara menginisialisasi bobot lapisan adapter. Mengalihkan True (default) menghasilkan inisialisasi default dari implementasi referensi Microsoft, dengan bobot LoRA B disetel ke 0. Ini berarti bahwa tanpa pelatihan lebih lanjut, adapter LoRA akan menjadi no-op. Menetapkan inisialisasi ke False menghasilkan inisialisasi acak untuk LoRA A dan B, yang berarti LoRA bukan no-op sebelum pelatihan; pengaturan ini ditujukan untuk keperluan debugging. Mengalihkan 'gaussian' menghasilkan inisialisasi Gaussian yang diskalakan berdasarkan rank LoRA untuk lapisan linear dan embedding. Mengalihkan'loftq'untuk menggunakan inisialisasi LoftQ. Mengalihkan'eva'menghasilkan inisialisasi berbasis data untuk Adaptasi Varians yang Dijelaskan. EVA menginisialisasi LoRA berdasarkan SVD dari aktivasi input lapisan dan mencapai kinerja SOTA berkat kemampuannya beradaptasi dengan data finetuning. Mengalihkan'olora'untuk menggunakan inisialisasi OLoRA. Mengalihkan'pissa'menghasilkan inisialisasi Principal Singular values and Singular vectors Adaptation (PiSSA), yang konvergen lebih cepat daripada LoRA dan pada akhirnya mencapai kinerja yang lebih unggul. Selain itu, PiSSA mengurangi error kuantisasi dibandingkan QLoRA, yang mengarah pada peningkatan lebih lanjut. Mengalihkan 'pissa_niter_[number of iters]' menginisiasi inisialisasi PiSSA berbasis Fast-SVD, di mana [number of iters] menunjukkan jumlah iterasi subspace untuk melakukan FSVD, dan harus berupa bilangan bulat non-negatif. Ketika [number of iters] disetel ke 16, inisialisasi model 7B dapat diselesaikan dalam hitungan detik, dan efek pelatihan kurang lebih setara dengan penggunaan SVD. Mengalihkan 'corda' menghasilkan inisialisasi Context-Oriented Decomposition Adaptation, yang konvergen bahkan lebih cepat daripada PiSSA dalam Instruction-Previewed Mode, dan lebih baik dalam mempertahankan pengetahuan dunia daripada LoRA dalam Knowledge-Preserved Mode. Mengalihkan 'astra' menghasilkan inisialisasi Activation-Space Tail-Eigenvector Low-Rank Adaptation, yang memproyeksikan bobot dasar ke ruang eigen dari aktivasi output yang diperkirakan dari dataset kalibrasi kecil. Mengalihkan "orthogonal" menghasilkan LoRA A dan B diinisialisasi secara ortogonal; dalam hal ini, menyerupai "olora", tetapi bobot dasar dibiarkan tidak tersentuh (memerlukan r genap, saat ini hanya didukung untuk lapisan linear). Mengalihkan "mica" menghasilkan inisialisasi Minor Component Adaptation (MiCA), yang menginisialisasi B dari r vektor singular kiri dari bobot dasar yang terkait dengan nilai singular terkecil, menyetel A ke nol, dan membekukan B selama pelatihan; hanya A yang diperbarui. Saat ini didukung untuk lapisan linear dan embedding. Mengalihkan "nora" menghasilkan inisialisasi Normalized Low-Rank Adaptation (NoRA), yang menormalisasi setiap kolom dari bobot LoRA A yang diinisialisasi secara acak ke norma L2 satuan dan menyetel bobot LoRA B ke nol. Normalisasi hanya diterapkan saat inisialisasi; bobot dasar tidak berubah dan baik A maupun B tetap dapat dilatih. Pengaturan yang direkomendasikan adalah lora_alpha sama dengan r dengan use_rslora=False, yang mempertahankan rasio 1:1 dan faktor skala 1. Saat ini didukung untuk lapisan linear dan untuk nn.Parameters yang ditargetkan dengan target_parameters.Principal Singular values and Singular vectors Adaptation (PiSSA), yang konvergen lebih cepat daripada LoRA dan pada akhirnya mencapai kinerja yang lebih unggul. Selain itu, PiSSA mengurangi error kuantisasi dibandingkan dengan QLoRA, sehingga menghasilkan peningkatan lebih lanjut. Mengirimkan
'pissa_niter_[number of iters]'akan memulai inisialisasi PiSSA berbasis Fast-SVD, di mana[number of iters]menunjukkan jumlah iterasi subspace untuk melakukan FSVD, dan harus berupa bilangan bulat non-negatif. Ketika[number of iters]diatur ke 16, inisialisasi model 7B dapat diselesaikan dalam hitungan detik, dan efek pelatihan kurang lebih setara dengan penggunaan SVD. Mengirimkan'corda'akan menghasilkan inisialisasi Context-Oriented Decomposition Adaptation, yang konvergen bahkan lebih cepat daripada PiSSA dalam Instruction-Previewed Mode, dan lebih baik dalam mempertahankan pengetahuan dunia dibandingkan LoRA dalam Knowledge-Preserved Mode. Mengirimkan'astra'akan menghasilkan inisialisasi Activation-Space Tail-Eigenvector Low-Rank Adaptation, yang memproyeksikan bobot dasar ke ruang eigen dari aktivasi output yang diperkirakan dari dataset kalibrasi kecil. Mengirimkan"orthogonal"akan menghasilkan inisialisasi LoRA A dan B secara ortogonal; dalam hal ini, metode ini menyerupai"olora", tetapi bobot dasar dibiarkan tidak diubah (memerlukanrgenap, dan saat ini hanya didukung untuk lapisan linear). Mengirimkan"mica"akan menghasilkan inisialisasi Minor Component Adaptation (MiCA), yang menginisialisasi B dari r vektor singular kiri dari bobot dasar yang terkait dengan nilai singular terkecil, mengatur A ke nol, dan membekukan B selama pelatihan; hanya A yang diperbarui. Saat ini didukung untuk lapisan linear dan embedding. Mengirimkan"nora"akan menghasilkan inisialisasi Normalized Low-Rank Adaptation (NoRA), yang menormalisasi setiap kolom dari bobot LoRA A yang diinisialisasi secara acak ke norma L2 satuan dan mengatur bobot LoRA B ke nol. Normalisasi hanya diterapkan saat inisialisasi; bobot dasar tidak berubah dan baik A maupun B tetap dapat dilatih. Pengaturan yang direkomendasikan adalahlora_alphasama denganrdenganuse_rslora=False, yang mempertahankan rasio 1:1 dan faktor penskalaan 1. Saat ini didukung untuk lapisan linear dan untuknn.Parameteryang ditargetkan dengantarget_parameters. - layers_to_transform (
Union[List[int], int]) — Indeks layer yang akan ditransformasi. Jika daftar int yang dilewatkan, adapter akan diterapkan pada indeks layer yang ditentukan dalam daftar ini. Jika satu integer yang dilewatkan, transformasi akan diterapkan pada layer di indeks ini. - layers_pattern (
Optional[Union[List[str], str]]) — Nama pola layer, hanya digunakan jikalayers_to_transformberbeda dariNone. Ini harus menargetkannn.ModuleListdari model, yang sering disebut'layers'atau'h'. - rank_pattern (
dict) — Pemetaan dari nama layer atau ekspresi regexp ke rank yang berbeda dari rank default yang ditentukan olehr. Sebagai contoh,{'^model.decoder.layers.0.encoder_attn.k_proj': 16}. - alpha_pattern (
dict) — Pemetaan dari nama layer atau ekspresi regexp ke alphas yang berbeda dari alpha default yang ditentukan olehlora_alpha. Sebagai contoh,{'^model.decoder.layers.0.encoder_attn.k_proj': 16}. - megatron_config (
Optional[dict]) — Argumen TransformerConfig untuk Megatron. Digunakan untuk membuat lapisan linear paralel LoRA. Anda dapat mendapatkannya seperti ini,core_transformer_config_from_args(get_args()), di mana kedua fungsi ini berasal dari Megatron. Argumen ini akan digunakan untuk menginisialisasi TransformerConfig dari Megatron. Anda perlu menentukan parameter ini ketika ingin menerapkan LoRA pada lapisan ColumnParallelLinear dan RowParallelLinear dari megatron. - megatron_core (
Optional[str]) — Modul inti dari Megatron yang akan digunakan, secara default"megatron.core". - trainable_token_indices (
Optional[Union[List[int], dict[str, List[int]]]]) — Memungkinkan Anda menentukan indeks token mana yang akan dihaluskan secara selektif tanpa perlu melatih ulang seluruh matriks embedding menggunakan metodepeft.TrainableTokensModel. Anda dapat menentukan indeks token dengan dua cara. Anda dapat menentukan daftar indeks yang akan menargetkan lapisan embedding input model (atau, jika tidak ditemukan,embed_tokens). Sebagai alternatif, Anda dapat menentukan kamus di mana kuncinya adalah nama modul embedding dan nilainya adalah daftar indeks token, misalnya{'embed_tokens': [0, 1, ...]}. Perhatikan bahwa pelatihan dengan FSDP memerlukanuse_orig_params=Trueuntuk menghindari masalah denganrequires_gradyang tidak seragam. - loftq_config (
Optional[LoftQConfig]) — Konfigurasi LoftQ. Jika ini bukan None, maka LoftQ akan digunakan untuk mengkuantisasi bobot backbone dan menginisialisasi lapisan Lora. Juga berikaninit_lora_weights='loftq'. Perhatikan bahwa Anda tidak boleh memberikan model terkuantisasi dalam kasus ini, karena LoftQ akan mengkuantisasi model itu sendiri. LoftQ hanya diterapkan pada lapisan linear, termasuk yang ditargetkan melaluitarget_parameters. Lapisan embedding dan konvolusional tidak didukung dan menggunakan inisialisasi LoRA default sebagai gantinya. Lapisannn.MultiheadAttentiontidak didukung dan akan memicu error. - eva_config (
Optional[EvaConfig]) — Konfigurasi EVA. Minimal, argumen dataset harus disetel (gunakan dataset yang sama seperti untuk finetuning). - corda_config (
Optional[CordaConfig]) — Konfigurasi CorDA. Jika ini bukan None, maka CorDA akan digunakan untuk membangun lapisan adapter. Juga laluinit_lora_weights='corda'. - astra_config (
Optional[AstraConfig]) — Konfigurasi Astra. Jika ini bukan None, maka Astra akan digunakan untuk membangun lapisan adapter. Selain itu, laluinit_lora_weights='astra', dan panggilpreprocess_astrasebelumget_peft_modeldalam kasus ini. - lora_ga_config (
Optional[LoraGAConfig]) — Konfigurasi LoRA-GA. Jika ini diteruskan, maka LoRA-GA akan digunakan untuk menginisialisasi lapisan adapter. Dalam kasus ini, juga setelinit_lora_weights='lora_ga'. - use_dora (
bool) — Aktifkan ‘Weight-Decomposed Low-Rank Adaptation’ (DoRA). Teknik ini menguraikan pembaruan bobot menjadi dua bagian, yaitu magnitudo dan arah. Arah ditangani oleh LoRA normal, sedangkan magnitudo ditangani oleh parameter yang dapat dipelajari secara terpisah. Hal ini dapat meningkatkan kinerja LoRA, terutama pada rank rendah. Saat ini, DoRA hanya mendukung lapisan linear dan Conv2D. DoRA memperkenalkan overhead yang lebih besar daripada LoRA murni, sehingga disarankan untuk menggabungkan bobot untuk inferensi. Untuk informasi lebih lanjut, lihat https://huggingface.co/papers/2402.09353. - velora_config (
Optional[VeloraConfig]) — Aktifkan VeLoRA dengan menyediakan VeloraConfig. VeLoRA mengganti backward pass khusus untuk proyeksi LoRA A yang menyimpan aktivasi terkompresi alih-alih aktivasi input penuh. - kasa_config (
Optional[KasaConfig]) — Aktifkan KaSA (Knowledge-aware Singular-value Adaptation) dengan menyediakan KasaConfig. KaSA memotongrkomponen singular terkecil dari bobot dasar yang dibekukan melalui satu kali SVD dan menyisipkan diagonal yang dapat dipelajari dari nilai singular di antara faktor A dan B LoRA. Saat ini hanya lapisan linear yang didukung. - alora_invocation_tokens (
List[int]) — Jika bukan None, aktifkan ‘Activated LoRA’ (aLoRA), dengan alora_invocation_tokens sebagai string invocation yang ditokenisasi untuk adapter (harus ada di semua string input model). Teknik ini secara selektif mengaktifkan bobot adapter hanya pada token selama dan setelah alora_invocation_tokens. Ketika digunakan dalam CausalLM, ini berarti KV cache sebelum invocation dapat dipertukarkan dengan milik model dasar (dan adapter aLoRA lain yang beroperasi dengan cara ini). Akibatnya, dalam pipeline inferensi yang melibatkan peralihan antara inferensi model dasar dan inferensi adapter (misalnya pipeline agentic, lihat paper untuk contoh), penghematan signifikan tercapai (dibandingkan LoRA) dengan menyimpan operasi prefill. Percepatan inferensi adapter secara keseluruhan sebesar satu orde magnitudo atau lebih dapat terjadi pada vLLM, tergantung pada panjang konteks bersama. Perhatikan bahwa penggabungan (merging) tidak mungkin dilakukan karena penerapan bobot yang bersifat selektif. - use_qalora (
bool) — Saat ini hanya diimplementasikan di GPTQ. Mengaktifkan Quantization-Aware Low-Rank Adaptation (QALoRA). Teknik ini menggabungkan pelatihan yang sadar kuantisasi dengan LoRA untuk meningkatkan kinerja model terkuantisasi. Hal ini dapat meningkatkan kinerja LoRA, terutama pada rank rendah. Saat ini, QALoRA hanya mendukung lapisan linear. - qalora_group_size (
int) — Parameter ukuran grup untuk pooling QALoRA, yang mengontrol faktor reduksi dimensi. Dimensi input di-pool menjadi grup dengan ukuran ini, sehingga mengurangi biaya komputasi. Nilai yang lebih tinggi memberikan kompresi lebih besar tetapi dapat mengurangi kualitas model. Parameter ini menentukan berapa banyak fitur asli yang dirata-ratakan untuk membuat satu fitur hasil pooling. Hanya digunakan ketikause_qalora=True. - monteclora_config (
Optional[MontecloraConfig]) — Konfigurasi Monteclora (Monte Carlo Low-Rank Adaptation). Jika diberikan, Monteclora akan digunakan untuk menambahkan sampling variational Monte Carlo di atas adapter LoRA. LihatMontecloraConfiguntuk detail tentang hyperparameter individual. - layer_replication (
List[Tuple[int, int]]) — Membangun tumpukan lapisan baru dengan menumpuk lapisan model asli sesuai dengan rentang yang ditentukan. Hal ini memungkinkan memperluas (atau memperkecil) model tanpa menduplikasi bobot model dasar. Lapisan baru akan semuanya memiliki adapter LoRA terpisah yang terpasang di atasnya. - runtime_config (
LoraRuntimeConfig) — Konfigurasi runtime (yang tidak disimpan atau dipulihkan). - lora_bias (
bool) — Nilai defaultnya adalahFalse. Menentukan apakah akan mengaktifkan istilah bias untuk parameter LoRA B. Biasanya, ini sebaiknya dinonaktifkan. Kasus penggunaan utamanya adalah ketika bobot LoRA diekstrak dari parameter yang telah dilatih ulang secara penuh, sehingga bias dari parameter tersebut dapat diperhitungkan. - target_parameters (
List[str], opsional) — Daftar nama parameter yang akan diganti dengan LoRA. Argumen ini berperilaku serupa dengantarget_modules, kecuali bahwa nama parameter harus diberikan. Umumnya, Anda sebaiknya menggunakantarget_modulesuntuk menargetkan modul (misalnyann.Linear). Namun, dalam beberapa situasi, hal ini tidak mungkin dilakukan. Misalnya, pada banyak lapisan mixture of expert (MoE) di HF Transformers, alih-alih menggunakannn.Linear, sebuahnn.Parameterdigunakan. PEFT biasanya menimpa metodeforwarduntuk LoRA, tetapi untuknn.Parameter, tidak ada metode tersebut. Oleh karena itu, untuk menerapkan LoRA pada parameter tersebut, parameter itu perlu ditargetkan dengantarget_parameters. Sebagai contoh, untuk Llama4, Anda dapat meneruskan:target_parameters=['feed_forward.experts.gate_up_proj', 'feed_forward.experts.down_proj]. Meneruskan string untuk pencocokan regex belum diimplementasikan. Perhatikan bahwa ketika model dikompilasi dan menggunakantarget_parameters, kompilasi ulang dan/atau graph breaks diharapkan terjadi. Disarankan untuk tidak menggunakan keduanya secara bersamaan. - use_bdlora (
Optional[BdLoraConfig]) — Aktifkan BD-LoRA (Block-Diagonal LoRA) dengan menyediakan BdLoraConfig. Teknik ini menggunakan matriks blok-diagonal untuk faktor LoRA-A atau LoRA-B guna memungkinkan penyajian multi-LoRA yang lebih cepat dengan menghilangkan overhead komunikasi dalam pengaturan terdistribusi. - arrow_config (
Optional[ArrowConfig]) — Konfigurasi yang diperlukan untuk menerapkan routing arrow pada model. - ensure_weight_tying (
bool, opsional) — Apakah akan mengikat bobot atau tidak setelah inisialisasi peft. Hal ini akan memastikan bahwa adapter yang ditambahkan ke lapisan yang terikat juga ikut terikat. Ini hanya berlaku untuk lapisan yang diteruskan melaluimodules_to_savedantarget_modules.
Ini adalah kelas konfigurasi untuk menyimpan konfigurasi dari LoraModel.
Mengembalikan konfigurasi untuk model adapter Anda sebagai kamus. Menghapus konfigurasi runtime.
LoraModel
kelas peft.LoraModel
< source >( modelpeft_config: Union[PeftConfig, dict[str, PeftConfig]]adapter_name: strlow_cpu_mem_usage: bool = Falsestate_dict: Optional[dict[str, torch.Tensor]] = None ) → torch.nn.Module
Parameter
- model (
torch.nn.Module) — Model yang akan diadaptasi. - config (LoraConfig) — Konfigurasi model Lora.
- adapter_name (
str) — Nama adapter, secara default"default". - low_cpu_mem_usage (
bool,optional, defaults toFalse) — Membuat bobot adapter kosong pada perangkat meta. Berguna untuk mempercepat proses pemuatan.
Mengembalikan
torch.nn.Module
Model Lora.
Membuat model Low Rank Adapter (LoRA) dari model transformers yang telah dilatih sebelumnya.
Metode ini dijelaskan secara detail di https://huggingface.co/papers/2106.09685.
Contoh:
>>> from transformers import AutoModelForSeq2SeqLM
>>> from peft import LoraConfig, get_peft_model
>>> config = LoraConfig(
... task_type="SEQ_2_SEQ_LM",
... r=8,
... lora_alpha=32,
... target_modules=["q", "v"],
... lora_dropout=0.01,
... )
>>> model = AutoModelForSeq2SeqLM.from_pretrained("t5-base")
>>> lora_model = get_peft_model(model, config)>>> import torch
>>> import transformers
>>> from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
>>> rank = ...
>>> target_modules = ["q_proj", "k_proj", "v_proj", "out_proj", "fc_in", "fc_out", "wte"]
>>> config = LoraConfig(
... r=4, lora_alpha=16, target_modules=target_modules, lora_dropout=0.1, bias="none", task_type="CAUSAL_LM"
... )
>>> quantization_config = transformers.BitsAndBytesConfig(load_in_8bit=True)
>>> tokenizer = transformers.AutoTokenizer.from_pretrained(
... "kakaobrain/kogpt",
... revision="KoGPT6B-ryan1.5b-float16", # or float32 version: revision=KoGPT6B-ryan1.5b
... bos_token="[BOS]",
... eos_token="[EOS]",
... unk_token="[UNK]",
... pad_token="[PAD]",
... mask_token="[MASK]",
... )
>>> model = transformers.GPTJForCausalLM.from_pretrained(
... "kakaobrain/kogpt",
... revision="KoGPT6B-ryan1.5b-float16", # or float32 version: revision=KoGPT6B-ryan1.5b
... pad_token_id=tokenizer.eos_token_id,
... use_cache=False,
... device_map={"": rank},
... torch_dtype=torch.float16,
... quantization_config=quantization_config,
... )
>>> model = prepare_model_for_kbit_training(model)
>>> lora_model = get_peft_model(model, config)Atribut:
- model (PreTrainedModel) — Model yang akan diadaptasi.
- peft_config (LoraConfig): Konfigurasi model Lora.
add_weighted_adapter
< source >( adapters: list[str]weights: list[float]adapter_name: strcombination_type: Literal['svd', 'linear', 'cat', 'ties', 'ties_svd', 'dare_ties', 'dare_linear', 'dare_ties_svd', 'dare_linear_svd', 'magnitude_prune', 'magnitude_prune_svd'] = 'svd'svd_rank: int | None = Nonesvd_clamp: int | None = Nonesvd_full_matrices: bool = Truesvd_driver: str | None = Nonedensity: float | None = Nonemajority_sign_method: Literal['total', 'frequency'] = 'total' )
Parameter
- adapters (
list) — Daftar nama adapter yang akan digabungkan. - weights (
list) — Daftar bobot untuk setiap adapter. Bobot dapat bernilai positif atau negatif, sehingga memungkinkan penambahan maupun pengurangan efek adapter. - adapter_name (
str) — Nama adapter baru. - combination_type (
str) — The merging type can be one of [svd,linear,cat,ties,ties_svd,dare_ties,dare_linear,dare_ties_svd,dare_linear_svd,magnitude_prune,magnitude_prune_svd]. When using thecatcombination_type, the rank of the resulting adapter is equal to the sum of all adapters ranks (the mixed adapter may be too big and result in OOM errors). Note thatcatandsvdare precise methods and will give you good accuracy,linearis efficient but a very rough approximation and should be avoided if you can afford it. - svd_rank (
int, opsional) — Rank dari adapter keluaran untuk svd. Jika None diberikan, akan menggunakan rank maksimum dari adapter yang digabungkan. - svd_clamp (
float, opsional) — Ambang batas kuantil untuk membatasi (clamping) output dekomposisi SVD. Jika None diberikan, jangan lakukan clamping. Defaultnya None. - svd_full_matrices (
bool, opsional) — Mengontrol apakah SVD penuh atau tereduksi yang dihitung, dan dengan demikian, bentuk tensor U dan Vh yang dikembalikan. Defaultnya True. - svd_driver (
str, opsional) — Nama metode cuSOLVER yang akan digunakan. Argumen kata kunci ini hanya berfungsi saat penggabungan dilakukan di CUDA. Dapat berupa salah satu dari [None,gesvd,gesvdj,gesvda]. Untuk informasi lebih lanjut, silakan merujuk ke dokumentasitorch.linalg.svd. Nilai default adalah None. - density (
float, opsional) — Nilai antara 0 dan 1. 0 berarti semua nilai dipangkas dan 1 berarti tidak ada nilai yang dipangkas. Seharusnya digunakan dengan [ties,ties_svd,dare_ties,dare_linear,dare_ties_svd,dare_linear_svd,magnintude_prune,magnitude_prune_svd] - majority_sign_method (
str) — Metode, harus salah satu dari [“total”, “frequency”], yang digunakan untuk mendapatkan magnitudo nilai tanda. Harus digunakan dengan [ties,ties_svd,dare_ties,dare_ties_svd]
Metode ini menambahkan adapter baru dengan menggabungkan adapter yang diberikan dengan bobot yang diberikan.
Saat menggunakan cat combination_type, Anda perlu menyadari bahwa rank dari adapter yang dihasilkan akan sama dengan
jumlah dari semua rank adapter. Jadi, dimungkinkan adapter campuran menjadi terlalu besar dan menyebabkan error OOM.
subtract_mutated_init
< source >( output_state_dict: dict[str, torch.Tensor]adapter_name: strkwargs = None )
Fungsi ini dapat menghitung pembaruan PiSSA/CorDA/OLoRA dengan membandingkan parameter adapter PiSSA/CorDA/OLoRA di output_state_dict dengan nilai awal PiSSA/CorDA/OLoRA di adapter_name, sehingga mengonversi PiSSA/CorDA/OLoRA menjadi LoRA.
Metode seperti PiSSA menghapus sebagian bobot dasar model untuk pelatihan dan karenanya tidak mudah ditukar. Namun, jika Anda mengetahui bobot pra-pelatihan awal dan bobot pasca-pelatihan, Anda dapat menghitung \Delta W dan menggunakannya sebagai adapter LoRA.
Langkah komputasi:
- (inisialisasi PiSSA
- (PiSSA setelah pelatihan)
- (Menurunkan dW untuk LoRA
Utilitas
ArrowConfig
kelas peft.ArrowConfig
< source >( top_k: int = 3router_temperature: float = 1.0use_gks: bool = Falserng_seed: Optional[int] = None )
Ini adalah kelas sub-konfigurasi untuk menyimpan konfigurasi algoritma Arrow dan GenKnowSub. Arrow adalah algoritma routing untuk menggabungkan modul LoRA yang telah dilatih guna menyelesaikan tugas baru, yang diusulkan dalam ‘https://huggingface.co/papers/2405.11157’. GenKnowSub adalah penyempurnaan pada modul yang telah dilatih sebelum digabungkan melalui Arrow, yang diperkenalkan dalam ‘https://aclanthology.org/2025.acl-short.54/’
LoftQ
replace_lora_weights_loftq
peft.replace_lora_weights_loftq
< source >( peft_modelmodel_path: Optional[str] = Noneadapter_name: str = 'default'callback: Optional[Callable[[torch.nn.Module, str], bool]] = None )
Parameter
- peft_model (
PeftModel) — Model yang bobotnya akan diganti. Harus berupa model PEFT terkuantisasi dengan lapisan LoRA. - model_path (
Optional[str]) — Path ke file safetensors model. Jika model tersebut adalah model Hugging Face, path ini akan disimpulkan dari config model. Jika tidak, path ini harus disediakan. - adapter_name (
str) — Nama adapter untuk menggantikan bobot. Nama adapter default adalah “default”. - callback (
Optional[Callable[[PeftModel, str], bool]]) — Fungsi callback yang akan dipanggil setelah setiap modul diganti. Fungsi callback ini harus menerima model dan nama modul saat ini sebagai input, lalu mengembalikan nilai boolean yang menunjukkan apakah penggantian tersebut harus dipertahankan. Jika callback mengembalikan False, penggantian akan dibatalkan. Hal ini sangat berguna untuk memastikan bahwa inisialisasi LoftQ benar-benar mengurangi error kuantisasi dari model. Sebagai contoh, callback ini dapat menghasilkan logits untuk input tertentu dan membandingkannya dengan logits dari model asli yang tidak dikuantisasi dengan input yang sama, dan hanya mengembalikanTruejika terdapat peningkatan. Karena ini adalah optimasi greedy, dimungkinkan bahwa pemanggilan fungsi ini berulang kali menghasilkan peningkatan secara bertahap.
Ganti bobot LoRA dari model yang dikuantisasi dengan bitsandbytes, menggunakan teknik LoftQ.
Penggantian dilakukan secara langsung dengan memuat bobot non-kuantisasi dari file model safetensors yang disimpan secara lokal dan menginisialisasi bobot LoRA sehingga kesalahan kuantisasi antara bobot asli dan bobot terkuantisasi diminimalkan.
Karena lazy loading tidak mungkin dilakukan dengan pickle, file checkpoint PyTorch biasa tidak dapat didukung.
Tergantung pada ukuran model, pemanggilan fungsi ini mungkin memerlukan waktu untuk selesai.
LoftQConfig
kelas peft.LoftQConfig
< source >( loftq_bits: int = 4loftq_iter: int = 1 )
Ini adalah kelas sub-konfigurasi untuk menyimpan konfigurasi dari LoraModel.
Eva
EvaConfig
kelas peft.EvaConfig
< source >( rho: float = 2.0tau: float = 0.99use_label_mask: bool = Truelabel_mask_value: int = -100whiten: bool = Falseadjust_scaling_factors: bool = True )
Parameter
- rho (
float) — Nilai Rho untuk redistribusi EVA (>= 1.0). Rank maksimum untuk suatu layer adalah lora_r * rho. Default adalah 2.0, yang berarti rank maksimum yang diizinkan untuk suatu layer adalah 2r. Meningkatkan rho akan memungkinkan tingkat redistribusi rank yang lebih tinggi antar layer. Beberapa model pre-trained mungkin lebih sensitif terhadap redistribusi rank. Oleh karena itu, dapat bermanfaat untuk mencoba rho=1.0 (tanpa redistribusi) jika performanya lebih rendah dari yang diharapkan. - tau (
float) — Ambang batas kemiripan kosinus untuk penghentian dini. Membandingkan kemiripan kosinus dari vektor singular kanan antara dua langkah SVD yang berurutan. Jika kemiripan kosinus berada di atas ambang batas ini, iterasi SVD akan dihentikan. Nilai default adalah 0.99. - use_label_mask (
bool) — Gunakan label mask untuk inisialisasi EVA. Ini berarti posisi di mana labels=label_mask_value diabaikan untuk komputasi SVD. Mengatur use_label_mask=True lebih disarankan dalam kebanyakan kasus dan dapat sangat bermanfaat untuk percakapan multi-turn. Nilai defaultnya adalah True. Menyaring item berdasarkan label mask terkadang dapat menyebabkan ukuran batch yang kecil dan sebagai akibatnya ketidakstabilan dalam komputasi SVD. Untuk kasus di mana sebagian besar item batch akan disaring, set use_label_mask=False. - label_mask_value (
int) — Jika use_label_mask=True, nilai yang dicari untuk mem-mask token yang diabaikan. Default adalah -100. - whiten (
bool) — Terapkan whitening pada vektor singular. Default adalah False. Whitening telah terbukti bermanfaat untuk EVA di domain visi. - adjust_scaling_factors (
bool) — Menyesuaikan faktor penskalaan LoRA setelah redistribusi rank. Mengatur ini ke True berarti faktor penskalaan disesuaikan sehingga semua gradien LoRA memiliki skala yang sama terlepas dari rank-nya. Default adalah True.
Ini adalah kelas sub-konfigurasi untuk menyimpan konfigurasi inisialisasi berbasis data melalui EVA. EVA diperkenalkan dalam Explained Variance Adaptation.
initialize_lora_eva_weights
peft.initialize_lora_eva_weights
< source >( model: Moduledataloader: collections.abc.Iterable | None = Noneeva_state_dict: dict | None = Noneforward_fn: collections.abc.Callable | None = <function forward_fn_dict at 0x7f240ea44e00>prepare_model_inputs_fn: collections.abc.Callable | None = <function prepare_model_inputs_fn_language_modeling at 0x7f240ea44bf0>prepare_layer_inputs_fn: collections.abc.Callable | dict[str, collections.abc.Callable] | None = <function prepare_layer_inputs_fn_language_modeling at 0x7f240ea44d50>adapter_name: str = 'default'gather_distributed_inputs: bool = Trueshow_progress_bar: bool = True ) → model (torch.nn.Module)
Parameter
- model (PeftModel) — Model peft untuk menghitung SVD.
- dataloader (Optional[Iterable]) — Dataloader yang akan digunakan untuk forward pass. Jika None, eva_state_dict harus disediakan.
- eva_state_dict (Optional[dict]) —
state_dict yang akan dimuat ke dalam model. Jika None, dataloader harus disediakan dan state_dict akan dihitung menggunakan
get_eva_state_dict. - forward_fn (Callable) —
Fungsi forward yang digunakan untuk forward pass. Menerima dua argumen:
modeldaninputs. Perilaku default adalahreturn model(**inputs) - prepare_model_inputs_fn (Optional[Callable]) —
Fungsi ini menerima input model dan peft_config, lalu meneruskan output ke
prepare_layer_inputs_fn. Dapat digunakan untuk memodifikasi input ke komputasi SVD berdasarkan input model asli. Misalnya, untuk pemodelan bahasa, attention mask digunakan untuk menentukan indeks mana yang merupakan token padding dan tidak boleh digunakan untuk SVD. Setiap fungsi yang didefinisikan di sini mengharapkan dua argumen:model_inputdanpeft_config.peft.tuners.lora.eva.prepare_model_inputs_fn_language_modelingdigunakan secara default. - prepare_layer_inputs_fn (Union[Callable, Dict[str, Callable], None]) —
Fungsi ini menerima input layer, input model (yang mungkin telah dimodifikasi oleh
prepare_model_inputs_fn) dan nama layer, lalu mengembalikan input yang harus digunakan untuk SVD untuk layer tersebut. Fungsi kustom yang didefinisikan di sini mengharapkan tiga argumen:layer_input,model_input, danlayer_namedan harus mengembalikan tensor 2d. Logika default dapat ditemukan di peft.tuners.lora.eva.prepare_layer_inputs_fn_language_modeling dan berfungsi untuk pemodelan bahasa. Dalam kasus ini model_inputs adalah mask yang digunakan untuk menentukan indeks mana yang harus digunakan untuk SVD (dibuat olehprepare_model_inputs_fn_language_modeling). - adapter_name (str) — Nama adapter untuk menginisialisasi bobot.
- gather_distributed_inputs (bool) — Apakah akan mengumpulkan input layer dari semua rank. Default adalah True yang berarti dalam pengaturan distributed, input layer akan dikumpulkan dari semua rank untuk komputasi SVD. Untuk pengaturan non-distributed, argumen ini diabaikan. Atur ke False jika Anda menggunakan dataloader non-distributed dalam pengaturan distributed.
- show_progress_bar (bool) — Apakah akan menampilkan bilah kemajuan. Default adalah True.
Mengembalikan
model (torch.nn.Module)
Model dengan bobot LoRA yang telah diinisialisasi.
Inisialisasi bobot lapisan LoRA menggunakan metode EVA.
Fungsi ini menginisialisasi bobot dari lapisan LoRA menggunakan metode EVA. Fungsi ini menghitung SVD untuk setiap lapisan adapter dan memperbarui bobot sesuai dengan itu.
get_eva_state_dict
peft.get_eva_state_dict
< source >( model: Moduledataloader: Iterablepeft_config: peft.tuners.lora.config.LoraConfig | None = Noneforward_fn: collections.abc.Callable | None = <function forward_fn_dict at 0x7f240ea44e00>prepare_model_inputs_fn: collections.abc.Callable | None = <function prepare_model_inputs_fn_language_modeling at 0x7f240ea44bf0>prepare_layer_inputs_fn: collections.abc.Callable | dict[str, collections.abc.Callable] | None = <function prepare_layer_inputs_fn_language_modeling at 0x7f240ea44d50>adapter_name: str = 'default'gather_distributed_inputs: bool = Trueshow_progress_bar: bool = True ) → eva_state_dict (dict)
Parameter
- model (torch.nn.Module) — Model untuk menghitung SVD. Tidak perlu berupa PeftModel.
- dataloader (Iterable) — Dataloader yang digunakan untuk forward pass.
- peft_config (Optional[LoraConfig]) —
Konfigurasi untuk lapisan LoRA. Hanya diperlukan jika
modelbukan PeftModel. - forward_fn (Callable) —
Fungsi forward yang digunakan untuk forward pass. Menerima dua argumen:
modeldaninputs. Perilaku default adalahreturn model(**inputs) - prepare_model_inputs_fn (Optional[Callable]) —
Fungsi ini menerima input model dan peft_config, lalu meneruskan output ke
prepare_layer_inputs_fn. Dapat digunakan untuk memodifikasi input ke komputasi SVD berdasarkan input model asli. Misalnya, untuk pemodelan bahasa, attention mask digunakan untuk menentukan indeks mana yang merupakan token padding dan tidak boleh digunakan untuk SVD. Setiap fungsi yang didefinisikan di sini mengharapkan dua argumen:model_inputdanpeft_config.peft.tuners.lora.eva.prepare_model_inputs_fn_language_modelingdigunakan secara default. - prepare_layer_inputs_fn (Union[Callable, Dict[str, Callable], None]) —
Fungsi ini menerima input layer, input model (yang mungkin telah dimodifikasi oleh
prepare_model_inputs_fn) dan nama layer, lalu mengembalikan input yang harus digunakan untuk SVD untuk layer tersebut. Fungsi kustom yang didefinisikan di sini mengharapkan tiga argumen:layer_input,model_input, danlayer_namedan harus mengembalikan tensor 2d. Logika default dapat ditemukan di peft.tuners.lora.eva.prepare_layer_inputs_fn_language_modeling dan berfungsi untuk pemodelan bahasa. Dalam kasus ini model_inputs adalah mask yang digunakan untuk menentukan indeks mana yang harus digunakan untuk SVD (dibuat olehprepare_model_inputs_fn_language_modeling). - adapter_name (str) — Nama adapter untuk menghitung SVD.
- gather_distributed_inputs (bool) — Apakah akan mengumpulkan input layer dari semua rank. Default adalah True yang berarti dalam pengaturan distributed, input layer akan dikumpulkan dari semua rank untuk komputasi SVD. Untuk pengaturan non-distributed, argumen ini diabaikan. Atur ke False jika Anda menggunakan dataloader non-distributed dalam pengaturan distributed.
- show_progress_bar (bool) — Apakah akan menampilkan bilah kemajuan. Default adalah True.
Mengembalikan
eva_state_dict (dict)
Kamus keadaan yang berisi komponen SVD untuk setiap lapisan.
Hitung SVD untuk setiap layer dalam model.
Fungsi ini menghitung Singular Value Decomposition (SVD) untuk setiap layer dalam model. Fungsi ini menggunakan metode PCA inkremental untuk menghitung komponen SVD. Fungsi ini juga memeriksa konvergensi komponen yang dihitung menggunakan kemiripan kosinus. Distribusi rank untuk setiap layer ditentukan berdasarkan rasio varians yang dijelaskan.
LoraGAConfig
kelas peft.LoraGAConfig
< source >( direction: Literal['ArBr', 'A2rBr', 'ArB2r', 'random'] = 'ArB2r'scale: Literal['stable', 'weight_svd', 'gd_scale', 'unit'] = 'stable'stable_gamma: int = 16 )
Parameter
- direction (
Literal["ArBr", "A2rBr", "ArB2r", "random"]) — Strategi untuk mendistribusikan komponen SVD gradien ke matriks lora_A dan lora_B.- “ArBr”: Indeks bergantian (A mengambil ganjil, B mengambil genap)
- “A2rBr”: A mengambil indeks [r:2r], B mengambil indeks [:r]
- “ArB2r”: A mengambil indeks [:r], B mengambil indeks [r:2r] (disarankan)
- “random”: Pemilihan indeks secara acak Default: “ArB2r”
- scale (
Literal["stable", "weight_svd", "gd_scale", "unit"]) — Strategi penskalaan untuk inisialisasi adapter.- “stable”: Penskalaan stabil dengan parameter gamma
- “weight_svd”: Skala berdasarkan nilai singular matriks bobot
- “gd_scale”: penskalaan berbasis penurunan gradien
- “unit”: Tidak ada penskalaan tambahan Default: “stable”
- stable_gamma (
int) — Parameter gamma untuk metode penskalaan stabil. Default: 16
Ini adalah kelas sub-konfigurasi untuk menyimpan konfigurasi inisialisasi LoRA-GA.
LoRA-GA (Low-Rank Adaptation with Gradient Approximation) menggunakan informasi gradien selama inisialisasi untuk mencapai konvergensi yang lebih cepat (percepatan 2-4x) dengan menyelaraskan bobot adapter awal dengan arah gradien fine-tuning penuh.
Referensi: https://arxiv.org/abs/2407.05000
Utilitas
peft.tuners.lora.loraga.estimate_gradients
< source >( model: Modulelora_config: LoraConfigtrain_step: Callable )
Perkirakan gradien untuk inisialisasi LoRA-GA.
Fungsi ini memungkinkan komputasi gradien HANYA pada bobot modul target dan menjalankan callback train_step. Ini lebih hemat memori dibandingkan mengaktifkan gradien secara global.
peft.preprocess_loraga
< source >( model: Modulelora_config: LoraConfigtrain_step: Callablecache_file: str | None = None )
Parameter
- model (
nn.Module) — Model yang akan dipreprocess. - lora_config (
LoraConfig) — Konfigurasi Lora dari model.lora_config.lora_ga_configharus diatur. - train_step (
Callable[[], None]) — Callback untuk menjalankan estimasi gradien. Biasanya, Anda harus menjalankan jalur maju (forward) dan mundur (backward) model di callback ini. Gradien akan diakumulasi di semua pemanggilan di dalam callback ini. - cache_file (
Optional[str]) — Path opsional ke file cache untuk menyimpan/memuat gradien. Jika disediakan dan file tersebut ada, gradien akan dimuat dari cache. Sebaliknya, gradien akan diperkirakan dan disimpan ke path ini.
Bangun bidang LoRA-GA yang diperlukan untuk model dengan memperkirakan gradien.
Untuk setiap lapisan linear, gradien akan diperkirakan dengan menjalankan callback train_step yang disediakan. Gradien-gradien ini kemudian dilampirkan ke modul-modul dan digunakan selama inisialisasi.
Setelah selesai, bidang-bidang berikut diatur untuk setiap modul target:
_peft_loraga_grad (torch.Tensor):
Gradien terakumulasi untuk matriks bobot.
Reduksi Dimensi Intruder
peft.tuners.lora.intruders.reduce_intruder_dimension
< source >( peft_modelold_adapter_name = 'default'new_adapter_name = 'intruder_reduced'top_k = 10threshold_epsilon = 0.5mitigation_lambda = 0.75logging_sink = <built-in function print> )
Parameter
- peft_model —
Model PEFT dengan adapter LoRA yang dimuat dengan nama yang diberikan dalam
old_adapter_name. Saat ini, model campuran tidak didukung. - top_k (default — 10) Pertimbangkan dimensi top-k untuk deteksi intruder. Semakin besar nilainya, semakin banyak dimensi yang akan dipertimbangkan untuk analisis deteksi intruder (dan semakin banyak false-positive yang mungkin terjadi). Beroperasi pada kemiripan kosinus antara bobot dasar dan bobot adapter yang diurutkan secara kasar berdasarkan pengaruh dimensi (ditentukan oleh singular value decomposition), sehingga top-k sebesar 10 akan melihat 10 dimensi yang paling ‘penting’.
- threshold_epsilon (default — 0.5) Nilai ambang batas untuk menganggap kemiripan kosinus antara bobot dasar dan bobot adapter sebagai intruder. Menurut makalah tersebut, dimensi intruder menunjukkan kemiripan kosinus absolut yang mendekati nol dengan vektor singular yang telah dilatih sebelumnya. Semakin rendah nilai ini, semakin sedikit dimensi intruder potensial yang diidentifikasi. Semakin tinggi nilainya, semakin banyak false-positives potensial yang dianggap sebagai intruder.
- mitigation_lambda (default — 0.75) Bagian relatif dari dimensi intruder yang dikurangkan dari delta weight adapter. Semakin tinggi nilainya, semakin banyak dimensi intruder yang dikurangkan, tetapi semakin banyak informasi yang hilang. Lihat Gambar 8 di paper untuk analisis trade-off.
- logging_sink (default — print) Fungsi yang mencetak informasi tentang proses mitigasi. Atur ke None jika Anda tidak ingin ada output.
Mitigasi dimensi intruder berdasarkan https://huggingface.co/papers/2410.21228 (“LoRA vs Full Fine-tuning: An Illusion of Equivalence”).
Metode ini dapat memulihkan pengetahuan sebelumnya (yaitu mengurangi *forgetting*) dengan memproses ulang *low-rank adapters* yang sudah dilatih. Hal ini menimbulkan biaya berupa akurasi tugas - penyetelan nilai migration_lambda dapat digunakan untuk menyeimbangkan kedua faktor tersebut.
Setelah mitigasi selesai, akan ada adapter baru dengan nama yang diatur di new_adapter_name yang juga ditetapkan sebagai adapter aktif saat ini. Oleh karena itu, inferensi pada model yang telah dimitigasi akan menggunakan adapter yang telah dimodifikasi. Untuk beralih kembali ke adapter asli, Anda dapat menggunakan peft_model.set_adapter(<old_adapter_name>).
Saat ini, hanya LoRA yang didukung karena belum jelas apakah metode ini dapat digeneralisasi ke metode delta-weight lainnya.