FLOPs
FLOPs는 모델이 순전파 한 번에 필요한 부동소수점 연산 횟수로, 연산 비용을 측정하는 표준 지표입니다. FLOPs의 계산, 비교, 감소 방법을 다룹니다.
FLOPs(부동소수점 연산 횟수)는 신경망이 이미지 한 장이나 토큰 하나와 같은 입력 하나를 처리하기 위해 수행하는 산술 연산 수를 나타내며, 대부분 각 레이어의 곱셈과 덧셈으로 구성됩니다. FLOPs는 실행 하드웨어와 관계없이 모델의 연산 비용을 측정하므로 아키텍처의 연산량을 비교하는 표준 지표입니다. 비전 모델은 일반적으로 지정된 입력 크기에서 GFLOPs(십억 회 연산)로 표시하며, 대형 모델의 학습에 사용된 총 연산량도 FLOPs로 나타냅니다.
FLOPs, FLOPS, MACs 비교#
비슷해 혼동하기 쉬운 용어는 다음 세 가지입니다:
- FLOPs(소문자 s): 부동소수점 연산 횟수이며 모델과 입력 크기의 속성입니다. 수행해야 하는 작업량을 측정합니다.
- FLOPS(대문자 S): 초당 부동소수점 연산 횟수이며 GPU와 같은 하드웨어의 성능 특성입니다. 작업을 얼마나 빠르게 수행할 수 있는지 나타냅니다. 모델의 FLOPs를 장치의 최대 FLOPS로 나누면 가능한 최단 실행 시간을 구할 수 있습니다.
- MACs: 곱셈 누산 연산입니다. 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보다 많은 연산이 필요합니다.










