PEFT documentation

PaCA: Partial Connection Adaptation

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

PaCA: Partial Connection Adaptation

PaCA (ICLR 2025) — это метод PEFT, нацеленный на скорость обучения и потребление памяти для активаций. Он дообучает r случайно выбранных входных столбцов («частичные соединения») каждого целевого предобученного веса. Единственными обучаемыми параметрами являются обновления этих столбцов; в отличие от LoRA, PaCA не добавляет дополнительных матриц низкого ранга.

Методы, такие как LoRA, добавляют небольшой низко-ранговый блок рядом с каждым предобученным слоем. Блок требует немного FLOPs, но выполняется последовательно с предобученным слоем и хранит собственную копию входных активаций для обратного прохода. PaCA избегает обоих этих недостатков:

  • Один GEMM на слой. Адаптированные столбцы записываются в предобученные веса непосредственно перед их матричным умножением и восстанавливаются сразу после него, поэтому и прямое, и обратное распространение выполняют по одному матричному умножению, точно так же, как замороженный базовый слой.
  • Частичные активации. Градиент адаптированных столбцов зависит только от соответствующих r входных каналов, поэтому для обратного прохода сохраняются только они, а не весь вход.

С точки зрения результирующих весов адаптер PaCA эквивалентен адаптеру LoRA ранга r, матрица A которого является фиксированным селектором столбцов: W' = W + delta @ S, где S выбирает r столбцов. Следовательно, его можно без потерь преобразовать в адаптер LoRA ранга r с помощью convert_to_lora(), например, для использования в стеке инференса LoRA.

Когда использовать PaCA:

  • Вы хотите достичь точности на уровне LoRA, но с более быстрыми шагами дообучения и меньшим потреблением памяти для активаций, например, чтобы обрабатывать более длинные последовательности или увеличивать размер батча на том же GPU.
  • Вам нужен адаптер, который объединяется точно с базовыми весами (обновление представляет собой обычное обновление столбца).

Текущие ограничения:

  • Поддерживаются только слои nn.Linear (включая квантованные линейные слои).
  • PaCA выполняет matmul самостоятельно, а не вызывает forward базового слоя, поэтому forward-хуки, зарегистрированные на базовом слое, не вызываются (выдаётся предупреждение). Зарегистрируйте хуки на слое PaCA.
  • Смешанные батчи адаптеров (аргумент adapter_names) не поддерживаются.
  • Обучение с разбитыми весами (FSDP, DeepSpeed ZeRO-3) пока не протестировано.
  • Поддерживается torch.compile: при компиляции операции замены столбцов, matmul и восстановления выполняются как непрозрачные пользовательские операции (torch.ops.peft.paca_linear_forward/_backward), поэтому компилятор не копирует базовые веса. Для этого требуется torch.library.custom_op (PyTorch >= 2.4); в противном случае трассируется реализация в режиме eager.
  • paca_alpha / r масштабирует обновление столбца и, следовательно, действует как множитель эффективной скорости обучения.
  • Для инференса объедините адаптер (merge_and_unload()); необъединённый forward по-прежнему будет подставлять и убирать столбцы при каждом вызове.

Использование

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()

По умолчанию каждый целевой слой дообучает r случайно выбранных столбцов; в статье показано, что этот подход работает на уровне с выбором столбцов по норме весов или по накопленным градиентам. Чтобы выбрать столбцы самостоятельно, например, чтобы попробовать другую стратегию выбора или использовать другое количество столбцов на слой, передайте paca_indices_pattern. Его ключами являются имена слоёв или регулярные выражения, как в rank_pattern 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))},
)

Слои, соответствующие ключу, дообучают указанные столбцы, все остальные целевые слои выбирают r случайных столбцов. Масштабирование равно paca_alpha / r, где r — значение из конфигурации для каждого слоя, поэтому paca_alpha имеет одинаковый смысл для всех слоёв.

Аннотация из статьи:

Алгоритмы параметрически эффективной дообучения (PEFT) снижают потребление памяти и вычислительные затраты при дообучении больших моделей нейронных сетей, обучая лишь небольшое количество дополнительных параметров адаптеров, а не всю модель целиком. Однако снижение вычислительных затрат за счёт PEFT не обязательно приводит к сокращению времени обучения; хотя вычислительные затраты адаптерных слоёв значительно меньше, чем у предобученных слоёв, хорошо известно, что эти два типа слоёв обрабатываются последовательно на GPU, что приводит к значительным накладным расходам на задержку. LoRA и его варианты избегают этой задержки, объединяя матрицы адаптеров низкого ранга с предобученными весами во время вывода. Однако эти слои нельзя объединить во время обучения, поскольку предобученные веса должны оставаться замороженными, в то время как матрицы адаптеров низкого ранга непрерывно обновляются в течение всего процесса обучения. Кроме того, LoRA и его варианты не снижают потребление памяти на активации, так как первая матрица адаптера низкого ранга по-прежнему требует входных активаций предобученных весов для вычисления градиентов весов. Для решения этой проблемы мы предлагаем Partial Connection Adaptation (PaCA), который дообучает случайно выбранные частичные соединения внутри предобученных весов, вместо введения адаптерных слоёв в модель. PaCA не только повышает скорость обучения, устраняя временные накладные расходы, связанные с последовательной обработкой адаптерных и предобученных слоёв, но и снижает потребление памяти на активации, поскольку для вычисления градиентов необходимо хранить только частичные, а не полные активации. По сравнению с LoRA, PaCA сокращает время обучения на 22% и общее потребление памяти на 16%, сохраняя при этом сопоставимую точность в различных сценариях дообучения, таких как дообучение на наборе данных MMLU и инструкционное дообучение на наборе данных Oasst1. PaCA также можно комбинировать с квантованием, что позволяет дообучать большие модели, такие как LLaMA3.1-70B. Кроме того, PaCA позволяет обучать с последовательностями на 23% длиннее и повышает пропускную способность на 16% как на GPU NVIDIA A100, так и на HPU INTEL Gaudi2 по сравнению с LoRA.

Обзор бенчмарков

API

PacaConfig

класс peft.PacaConfig

< >

( 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 )

Параметры

  • r (int, необязательный, по умолчанию 8) — Количество входных столбцов (частичных связей), которые дообучаются в каждом целевом слое. Для веса размерности (out_features, in_features) PaCA обучает r * out_features параметров, то же количество, что и у матрицы B адаптера LoRA с рангом r. Не должно превышать in_features.
  • paca_alpha (int, необязательный, по умолчанию 8) — Коэффициент масштабирования. Обновление выбранных столбцов вычисляется как paca_alpha / r * delta. Как и lora_alpha, этот параметр действует как множитель эффективной скорости обучения адаптера.
  • target_modules (Union[list[str], str], необязательный) — Список имён модулей или регулярное выражение для имён модулей, которые следует заменить на PaCA. Например, ['q_proj', 'v_proj'] или '.*decoder.*(SelfAttention|EncDecAttention).*(q|v)$'. Если указано значение 'all-linear', выбираются все линейные модули, кроме выходного слоя. Поддерживаются только слои nn.Linear.
  • exclude_modules (Union[list[str], str], необязательный) — Имена модулей, к которым не следует применять адаптер. При передаче строки выполняется сопоставление по регулярному выражению. При передаче списка строк выполняется точное совпадение или проверяется, заканчивается ли имя модуля каким-либо из переданных строк.
  • layers_to_transform (Union[list[int], int], необязательный) — Индексы слоев, которые необходимо преобразовать. Если этот аргумент указан, PEFT преобразует только те индексы слоев, которые перечислены в этом списке. Если передано одно целое число, PEFT преобразует только слой с этим индексом.
  • layers_pattern (Optional[Union[list[str], str]], необязательный) — Имя шаблона слоя, используется только в том случае, если layers_to_transform отличается от None. Этот параметр должен указывать на nn.ModuleList модели, который часто называется 'layers' или 'h'.
  • random_seed (int, необязательный, по умолчанию None) — Значение seed, используемое для выбора частичных соединений. Каждый слой использует собственный выбор, производный от этого seed и имени слоя. Если None, используется глобальный генератор случайных чисел torch. Выбранные индексы всегда сохраняются в контрольной точке адаптера, поэтому seed не требуется для загрузки обученного адаптера.
  • paca_indices_pattern (dict, необязательный) — Необязательное сопоставление имён слоёв или регулярных выражений с индексами входных столбцов, которые дообучаются в соответствующих слоях вместо случайно выбранных r, например {'^model.layers.0.self_attn.q_proj': [0, 2, 4]}. Это также позволяет использовать разное количество столбцов для каждого слоя. Индексы слоя должны быть уникальными и меньше in_features. Масштабирование составляет paca_alpha / r, где r — значение из этой конфигурации во всех слоях, независимо от количества заданных индексов. Целевые слои, не соответствующие ни одному ключу, используют r случайно выбранных столбцов.
  • init_weights (bool, необязательный, по умолчанию True) — Если True, обновление выбранных столбцов инициализируется нулями, то есть адаптированная модель идентична базовой модели на этапе инициализации. Установите False, чтобы инициализировать случайными значениями; это предназначено только для тестирования.
  • modules_to_save (list[str], необязательный) — Список модулей, помимо слоёв PaCA, которые должны быть установлены как обучаемые и сохранены в итоговой контрольной точке. Например, в задачах классификации последовательностей или классификации токенов последний слой classifier/score инициализируется случайным образом, поэтому его необходимо сделать обучаемым и сохранить.

Это класс конфигурации для хранения конфигурации модели PacaModel.

PaCA (Partial Connection Adaptation, https://huggingface.co/papers/2503.01905) выполняет дообучение r случайно выбранных входных столбцов (частичных соединений) каждого целевого предобученного веса. Единственными обучаемыми параметрами являются обновления этих столбцов; в отличие от LoRA, PaCA не добавляет дополнительных матриц низкого ранга. Непосредственно перед умножением матриц адаптированные столбцы подставляются в предобученный вес и восстанавливаются сразу после него, благодаря чему как прямой, так и обратный проход выполняют по одному GEMM, а в памяти для обратного прохода сохраняются только r выбранных входных канала.

PacaModel

класс peft.PacaModel

< >

( 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

Параметры

  • model (PreTrainedModel) — Модель, подлежащая адаптации.
  • config (PacaConfig) — конфигурация модели PaCA.
  • adapter_name (str) — имя адаптера, по умолчанию "default".
  • low_cpu_mem_usage (bool, optional, по умолчанию False) — Создаёт пустые веса адаптера на meta-устройстве. Полезно для ускорения процесса загрузки.

Возвращает

torch.nn.Module

Модель PaCA.

Создаёт модель Partial Connection Adaptation (PaCA) на основе предобученной модели. Метод описан в https://huggingface.co/papers/2503.01905.

Пример:

>>> 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)

Атрибуты:

  • model (PreTrainedModel) — Модель, подлежащая адаптации.
  • peft_config (PacaConfig): конфигурация модели PaCA.
Update on GitHub