一块一直发烫的板子
调试台上那块开发板只有巴掌大,跑着一个参数规模不算大的模型,风扇从开机响到关机。有人顺口说,压一压不就行了。这句话在工程里几乎每天都能听到,但“压一压”从来不是一个动作,而是一串需要签字确认的取舍。
被压掉的三样东西,其实不一样
模型压缩常被当成一个整体来谈,底下其实挂着几件互不相同的事:
- 降低数值精度。把权重和激活从高比特换成低比特,显存占用和访存带宽随之下降,推理往往更快。
- 删减结构。把贡献微弱的连接、通道或层去掉,得到一个更稀疏或更窄的网络。
- 迁移行为。让一个小模型去模仿大模型的输出分布,压掉的是“参数从哪来”,而不是已有参数本身。
三者省的是不同的资源:第一类省带宽,第二类省算力,第三类省的是部署时的推理开销,代价则转移到训练阶段。混为一谈,就容易在选型时对错号。
省下来的,和在别处花掉的
低比特量化最容易被低估的地方,是它在平均值上几乎看不出问题。常规测试集上的指标可能只掉一点点,但真正上线后暴露麻烦的,往往是长尾输入——罕见表述、边界数值、格式不规整的文本。平均值掩盖的正是这些。
剪枝听起来更“干净”,但稀疏的模型在通用硬件上不一定跑得快。硬件喜欢规整,删出来的空洞如果填不回整齐的矩阵形状,加速比就会打折,甚至不如不剪。这是不少人踩过的坑。
蒸馏的账最好算也最难算:部署端轻了,训练端重了,而且需要一份足够可靠的教师输出。它压的是推理成本,不是总成本。
指标没掉,不等于没坏
评估压缩效果时,用通用基准看一眼是不够的。更实际的做法,是拿自己的真实输入分布做对照:同一批请求,压缩前后逐条比对输出差异,看差异集中在哪类输入上。如果差异恰好落在业务最在意的那一小撮请求上,整体指标再好看也没意义。
还有一层常被忽略:量化会改变输出的稳定性。同一个问题问两次,答案的措辞波动可能变大。对需要一致性的场景,这种漂移比精度下降更难排查。
什么情况下不该压
有些系统里,模型根本不是瓶颈。耗时大头在数据预处理、序列化、调度排队或者网络往返,这时候花两周做模型压缩,收益可能被一次接口改造盖过去。先做一次端到端的耗时拆解,再决定要不要动模型,顺序不该反。
另一条边界更硬:压缩不会凭空造出信息。任务本身依赖细粒度的数值推理、依赖长链条的精确计算时,低比特带来的损失会最先在中间步骤上累积,而不是在最终答案上温和地体现。这类任务往往压到某个程度就突然失效,而不是缓慢退化。
一个更朴素的问题
所以在动手之前,值得先问一句:现在缺的到底是显存、是延迟,还是并发能力?三者对应的手段并不相同,混着做,往往哪一项都没解决。模型压缩是一门把资源换回来的手艺,换什么、放弃什么,最好在开始之前就写清楚。