PEFT documentation
PaCA: Thích ứng kết nối một phần
PaCA: Thích ứng kết nối một phần
PaCA (ICLR 2025) là một phương pháp PEFT nhắm vào tốc độ huấn luyện và bộ nhớ kích hoạt. Nó tinh chỉnh r cột đầu vào được chọn ngẫu nhiên (“các kết nối một phần”) của mỗi trọng số tiền huấn luyện được nhắm tới. Các tham số có thể huấn luyện duy nhất là các bản cập nhật của những cột này; khác với LoRA, PaCA không thêm bất kỳ ma trận hạng thấp bổ sung nào.
Các phương pháp như LoRA chạy một nhánh hạng thấp nhỏ bên cạnh mỗi lớp được huấn luyện trước. Nhánh này cần ít FLOPs, nhưng nó được thực thi tuần tự với lớp được huấn luyện trước và giữ một bản sao riêng của kích hoạt đầu vào cho bước truyền ngược. PaCA tránh được cả hai:
- Mỗi lớp một GEMM. Các cột đã được điều chỉnh được ghi đè lên trọng số được huấn luyện trước ngay trước phép nhân ma trận của nó và được khôi phục ngay sau đó, do đó cả tiến trình thuận và tiến trình nghịch đều chỉ thực hiện một phép nhân ma trận duy nhất, giống hệt như lớp cơ bản đã được đóng băng.
- Kích hoạt một phần. Gradient của các cột đã thích ứng chỉ phụ thuộc vào
rkênh đầu vào tương ứng, do đó chỉ những kênh này được lưu cho bước truyền ngược thay vì toàn bộ đầu vào.
Về mặt trọng số kết quả, một adapter PaCA tương đương với một adapter LoRA có rank r mà ma trận A của nó là một bộ chọn cột cố định: W' = W + delta @ S, trong đó S chọn r cột. Do đó, nó có thể được chuyển đổi thành một adapter LoRA có rank r mà không mất mát thông qua convert_to_lora(), ví dụ để triển khai nó với một stack suy luận LoRA.
Khi nào nên sử dụng PaCA:
- Bạn muốn độ chính xác ở mức LoRA nhưng các bước fine-tuning nhanh hơn và bộ nhớ kích hoạt thấp hơn, ví dụ để chạy các chuỗi dài hơn hoặc các batch lớn hơn trên cùng một GPU.
- Bạn cần một adapter gộp chính xác vào trọng lượng cơ sở (cập nhật là một cập nhật cột đơn thuần).
Các ràng buộc hiện tại:
- Chỉ các lớp
nn.Linear(bao gồm cả các lớp tuyến tính đã lượng tử hóa) được hỗ trợ. - PaCA tự thực hiện phép nhân ma trận thay vì gọi
forwardcủa lớp cơ bản, do đó các forward hook được đăng ký trên lớp cơ bản sẽ không được gọi (một cảnh báo sẽ được phát ra). Hãy đăng ký hook trên lớp PaCA thay vào đó. - Các lô adapter hỗn hợp (tham số
adapter_names) không được hỗ trợ. - Việc huấn luyện với trọng số phân mảnh (FSDP, DeepSpeed ZeRO-3) vẫn chưa được kiểm tra.
torch.compileđược hỗ trợ: trong quá trình biên dịch, các thao tác hoán đổi cột, matmul và khôi phục được thực thi dưới dạng các op tùy chỉnh không trong suốt (torch.ops.peft.paca_linear_forward/_backward), do đó trình biên dịch không sao chép trọng số cơ sở. Điều này yêu cầutorch.library.custom_op(PyTorch >= 2.4); nếu không, cài đặt eager sẽ được trace.paca_alpha / rđiều chỉnh bước cập nhật cột và do đó đóng vai trò là hệ số nhân của tốc độ học hiệu dụng.- Để suy luận, hãy hợp nhất adapter (
merge_and_unload()); forward chưa hợp nhất vẫn sẽ hoán đổi các cột vào và ra ở mỗi lần gọi.
Cách sử dụng
from transformers import AutoModelForCausalLM
from peft import PacaConfig, get_peft_model
model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-3.2-3B")
config = PacaConfig(r=16, paca_alpha=16, target_modules="all-linear", random_seed=0)
model = get_peft_model(model, config)
model.print_trainable_parameters()Mặc định, mỗi lớp được nhắm đến sẽ tinh chỉnh r cột được chọn ngẫu nhiên; trong bài báo, cách này cho kết quả tương đương với việc chọn cột theo chuẩn trọng số hoặc theo gradient tích lũy. Để tự chọn các cột, chẳng hạn để thử một chiến lược chọn khác hoặc sử dụng một số lượng cột khác nhau cho mỗi lớp, hãy truyền paca_indices_pattern. Các khóa của nó là tên lớp hoặc biểu thức chính quy, giống như rank_pattern của LoRA:
config = PacaConfig(
r=16,
paca_alpha=16,
target_modules=["q_proj", "v_proj"],
paca_indices_pattern={"layers.0.self_attn.q_proj": [0, 2, 4, 6], "layers.1.self_attn.v_proj": list(range(32))},
)Các lớp khớp với một khóa sẽ tinh chỉnh các cột được chỉ định, trong khi tất cả các lớp mục tiêu khác sẽ chọn r cột ngẫu nhiên. Hệ số tỷ lệ là paca_alpha / r với r của cấu hình trong mỗi lớp, do đó paca_alpha có ý nghĩa giống nhau cho tất cả các lớp.
Tóm tắt từ bài báo là:
Các thuật toán tinh chỉnh hiệu quả tham số (PEFT) trước đây giảm thiểu lượng bộ nhớ sử dụng và chi phí tính toán khi tinh chỉnh các mô hình mạng nơ-ron lớn bằng cách chỉ huấn luyện một vài tham số adapter bổ sung, thay vì toàn bộ mô hình. Tuy nhiên, việc giảm chi phí tính toán nhờ PEFT không nhất thiết dẫn đến việc giảm thời gian huấn luyện; mặc dù chi phí tính toán của các lớp adapter nhỏ hơn nhiều so với các lớp được huấn luyện trước, nhưng đã được biết rộng rãi rằng hai loại lớp này được xử lý tuần tự trên GPU, dẫn đến độ trễ đáng kể. LoRA và các biến thể của nó tránh được độ trễ này bằng cách gộp các ma trận adapter hạng thấp với trọng số được huấn luyện trước trong quá trình suy luận. Tuy nhiên, các lớp này không thể được gộp trong quá trình huấn luyện vì trọng số được huấn luyện trước phải được giữ nguyên trong khi các ma trận adapter hạng thấp được cập nhật liên tục trong suốt quá trình huấn luyện. Hơn nữa, LoRA và các biến thể của nó không giảm bộ nhớ kích hoạt, vì ma trận adapter hạng thấp đầu tiên vẫn cần các kích hoạt đầu vào của trọng số được huấn luyện trước để tính toán gradient trọng số. Để giảm thiểu vấn đề này, chúng tôi đề xuất Thích ứng Kết nối Một phần (PaCA), tinh chỉnh các kết nối một phần được chọn ngẫu nhiên bên trong trọng số được huấn luyện trước thay vì đưa các lớp adapter vào mô hình. PaCA không chỉ tăng tốc độ huấn luyện bằng cách loại bỏ độ trễ thời gian do xử lý tuần tự của các lớp adapter và lớp được huấn luyện trước, mà còn giảm bộ nhớ kích hoạt vì chỉ cần lưu trữ các kích hoạt một phần, thay vì toàn bộ kích hoạt, để tính toán gradient. So với LoRA, PaCA giảm thời gian huấn luyện 22% và tổng lượng bộ nhớ sử dụng 16%, trong khi duy trì độ chính xác tương đương trong các kịch bản tinh chỉnh khác nhau, chẳng hạn như tinh chỉnh trên bộ dữ liệu MMLU và tinh chỉnh chỉ thị trên bộ dữ liệu Oasst1. PaCA cũng có thể kết hợp với lượng tử hóa, cho phép tinh chỉnh các mô hình lớn như LLaMA3.1-70B. Ngoài ra, PaCA cho phép huấn luyện với độ dài chuỗi dài hơn 23% và cải thiện thông lượng 16% trên cả GPU NVIDIA A100 và HPU INTEL Gaudi2 so với LoRA.
Tổng quan về benchmark
API
PacaConfig
lớp peft.PacaConfig
< 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 = 8paca_alpha: int = 8target_modules: list[str] | str | None = Noneexclude_modules: list[str] | str | None = Nonelayers_to_transform: list[int] | int | None = Nonelayers_pattern: list[str] | str | None = Nonerandom_seed: int | None = Nonepaca_indices_pattern: dict | None = <factory>init_weights: bool = Truemodules_to_save: list[str] | None = None )
Tham số
- r (
int, tuỳ chọn, mặc định là8) — Số lượng cột đầu vào (kết nối một phần) được tinh chỉnh trong mỗi lớp được nhắm tới. Đối với trọng số có hình dạng(out_features, in_features), PaCA huấn luyệnr * out_featurestham số, cùng số lượng với ma trậnBcủa bộ thích ứng LoRA có bậcr. Không được vượt quáin_features. - paca_alpha (
int, tùy chọn, mặc định là8) — Hệ số tỷ lệ. Bản cập nhật của các cột được chọn làpaca_alpha / r * delta. Giống nhưlora_alpha, tham số này đóng vai trò là hệ số nhân của tốc độ học hiệu dụng của adapter. - target_modules (
Union[list[str], str], tùy chọn) — Danh sách tên module hoặc biểu thức regex của các tên module cần thay thế bằng PaCA. Ví dụ,['q_proj', 'v_proj']hoặc'.*decoder.*(SelfAttention|EncDecAttention).*(q|v)$'. Nếu được chỉ định là'all-linear', tất cả các module linear ngoại trừ lớp output sẽ được chọn. Chỉ hỗ trợ các lớpnn.Linear. - exclude_modules (
Union[list[str], str], tùy chọn) — Tên của các module không áp dụng adapter. Khi truyền một chuỗi, một phép khớp regex sẽ được thực hiện. Khi truyền một danh sách các chuỗi, một phép khớp chính xác sẽ được thực hiện hoặc kiểm tra xem tên của module có kết thúc bằng bất kỳ chuỗi nào được truyền vào hay không. - layers_to_transform (
Union[list[int], int], tùy chọn) — Các chỉ số lớp cần biến đổi. Nếu đối số này được chỉ định, PEFT sẽ chỉ biến đổi các chỉ số lớp được liệt kê trong danh sách này. Nếu một số nguyên duy nhất được truyền vào, PEFT sẽ chỉ biến đổi lớp tại chỉ số đó. - layers_pattern (
Optional[Union[list[str], str]], tuỳ chọn) — Tên mẫu lớp, chỉ được sử dụng nếulayers_to_transformkhácNone. Giá trị này nên nhắm đếnnn.ModuleListcủa mô hình, thường được gọi là'layers'hoặc'h'. - random_seed (
int, tùy chọn, mặc định làNone) — Seed được dùng để chọn các kết nối một phần. Mỗi lớp sử dụng một lựa chọn khác nhau được suy ra từ seed này và tên của lớp. NếuNone, bộ tạo số ngẫu nhiên toàn cục của torch sẽ được sử dụng. Các chỉ số được chọn luôn được lưu trong checkpoint của adapter, do đó seed không cần thiết để tải một adapter đã được huấn luyện. - paca_indices_pattern (
dict, tùy chọn) — Bản ánh xạ tùy chọn từ tên lớp hoặc biểu thức chính quy đến các chỉ số cột đầu vào được tinh chỉnh trong các lớp khớp thay vìrcột được chọn ngẫu nhiên, ví dụ{'^model.layers.0.self_attn.q_proj': [0, 2, 4]}. Điều này cũng cho phép số lượng cột khác nhau cho mỗi lớp. Các chỉ số của một lớp phải duy nhất và nhỏ hơnin_features. Hệ số tỷ lệ làpaca_alpha / rvớircủa cấu hình này trong tất cả các lớp, độc lập với số lượng chỉ số được cung cấp. Các lớp đích không khớp với bất kỳ khóa nào sẽ sử dụngrcột được chọn ngẫu nhiên. - init_weights (
bool, tùy chọn, mặc định làTrue) — NếuTrue, việc cập nhật các cột được chọn sẽ được khởi tạo bằng 0, tức là mô hình đã thích ứng giống hệt với mô hình gốc tại thời điểm khởi tạo. Đặt thànhFalseđể khởi tạo bằng các giá trị ngẫu nhiên; điều này chỉ dành cho mục đích kiểm thử. - modules_to_save (
list[str], tùy chọn) — Danh sách các module ngoài các lớp PaCA cần được đặt là có thể huấn luyện và lưu trong checkpoint cuối cùng. Ví dụ, trong các tác vụ Phân loại Chuỗi hoặc Phân loại Token, lớp cuối cùngclassifier/scoređược khởi tạo ngẫu nhiên và do đó cần phải có thể huấn luyện và được lưu lại.
Đây là lớp cấu hình để lưu trữ cấu hình của một PacaModel.
PaCA (Partial Connection Adaptation, https://huggingface.co/papers/2503.01905) tinh chỉnh r cột đầu vào được chọn ngẫu nhiên (các kết nối một phần) của mỗi trọng số tiền huấn luyện được nhắm tới. Các tham số có thể huấn luyện duy nhất là các bản cập nhật của những cột này; khác với LoRA, PaCA không thêm bất kỳ ma trận hạng thấp bổ sung nào. Ngay trước phép nhân ma trận, các cột đã thích ứng được thay thế vào trọng số tiền huấn luyện và được khôi phục ngay sau đó, do đó cả tiến trình thuận và nghịch đều chỉ thực hiện một GEMM duy nhất, và chỉ có r kênh đầu vào được chọn là được giữ trong bộ nhớ cho bước nghịch.
PacaModel
lớp peft.PacaModel
< 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
Tham số
- model (PreTrainedModel) — Mô hình cần được thích ứng.
- config (PacaConfig) — Cấu hình của mô hình PaCA.
- adapter_name (
str) — Tên của adapter, mặc định là"default". - low_cpu_mem_usage (
bool,optional, mặc định làFalse) — Tạo trọng số adapter rỗng trên thiết bị meta. Hữu ích để tăng tốc quá trình tải.
Trả về
torch.nn.Module
Mô hình PaCA.
Tạo mô hình Thích ứng Kết nối Một phần (PaCA) từ một mô hình được huấn luyện trước. Phương pháp này được mô tả tại https://huggingface.co/papers/2503.01905.
Ví dụ:
>>> from transformers import AutoModelForCausalLM
>>> from peft import PacaConfig, get_peft_model
>>> base_model = AutoModelForCausalLM.from_pretrained("facebook/opt-125m")
>>> config = PacaConfig(r=16, paca_alpha=16, target_modules="all-linear")
>>> model = get_peft_model(base_model, config)Thuộc tính:
- model (PreTrainedModel) — Mô hình cần được thích ứng.
- peft_config (PacaConfig): Cấu hình của mô hình PaCA.