PEFT documentation
Prefix tuning
Prefix tuning

Prefix tuning thêm một chuỗi các vector đặc thù cho tác vụ vào đầu chuỗi đầu vào, có thể được học trong khi giữ nguyên mô hình được huấn luyện trước. Các tham số prefix được chèn vào tất cả các lớp của mô hình.
Tóm tắt từ bài báo là:
Fine-tuning là cách thực tế để khai thác các mô hình ngôn ngữ lớn được huấn luyện trước nhằm thực hiện các tác vụ downstream. Tuy nhiên, phương pháp này thay đổi tất cả các tham số của mô hình ngôn ngữ, do đó đòi hỏi phải lưu trữ một bản sao đầy đủ cho mỗi tác vụ. Trong bài báo này, chúng tôi đề xuất prefix-tuning, một phương án thay thế nhẹ nhàng cho fine-tuning trong các tác vụ sinh ngôn ngữ tự nhiên, giữ nguyên các tham số của mô hình ngôn ngữ nhưng tối ưu hóa một vector liên tục nhỏ, đặc thù cho từng tác vụ (gọi là prefix). Prefix-tuning lấy cảm hứng từ prompting, cho phép các token tiếp theo chú ý đến prefix này như thể nó là các “token ảo”. Chúng tôi áp dụng prefix-tuning cho GPT-2 trong tác vụ sinh văn bản từ bảng và cho BART trong tác vụ tóm tắt. Chúng tôi nhận thấy rằng bằng cách chỉ học 0,1% số tham số, prefix-tuning đạt được hiệu suất tương đương trong cài đặt dữ liệu đầy đủ, vượt trội hơn fine-tuning trong các cài đặt dữ liệu ít, và ngoại suy tốt hơn đối với các ví dụ có chủ đề chưa từng thấy trong quá trình huấn luyện.
Lưu ý Đối với các mô hình encoder-decoder (seq2seq), tiền tố chỉ được áp dụng cho phần decoder, điều này không khớp với quy định trong bài báo (xem ví dụ Hình 2). Prefix tuning vẫn có thể được tinh chỉnh trên các kiến trúc mô hình này nhưng hiệu suất có thể không tối ưu; hãy cân nhắc sử dụng các phương pháp PEFT khác cho các mô hình encoder-decoder.
Prefix tuning rất giống với prompt tuning. Sự khác biệt chính là các tham số prefix được chèn vào tất cả các lớp của mô hình, trong khi prompt tuning chỉ thêm các tham số prompt vào các embedding đầu vào của mô hình. Các tham số prefix cũng được tối ưu hóa bởi một mạng feed-forward (FFN) riêng biệt thay vì huấn luyện trực tiếp trên các soft prompt vì điều này gây ra sự bất ổn và làm giảm hiệu suất. Mạng FFN sẽ bị loại bỏ sau khi cập nhật các soft prompt.
Do đó, các tác giả nhận thấy rằng prefix tuning thể hiện hiệu suất tương đương với việc tinh chỉnh hoàn toàn một mô hình, mặc dù có ít tham số hơn 1000 lần, và nó thậm chí còn hoạt động tốt hơn trong các cài đặt có ít dữ liệu.
Cách sử dụng cơ bản
Tạo một PrefixTuningConfig với loại tác vụ và số lượng token ảo cần thêm và học.
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()Các Khởi Tạo Có Thể
Mặc định, prefix tuning sử dụng các token ảo được khởi tạo ngẫu nhiên. Ngoài ra, bạn cũng có thể khởi tạo các vector này sao cho gần với một phép toán không làm gì (khởi tạo bằng 0, nó vẫn sẽ dịch chuyển một chút khối lượng xác suất). Điều này có nghĩa là các prefix được tiêm vào KV-cache sẽ có ít tác động hơn ngay từ đầu và làm giảm phương sai trong hiệu suất huấn luyện.
PEFT cũng cung cấp các tiện ích để khởi tạo bộ thích ứng prefix-tuning từ một tiền tố KV cache hiện có (ví dụ, từ p token đầu tiên của một prompt/corpus). Tính năng này chỉ được hỗ trợ khi prefix_projection=False (mặc định), vì trong trường hợp đó, các tham số được học chính là tiền tố KV.
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,
)
Hãy đảm bảo văn bản đủ dài để tạo ra ít nhất num_virtual_tokens token, nếu không quá trình khởi tạo sẽ thất bại.
Như một hướng dẫn:
- bắt đầu với một chuỗi khởi đầu trung tính bằng cách sử dụng
initialize_kv_prefix_from_text, nó có thể là một chuỗi rất ngắn như “Question: ” - nếu điều đó không hữu ích, hãy sử dụng một chuỗi dài hơn có liên quan đến tác vụ (tức là một prompt được thiết kế kỹ thuật), cho bạn nhiều token ảo hơn để khớp nhưng cũng tăng khả năng điều hướng mô hình
- nếu không thể sử dụng văn bản khởi tạo hoặc bạn muốn kiểm tra nhanh xem prefix tuning có khả thi hay không, hãy sử dụng zero init không có projection
Tổng quan về benchmark
API
PrefixTuningConfig
lớp peft.PrefixTuningConfig
< 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 = 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 )
Tham số
- init_weights (
Optional[str]) — Nếu không được đặt, các trọng số sẽ được khởi tạo ngẫu nhiên; nếu được đặt thành “zero”, các trọng số sẽ được khởi tạo sao cho các kích hoạt sẽ là một phép toán không (zero). - encoder_hidden_size (
int) — Kích thước ẩn của bộ mã hóa prompt. - prefix_projection (
bool) — Xác định có dự chiếu các nhúng tiền tố hay không.
Đây là lớp cấu hình để lưu trữ cấu hình của PrefixEncoder.
PrefixEncoder
lớp peft.PrefixEncoder
< source >( config )
Tham số
- config (PrefixTuningConfig) — Cấu hình của bộ mã hóa prefix.
Mô hình torch.nn để mã hóa phần tiền tố.
Ví dụ:
>>> 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)Thuộc tính:
- embedding (
torch.nn.Embedding) — Lớp embedding của bộ mã hóa tiền tố. - transform (
torch.nn.Sequential) — MLP hai lớp để biến đổi các embedding tiền tố nếuprefix_projectionlàTrue. - prefix_projection (
bool) — Xác định có dự chiếu các nhúng tiền tố hay không.
Hình dạng đầu vào: (batch_size, num_virtual_tokens)
Hình dạng đầu ra: (batch_size, num_virtual_tokens, 2*layers*hidden)
Tải các embedding prompt đã được làm phẳng và lưu bởi PEFT (prompt_embeddings).
Đối với prefix tuning, tính năng này chỉ được hỗ trợ khi prefix_projection=False, vì trong trường hợp đó, các tham số được học chính là tiền tố KV (embedding.weight có hình dạng [num_virtual_tokens, num_layers*2*token_dim]).
Nếu prefix_projection=True, các tham số sẽ là (nhúng token ảo + một MLP) và không có cách tổng quát nào để đảo ngược phép chiếu nhằm khôi phục các tham số đó từ một tiền tố KV đã được làm phẳng.