flops-counter.pytorch
sovrasov/flops-counter.pytorch加载项目详情…
本应用为开源项目,仅供学习研究,请遵守其开源协议。
加载项目详情…
本应用为开源项目,仅供学习研究,请遵守其开源协议。
想象你是一名厨师,要为一场宴会准备 500 份菜品。在采购食材之前,你是不是得先知道每道菜需要多少原料?深度学习模型的训练和部署也是同样的道理——在把模型跑起来之前,你得先搞清楚它到底有多"重",也就是需要多少计算量。
这就是 ptflops 存在的意义。它是一个专门为 PyTorch 框架打造的模型计算量统计工具,能够精确计算出神经网络的 FLOPs(Floating Point Operations,浮点运算次数,即乘加操作数)和参数量。你不需要实际运行模型,只要把模型结构扔给它,它就能告诉你:这个模型每秒要处理多少次乘加运算、有多少参数、每个层的计算开销分别是多少。
这个工具的作者是 Sergey Sovrasov(GitHub ID: sovrasov),他在计算机视觉模型优化领域有着深厚的积累。项目自发布以来累计获得 2983 stars,被广泛用于模型效率分析、架构对比、论文实验数据验证等场景。
ptflops 的核心 API 是 get_model_complexity_info(),使用方式极其简单:
import torchvision.models as models
from ptflops import get_model_complexity_info
net = models.resnet50()
macs, params = get_model_complexity_info(net, (3, 224, 224), as_strings=True)
print(f"Computational complexity: {macs}")
print(f"Number of parameters: {params}")
输出示例(以 ResNet50 为例):
Computational complexity: 4.13 GMac
Number of parameters: 25.56 M
只需开启 print_per_layer_stat=True,ptflops 就能打印出每个层的详细开销:
Layer Name | Params(M) | MACs(G) | Percentage
-----------------------------------------------------------------------------
conv1 | 0.02 | 0.20 | 4.83%
layer1.0.conv1 | 0.04 | 0.40 | 9.66%
layer1.0.conv2 | 0.37 | 3.58 | 86.52%
这种逐层拆解对于定位模型瓶颈极为有用。当你发现某个自定义层的计算量异常高时,可以针对性地做剪枝或优化。
ptflops 提供了两个计算后端,这是它区别于其他 FLOPs 工具的独特设计:
| 后端 | 适用场景 | 特点 |
|---|---|---|
| aten(默认推荐) | Transformer、混合架构、通用模型 | 基于 aten 算子,计算覆盖最全面,支持更多操作类型 |
| pytorch | CNN、传统模型 | 基于 nn.Module 层级,对 CNN 有更好的逐层分析精度 |
对于 ViT、Swin Transformer 等现代架构,必须使用 aten 后端(pytorch 后端对 ViT-B/16 给出的 FLOPs 是 17.61G,明显偏高;aten 后端正确值为 16.86G)。
如果你的模型包含自定义层或第三方库模块,ptflops 支持通过 custom_modules_hooks 注入自定义计算逻辑:
def my_custom_hook(m, input, output):
# 手动指定该层的 FLOPs 计算方式
...
macs, params = get_model_complexity_info(
model, (3, 224, 224),
custom_modules_hooks={MyCustomLayer: my_custom_hook}
)
ptflops 的代码结构简洁清晰,核心位于 ptflops/ 目录:
ptflops/
├── flops_counter.py # 主入口,get_model_complexity_info()
├── pytorch_engine.py # pytorch 后端实现
├── aten_engine.py # aten 后端实现(推荐)
├── pytorch_ops.py # 各操作层的 FLOPs 映射表
├── utils.py # 单位换算工具
└── __init__.py # 导出接口
pytorch 后端原理:通过 register_forward_hook 在每个 nn.Module 的前向传播时注入计数器,自动累加该层的乘加操作数。额外 patch 了 torch.nn.functional 中的函数(如 F.linear、F.gelu 等),确保函数式操作也能被统计进来。
aten 后端原理:基于 PyTorch 的 aten(ATen)底层算子层做统计,覆盖范围更广,支持更复杂的模型结构。
# PyTorch 2.0+
pip install ptflops
# PyTorch 1.x
pip install ptflops==0.7.2.2
import torchvision.models as models
from ptflops import get_model_complexity_info
for name, constructor in [('efficientnet_b0', models.efficientnet_b0),
('efficientnet_b3', models.efficientnet_b3)]:
net = constructor()
macs, params = get_model_complexity_info(net, (3, 224, 224), as_strings=True, backend='aten')
print(f"{name}: {macs}, {params}")
这在论文写作或模型选型时非常实用——你可以快速建立一张"模型复杂度对比表",不必每次都实际跑一遍。
ptflops 作为一个理论计算量估算工具,有几点需要注意:
实际运行开销 ≠ 理论 FLOPs:因为内存访问、并行度、硬件特性等因素,不同模型的实际推理速度与 FLOPs 并不完全成正比。例如,ShuffleNetV2 的 FLOPs 较高,但实际推理速度反而更快。
aten 后端不支持 per-layer 精确统计:aten 后端以算子粒度统计,无法像 pytorch 后端那样给出精确到每个 nn.Module 的拆分。因此做 CNN 逐层分析时,推荐用 pytorch 后端。
自定义 hook 需要手动维护:如果项目迭代中新增了自定义层,别忘了同步更新 custom_modules_hooks。
复杂输入需要 input_constructor:多输入模型(如目标检测中的 image + boxes)需要自行编写 input_constructor,不能直接传入 tuple。
在模型效率研究领域,FLOPs 是评估模型复杂度的事实标准。ptflops 凭借以下优势,在众多同类工具中脱颖而出:
目前,它在 GitHub 上拥有近 3000 个 star,是 PyTorch 生态中计算复杂度分析方向的标杆工具。
总结:如果你在做深度学习模型研发、论文写作、模型选型或优化工作,ptflops 是你工具箱中不可或缺的一员。它让"模型的重量"变得可量化、可对比,是每一位 PyTorch 开发者都应该掌握的基础工具。