PEFT documentation

Lily: Thích ứng liên kết bậc thấp giữa các lớp

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

Lily: Thích ứng liên kết bậc thấp giữa các lớp

Lily là một kỹ thuật tinh chỉnh hiệu quả về tham số, đưa vào việc chia sẻ trọng số giữa các lớp cho các ma trận adapter. Thay vì học một cặp AB độc lập cho mỗi lớp như trong LoRA, Lily sử dụng các adapter A chia sẻ cục bộ (mỗi A được chia sẻ qua một khối gồm stride_A lớp liên tiếp) và các chuyên gia B chia sẻ toàn cục (một nhóm nhỏ gồm num_B adapter B được chia sẻ cho tất cả các lớp). Tại mỗi lần truyền tiến, một bộ định tuyến phụ thuộc vào dữ liệu, nhẹ nhàng, sẽ tính toán tổ hợp có trọng số softmax của các chuyên gia B để tạo ra B hiệu dụng cho lớp và đầu vào đó.

Việc chia sẻ này có thể giảm tổng số ma trận adapter từ 2N (LoRA tiêu chuẩn) xuống còn N / stride_A + num_B, giải phóng ngân sách tham số để sử dụng rank r lớn hơn nhiều — thường là 2×–4× so với rank bạn sẽ dùng trong LoRA. Rank cao hơn và khả năng kết nối chéo tốt hơn làm tăng rank hiệu dụng của bản cập nhật trọng số ΔW = A × combined_B, dẫn đến hiệu suất thích ứng tốt hơn.

Vì tổ hợp B là phụ thuộc vào dữ liệu (trọng số của router phụ thuộc vào kích hoạt đầu vào tại thời điểm chạy), merge và unmerge không được hỗ trợ. Nếu việc gộp trọng số là cần thiết cho triển khai của bạn, hãy cân nhắc các phương pháp khác như LoRA.

Hiện tại, Lily có các ràng buộc bổ sung sau:

  • Chỉ hỗ trợ các lớp nn.Linear.
  • Các lớp lượng tử hóa không được hỗ trợ.

Nếu các ràng buộc này không phù hợp với trường hợp sử dụng của bạn, hãy cân nhắc các phương pháp khác.

Tóm tắt từ bài báo là:

Phương pháp thích ứng bậc thấp (LoRA) là một phương pháp tinh chỉnh hiệu quả tham số (PEFT) được sử dụng rộng rãi, học các cập nhật trọng số ΔW = AB cho các trọng số W được huấn luyện trước thông qua các bộ thích ứng bậc thấp A và B. Trong khi LoRA đảm bảo hiệu quả phần cứng, các cập nhật trọng số bậc thấp của nó lại giới hạn hiệu suất thích ứng. Trong bài báo này, chúng tôi đề xuất thích ứng bậc thấp liên kết giữa các lớp (Lily), một phương pháp PEFT mới giới thiệu một khung liên kết với các chuyên gia A được chia sẻ cục bộ và các chuyên gia B được chia sẻ toàn cục. Cấu trúc này loại bỏ các cặp AB theo lớp dư thừa, cho phép ΔW có bậc cao hơn với số tham số bằng hoặc ít hơn. Để tăng cường khả năng biểu đạt, chúng tôi sử dụng các bộ định tuyến phụ thuộc vào dữ liệu để xác định các liên kết A-B, ngăn các chuyên gia B hội tụ về cùng một hành vi và cải thiện sức mạnh biểu diễn trên các miền khác nhau. Các thí nghiệm trên nhiều chế độ, kiến trúc và kích thước mô hình chứng minh hiệu suất và hiệu quả vượt trội của Lily.

Tổng quan về benchmark

API

LilyConfig

lớp peft.LilyConfig

< >

( 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 = 32stride_A: int = 1num_B: int = 2scaling: float = 1.0target_modules: Optional[Union[list[str], str]] = Noneexclude_modules: Optional[Union[list[str], str]] = Nonemodules_to_save: Optional[list[str]] = Nonelayers_to_transform: Optional[Union[list[int], int]] = Nonelayers_pattern: Optional[Union[list[str], str]] = Noneinit_weights: bool = True )

Tham số

  • r (int) — Hạng của Lily. Xác định chiều ẩn bên trong của mỗi adapter và hạng của bản cập nhật trọng số A @ B. Trong Lily, vì số lượng adapter thường nhỏ hơn so với LoRA, mỗi adapter cần mang nhiều sức chứa hơn, do đó khuyến nghị sử dụng r lớn hơn so với LoRA — thường là 2x, 3x hoặc 4x so với hạng LoRA mà bạn thường dùng. Tổng số tham số có thể huấn luyện tỷ lệ với r * (total_layers / stride_A + num_B), vì vậy việc tăng r trong khi giữ stride_A lớn và num_B nhỏ là sự đánh đổi được khuyến nghị.
  • stride_A (int) — Số lượng các lớp liên tiếp chia sẻ chung một adapter A. Ví dụ, nếu stride_A=4, mỗi 4 lớp kề nhau chia sẻ cùng một adapter A, dẫn đến total_layers / stride_A adapter A khác biệt tính chung. Adapter A nén đầu vào thành một biểu diễn hạng thấp có kích thước r. stride_A không được nhỏ hơn
    1. Suggested values: 2, 3, or 4 (i.e. sharing every 2, 3, or 4 layers). Keeping stride_A large (fewer distinct A adapters) and increasing r instead leads to better performance than the opposite trade-off (small stride_A, small r). Setting stride_A=1 means every layer has its own A adapter. NOTE: the A sharing happens within each target (layers with the same target suffix). For example, if your target_modules are ['q_proj', 'v_proj'] and you set stride_A=2, then every 2 adjacent q_proj layers will share an A adapter, and every 2 adjacent v_proj layers will share another A adapter, but the q_proj and v_proj layers will not share A adapters with each other since they have different suffixes.
  • num_B (int) — Số lượng adapter B dùng chung. Khác với adapter A (được nhóm theo từng lớp), tất cả các adapter B đều được dùng chung toàn cục trên mọi lớp. Với mỗi lần truyền tiến, một router sẽ tính tổ hợp có trọng số của tất cả num_B adapter B (sử dụng trọng số được chuẩn hóa bằng softmax) để tạo ra một adapter B kết hợp duy nhất, sau đó chiếu biểu diễn hạng thấp trở lại chiều gốc. Khuyến nghị đặt num_B ở cùng bậc với total_layers / stride_A. Các giá trị gợi ý: total_layers / 2, total_layers / 3, hoặc total_layers / 4. Tương tự như stride_A, nên ưu tiên num_B nhỏ hơn với r lớn hơn thay vì num_B lớn hơn với r nhỏ hơn. LƯU Ý: để huấn luyện router, bạn cần ít nhất 2 adapter B (tức là num_B >= 2), vì router học cách tính tổ hợp có trọng số của các adapter B. LƯU Ý: việc dùng chung B diễn ra trong mỗi target (các lớp có cùng hậu tố target). Ví dụ, nếu target_modules của bạn là ['q_proj', 'v_proj'] và bạn đặt num_B=4, thì sẽ có 4 adapter B dùng chung trên tất cả các lớp q_proj, và 4 adapter B khác dùng chung trên tất cả các lớp v_proj, nhưng các lớp q_proj và v_proj sẽ không dùng chung adapter B với nhau vì chúng có hậu tố khác nhau.
  • target_modules (Union[List[str], str], tùy chọn) — Tên của các module cần áp dụng Lily. Có thể là một danh sách các chuỗi tên module (ví dụ: ['q_proj', 'v_proj']) hoặc một mẫu regex (ví dụ: '.*decoder.*(SelfAttention|EncDecAttention).*(q|v)$'). Nếu không được chỉ định, Lily sẽ được áp dụng cho tất cả các lớp tuyến tính được hỗ trợ.
  • scaling (float) — Hệ số nhân vô hướng được áp dụng cho đầu ra kết hợp của adapter (scaling * A @ combined_B) trước khi cộng vào quá trình truyền thẳng của trọng số đóng băng. Khác với LoRA, Lily không sử dụng công thức alpha / r; thay vào đó, scaling là một hệ số nhân trực tiếp. Thiết kế này giúp việc quét các giá trị trên thang log trở nên đơn giản (ví dụ 0.01, 0.1, 1.0, 10.0). Giá trị tối ưu phụ thuộc vào tác vụ và nên được coi là một siêu tham số. Chúng tôi khuyến nghị bắt đầu với 1.0.
  • modules_to_save (List[str], tùy chọn) — Danh sách các module ngoài các lớp Lily 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ùng classifier/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.
  • 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 tham 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]], tùy chọn) — Tên của mẫu lớp, chỉ được sử dụng nếu layers_to_transform khác None và nếu mẫu lớp không nằm trong các mẫu lớp phổ biến. Tham số này nên nhắm đến nn.ModuleList của mô hình, thường được gọi là 'layers' hoặc 'h'.
  • init_weights (bool) — Có nên khởi tạo trọng số của bộ thích ứng Lily theo phương thức khởi tạo mặc định hay không: các ma trận A được khởi tạo bằng Kaiming uniform, và các ma trận B được khởi tạo bằng số không, đảm bảo rằng đầu ra của bộ thích ứng bằng không tại thời điểm bắt đầu huấn luyện và không gây nhiễu cho mô hình đã được huấn luyện trước. Rất khuyến nghị giữ giá trị này là True trừ khi bạn có lý do cụ thể để thay đổi.

Đây là lớp cấu hình để lưu trữ cấu hình của một LilyModel.

LilyModel

lớp peft.LilyModel

< >

( 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 (torch.nn.Module) — Mô hình cần được thích ứng.
  • config (LilyConfig) — Cấu hình của mô hình Lily.
  • adapter_name (str) — Tên của adapter, mặc định là "default".

Trả về

torch.nn.Module

Mô hình PEFT của Lily.

Tạo một mô hình Low-Rank Interconnected Adaptation Across Layers (Lily) từ một mô hình transformers được huấn luyện trước.

Phương pháp này được mô tả chi tiết tại https://arxiv.org/abs/2407.09946.

Thuộc tính:

  • model (PreTrainedModel) — Mô hình cần được thích ứng.
  • peft_config (LilyConfig): Cấu hình của mô hình Lily.
Update on GitHub