PEFT documentation

Prefix tuning

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v0.21.0).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Prefix tuning

Optimize the prefix parameters for each task (image source).

Prefix tuning menambahkan serangkaian vektor spesifik tugas ke awal urutan input yang dapat dipelajari sambil mempertahankan model pra-terlatih tetap beku. Parameter prefix disisipkan ke dalam semua lapisan model.

Abstrak dari makalah tersebut adalah:

Fine-tuning adalah cara de facto untuk memanfaatkan model bahasa pretrained berskala besar guna menjalankan tugas downstream. Namun, metode ini memodifikasi seluruh parameter model bahasa sehingga mengharuskan penyimpanan salinan lengkap untuk setiap tugas. Dalam makalah ini, kami mengusulkan prefix-tuning, alternatif ringan dari fine-tuning untuk tugas natural language generation, yang menjaga parameter model bahasa tetap beku, tetapi mengoptimalkan vektor tugas spesifik yang kecil dan kontinu (disebut prefix). Prefix-tuning terinspirasi dari prompting, memungkinkan token berikutnya untuk memperhatikan prefix ini seolah-olah prefix tersebut adalah “virtual tokens”. Kami menerapkan prefix-tuning pada GPT-2 untuk table-to-text generation dan pada BART untuk summarization. Kami menemukan bahwa dengan hanya mempelajari 0,1\% dari parameter, prefix-tuning memperoleh kinerja yang sebanding dalam pengaturan data penuh, melampaui fine-tuning dalam pengaturan data rendah, dan melakukan ekstrapolasi yang lebih baik ke contoh dengan topik yang tidak terlihat selama pelatihan.

Catatan Untuk model encoder-decoder (seq2seq), prefix hanya diterapkan pada decoder, yang tidak sesuai dengan spesifikasi paper (lihat misalnya Gambar 2). Prefix tuning masih dapat di-fine-tune pada arsitektur model ini, tetapi kinerjanya bisa kurang optimal; pertimbangkan untuk menggunakan metode PEFT lain untuk model encoder-decoder.

Prefix tuning sangat mirip dengan prompt tuning. Perbedaan utamanya adalah bahwa parameter prefix disisipkan ke dalam semua lapisan model, sedangkan prompt tuning hanya menambahkan parameter prompt ke embedding input model. Parameter prefix juga dioptimalkan oleh jaringan feed-forward (FFN) yang terpisah, bukan dengan melatih langsung pada soft prompt, karena hal tersebut menyebabkan ketidakstabilan dan menurunkan kinerja. FFN dibuang setelah soft prompt diperbarui.

Sebagai hasilnya, para penulis menemukan bahwa prefix tuning menunjukkan kinerja yang setara dengan finetuning penuh pada sebuah model, meskipun memiliki 1000x lebih sedikit parameter, dan kinerjanya bahkan lebih baik dalam pengaturan data rendah.

Penggunaan Dasar

Buat PrefixTuningConfig dengan tipe tugas dan jumlah token virtual yang akan ditambahkan dan dipelajari.

from peft import PrefixTuningConfig, get_peft_model

peft_config = PrefixTuningConfig(task_type="CAUSAL_LM", num_virtual_tokens=20)
model = get_peft_model(model, peft_config)
model.print_healthcheck()

Inisialisasi yang Mungkin

Secara default, prefix tuning menggunakan token virtual yang diinisialisasi secara acak. Ada juga opsi untuk menginisialisasi vektor agar mendekati no-op (jika diinisialisasi ke nol, hal itu masih akan menggeser massa probabilitas sedikit). Ini berarti bahwa prefix yang disuntikkan ke KV-cache memiliki dampak yang lebih kecil sejak awal dan mengurangi varians dalam kinerja pelatihan.

PEFT juga menyediakan utilitas untuk menginisialisasi adapter prefix-tuning dari prefix KV cache yang sudah ada (misalnya, dari p token pertama dari prompt/korpus). Ini hanya didukung ketika prefix_projection=False (default), karena dalam kasus tersebut parameter yang dipelajari adalah prefix KV itu sendiri.

from transformers import AutoModelForCausalLM, AutoTokenizer

from peft import PrefixTuningConfig, get_peft_model, initialize_kv_prefix_from_text

base = AutoModelForCausalLM.from_pretrained("gpt2")
tok = AutoTokenizer.from_pretrained("gpt2")

peft_cfg = PrefixTuningConfig(task_type="CAUSAL_LM", num_virtual_tokens=20, prefix_projection=False)
model = get_peft_model(base, peft_cfg)

initialize_kv_prefix_from_text(
    model,
    tok,
    text="...a long context with at least num_virtual_tokens tokens...",
    use_chat_template=False,
)m peft import PrefixTuningConfig, get_peft_model, initialize_kv_prefix_from_text

base = AutoModelForCausalLM.from_pretrained("gpt2")
tok = AutoTokenizer.from_pretrained("gpt2")

peft_cfg = PrefixTuningConfig(task_type="CAUSAL_LM", num_virtual_tokens=20, prefix_projection=False)
model = get_peft_model(base, peft_cfg)

initialize_kv_prefix_from_text(
    model,
    tok,
    text="...a long context with at least num_virtual_tokens tokens...",
    use_chat_template=False,
)

Pastikan teks cukup panjang untuk menghasilkan setidaknya num_virtual_tokens token, jika tidak inisialisasi akan gagal.

Sebagai pedoman:

  • mulai dengan urutan awal yang netral menggunakan initialize_kv_prefix_from_text, bisa berupa string yang sangat pendek seperti “Question: ”
  • jika itu tidak membantu, gunakan urutan yang lebih panjang dengan relevansi tugas (yaitu prompt yang direkayasa), sehingga Anda memiliki lebih banyak token virtual untuk diakomodasi, tetapi juga lebih banyak kendali terhadap model
  • jika tidak memungkinkan untuk menggunakan teks inisialisasi atau Anda ingin dengan cepat memeriksa apakah prefix tuning layak digunakan, gunakan inisialisasi nol tanpa proyeksi

Ikhtisar benchmark

API

PrefixTuningConfig

kelas peft.PrefixTuningConfig

< >

( 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 = Falsenum_virtual_tokens: int = Nonetoken_dim: int = Nonenum_transformer_submodules: Optional[int] = Nonenum_attention_heads: Optional[int] = Nonenum_layers: Optional[int] = Nonemodules_to_save: Optional[list[str]] = Noneinit_weights: typing.Literal['zero'] | None = Noneencoder_hidden_size: int = Noneprefix_projection: bool = False )

Parameter

  • init_weights (Optional[str]) — Jika tidak disetel, bobot diinisialisasi secara acak; jika disetel ke “zero”, bobot diinisialisasi sehingga aktivasi akan menjadi no-op (nol).
  • encoder_hidden_size (int) — Ukuran tersembunyi dari encoder prompt.
  • prefix_projection (bool) — Apakah akan memproyeksikan embedding prefix.

Ini adalah kelas konfigurasi untuk menyimpan konfigurasi dari PrefixEncoder.

PrefixEncoder

kelas peft.PrefixEncoder

< >

( config )

Parameter

Model torch.nn untuk mengodekan prefiks.

Contoh:

>>> from peft import PrefixEncoder, PrefixTuningConfig

>>> config = PrefixTuningConfig(
...     peft_type="PREFIX_TUNING",
...     task_type="SEQ_2_SEQ_LM",
...     num_virtual_tokens=20,
...     token_dim=768,
...     num_transformer_submodules=1,
...     num_attention_heads=12,
...     num_layers=12,
...     encoder_hidden_size=768,
... )
>>> prefix_encoder = PrefixEncoder(config)

Atribut:

  • embedding (torch.nn.Embedding) — Lapisan embedding dari encoder prefix.
  • transform (torch.nn.Sequential) — MLP dua lapis untuk mentransformasi embedding prefix jika prefix_projection adalah True.
  • prefix_projection (bool) — Apakah akan memproyeksikan embedding prefix.

Bentuk input: (batch_size, num_virtual_tokens)

Bentuk output: (batch_size, num_virtual_tokens, 2*layers*hidden)

load_prompt_embeddings

< >

( prompt_embeddings: Tensor )

Muat embedding prompt yang telah diratakan dan disimpan oleh PEFT (prompt_embeddings).

Untuk prefix tuning, ini hanya didukung ketika prefix_projection=False, karena dalam kasus tersebut parameter yang dipelajari adalah prefix KV itu sendiri (embedding.weight memiliki bentuk [num_virtual_tokens, num_layers*2*token_dim]).

Jika prefix_projection=True, parameternya adalah (virtual token embeddings + an MLP) dan tidak ada cara umum untuk membalikkan proyeksi guna memulihkan parameter tersebut dari KV prefix yang telah diratakan.

Update on GitHub