模型大小与推理速度:一个老工程师的直觉

做模型优化这些年,我见过太多人一上来就问:「怎么让模型跑得更快?」

其实这个问题背后,藏着三个关键变量:模型大小、推理速度、还有精度。这三者就像跷跷板,你压下去一头,另一头就会翘起来。

我个人习惯,拿到一个模型先看它的存储体积。你想想看,一个 500MB 的 YOLOv5 模型,跟一个 50MB 的剪枝版本,部署到 Jetson Nano 上的体验能一样吗?前者加载就要好几秒,后者几乎秒开。

核心结论:模型大小直接影响显存占用和带宽消耗。模型越大,推理时从显存搬运数据的开销就越大,延迟自然就上去了。

但这里有个坑——模型大小 ≠ 推理速度。我在项目中遇到过,一个参数量更小的模型,因为结构设计不合理(比如过多的分组卷积),实际跑起来反而比大模型还慢。所以,光看文件大小是不够的。

参数量与计算量:FLOPs 到底在算什么?

先说参数量(Params)。说白了,就是模型里所有可学习参数的总数。每个卷积核的权重、每个 BN 层的 gamma 和 beta,都算进去。

举个例子,一个标准的 3x3 卷积,输入通道 64,输出通道 128:

参数量 = 3 × 3 × 64 × 128 + 128(偏置) = 73,856

嗯,就这么简单。但要注意,参数量只决定模型能「记住」多少信息,并不直接决定它跑得快不快。

真正影响推理速度的,是计算量(FLOPs)——浮点运算次数。还是上面那个卷积,它处理一张 224x224 的图:

FLOPs = 2 × 3 × 3 × 64 × 128 × 224 × 224 ≈ 17.6 G

为什么乘 2?因为一次乘法和一次加法算两次运算。这个细节,我刚开始也经常搞混。

我的经验:参数量决定「存储成本」,FLOPs 决定「计算成本」。剪枝主要砍参数量,量化主要降 FLOPs 的位宽开销。两者配合,效果最好。

模型冗余的本质:为什么能剪掉一半还不掉点?

你可能会问:好好的模型,为什么会有冗余?

其实,深度学习模型天生就是过参数化的。我打个比方,你让 10 个人去搬一张桌子,其实 5 个人就够了,剩下 5 个人在「摸鱼」。模型里的很多神经元,权重接近零,或者输出高度相关,它们对最终结果贡献很小。

冗余的来源主要有三种:

  • 权重冗余:大量权重值接近 0,对输出影响微乎其微
  • 通道冗余:某些特征图之间高度相似,保留一个就够了
  • 结构冗余:某些层或分支在特定任务上是多余的

我记得有一次,对一个 YOLOv5s 做通道剪枝,剪掉 40% 的通道后,mAP 只掉了 0.3%。我当时还不太信,反复验证了好几遍。后来想通了——模型在训练时,为了拟合数据,会「过度学习」很多噪声模式。剪枝相当于帮它做了一次「断舍离」。

避坑指南:我曾经以为冗余越多越好剪,结果在一个轻量级模型(MobileNetV3)上翻车了。轻量模型本身冗余就少,强行剪枝会导致精度断崖式下跌。所以,大模型适合剪枝,小模型更适合量化

一张表看懂三者的关系

指标 定义 对推理速度的影响 优化手段
模型大小 存储体积(MB/GB) 影响加载时间和显存占用 量化、权重共享
参数量 可学习参数总数 间接影响(通过 FLOPs) 结构剪枝、低秩分解
FLOPs 浮点运算次数 直接影响延迟 通道剪枝、稀疏化

你看,这三者虽然相关,但优化时得对症下药。我见过有人花大力气把参数量砍了一半,结果 FLOPs 没怎么变,推理速度纹丝不动——这就是没搞清楚目标。

我的优化原则

做了几年模型优化,我总结了几条原则,分享给你:

  1. 先分析,再动手:用 profile 工具跑一遍,看瓶颈在哪。是计算密集还是访存密集?
  2. 剪枝和量化要分步走:先剪枝再量化,顺序别搞反。量化后的模型再做剪枝,精度很难恢复。
  3. 保留关键通道:剪枝时别只看权重大小,还要看通道对最终输出的贡献。我习惯用 BN 层的 gamma 值作为重要性指标。
  4. 验证要彻底:剪完一个层,马上跑一遍验证集。别等到全剪完了才发现精度崩了。

最后说一句:模型优化不是玄学,是工程。你理解得越深,踩的坑就越少。下一章,我会带你手撸一个简单的剪枝工具,到时候你就知道这些概念怎么落地了。