PEFT selective method

BitFit: Simple Parameter-efficient Fine-tuning for Transformer-based Masked Language-models

BitFit(BIas-Term FIne-Tuning)是一种稀疏的微调方法,仅对模型的bias以及特定任务的线性分类层进行调整,因此只需要调整不到0.1%的参数。它具有以下贡献:

  1. 对于每个微调任务,仅仅改变了很少的参数。
  2. 具有task-invariance,对于每个任务都只需要修改同样的参数集合。
  3. 更改的参数在整个参数空间中即是孤立的又是局部的。
  4. 在中小数据集上可以达到与full fine-tuning一样甚至更好的效果,在大数据集上可以与其他稀疏微调方式媲美,但是达不到full fine-tuning的效果。

BitFit与full fine-tuning、Diff-Pruning、Adapters的对比实验结果如下图所示:

BitFitCompare

Parameter-Efficient Transfer Learning with Diff Pruning

Diff pruning中的Diff来源于作者通过使用一个任务特定的difference向量来扩展基础模型,并基于这个diff向量实现PEFT。

作者首先将模型参数进行了重参数化:$\theta_\tau=\theta+\delta_\tau$,其中预训练模型的参数向量(第一项)是固定的,只微调diff向量(第二项)。当我们有多个下游任务的时候,预训练模型参数的存储成本会被每一个任务平摊,新任务仅有的新增成本就是对diff向量的存储,如果我们能够对diff向量进行正则化,让它足够稀疏,使得$\lVert\delta_\tau\rVert_0\ll\lVert\theta\rVert_0$,那么当下游任务越多的时候我们的微调策略就越高效。为了实现这个正则化,作者对diff向量使用了L0-norm(非零元素的个数):
$$
R(\theta_\tau)=R(\theta+\delta_\tau)=\lVert\delta_\tau \rVert_0=\sum_{i=1}^d 1{\delta_{\tau,i}\neq0}
$$
显然,这个正则是很难优化的,因为它不可微。于是,作者就寻找到了L0-norm的一个可微近似作为替代————借助了《Learning Sparse Neural Networks through L0 Regularization》论文中提到的一种使用松弛掩码向量进行基于梯度的 L0 稀疏学习的方法。解释有关其工作原理的内容超出了本文的范围,但是有很多资料已经解释清楚,例如这篇文章。本文只介绍具体做法:

  1. 首先通过hard-concrete分布构建一个掩码矩阵$\mathbf{z}_\tau$(对某些权重或输入进行遮罩操作,从而实现稀疏性或剪枝的效果)。
    $$
    \begin{aligned}
    &\mathbf{u}\sim U(\mathbf{0},\mathbf{1}), \\
    &\mathbf{s}_\tau=Sigmoid\left(\operatorname{log}\mathbf{u}-\operatorname{log}(1-\mathbf{u})+\alpha_\tau\right), \\
    &\hat{\mathbf{s}}_\tau=\mathbf{s}_\tau\times(r-l)+l, \\
    &\mathbf{z}_\tau=min(\mathbf{1},max(\mathbf{0},\hat{\mathbf{s}}_\tau) ).
    \end{aligned}
    $$
    $u$是从均匀分布中采样得到的随机数,$\alpha_\tau$是分布参数,在训练过程中与模型权重一起进行优化。通常情况下,对于模型中的每个参数值,会学习到一个单独的$\alpha_\tau$值。l和r是固定的超参数,通常在Diff Pruning中设置为-1.5和1.5。

  2. $\mathbf{z}_\tau$的大部分元素都是0或1,将其和模型参数相乘实现参数的筛选,公式如下:
    $$
    \delta_\tau=\theta\odot\mathbf{z}_\tau
    $$

  3. 将L0惩罚项加入loss,惩罚项定义如下:
    $$
    R(\theta_\tau)=\lambda\sum_{i=1}^d Sigmoid(\alpha_{\tau,i}-log\frac{-l}{r} )
    $$

经过上面三步之后,就可以得到可微的L0正则化,这使得模型拥有很好的稀疏率。然而,最理想的还是设置一个精确的稀疏率,因为有些应用会有参数预算限制。作者发现通过在训练后投影到目标 L0-ball 上实现精确的稀疏率更有高效,而且经验上也更有效。具体做法是对 diff向量$\delta_\tau$使用magnitude pruning(将权重低于某个阈值的全部剪枝掉),如果希望稀疏率为$t%$,那就只保留前$t%\times d$的参数。

Diff Pruning与full fine-tuning、Last layer、Adapters的对比实验结果如下图所示:

DIffPruningCompare

Efficient Fine-Tuning of BERT Models on the Edge

作者提出了一种Freeze And Reconfigure (FAR)的内存高效的训练方案,大致思想是削减占据参数总量66%的FFN参数,具体操作如下:

  1. 使用结构化的方式选择线性层中的微调权重,以避免对于内存的稀疏访问。

  2. FFN中的每一个节点都被当做一组参数,这些节点被分类成学习节点(fine-tuned)和非学习节点(freeze)两种。具体来说,在Priming过程(初始的几个微调迭代,具体迭代数由一个指定的百分数p决定)中,保存FFN的权重并进行微调。在Priming过程结束后用微调之后的FFN权重减去初始的FFN权重,并使用L1-norm计算每个Encoder的每个FFN层的每个节点的学习指标。接着根据学习指标对节点进行排序,排名节点总数前r%的节点被定义为学习节点,其余为非学习节点。

  3. 在后续微调过程中,将两种节点分离,并构造新的FFN子层,这便是FFN的Reconfigure。具体来说,如下图所示,FFN节点被重新配置为两个平行的子模块。这种重新配置确保了学习节点的内存能被分配在一起。最后,重新配置的FFN需要恢复其原本的输出顺序,使其输出与模型的参数一致,因此需要进行permutation。Reconfigure和permutation的组合相比内存访问、额外计算等成本代价要低得多。除此以外,使用Reconfigure能够避免像非结构化剪枝这样的方法中出现的内存访问问题、避免了稀疏的内存访问(耗时)、解决了PyTorch中无法仅针对单个参数禁用自动梯度计算,而只能针对整个层或子层进行禁用的问题。

    Reconfigure

FAR的对比和消融如下图所示:

FARCompare

FARAblation

Training Neural Networks with Fixed Sparse Masks

FISH-Mask是指pre-computing一个待更新的稀疏参数子集并在训练的迭代之中保持固定不变。具体操作如下:

  1. 根据每个参数的Fisher信息的近似估计每个参数的重要程度。Fisher信息矩阵是一个$|\theta|\times|\theta|$的矩阵,这在现实之中是难以计算的,因此需要将其近似为一个长度为$|\theta|$向量,这就是true Fisher approximation,其公式为:
    $$
    \hat{F_\theta}=\frac{1}{N}\sum_{i=1}^N\mathbb{E}_{y\sim p_\theta(y|x_i)}(\nabla_\theta\log p_\theta(y|x_i))^2
    $$
    容易发现我们需要计算类别y的期望,当类别数很小的时候是容易计算的,但是如果有很多类别,人们往往再次进行近似,得到empirical Fisher approximation,其公式为:
    $$
    \hat{F_\theta}=\frac{1}{N}\sum_{i=1}^N(\nabla_\theta\log p_\theta(y|x_i))^2
    $$

  2. 选择Fisher信息最大的k个参数构建FISH-mask。

FISH-Mask与full fine-tuning、BitFit、Diff Pruning的对比实验结果如下图所示:

FishMaskCompare

Comparison

方法 可训练参数量 改变的参数量
BitFit 0.05%~0.1% 0.05%~0.1%
Diff Pruning 200% 0.5%
FAR 6.6%~26.4% 6.6%~26.4%
Fish-Mask 0.01%~0.5% 0.01%~0.5%