PEFT documentation
通过 Householder 反射自适应(HRA)弥合低秩自适应与正交自适应之间的差距
通过 Householder 反射自适应(HRA)弥合低秩自适应与正交自适应之间的差距

HRA 提供了一个将 LoRA 与 OFT 联系起来的新视角,这意味着它可以通过利用 Householder 反射 来减少参数和计算成本,同时对预训练知识的损失施加惩罚,从而结合这两种策略的优势。它在不同模型(包括大型语言模型(LLMs)和条件图像生成器)上,始终能以更少的可训练参数实现更好的性能,并优于最先进的适配器。
HRA 构建了一条由 r 个可训练的 Householder 反射(HR)组成的链。由于 Householder 反射矩阵是正交矩阵,且正交矩阵的乘积也是正交矩阵,因此 HRA 满足正交微调(OFT)的理论保证。同时,HRA 也可以被视为一种低秩微调适配器。 r, 越大,可训练参数越多,从而带来更大的模型容量和更好的性能。此外,由于链式结构,HR 平面的正交性会影响 HRA 的容量和正则性。为了在模型容量和正则性之间取得平衡,在损失函数中添加了 HR 平面的正交性正则项。权重 可以控制正则项的强度。
该论文的摘要如下:
尽管遵循不同的技术路线,低秩和正交适配技术都能基于少量可训练参数,高效地将大规模预训练模型适配到特定任务或领域。在本研究中,我们弥合了这两种技术之间的差距,提出了一种基于 Householder 反射的简单而有效的适配方法。给定一个预训练模型,我们的方法通过让每个冻结的权重矩阵与一个由可学习 Householder 反射(HRs)链构建的正交矩阵相乘,来微调其层。这种基于 HR 的正交微调等价于一种自适应的低秩适配。此外,我们证明了与 HRs 对应的反射平面的正交性会影响模型的容量和正则性。这一分析促使我们对 HRs 的正交性进行正则化,从而得出了所提出的 Householder 反射适配(HRA)方法的不同实现。与最先进的方法相比,在适配大型语言模型和条件图像生成器时,HRA 以更少的可学习参数实现了更优的性能。代码可在 peft 和 HRA 上获取。
API
HRAConfig
类 peft.HRAConfig
< 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 = 8apply_GS: 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]] = Nonebias: str = 'none'modules_to_save: Optional[list[str]] = None )
参数
- r (
int) — HRA 在不同层中的秩。最好将 ‘r’ 设置为偶数;否则,默认的初始化方法将无法正常工作。 - apply_GS (
bool) — 是否应用 Gram-Schmidt 正交化。 - target_modules (
Optional[Union[List[str], str]]) — 要应用适配器(adapter)的模块名称。如果指定了此参数,则只有名称匹配的模块会被替换。传入字符串时,将执行正则表达式匹配。传入字符串列表时,将执行精确匹配,或检查模块名称是否以列表中的任一字符串结尾。如果指定为 ‘all-linear’,则选择所有线性模块,但排除输出层。如果未指定,将根据模型架构选择模块。如果架构未知,则会引发错误——在这种情况下,应手动指定目标模块。 - exclude_modules (
Optional[Union[List[str], str]]) — 不应用适配器的模块名称。传入字符串时,将执行正则表达式匹配。传入字符串列表时,将执行精确匹配,或检查模块名称是否以传入的任一字符串结尾。 - init_weights (
bool) — 是否执行 HRA 权重的初始化。 - layers_to_transform (
Union[List[int], int]) — 要转换的层索引。如果传入一个整数列表,则会将适配器应用于该列表中指定的层索引。如果传入单个整数,则会对该索引处的层应用转换。 - layers_pattern (
Optional[Union[List[str], str]]) — 层模式名称,仅在layers_to_transform不同于None时使用。它应指向模型的nn.ModuleList,该列表通常命名为'layers'或'h'。 - bias (
str) — HRA 的偏置类型。可以是'none'、'all'或'hra_only'。 - modules_to_save (
List[str]) — 除适配器层外,需要设置为可训练并在最终检查点中保存的模块列表。
这是用于存储 HRAModel 配置的类。
HRAModel
类 peft.HRAModel
< 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 (HRAConfig) — HRA 模型的配置。
- adapter_name (
str) — 适配器的名称,默认为"default"。 - low_cpu_mem_usage (
bool,optional, defaults toFalse) — 在 meta 设备上创建空的适配器权重。有助于加快加载过程。
返回值
torch.nn.Module
HRA 模型。
从预训练模型创建 Householder 反射自适应(HRA)模型。该方法在 https://huggingface.co/papers/2405.17484 中有详细描述。
示例:
>>> from diffusers import StableDiffusionPipeline
>>> from peft import HRAConfig, get_peft_model
>>> config_te = HRAConfig(
... r=8,
... target_modules=["k_proj", "q_proj", "v_proj", "out_proj", "fc1", "fc2"],
... init_weights=True,
... )
>>> config_unet = HRAConfig(
... r=8,
... target_modules=[
... "proj_in",
... "proj_out",
... "to_k",
... "to_q",
... "to_v",
... "to_out.0",
... "ff.net.0.proj",
... "ff.net.2",
... ],
... init_weights=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 (HRAConfig): HRA 模型的配置。