Skip to content

模型压缩

Model Compression

顾名思义,模型压缩(model compression)是一类技术的统称,用于在保持甚至提升模型性能的同时,减小模型的体积和计算复杂度。

llm optimization p307 1

这些技术的目标是让模型变得更小——这也是“模型压缩”这个名字的由来。通常来说,一个更小的模型被期望能够:

  • 具有更低的推理延迟:更小的模型能够更快地给出预测结果,因此非常适合实时或低延迟的应用场景。
  • 更易于扩展:由于计算需求更低,扩展起来也更容易。
  • 占用更少的内存。

我们将介绍能帮助我们实现这一目标的四种技术:

llm optimization p307 2

  • 知识蒸馏(Knowledge Distillation)
  • 剪枝(Pruning)
  • 低秩分解(Low-rank Factorization)
  • 量化(Quantization)

让我们逐一了解它们!

1)知识蒸馏

知识蒸馏是在几乎不牺牲性能的前提下缩小模型体积最简单、也最有效的方法之一。本质上,知识蒸馏是指训练一个更小、更简单的模型(称为“学生”模型),去模仿一个更大、更复杂的模型(称为“教师”模型)的行为。这个术语可以拆解来看:知识(Knowledge):指的是一个机器学习模型在训练过程中获得的理解、洞见或信息。这种“知识”通常体现在模型的参数、学到的模式,以及它做出预测的能力当中。

llm optimization p308 1

蒸馏(Distillation):在这个语境下,蒸馏指的是把知识从一个模型迁移或浓缩到另一个模型中。具体做法是训练学生模型去模仿教师模型的行为,从而有效地把教师模型的知识迁移过来。

llm optimization p309 1

这是一个分两步进行的过程:

  • 像平常一样训练那个大模型,这就是所谓的“教师”模型。
  • 训练一个更小的模型,目标是让它模仿大模型的行为,这就是所谓的“学生”模型。
  • 知识蒸馏的核心目标,是把知识、也就是学到的这些洞见,从教师模型迁移到学生模型中。这样一来,学生模型就能以更少的参数、更低的计算复杂度,达到与教师模型相当的性能。这项技术在直觉上也说得通:当然,如果类比现实中学术场景里的师生关系,学生模型也可能始终无法达到教师模型的水平。

llm optimization p309 2

但通过持续的训练,我们可以打造出一个几乎与大模型一样出色的小模型。以这种方式开发出来的一个经典例子就是 DistilBERT,它是 BERT 的学生模型。DistilBERT 比 BERT 小了大约 40%,这是相当悬殊的体积差异;但即便如此,它依然保留了 BERT 大约 97% 的自然语言理解(NLU)能力。更重要的是,DistilBERT 的推理速度还快了大约 60%。

2)剪枝

剪枝(Pruning)常用于基于树的模型中,做法是移除一些分支(或节点)来简化模型。

llm optimization p310 1

当然,去掉节点会导致模型准确率下降。因此,就决策树而言,核心思路是迭代地去掉一些子树——移除之后应当满足:

  • 分类代价的增幅尽可能小
  • 复杂度(或节点数)的降幅尽可能大

如下图所示:

llm optimization p311 1

在上图中,两棵子树造成的代价增幅是一样的。但显然,移除节点更多的那棵子树更划算,因为这样能更多地降低计算复杂度。同样的思路也可以迁移到神经网络中。正如你可能已经猜到的,神经网络中的剪枝,就是识别并去掉那些对模型整体性能贡献甚微的特定连接或神经元。

llm optimization p311 2

整层移除也是一种做法,但我们很少这样做,因为这可能导致权重矩阵维度不匹配。更何况,要量化某一层对最终输出的贡献本身就很困难。

因此,比起从已训练好的网络中直接移除某一层,重新定义一个不包含该层的架构往往是更好的做法。剪枝的目标,是在尽可能保留预测能力的同时,打造一个更紧凑的神经网络。这主要通过两种方式来实现:神经元剪枝(Neuron pruning):

llm optimization p312 1

其思路是从网络中整个地去掉某些节点,结果是代表各层的矩阵会变小。

llm optimization p312 2

这带来了更快的推理速度和更低的内存占用。权重剪枝(Weight pruning):

llm optimization p313 1

  • 这种做法是去掉网络中的连接边(edge)。
  • 权重剪枝可以理解为,把被移除的边在矩阵中对应的位置置为零。
  • 不过在这种情况下,矩阵的尺寸并不会受到影响。
  • 也就是说,矩阵的大小保持不变,但会变得稀疏。
  • 去掉这些边未必能加快推理速度,但确实有助于优化内存使用,因为稀疏矩阵通常比稠密矩阵占用更少的空间。注意:我们也可以同时去掉边和节点。从上述思路可以看出,从网络中移除不重要的权重(或节点)后,可以期待以下几方面的改善:
  • 更好的泛化能力
  • 更快的推理速度
  • 更小的模型体积

llm optimization p313 2

3)低秩分解

低秩分解(Low-rank Factorization)的核心思路,是用秩更低的矩阵去近似神经网络的权重矩阵。本质上,就是把复杂的权重矩阵表示为两个或更多个更简单矩阵的乘积。

llm optimization p314 1

如果我们先分别理解这几个术语,这个思路会更清晰:低秩(Low-rank):

  • 在线性代数中,一个矩阵的“秩”指的是该矩阵中线性无关的行(或列)的最大数量。
  • 因此,一个秩较低的矩阵,其线性无关的行或列数量就更少。
  • 这意味着它可以被近似为数量更少的一组基向量的组合,从而帮助我们降低维度。分解(Factorization):
  • 在数学中,“分解”指的是把一个复杂的数学对象(比如一个矩阵)表示为若干个更简单的数学对象的乘积。因此,低秩分解指的就是把给定的权重矩阵拆解为两个或更多个维度更低的矩阵的乘积。这些低维矩阵通常被称为“因子矩阵”或“基矩阵”。

让我们来看看它具体是怎么运作的。第 1 步)进行矩阵分解:在神经网络中,每一层都有一个权重矩阵,我们可以把这些原始的权重矩阵分解为更低秩的近似矩阵。

llm optimization p315 1

可供选择的矩阵分解方法有很多,比如奇异值分解(SVD)、非负矩阵分解(NMF)或截断 SVD(Truncated SVD)。第 2 步)指定秩:在矩阵分解中,你通常需要为低秩近似选定一个秩 k,它决定了奇异值的数量(对 SVD 而言)或因子的数量(对其他分解方法而言)。

llm optimization p316 1

秩 k 的选择,直接关系到“模型体积缩减”与“信息保留程度”之间的权衡。第 3 步)重建权重矩阵:一旦得到了这些低秩矩阵,你就可以用它们来代替原始权重矩阵,对输入进行变换。

llm optimization p316 2

这样做的好处是,可以在保留训练过程中学到的重要特征的同时,降低神经网络的计算复杂度。通过用低秩近似矩阵替换原始权重矩阵,我们能够有效减少模型的参数数量,从而减小

模型的体积。

4)量化

通常,神经网络的参数(各层权重)会用 32 位浮点数来表示,这样做的好处是能提供很高的精度。另外,由于参数通常不受限于任何特定的取值范围,所有深度学习框架默认都会给参数分配最大的数据类型。但使用最大的数据类型也意味着要消耗更多内存。正如你可能猜到的,量化(Quantization)指的是用更低位宽的表示方式——比如 16 位、8 位、4 位,甚至 1 位——来表示参数。

llm optimization p317 1

这样一来,存储模型参数所需的内存量会大幅下降。举例来说,假设你的模型有超过一百万个参数,每个参数都用 32 位浮点数表示;如果可行的话,改用 8 位数字来表示,能让内存占用大幅下降(约 75%),同时仍能表示相当大的取值范围。当然,量化也引入了“模型体积”与“精度”之间的权衡。

虽然降低参数的位宽能让模型变小,但也会带来精度损失,这意味着模型的预测结果会比原始的全精度模型更“近似”。因此,在为部署考虑量化方案时,仔细评估“模型体积/推理速度”与“准确率”之间的权衡就显得尤为重要。尽管存在这种权衡,但在模型体积是关键约束的场景中——比如边缘设备、移动应用,或是智能手机这类专用硬件——量化依然能发挥很大的作用。

模型压缩能让模型变得更小、更快,但 LLM 还带来了一些只会在推理阶段才显现出来的挑战。

为了应对这些挑战,我们会使用一些专为自回归解码设计的技术,比如 KV 缓存(KV caching)。

本站内容仅供学习交流,版权归原作者所有。