PEFT documentation
VeRA: адаптация на основе случайных матриц
VeRA: адаптация на основе случайных матриц
VeRA — это метод эффективной по параметрам дообучения, похожий на LoRA, но требующий ещё меньшего количества дополнительных параметров при обещании сопоставимого или даже лучшего результата. Благодаря этому он особенно полезен, когда бюджет параметров крайне ограничен, например, при масштабировании на очень большие модели. Сокращение числа обучаемых параметров достигается за счёт использования одних и тех же матриц низкого ранга во всех слоях и обучения лишь двух дополнительных векторов на слой.
Как работает VeRA
LoRA обновляет замороженную базовую модель, обучая две небольшие матрицы низкого ранга для каждого адаптируемого слоя. Ранг — это внутреннее измерение этих матриц, и он определяет, сколько вычислительной мощности имеет адаптер. В LoRA увеличение r или адаптация большего числа слоёв быстро увеличивает количество обучаемых параметров, поскольку каждый адаптируемый слой обучает собственную пару матриц низкого ранга.
VeRA сохраняет ту же идею адаптации с низким рангом, но меняет набор обучаемых параметров. Вместо обучения отдельных матриц с низким рангом для каждого слоя VeRA использует одну замороженную пару матриц с низким рангом, A и B, инициализированную случайным образом и общую для всех слоёв. Каждый адаптируемый слой обучает только два вектора масштабирования, vera_lambda_d и vera_lambda_b, которые масштабируют общие матрицы, чтобы получить специфичное для слоя обновление. Поскольку размер vera_lambda_d равен r, количество обучаемых параметров в VeRA по-прежнему растёт с увеличением r и числа адаптируемых слоёв. Однако этот рост происходит значительно медленнее, чем в случае LoRA, так как большие матрицы A и B являются общими и замороженными, а не обучаются отдельно для каждого слоя.
Именно поэтому VeRA может использовать меньше обучаемых параметров, чем LoRA. В упрощённом подсчёте параметров из статьи LoRA масштабируется как 2 * L_tuned * d_model * r, где L_tuned — количество адаптируемых слоёв, d_model — размерность модели, а r — ранг. VeRA масштабируется как L_tuned * (d_model + r), поскольку большие матрицы низкого ранга разделяются и замораживаются, а обучаются только более мелкие векторы для каждого слоя.
При сохранении параметров адаптера можно отказаться от хранения матриц низкого ранга, установив save_projection=False в VeraConfig. В этом случае эти матрицы будут восстановлены на основе фиксированного случайного зерна из аргумента projection_prng_key. Это уменьшает размер контрольной точки, но мы не можем гарантировать воспроизводимость на всех устройствах и во всех будущих версиях PyTorch. Если вы хотите обеспечить воспроизводимость, установите save_projection=True (это значение по умолчанию).
Для обработки различных форм адаптируемых слоёв VeRA инициализирует общие матрицы A и B максимальным требуемым размером для каждого измерения. Во время прямого прохода подматрицы A и B для данного слоя вырезаются из этих общих матриц и используются, как описано в статье. Например, адаптация двух линейных слоёв форм (100, 20) и (80, 50) создаст матрицы A и B форм (rank, 50) и (100, rank) соответственно. Затем, чтобы адаптировать слой формы (100, 20), будут извлечены подматрицы A и B форм (rank, 20) и (100, rank).
В настоящее время VeRA имеет следующее ограничение:
- Поддерживаются только слои
nn.Linear.
Аннотация из статьи:
Метод адаптации с низким рангом (LoRA) является популярным подходом, который сокращает количество обучаемых параметров при дообучении больших языковых моделей, однако по-прежнему сталкивается с острыми проблемами хранения при масштабировании на ещё более крупные модели или при развёртывании множества адаптированных моделей для отдельных пользователей или задач. В данной работе мы представляем метод адаптации на основе векторов случайных матриц (VeRA), который значительно сокращает количество обучаемых параметров по сравнению с LoRA, сохраняя при этом тот же уровень производительности. Это достигается за счёт использования одной пары матриц с низким рангом, общей для всех слоёв, и обучения небольших масштабирующих векторов. Мы демонстрируем его эффективность на бенчмарках GLUE и E2E, задачах классификации изображений, а также показываем его применение в инструкционном дообучении языковых моделей на 7B и 13B параметров.
Когда использовать VeRA
VeRA — хороший выбор, когда:
- Вы хотите минимизировать количество обучаемых параметров, сохраняя производительность, сопоставимую с LoRA.
- Необходимо хранить или разворачивать множество адаптеров, специфичных для конкретных задач, где более мелкие контрольные точки адаптеров снижают требования к хранилищу.
- Вы дообучаете очень большие языковые модели в условиях строгих ограничений по памяти или количеству параметров.
Когда не следует использовать VeRA
VeRA может не быть лучшим выбором, когда:
- Для каждого адаптируемого слоя требуются независимые матрицы низкого ранга, что обеспечивает большую гибкость в обучаемых параметрах адаптеров.
- Ваша модель требует адаптации типов модулей, отличных от
nn.Linear, поскольку VeRA в настоящее время поддерживает только линейные слои. - Ваша модель содержит адаптированные линейные слои с сильно различающимися размерами входных и выходных данных. Поскольку VeRA использует одну пару матриц проекции для всех адаптированных слоёв, эти матрицы должны быть рассчитаны под максимальную форму. Модели с большим разбросом форм слоёв (например, слои ап- и даун-проекций в трансформере) могут, следовательно, требовать избыточного выделения памяти для общих матриц проекции, что снижает часть преимущества VeRA в эффективности параметров.
Обзор бенчмарков
API
VeRAConfig
класс peft.VeraConfig
< 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 = 256target_modules: Optional[Union[list[str], str]] = Noneprojection_prng_key: int = 0save_projection: bool = Truevera_dropout: float = 0.0d_initial: float = 0.1fan_in_fan_out: bool = Falsebias: str = 'none'modules_to_save: Optional[list[str]] = Noneinit_weights: bool = Truelayers_to_transform: Optional[Union[list[int], int]] = Nonelayers_pattern: Optional[Union[list[str], str]] = None )
Параметры
- r (
int, необязательный, по умолчанию256) — размерность параметра VeRA («ранг»). Здесь следует выбирать значения выше, чем ранги LoRA, поскольку VeRA использует значительно меньше параметров, чем LoRA (см. Таблицу 1). - target_modules (
Union[List[str], str]) — Имена модулей, к которым применяется Vera. Поддерживаются только линейные слои. - projection_prng_key (
int) — Ключ инициализации Vera PRNG. Используется для инициализации vera_A и vera_B для новых моделей или при загрузке контрольной точки, в которую эти проекции не были включены. По умолчанию0. - save_projection (
bool) — Сохранять ли проекции vera_A / vera_B в state dict вместе с весами lambda_b / lambda_d для каждого слоя. Это увеличит размер контрольной точки, но гарантирует возможность перезагрузки контрольной точки на всех конфигурациях системы. По умолчаниюTrue. - vera_dropout (
float) — Вероятность dropout для слоёв Vera. - d_initial (
float, необязательный, по умолчанию0.1) — Начальное значение для вектораvera_lambda_d, используемое при инициализации параметров VeRA. Рекомендуется использовать малые значения (<=0.1) (см. таблицу 6c в статье). - fan_in_fan_out (
bool) — Установите это значение в True, если заменяемый слой хранит веса в формате (fan_in, fan_out). Например, gpt-2 используетConv1D, который хранит веса в формате (fan_in, fan_out), поэтому это значение должно быть установлено вTrue. - bias (
str) — Тип смещения для Vera. Может принимать значения ‘none’, ‘all’ или ‘vera_only’. Если указано ‘all’ или ‘vera_only’, соответствующие смещения будут обновляться в процессе обучения. Обратите внимание, что это означает: даже при отключении адаптеров модель не будет выдавать тот же результат, что и базовая модель без адаптации. - modules_to_save (
List[str]) — Список модулей, помимо слоёв Vera, которые должны быть установлены как обучаемые и сохранены в итоговой контрольной точке. - init_weights (
bool) — Определяет, следует ли инициализировать веса слоёв Vera с использованием их начальной инициализации по умолчанию. Не изменяйте этот параметр, если вы точно не знаете, что делаете. - layers_to_transform (
Union[List[int],int]) — Индексы слоев для преобразования. Если этот аргумент указан, преобразования Vera применяются к слоям с индексами, указанными в этом списке. Если передано одно целое число, преобразования Vera применяются к слою с этим индексом. - layers_pattern (
Optional[Union[List[str], str]]) — Имя шаблона слоя, используется только в том случае, еслиlayers_to_transformотличается отNone. Этот параметр должен указывать наnn.ModuleListмодели, который часто называется'layers'или'h'.
Это класс конфигурации для хранения конфигурации модели VeraModel.
VeRAModel
класс peft.VeraModel
< 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
Параметры
- model (PreTrainedModel) — Модель, подлежащая адаптации.
- config (VeraConfig) — конфигурация модели Vera.
- adapter_name (
str) — имя адаптера, по умолчанию"default". - low_cpu_mem_usage (
bool,optional, по умолчаниюFalse) — Создаёт пустые веса адаптера на meta-устройстве. Полезно для ускорения процесса загрузки.
Возвращает
torch.nn.Module
Модель Vera.
Создаёт модель Vector-based Random Matrix Adaptation (Vera) на основе предобученной модели transformers.
Пример:
>>> from transformers import AutoModelForCausalLM
>>> from peft import VeraConfig, get_peft_model
>>> base_model = AutoModelForCausalLM.from_pretrained("facebook/opt-125m")
>>> config = VeraConfig(r=128)
>>> model = get_peft_model(base_model, config)Атрибуты:
- model (PreTrainedModel) — Модель, подлежащая адаптации.
- peft_config (VeraConfig): конфигурация модели Vera.