在自然语言处理领域,模型压缩一直是研究热点。最近Sharma等人提出的LASER(LAyer SElective Rank reduction)技术,通过截断奇异值分解(tSVD)对大型语言模型进行压缩,不仅减少了参数数量,在某些情况下还能提升模型性能。这种看似违反直觉的现象背后,其实有着深刻的数学原理。
奇异值分解(SVD)是线性代数中的核心工具,它可以将任意矩阵M分解为三个矩阵的乘积:M = UΣVᵀ。其中U和V是正交矩阵,Σ是对角矩阵,对角线上的元素就是奇异值。当我们按奇异值大小降序排列后,保留前q个最大的奇异值(即截断SVD),就能得到一个低秩近似矩阵。
关键提示:在实际应用中,我们通常观察到奇异值衰减很快,这意味着前几个奇异值往往包含了矩阵的大部分信息。这是tSVD能够有效工作的数学基础。
在PyTorch中实现tSVD非常简单:
python复制U, sigma, V = torch.svd_lowrank(weight, q=q)
这里q决定了保留的奇异值数量。实践中,我们更常用比例q/r(r是矩阵的秩,即min(m,n))来控制压缩程度。例如q/r=0.25表示保留25%的奇异值。
本次实验选用Mistral-7B-instruct-v0.1模型,重点处理其Transformer层中的线性变换部分。具体来说,我们对以下7种投影矩阵应用LASER技术:
实现时创建了LaserLinear模块替代原有线性层:
python复制class LaserLinear(torch.nn.Module):
def __init__(self, weight: torch.Tensor, ratio: float):
super().__init__()
max_rank = min(weight.shape)
q = int(max_rank * ratio)
U, sigma, V = torch.svd_lowrank(weight, q=q, niter=2)
self.U = torch.nn.Parameter(U)
self.sigma = torch.nn.Parameter(sigma)
self.V = torch.nn.Parameter(V)
def forward(self, input: torch.Tensor) -> torch.Tensor:
return input @ (self.U @ torch.diag(self.sigma) @ self.V.T).T
实验采用了一个巧妙的层选择策略:从顶部开始逐层应用LASER,设置一个阈值层n,n层以下保留原权重,n层及以上使用tSVD近似。这种设计让我们能精确控制压缩的深度。
参数压缩比例与q/r的关系如下表所示:
| q/r 比率 | 参数占比原始模型 |
|---|---|
| 0.1 | ~17% |
| 0.25 | ~37% |
| 0.5 | ~70% |
操作心得:实际实现时发现,反向遍历层数(从顶层开始)比正向遍历更高效,因为顶层参数通常对最终输出的影响更直接。
使用固定提示"the capital of Britain is"进行测试,观察不同压缩配置下的生成效果。结果显示:
这表明更高的压缩比率(保留更多奇异值)允许我们对更多层进行压缩而不显著损害性能。
在代码生成任务HumanEval上,我们观察到一些有趣现象:
| 阈值层 | q/r=0.1 (Pass@1) | q/r=0.25 (Pass@1) | q/r=0.5 (Pass@1) |
|---|---|---|---|
| 31 | 0.1768 | 0.1768 | 0.1768 |
| 30 | 0.1707 | 0.1403 | 0.1829 |
| 29 | 0.1524 | 0.2012 | 0.2134 |
| 28 | 0.0183 | 0.1463 | 0.2134 |
| 27 | 0.0060 | 0.0366 | 0.2195 |
令人惊讶的是,在某些配置下(如q/r=0.5,阈值层27),压缩后的模型性能甚至超过了原始模型。这可能是因为:
虽然主要目标是保持性能,但参数压缩确实带来了内存节省:
| 阈值层 | q/r=0.1 参数占比 | q/r=0.25 参数占比 | q/r=0.5 参数占比 |
|---|---|---|---|
| 31 | 100% | 100% | 100% |
| 30 | ~97% | ~98% | ~99% |
| 29 | ~95% | ~96% | ~98% |
| 28 | ~92% | ~94% | ~97% |
| 27 | ~90% | ~92% | ~96% |
注意事项:实际内存节省会小于参数减少比例,因为模型结构、激活值等开销仍然存在。但在部署场景中,即使是5-10%的节省也可能很有价值。
基于实验结果,我们总结出以下LASER应用原则:
问题1:应用LASER后模型输出完全混乱
问题2:压缩后性能提升不明显
问题3:实际部署时加速不明显
LASER技术不仅适用于Mistral模型,也可以推广到其他Transformer架构。在实际项目中,我们还发现:
一个值得探索的方向是分析不同层权重矩阵的奇异值分布,这可以帮助我们:
我在实际应用中发现,顶层权重矩阵的奇异值通常衰减更快,这解释了为什么顶层更适合压缩。而底层矩阵的奇异值分布更平缓,可能需要保留更多奇异值才能维持性能。