FourierFT:离散傅里叶变换微调
FourierFT 是一种参数高效的微调技术,它利用离散傅里叶变换来压缩模型的可调权重。这种方法在 GLUE 基准测试和使用更少参数的常见 ViT 分类任务中优于 LoRA。
FourierFT 目前具有以下限制
- 仅支持
nn.Linear
层。 - 不支持量化层。
如果这些限制不适合您的用例,请考虑使用其他方法。
论文摘要如下
低秩自适应 (LoRA) 近年来在微调基础模型方面引起了极大的兴趣。它通过引入低秩矩阵 A 和 B 来表示权重变化,从而有效地减少了可训练参数的数量,即 Delta W=BA。尽管 LoRA 取得了进展,但在处理大量自定义自适应或更大的基础模型时,它面临着存储挑战。在这项工作中,我们旨在利用傅里叶变换强大的表达能力来进一步压缩可训练参数。具体来说,我们引入了 FourierFT,它将 Delta W 视为空间域中的矩阵,并且只学习其频谱系数的一小部分。利用训练后的频谱系数,我们实现了逆离散傅里叶变换来恢复 Delta W。从经验上看,我们的 FourierFT 方法在各种任务上,包括自然语言理解、自然语言生成、指令微调和图像分类,都显示出与 LoRA 相当甚至更好的性能,并且参数更少。例如,在对 LLaMA2-7B 模型进行指令微调时,FourierFT 的可训练参数仅为 0.064M,而 LoRA 的可训练参数为 33.5M,FourierFT 的性能却超过了 LoRA。
FourierFTConfig
class peft.FourierFTConfig
< source >( peft_type: Union = None auto_mapping: Optional = None base_model_name_or_path: Optional = None revision: Optional = None task_type: Union = None inference_mode: bool = False n_frequency: int = 1000 scaling: float = 150.0 random_loc_seed: Optional[int] = 777 fan_in_fan_out: bool = False target_modules: Optional[Union[list[str], str]] = None bias: str = 'none' modules_to_save: Optional[list[str]] = None layers_to_transform: Optional[Union[list[int], int]] = None layers_pattern: Optional[str] = None n_frequency_pattern: Optional[dict] = <factory> init_weights: bool = False )
参数
- n_frequency (
int
) — 离散傅里叶变换的可学习频率数量。‘n_frequency’ 是一个大于 0 且小于或等于 d^2 的整数(假设权重 W 的维度为 d×d)。此外,它也是更新每个 delta W 权重所需的训练参数数量。‘n_frequency’ 会影响 PEFT 的性能和效率。具体来说,它对训练速度几乎没有影响,但其更高的值(通常)会导致更大的 GPU 内存成本和更好的准确性。在相同的target_modules
下,LoRA 的参数数量是 FourierFT 的 (2 * d * r / n_frequency) 倍。以下关于 ‘n_frequency’ 设置的示例可以作为用户的参考。对于使用 RoBERTa-large 模型的 NLU 任务,采用 ‘n_frequency’: 1000 几乎可以实现与 LoRA 中 ‘r’: 8 相似的结果。此时,LoRA 的参数数量大约是 FourierFT 的 16 倍。对于使用 ViT-large 模型的图像分类任务,采用 ‘n_frequency’: 3000 几乎可以实现与 LoRA 中 ‘r’: 16 相似的结果,其中 LoRA 的参数数量大约是 FourierFT 的 11 倍。 - scaling (
float
) — 用于 delta W 矩阵的缩放值。这是一个重要的超参数,用于缩放,类似于 LoRA 方法中的 ‘lora_alpha’ 参数。‘scaling’ 可以在超参数搜索过程中确定。但是,如果用户想要跳过此过程,则可以参考以下情况下的设置。对于所有 NLU (GLUE) 任务,对于 RoBERTa-base 和 RoBERTa-large 模型,此参数可以设置为 100.0 或 150.0。对于所有指令微调,对于 LLaMA 系列模型,此参数可以设置为 300.0。对于所有图像分类任务,对于 ViT-base 和 ViT-large 模型,此参数可以设置为 300.0。 - random_loc_seed (
int
) — 频率随机位置的种子,即频谱条目矩阵。 - target_modules (
Union[list[str],str]
) — 要用 FourierFT 替换的模块名称列表或模块名称的正则表达式。例如,[‘q’, ‘v’] 或 ‘.decoder.(SelfAttention|EncDecAttention).*(q|v)$‘。只支持线性层。 - fan_in_fan_out (
bool
) — 如果要替换的层将权重存储为 (fan_in, fan_out) 形式,则将其设置为 True。 - bias (
str
) — FourierFT 的偏差类型。 可以是 ‘none’,‘all’ 或 ‘fourier_only’。 - modules_to_save (
list[str]
) — 除 FourierFT 层之外,需要设置为可训练并在最终检查点中保存的模块列表。 例如,在序列分类或令牌分类任务中,最后一层classifier/score
是随机初始化的,因此需要可训练并保存。 - layers_to_transform (
Union[list[int],int]
) — 要转换的层索引,如果指定了此参数,PEFT 将仅转换在此列表中指定的层索引。 如果传递单个整数,PEFT 将仅转换此索引处的层。 - layers_pattern (
str
) — 层模式名称,仅在layers_to_transform
与 None 不同且层模式不在通用层模式中时使用。 - n_frequency_pattern (
dict
) — 将层名称或正则表达式映射到与默认指定不同的 n_frequency。 例如,{model.decoder.layers.0.encoder_attn.k_proj: 1000
}。 - init_weights (
bool
) — 傅里叶权重的初始化。 如果频谱初始化为标准正态分布,则将其设置为 False。 如果频谱初始化为零,则将其设置为 True。
这是用于存储 FourierFTModel 配置的配置类。
FourierFTModel
class peft.FourierFTModel
< source >( model config adapter_name low_cpu_mem_usage: bool = False ) → torch.nn.Module
参数
- model (
torch.nn.Module
) — 要适配的模型。 - config (FourierFTConfig) — FourierFT 模型的配置。
- adapter_name (
str
) — 适配器的名称,默认为"default"
。 - low_cpu_mem_usage (
bool
,optional
, defaults toFalse
) — 在 meta 设备上创建空的适配器权重。有助于加快加载过程。
返回
torch.nn.Module
FourierFT 模型。
从预训练的 transformers 模型创建 FourierFT 模型。
该方法在 https://arxiv.org/abs/2405.03003 中进行了详细描述。
属性:
- model (PreTrainedModel) — 要适配的模型。
- peft_config (FourierFTConfig): Fourier 模型的配置。
删除现有适配器。
merge_and_unload
< source >( progressbar: bool = False safe_merge: bool = False adapter_names: Optional[list[str]] = None )
此方法将傅里叶层合并到基础模型中。如果有人想将基础模型用作独立模型,则需要这样做。
set_adapter
< 源代码 > ( adapter_name: str | list[str] )
设置活动适配器。
通过移除所有傅里叶模块但不进行合并来获取基础模型。这会返回原始的基础模型。