E³-PRUNER 论文阅读
华为的一个剪枝方法
简单来说,逻辑上有两个关键点:
- 剪枝
- 微调模型
在训练的循环过程中,在开始的循环中先联合了剪枝和微调,之后只进行微调
搜索剪枝
Naive的来看,给定一个参数K,让模型最终剪去K层的layer,只需要暴力遍历所有的结果并评估分数就行。只要对所有的数据集进行C(L,K)=K!(L−K)!L!次计算
抛开这千万到万亿次遍历×万级的数据的计算,直接剪枝还容易导致出现伪最优,因为一次性剪去K层之后,输出的肯定是胡话,在胡话里选出一个最优的是不合适的
那如果一个一个的剪呢,也同样容易造成错误。因为剪去一层是不可复原的,也就是剪的这一个可能实际上是一个比较有用的层,但是在当前的数据中没有显现;也就是说贪心算法在这个过程中基本上得到的不是最优的结果
综上都是离散剪枝带来的问题。离散剪枝导致没有容错,而E3-PRUNER 使用了 Gumbel-TopK 方法,旨在将离散的 Top-K 变成可微分的
Gumbel-TopK 算法
Require: Layer scoreS, temperatureτ, number of retained layers k.
1:S1=S+Gumbel(0,1)2:M~1=03:fori=1tokdo4:Si+1=Si+log(1−Softmax(τSi))5:M~i+1=M~i+Softmax(τSi)6:end for7:M=STE(TopK(M~k+1,k))8:returnPruning maskM
如上面的公式展示的,每一层都有一个分数S,在初始的时候给每个分数都加了一个Gumbel噪声,防止分数平均导致微小变化产生巨大分数变化
第4行会对重复的高分进行”惩罚”,防止重复选几个特定的层;关键在于STE(Straight-Through Estimator,直通估计器)让back-propagation能够运算
至于τ,则采用的是线性退火的形式,在初期能探索更多的可能
迭代过程如下:
M~i+1=M~i+Softmax(τSi),Si+1=Si+log(1−Softmax(τSi))
微调
1.联合训练
剪去某个特殊层之后,模型的权重应该跟着微调,否则就会精度断崖下降
算法1:
Params:
- LLM Θ
- total iteration T
- mask searching iteration turns TM
- layer score S
- layer mask M
- total layers L.
1:fort=1toTdo2:τ=1−β⋅t/T,k′=L−⌈(L−k)⋅t/T⌉3:ift≤TM:4:M=Gumbel-TopK(S,τ,k′)5:S=S−λ⋅∂L(x,Θ,M)/∂S6:end if7:Θ=Θ−λ⋅∂L(x,Θ,M)/∂Θ8:end for9:returnPruned modelΘ∗
这里值得关注的就是这里的反向传播,得益于 STE (Straight-Through Estimator) 得以实现
而这里的 Gumbel-TopK 的算法如下
算法2:
Params:
- Layer score S
- temperature τ
- layers k
1:S1=S+Gumbel(0,1)2:M1~=03:for i=1 to k do4:M=Gumbel-TopK(S,τ,k′)5:S=S−λ⋅∂L(x,Θ,M)/∂S6:end if7:Θ=Θ−λ⋅∂L(x,Θ,M)/∂Θ8:end for9:returnPruned modelΘ∗
文中提到的loss函数是这样的:
{Θ∗,M∗}=argminΘ,ML(x;Θ,M)s.t.∥M∥0=k
也就是自适应蒸馏损失:
Ladaptive-KD=N1∑i=1NH(Softmax(zt(i))c)⋅∑c∈SiKSoftmax(zt(i))c⋅log(Softmax(zs(i))cSoftmax(zt(i))c)
它由两部分组成:
token损失:
Ltoken=∑c∈SiKSoftmax(zt(i))c⋅log(Softmax(zs(i))cSoftmax(zt(i))c)
这里的zs是 student 的输出,zt是 teacher 的输出。由于现场推理开销大,所以 teacher 输出的 top-K 个 logits 是事先计算好并保存的
权重:
Wi=H(Softmax(zt(i))c)
2.后训练
如算法1展示的那样,在k轮的联合训练之后,再进行了T−k轮的单独对模型的调参,目标是在固定模型框架的基础上恢复精度
延申
比起直接对齐向量方向的训练,对齐输出分布的训练往往上限更高,因为方向上的对齐不一定能带来最终logits的更加准确
当大模型最终输出了一个h之后,由z=Wuh得到最终的logits
由于剪枝之后预测的h多少有偏差。我们假设是h′=h+Δh,这时z′=Wuh′=Wu(h+Δh)=z+WuΔh
可以看到最终logits的分布并不是单纯依赖于Δh也就是向量的相似,而是依赖于WuΔh这个整体
也就是说即使在Δh相差很大的情况下,只要这个Δh向量中的元素的分布能和Wu矩阵的零空间高度重合,最终的logits就是被很好拟合的
反之,就算得到很小的Δh,如果他恰巧和Wu中的有大元素的空间重合,产生的Δz这个误差也会很大,这就是为什么方向的对齐的上限会低一点
但是相应的他的训练成本会比输出对齐的训练要低,最后得到的结果和输出分布训练的向量差距也不会那么大,只要post train的时候去对齐一下输出,理论上就能得到更好的效果