FLOPs
FLOPsは、モデルが1回の順伝播で必要とする浮動小数点演算の数であり、計算コストを測る標準的な指標です。算出、比較、削減の方法を解説します。
FLOPs(浮動小数点演算数)は、ニューラルネットワークが1つの入力、たとえば1枚の画像や1つのトークンを処理する際に実行する演算の数を表します。その大部分は、各層内の乗算と加算です。この数値は実行するハードウェアに依存せずモデルの計算コストを測るため、アーキテクチャごとの計算負荷を比較する標準的な指標です。ビジョンモデルでは、指定された入力サイズでのGFLOPs(数十億回の演算数)が通常示され、大規模モデルの学習に使われる総計算量もFLOPsで示されます。
FLOPs、FLOPS、MACsの違い#
似た用語が3つあり、混同しやすいため注意が必要です。
- FLOPs(小文字のs):浮動小数点演算の数で、モデルと入力サイズに依存します。実行が必要な処理量を示します。
- FLOPS(大文字のS):1秒あたりの浮動小数点演算数で、GPUなどのハードウェアの性能を表します。処理速度を示し、モデルのFLOPsをデバイスのピークFLOPSで割ると、理論上の最短実行時間が得られます。
- MACs:積和演算数です。1 MACは乗算1回と加算1回に相当するため、1 MACは2 FLOPsに相当します。論文やツールによってはMACsをFLOPsという名称で報告しており、その場合は数値が半分になります。
FLOPsの数え方#
ネットワークのFLOPsの大部分は、行列乗算と畳み込みによるものです。入力数がn、出力数がmの全結合層は、入力1つあたり約2 × n × m FLOPsかかります。畳み込みでは出力値ごとに1つの内積を計算するため、計算コストは2 × C_in × k × k × C_out × H_out × W_outです。ここで、kはカーネルサイズ、H_out × W_outは出力解像度です。活性化関数、正規化、加算のコストは比較的小さくなります。以下の例では、式で1つの畳み込みのコストを計算し、PyTorchに組み込まれたFLOPsカウンターで確認します。
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倍です。これはスケーリング則の研究に基づく経験則で、学習実行の総計算量を6 × パラメーター数 × 学習トークン数と見積もります。
FLOPsと実際の速度#
FLOPsから予測できる速度はおおよそのものです。レイテンシはメモリ転送、各演算の並列化のしやすさ、ハードウェアに最適化カーネルがあるかどうかにも左右されます。ShuffleNet V2の論文では、FLOPsが同程度のネットワークでも、同じデバイス上で速度が明確に異なる場合があることが示されました。また、FLOPsが少ない深さ方向畳み込みは、演算量ではなくメモリ帯域幅がボトルネックになることがよくあります。最適化もそれぞれ異なる要素に作用します。モデルプルーニングや入力サイズの縮小は演算を削減しますが、モデル量子化は演算数を変えず、8ビット整数演算によって各演算のコストを下げます。そのため、FLOPsは、対象デバイスで推論レイテンシを測定する前の初期スクリーニングに最適です。たとえばUltralyticsのベンチマークモードを使って測定できます。
モデル選定におけるFLOPs#
モデルファミリーは複数のサイズで公開され、チームは計算量と精度のバランスを選べます。Ultralytics Academyのモデルサイズに関するレッスンでは、この選択方法を説明しています。入力サイズが640×640の場合、Ultralytics YOLO26は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を出力します。入力の各辺を2倍にすると演算数は約4倍になります。そのため、1,280ピクセルでYOLO26nを実行すると、640ピクセルで実行するパラメーター数4倍のYOLO26sの20.9 GFLOPsを上回る計算コストがかかります。










