FLOPs
FLOPs 用于统计模型完成一次前向传播所需的浮点运算次数,是衡量计算成本的标准指标。了解如何统计、比较和减少 FLOPs。
FLOPs(浮点运算次数)统计神经网络处理一个输入(例如一张图像或一个词元)所执行的算术运算,主要是各层中的乘法和加法。该计数衡量模型的计算成本,不受运行硬件影响,因此是比较不同架构计算量的标准方法。视觉模型通常会报告指定输入尺寸下的 GFLOPs(十亿次运算);训练大型模型所用的总计算量也会以 FLOPs 表示。
FLOPs、FLOPS 与 MACs#
这三个术语很相似,容易混淆:
- FLOPs(小写 s):浮点运算次数,是模型和输入尺寸的属性,用于衡量需要完成多少工作。
- FLOPS(大写 S):每秒浮点运算次数,是 GPU 等硬件的属性,用于衡量完成工作的速度。模型的 FLOPs 除以设备的峰值 FLOPS,即可得出最短可能运行时间。
- MACs:乘加运算次数。一次 MAC 包含一次乘法和一次加法,因此一次 MAC 等于两次 FLOPs。有些论文和工具会将 MACs 称为 FLOPs,使其数值减半。
FLOPs 的计数方法#
网络的大部分 FLOPs 来自矩阵乘法和卷积。一个具有 n 个输入和 m 个输出的全连接层,每个输入大约需要 2 × n × m FLOPs。卷积会为每个输出值计算一个点积,因此其计算量为 2 × C_in × k × k × C_out × H_out × W_out,其中 k 是卷积核尺寸,H_out × W_out 是输出分辨率。激活函数、归一化和加法操作所需的计算量相对较少。下面的示例使用公式计算一个卷积的开销,并通过 PyTorch内置的 FLOP 计数器进行验证:
import torch
from torch.utils.flop_counter import FlopCounterMode
# A 3x3 convolution mapping 64 channels to 128 on an 80x80 feature map
conv = torch.nn.Conv2d(64, 128, kernel_size=3, padding=1, bias=False)
x = torch.randn(1, 64, 80, 80)
# Each output value needs 64*3*3 multiply-accumulates (MACs); 1 MAC = 2 FLOPs
macs = 128 * 80 * 80 * 64 * 3 * 3
print(f"By formula: {2 * macs / 1e9:.3f} GFLOPs ({macs / 1e9:.3f} GMACs)")
# PyTorch's FLOP counter traces the real forward pass
with FlopCounterMode(display=False) as counter:
conv(x)
print(f"Counted: {counter.get_total_flops() / 1e9:.3f} GFLOPs")两行代码都输出 0.944 GFLOPs;公式计算这一行还显示,同一层为 0.472 GMACs,即 FLOPs 数值的一半。对于 Transformer,一次前向传播每个参数、每个词元大约需要 2 FLOPs,训练则约需 6 FLOPs。这是根据缩放定律研究得出的经验法则,用于将训练过程的总计算量估算为 6 × 参数数量 × 训练词元数量。
FLOPs 与实际运行速度#
FLOPs 只能粗略预测速度。延迟还取决于内存传输、每种运算的并行化效率,以及硬件是否针对其优化了内核。ShuffleNet V2 论文表明,即使 FLOPs 相近,网络在同一设备上的运行速度也可能明显不同;FLOPs 较低的深度卷积往往受限于内存带宽,而非运算能力。优化也会影响不同因素。模型剪枝和缩小输入尺寸会减少运算,而模型量化不会改变运算数量,但通过使用 8 位整数计算降低每次运算成本。因此,FLOPs 最适合作为初步筛选指标,之后应在目标设备上测量推理延迟,例如使用 Ultralytics 的基准测试模式:
FLOPs 在模型选择中的作用#
模型系列会发布多种尺寸,让团队在准确率和计算量之间进行权衡;Ultralytics Academy 的模型尺寸课程会讲解如何选择。Ultralytics YOLO26在 640×640 输入尺寸下的计算量从 YOLO26n 的 5.5 GFLOPs 到 YOLO26x 的 194.4 GFLOPs 不等,model.info() 会打印任何已加载模型的 GFLOPs。电池供电的无人机和手机会使用最小的变体,而云服务器则可以承担最大的变体。由于卷积网络的计算成本随像素数量增加,输入尺寸对 FLOPs 的影响与模型尺寸一样大:
from ultralytics import YOLO
from ultralytics.utils.torch_utils import get_flops
# Load the smallest YOLO26 detection model and fuse its layers, as for inference
model = YOLO("yolo26n.pt")
model.fuse()
# Count GFLOPs for the same model at three input resolutions
for imgsz in [320, 640, 1280]:
print(f"{imgsz}px: {get_flops(model.model, imgsz):.1f} GFLOPs")循环输出 1.3、5.5 和 23.4 GFLOPs:输入边长每翻一倍,计算量大约会变为四倍。因此,在 1,280 像素下运行 YOLO26n 的成本高于 640 像素下 YOLO26s 的 20.9 GFLOPs,尽管 YOLO26s 的参数量是前者的四倍。










