PEFT documentation
LoHa
LoHa

Метод низкорангового произведения Хадама (LoHa) похож на LoRA, за исключением того, что он аппроксимирует большую матрицу весов с помощью большего количества низкоранговых матриц и комбинирует их с использованием произведения Хадама. Этот метод ещё более параметрически эффективен, чем LoRA, и обеспечивает сопоставимую производительность. LoHa был изначально предложен для федеративного обучения (FedPara), но хорошо работает как универсальный метод PEFT и особенно популярен для дообучения моделей генерации изображений, таких как Stable Diffusion.
Примечание: LoHa входит в семейство адаптеров LyCORIS. Его близкий родственник LoKr использует произведение Кронекера вместо произведения Хадамарда.
Аннотация из статьи:
В данной работе мы предлагаем коммуникационно-эффективную параметризацию FedPara для федеративного обучения (FL), позволяющую снизить нагрузку, связанную с частыми загрузками и выгрузками моделей. Наш метод переопределяет весовые параметры слоёв с использованием весов низкого ранга, за которыми следует произведение Хадамарда. В отличие от традиционной параметризации низкого ранга, наш метод FedPara не ограничен условиями низкого ранга, что обеспечивает значительно большую ёмкость модели. Это свойство позволяет достичь сопоставимого качества при снижении затрат на коммуникацию в 3–10 раз по сравнению с моделью, использующей исходные слои, чего невозможно добиться с помощью классических методов низкого ранга. Эффективность нашего метода можно дополнительно повысить за счёт его сочетания с другими эффективными оптимизаторами FL. Кроме того, мы расширяем наш метод на применение в персонализированном федеративном обучении, pFedPara, который разделяет параметры на глобальные и локальные. Мы показываем, что pFedPara превосходит конкурирующие методы персонализированного FL, используя более чем в три раза меньше параметров.
Разложение низкого ранга может влиять на производительность, поскольку обновления весов ограничены пространством низкого ранга, что может сужать выразительность модели. Однако не всегда целесообразно использовать более высокий ранг, так как это увеличивает количество обучаемых параметров. Для решения этой проблемы LoHa был применён к диффузионным моделям, где способность генерировать разнообразные изображения является важным фактором. LoHa также должен работать с общими типами моделей, но поддержка слоёв встраиваний (embedding layers) в настоящее время не реализована в PEFT.
LoHa использует произведение Хадамада (посимвольное произведение) вместо матричного произведения. представляется четырьмя меньшими матрицами вместо двух — как в LoRA — и каждая пара этих матриц низкого ранга объединяется с помощью произведения Хадамада. В результате может иметь то же количество обучаемых параметров, но более высокий ранг и выразительность.
Когда использовать LoHa
LoHa — хороший выбор, когда:
- Вы дообучаете модели генерации изображений (UNet Stable Diffusion или текстовый энкодер), где это применение наиболее распространено.
- Вы хотите получить более высокий эффективный ранг, чем у LoRA, при том же количестве обучаемых параметров, поскольку гадардовское произведение двух матриц низкого ранга охватывает подпространство большего размера, чем одно произведение низкого ранга.
- Вы хотите комбинировать различные методы PEFT на этапе инференса с помощью
PeftMixedModel, например, LoHa вместе с LoKr.
LoHa поддерживает линейные слои и слои Conv2d. Для задач, в которых дополнительно требуется адаптация слоя встраивания, рассмотрите использование LoRA.
Использование
from diffusers import StableDiffusionPipeline
from peft import LoHaConfig, get_peft_model
config_unet = LoHaConfig(
r=8,
alpha=8,
target_modules=[
"to_k",
"to_q",
"to_v",
"to_out.0",
"proj_in",
"proj_out",
],
rank_dropout=0.0,
module_dropout=0.0,
use_effective_conv2d=True,
)
pipeline = StableDiffusionPipeline.from_pretrained("runwayml/stable-diffusion-v1-5")
pipeline.unet = get_peft_model(pipeline.unet, config_unet)
pipeline.unet.print_healthcheck()Обзор бенчмарков
API
LoHaConfig
класс peft.LoHaConfig
< 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 = Falserank_pattern: Optional[dict] = <factory>alpha_pattern: Optional[dict] = <factory>r: int = 8alpha: int = 8rank_dropout: float = 0.0module_dropout: float = 0.0use_effective_conv2d: bool = Falsetarget_modules: Optional[Union[list[str], str]] = Noneexclude_modules: Optional[Union[list[str], str]] = Noneinit_weights: bool = Truelayers_to_transform: Optional[Union[list[int], int]] = Nonelayers_pattern: Optional[Union[list[str], str]] = Nonemodules_to_save: Optional[list[str]] = None )
Параметры
- r (
int) — ранг LoHa. - alpha (
int) — Параметр alpha для масштабирования LoHa. - rank_dropout (
float) — Вероятность dropout для размерности rank во время обучения. - module_dropout (
float) — Вероятность dropout для отключения модулей LoHa во время обучения. - use_effective_conv2d (
bool) — Использовать параметр effective decomposition для Conv2d (и Conv1d) с ksize > 1 («Proposition 3» из статьи FedPara). - target_modules (
Optional[Union[List[str], str]]) — Имена модулей, к которым следует применить адаптер. Если это значение указано, будут заменены только модули с указанными именами. При передаче строки выполняется сопоставление по регулярному выражению. При передаче списка строк выполняется точное совпадение или проверяется, заканчивается ли имя модуля каким-либо из переданных строк. Если это значение указано как ‘all-linear’, выбираются все линейные/Conv1D модули, за исключением выходного слоя. Если это значение не указано, модули выбираются в соответствии с архитектурой модели. Если архитектура неизвестна, будет выброшена ошибка — в этом случае следует указать целевые модули вручную. - exclude_modules (
Optional[Union[List[str], str]]) — Имена модулей, к которым не следует применять адаптер. При передаче строки выполняется сопоставление по регулярному выражению. При передаче списка строк выполняется точное совпадение или проверяется, заканчивается ли имя модуля каким-либо из переданных строк. - init_weights (
bool) — Определяет, следует ли выполнять инициализацию весов адаптера. По умолчанию установлено значениеTrue; передачаFalseне рекомендуется. - layers_to_transform (
Union[List[int], int]) — Индексы слоёв, подлежащих трансформации. Если передан список целых чисел, адаптер будет применён к слоям с индексами, указанными в этом списке. Если передано одно целое число, трансформации будут применены к слою с этим индексом. - layers_pattern (
Optional[Union[List[str], str]]) — Имя шаблона слоя, используется только в том случае, еслиlayers_to_transformотличается отNone. Этот параметр должен указывать наnn.ModuleListмодели, который часто называется'layers'или'h'. - rank_pattern (
dict) — Соответствие между именами слоёв или регулярными выражениями и рангами, отличными от ранга по умолчанию, заданного параметромr. Например,{'^model.decoder.layers.0.encoder_attn.k_proj': 16}. - alpha_pattern (
dict) — Соответствие между именами слоёв или регулярными выражениями и значениями alpha, отличными от значения alpha по умолчанию, заданного параметромalpha. Например,{'^model.decoder.layers.0.encoder_attn.k_proj': 16}. - modules_to_save (
Optional[List[str]]) — Список модулей, помимо адаптерных слоёв, которые нужно сделать обучаемыми и сохранить в итоговой контрольной точке.
Это класс конфигурации для хранения конфигурации модели LoHaModel.
LoHaModel
класс peft.LoHaModel
< 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 (
torch.nn.Module) — Модель, к которой будут прикреплены слои адаптивного тюнера. - config (LoHaConfig) — конфигурация модели LoHa.
- adapter_name (
str) — имя адаптера, по умолчанию"default". - low_cpu_mem_usage (
bool,optional, по умолчаниюFalse) — Создаёт пустые веса адаптера на meta-устройстве. Полезно для ускорения процесса загрузки.
Возвращает
torch.nn.Module
Модель LoHa.
Создаёт модель Low-Rank Hadamard Product на основе предобученной модели. Метод частично описан в https://huggingface.co/papers/2108.06098 Текущая реализация в значительной степени заимствована из https://github.com/KohakuBlueleaf/LyCORIS/blob/eb460098187f752a5d66406d3affade6f0a07ece/lycoris/modules/loha.py
Пример:
>>> from diffusers import StableDiffusionPipeline
>>> from peft import LoHaConfig, get_peft_model
>>> config_te = LoHaConfig(
... r=8,
... alpha=32,
... target_modules=["k_proj", "q_proj", "v_proj", "out_proj", "fc1", "fc2"],
... rank_dropout=0.0,
... module_dropout=0.0,
... init_weights=True,
... )
>>> config_unet = LoHaConfig(
... r=8,
... alpha=32,
... target_modules=[
... "proj_in",
... "proj_out",
... "to_k",
... "to_q",
... "to_v",
... "to_out.0",
... "ff.net.0.proj",
... "ff.net.2",
... ],
... rank_dropout=0.0,
... module_dropout=0.0,
... init_weights=True,
... use_effective_conv2d=True,
... )
>>> model = StableDiffusionPipeline.from_pretrained("runwayml/stable-diffusion-v1-5")
>>> model.text_encoder = get_peft_model(model.text_encoder, config_te)
>>> model.unet = get_peft_model(model.unet, config_unet)Атрибуты:
- model (
~torch.nn.Module) — Модель, подлежащая адаптации. - peft_config (LoHaConfig): конфигурация модели LoHa.