先设想一个具体的场景:一台两三年前买的手机,存储还剩一些,芯片不算新,但你想让一个对话助手在飞行模式下也能用。模型文件躺在那里,装得下,却跑不动。内存塞不进,发热也压不住。这类问题在工程上往往通过把模型本身改小来解决,而不用换更大的芯片。也就是模型压缩。
真正被压缩的,其实是三样东西
很多人以为压缩就是把文件变小,像打包一个 zip。但权重文件变小并不是目的,真正的目的是让推理时的内存占用、带宽和计算量同时降下来。所以压缩通常涉及三处改动:
- 参数的存储精度。原本用较高精度保存的权重,改成更低的位宽表示,体积和访存压力一起减少。
- 参数的数量。通常要找出对输出影响小的部分再删掉,避免随机删除;另一种做法是用低秩分解,把一个大矩阵近似成两个小矩阵相乘。
- 计算路径。让不同的输入只走其中一部分,或者把多个专家的能力合并到一个更小的结构里。
这三条路常常叠加使用,但也互相牵制。位宽降得太狠,精度掉得明显;剪得太多,模型在某些长尾输入上开始出错,而错误往往不在你测试的那批样本里。
量化为什么比剪枝更常被用
量化只改变数值表示,网络结构不动,工程落地相对简单,工具链也成熟,因此在实际部署里出现得更频繁。剪枝和蒸馏则需要更多的重训练和结构调整,牵动的东西多,验证成本也高。这里的问题往往是你能接受多大的返工,而很难用哪条路更优越来简单概括。一个已经很稳定的训练流程,通常不愿意为了体积收益推翻重来。
压缩之后,问题才刚开始
把模型压小,只是把一个原本跑不动的模型变成跑得动。接下来要回答的是它还能不能干原来的活。以下几种典型的退化,值得在设计阶段就写进验收清单:
- 整体指标看着没变,但某一类输入的错误率上升,比如数字、否定句、长段落里的关键信息。
- 输出变得更短、更平,遇到需要多步推理的问题容易停在第一步。
- 对提示词的细微变化更敏感,同样的意思换个说法,结果差很多。
这些问题很难靠一个大而化之的评测集发现。比较务实的做法是先把真实业务里出现过的、曾经出错过的输入收集起来,用小批量反复测,看压缩前后的差异集中在哪儿。这项工作琐碎,却往往比调参更能决定上线与否。
一个容易被忽略的边界
模型压缩有明确的成本,也不该被当成默认选项。当任务本身要求高精度、或者模型规模本就不大时,压缩带来的收益可能被验证成本抵消。还有一种情况:端侧算力和内存的增长速度,有时会让原本必须压缩的场景变得不那么紧迫。所以值得先问一句:是真的塞不进去,还是只是没调好。
从工程角度看,模型压缩更像一次预算分配:把有限的参数、位宽和算力,分配到对结果真正重要的地方。它考验的是你对模型在具体场景里会怎么出错的了解,而非某一个技巧。这件事没法完全自动化,也正因为如此,它还需要人来下判断。