量化与蒸馏:把模型变小
"两种把模型缩小的不同方式——一种改变它的数字,另一种训练一个更小的副本。下面讲清楚各自如何运作、以及何时该用哪一个。"
大模型运行起来代价高昂。它们需要大量内存、大量计算,而且响应比小模型更慢。所以大量的实用 AI 工作,都在于把模型变小而又不让它明显变差。有两种技术主导着这项努力,它们常被相提并论,尽管二者建立在完全不同的原理之上。量化通过更紧凑地存储模型的数字来缩小它。蒸馏通过训练一个更小的模型去模仿一个更大的模型来缩小它。理解二者的区别,是知道该拉哪根杠杆的关键。
本文用大白话解释两者,逐一走过各自所做的权衡,并提供一种实用的思路,去思考"更小"在一开始究竟是不是正确的目标。
为什么尺寸是一个值得解决的问题
一个模型,归根结底,是一大堆被称为参数的数字——它在训练期间学到的那些值。更大的模型有更多参数,而更多参数意味着更多内存来容纳它们、更多算术来运行它们。这直接转化为成本、延迟,以及一个模型在物理上能住在哪里。一个小到能在手机或一台普通服务器上运行的模型,开启了那些数据中心里的庞然大模型无法廉价或迅速服务的用途。
所以压缩的目标,不是为了小而小。它是要把一个模型塞进一个更紧的内存、金钱或时间的预算里,同时尽可能多地保住它的能力。有意思的问题永远是同一个:在质量下降到对你的任务而言要紧的程度之前,你能把它缩小多少?
量化:把同一个模型存得更紧凑
模型中的每个参数都是一个数字,而数字可以用不同的精度级别来存储。一个高精度的数字保留许多比特来捕捉细微的层次;一个低精度的数字用更少的比特、更粗略地捕捉那个值。量化就是把一个模型的参数从高精度转换到较低精度的行为——把每个数字打包进更小的空间里。
这种直觉就像把一张照片以较低的质量设置来保存。图像依然认得出,文件小得多,而且对大多数用途来说你看不出区别。一个量化后的模型保持着相同的结构和相同的所学知识;它只是更粗略地表示每个值。因为这些数字占的地方更少,模型用的内存更少,而且往往跑得更快,因为搬运和相乘更小的数字代价更低。
代价在于,更粗略的数字会丢失细节。把精度压得足够低,舍入误差就会累积,直到模型的行为退化——答案变得不那么准确,在更难的任务上尤其如此。存在一个甜蜜点,而找到它就是全部的关键所在。适度的量化在质量上往往几乎是免费的;激进的量化则开始咬人了。
蒸馏:训练一个更小的模型去模仿一个更大的模型
蒸馏走的是一条不同的路。它不是压缩一个已有模型的数字,而是从零构建一个全新的、更小的模型,并训练它去模仿一个大模型。大模型是"教师",小模型是"学生",学生通过观察教师的输出、并尝试复现它们来学习。
这之所以比单纯地用原始数据训练一个小模型更管用,原因很微妙。当一个教师模型对一个输入做出回应时,它的输出携带的信息比一个简单的对或错的标签更多——它反映了教师如何权衡不同的可能性,而这捕捉到了关于问题结构的某种东西。学生从那个更丰富的信号中学习。其结果可以是一个小得多的模型,在它被训练去模仿的那类输入上,表现得惊人地接近它的教师,因为它继承了教师所学到的判断力,而不是独自重新发现它。
这里的代价与量化的不同。一个蒸馏出的模型,确实是一个不同的、更小的模型,所以它的上限更低。它倾向于在教师所演示过的领地上表现良好,而在远离那片领地的输入上可能掉链子。蒸馏在前期也要付出实实在在的努力——你得跑一遍训练流程——而量化相对而言,可以很快地应用到一个做好的模型上。
把核心区别明明白白地说出来
量化保持同一个模型,改变的是它的数字如何被存储。蒸馏扔掉大模型,训练一个新的、更小的模型去表现得像它。一个是表示方式的改变;另一个是模型本身的改变。这个区别解释了它们之间的每一项权衡:量化应用起来快、且保住了原模型的完整结构,但在它能缩小到何种程度而质量不受损上是有限的;而蒸馏能产出小得多、快得多的模型,却需要训练的努力,并产出一个上限确实更低的模型。
在二者之间选择——以及把它们结合起来
实际要问的问题是:你的约束究竟是什么。如果你有一个喜欢的模型,只是需要让它塞进更少的内存、或跑得快一点,那么量化是更省力的第一步;应用一个适度的级别,在你自己的任务上度量质量,并在它退化之前停手。如果你需要的东西,比单靠量化所能交付的小得多、快得多——小到能放进一个受限的设备,或便宜到能以极高的量来运行——那么蒸馏就是把你带到那里的更重的工具。
至关重要的是,这两者并非对手。它们运作在不同的原理上,所以可以叠加。一条常见的生产路径是:把一个大模型蒸馏成一个更小的学生,然后再量化那个学生,把两种节省都收入囊中。蒸馏得到的更小模型减少了参数的数量;量化则降低了每个剩余参数的存储成本。结合起来,它们能压缩得比单用任何一种都多得多——只要你在每一步都持续度量质量。
如何知道你是否走得太远
无论哪种技术,都不会告诉你它何时已经伤害了你的应用——只有你自己的评估才会。两种情况下的纪律都一样:组装一小组能代表你真实任务的输入,对"什么才算一个好的输出"有一个清晰的概念,并恰恰在那些输入上,把压缩后的模型与原模型对比。要特别留意那些更难的范例和边缘情形,因为压缩往往先让困难的任务退化,而让简单的看上去没事。一个仍然在简单输入上拿满分、却在难的上面悄悄失手的模型,正是你缩过了那个甜蜜点的经典征兆。
总结
量化和蒸馏都把模型变小,但它们不是同一招。量化把同一个模型的数字存得更紧凑——应用起来快,结构被保住,但能走多远有限。蒸馏训练一个新的、更小的模型去模仿一个更大的——更费力,缩小幅度大得多,上限更低。按你的约束来选,在需要时把它们结合,并让一个从你自己任务构建出的评估,来告诉你"小"何时已经变得太小。只有当一个模型在你真正需要它做的事情上依然足够好时,"更小"才更好。
