YOLO 아키텍처 설명: YOLOv3부터 YOLO26까지#
모든 Ultralytics YOLO 모델은 세 단계로 구성됩니다. 특징을 추출하는 백본, 여러 스케일에 걸쳐 특징을 융합하는 넥, 그리고 박스와 클래스를 예측하는 헤드입니다. 이 가이드에서는 각 단계를 구성하는 모듈과 YOLOv3부터 YOLO26까지 모듈이 어떻게 변경되었는지 설명하고, 각 구성 요소를 ultralytics/cfg/models/ 아래의 구성 파일 정의와 ultralytics/nn/modules/의 모듈 클래스까지 추적합니다.
각 모델은 YAML 파일에서 레이어의 순서가 지정된 목록으로 선언되며, 모든 레이어는 [from, repeats, module, args] 형식을 따릅니다. 즉, 어떤 레이어가 입력을 제공하는지, 모듈이 몇 번 반복되는지, 레이어 클래스(Conv, C3k2, SPPF, Detect, …), 그리고 생성자 인수를 지정합니다. Model YAML Configuration Guide에서는 이 형식과 함께 repeats 및 args이 변형의 depth 및 width 배수에 따라 어떻게 스케일링되는지, 그리고 모듈 해석 시스템 전체를 설명합니다. 이 가이드에서는 모듈 자체와 버전별 변경 사항에 중점을 둡니다.
세 가지 단계#
모든 Ultralytics YOLO 모델은 이미지를 서로 다른 역할을 가진 세 개의 순차적인 단계를 거쳐 처리합니다.
| 단계 | 역할 | 출력 |
|---|---|---|
| 백본 | 입력 이미지에서 여러 해상도의 특징을 추출합니다 | stride 8, 16, 32의 특징 맵(P3, P4, P5) |
| 넥 | 작은 객체와 큰 객체 모두 문맥 정보를 갖도록 여러 스케일의 특징을 융합합니다 | 멀티스케일 융합 특징 맵 |
| 헤드 | 융합된 특징으로부터 바운딩 박스와 클래스 점수를 예측합니다 | 앵커 포인트별 감지 결과 |
기본 단위는 conv.py에 정의된 Conv 블록입니다. 이 블록은 2D convolution, batch normalization, SiLU activation을 순서대로 적용합니다. 아래의 더 큰 모든 모듈은 Conv 블록을 조합하여 구성됩니다.
아키텍처 다이어그램#
각 버전은 동일한 백본 → 넥 → 헤드 골격을 유지하면서 특정 단계를 변경합니다. 아래 탭에는 버전별 구조가 표시됩니다. 백본과 넥 단계는 ultralytics/cfg/models/의 구성 파일을 따르지만, YOLOv3 및 YOLOv5 헤드는 패키지 구성에 실제로 포함된 앵커 프리 u 변형 헤드가 아니라 원래의 앵커 기반 형식으로 그려집니다. 탭을 차례로 확인하면 각 세대에서 추가된 내용을 볼 수 있습니다. 요약하면 YOLOv3는 FPN만 사용하는 앵커 기반 detector이고, YOLOv5는 bottom-up PAN 경로와 SPPF를 추가했으며, YOLOv8은 앵커 프리 DFL 헤드와 함께 C2f 블록으로 전환했고, YOLO11은 C2PSA attention과 C3k2 블록을 삽입했으며, YOLO26은 SPPF residual을 추가하고 헤드를 NMS-free 및 DFL-free로 만들었습니다. 노드 색상은 문서 다이어그램의 규칙을 따릅니다. 녹색은 입력, 파란색은 백본, 슬레이트색은 spatial pooling 및 attention, 주황색은 넥, 보라색은 헤드와 출력을 나타냅니다.
flowchart TD
IN[Input 640x640]:::start --> ST[Conv stem<br/>5x stride-2 down to P1-P5]:::proc
ST --> BB[Darknet-53 backbone<br/>stacked Bottleneck]:::proc
BB --> FPN[Neck FPN only<br/>top-down Upsample + Concat]:::decide
FPN --> HD[Detect head<br/>3 scales, anchor-based]:::out
HD --> O[Predictions + NMS]:::out
classDef start fill:#4CAF50,color:#fff
classDef proc fill:#2196F3,color:#fff
classDef decide fill:#FF9800,color:#fff
classDef out fill:#9C27B0,color:#fffYOLOv3 및 YOLOv5 다이어그램은 원래의 앵커 기반 헤드를 보여줍니다. ultralytics 패키지에는 앵커 프리 YOLOv3u 및 YOLOv5u 구성이 포함되어 있습니다. 이 구성은 동일한 Darknet-53 및 C3 백본에 YOLOv8의 Detect 헤드를 사용하며, Detection Head에서 설명합니다.
백본 블록: Bottleneck → C3 → C2f → C3k2#
백본은 stride-2 Conv downsampling 레이어 사이에 반복되는 CSP (Cross-Stage Partial) 블록을 쌓습니다. 이 반복 블록이 버전별로 가장 크게 변경된 부분입니다. 아래의 모든 블록은 block.py에 있으며, c1/c2는 입력/출력 채널이고 c = 0.5 * c2는 hidden width입니다.
Bottleneck (YOLOv3)#
기본 단위는 Bottleneck입니다. 두 개의 Conv 레이어(기본 커널 (3, 3))로 구성되며, shortcut=True 및 c1 == c2일 때 선택적으로 residual add를 수행합니다. YOLOv3의 Darknet-53 백본은 CSP 분할 없이 이 블록을 직접 쌓으며, 세 가지 스케일(stride 8, 16, 32)에서 감지합니다.
C3 (YOLOv5)#
YOLOv5의 C3은 두 개의 1x1 convolution을 통해 입력을 분할합니다. cv1은 n개의 Bottleneck 순차 블록(커널 (1, 1) 다음 (3, 3))으로 전달되고, cv2은 이를 우회합니다. 두 경로를 concatenate한 후 세 번째 1x1 Conv으로 융합합니다.
def forward(self, x):
# C3: bottleneck path m(cv1(x)) concatenated with bypass cv2(x), then fused by cv3
return self.cv3(torch.cat((self.m(self.cv1(x)), self.cv2(x)), 1))마지막 bottleneck 출력만 fusion conv에 도달하므로 cv3은 특징 맵 2개를 입력으로 받습니다.
C2f (YOLOv8)#
YOLOv8의 C2f("CSP Bottleneck with 2 convolutions, faster")은 fusion conv에 전달되는 특징을 변경합니다.
cv1 = Conv(c1, 2 * c, 1)다음chunk(2)이 출력을 두 개의c채널 tensor로 분할합니다.n개의Bottleneck(c, c)블록(커널(3, 3),(3, 3))이 순차적으로 실행되며, 각 블록은 이전 블록의 출력을 입력으로 받습니다.- 모든
n + 2중간 tensor를 concatenate한 후cv2 = Conv((2 + n) * c, c2, 1)로 융합합니다.
C3은 fusion conv에 특징 맵 2개를 전달하는 반면, C2f은 n + 2개를 전달합니다. 즉, 모든 중간 bottleneck 출력이 재사용됩니다.
C3k2 (YOLO11 및 YOLO26)#
YOLO11과 YOLO26은 C3k2를 사용합니다. 이는 반복 단위를 교체하는 C2f의 subclass입니다. 각 n 블록은 생성자 플래그에 따라 다음 중 하나가 됩니다.
- 일반
Bottleneck(기본값,c3k=False), C3k블록(c3k=True) — 커널 크기를 구성할 수 있는C3변형, 또는Bottleneck+PSABlock쌍(attn=True).
두 번째 YAML 인수는 c3k을 설정합니다. 단, 스케일이 m, l 또는 x이면 True로 강제됩니다. 이것이 하나의 yolo11.yaml로 다섯 가지 변형을 모두 처리하는 방식입니다. 따라서 [-1, 2, C3k2, [512, False]]은 Bottleneck 내부를 n 및 s에서 빌드하지만, C3k 내부는 m, l 및 x에서 빌드합니다. 512는 스케일링 전 채널 수이며, 변형의 width 배수에 따라 n에서는 128로, x에서는 768로 변환됩니다. CSP 모듈에서 repeats 필드(여기서는 변형의 depth 배수로 스케일링되기 전의 2)는 별도의 모듈을 쌓는 대신 블록의 내부 반복 횟수가 됩니다.
Spatial Pooling: SPP → SPPF#
백본 끝에서는 spatial-pyramid-pooling 블록이 receptive field를 확장합니다. YOLOv5는 기존의 multi-kernel SPP을 SPPF(Spatial Pyramid Pooling - Fast)으로 대체했습니다. 이는 하나의 MaxPool2d(kernel_size=5, stride=1, padding=2)를 연속해서 n = 3번 적용하고, 입력과 세 개의 pooling 출력을 concatenate한 뒤 1x1 Conv로 융합합니다. 연결된 5x5 pooling이 더 큰 커널의 receptive field를 포함하므로, 이는 SPP(k=(5, 9, 13))과 수학적으로 동등하면서도 더 저렴합니다.
YOLO26은 shortcut 플래그(SPPF, [1024, 5, 3, True])를 전달합니다. 가장 깊은 레이어에서 c1 == c2 == 1024이므로 SPPF은 residual connection(return y + x)을 추가합니다.
Spatial Attention: C2PSA (YOLO11+)#
YOLO11은 SPPF 뒤에 **C2PSA**을 추가했습니다. 이는 활성 branch가 n개의 PSABlock(Position-Sensitive Attention) 모듈을 쌓은 CSP 블록입니다. cv1 = Conv(c1, 2 * c, 1)가 특징을 분할하고, 절반은 PSABlock stack을 통과하며, cv2 = Conv(2 * c, c1, 1)이 concatenate 결과를 융합합니다. 각 PSABlock은 multi-head attention에 이어 두 레이어 feed-forward network(Conv(c, 2 * c, 1) → Conv(2 * c, c, 1))를 적용하며, 각각 residual connection을 사용합니다. YOLO26은 동일한 C3k2 + C2PSA 백본을 유지합니다.
넥: FPN + PAN#
넥은 top-down Feature Pyramid Network (FPN)에 이어 bottom-up Path Aggregation Network (PAN)을 사용하여 백본의 P3/P4/P5 특징 맵을 융합합니다. YAML head 섹션에서 FPN은 nn.Upsample + Concat(semantic information을 더 높은 해상도로 전달)이고, PAN은 stride-2 Conv + Concat(localization information을 다시 위로 전달)입니다.
# YOLO11 head (FPN top-down, then PAN bottom-up)
- [-1, 1, nn.Upsample, [None, 2, "nearest"]]
- [[-1, 6], 1, Concat, [1]] # cat backbone P4
- [-1, 2, C3k2, [512, False]] # 13
# ... second upsample + concat to P3 ...
- [-1, 1, Conv, [256, 3, 2]]
- [[-1, 13], 1, Concat, [1]] # cat head P4 (PAN)
- [-1, 2, C3k2, [512, False]] # 19넥은 해당 세대의 백본 블록을 재사용합니다. YOLOv5에서는 C3, YOLOv8에서는 C2f, YOLO11 및 YOLO26에서는 C3k2를 사용하므로, 각 merge point에서 백본과 동일한 모듈이 실행됩니다. 세 개의 융합 출력이 헤드로 전달됩니다. YOLOv3는 예외로, 넥이 top-down FPN만 사용합니다. 해당 YAML head에는 stride-2 downsampling이 없으므로 YOLOv5에서 도입한 bottom-up PAN 경로가 없습니다.
Detection Head: Anchor-Based → Anchor-Free → NMS-Free#
헤드는 세 개의 융합 특징 맵을 detection task의 예측으로 변환합니다. 설계는 버전이 바뀌면서 앵커 기반에서 앵커 프리, 다시 NMS-free 방식으로 변경되었습니다.
앵커 프리, decoupled Detect#
원래 YOLOv3와 YOLOv5는 anchor-based coupled head를 사용했습니다. 즉, 사전 정의된 anchor box와 box 및 class 예측을 위한 공유 branch를 사용했습니다. 독립적인 ultralytics/yolov3 및 ultralytics/yolov5 repository는 이 anchor-based 설계를 유지합니다. 반면 기본 ultralytics 패키지에는 앵커 프리 YOLOv3u 및 YOLOv5u 변형이 포함되어 있습니다. 이 변형은 동일한 Darknet-53 및 C3 백본에 YOLOv8의 앵커 프리 Detect 헤드를 사용합니다. 여기서 설명하는 yolov3.yaml 및 yolov5.yaml 구성은 과거의 설계가 아닌 이러한 u 변형입니다.
Detect 헤드(head.py)는 앵커 프리 및 decoupled 방식입니다. 각 pyramid level에서 두 개의 병렬 branch를 실행하며, anchor box를 기준으로 하지 않고 grid point에서 직접 예측합니다.
- Box branch (
cv2):Conv(x, c2, 3)→Conv(c2, c2, 3)→Conv2d(c2, 4 * reg_max, 1). - Class branch (
cv3): YOLO11 및 YOLO26에서는 두 개의 depthwise-separable 블록(DWConv+1x1 Conv) →Conv2d(c3, nc, 1)이고, YOLOv8에서는 legacy 변형인 두 개의3x3 Conv레이어 →Conv2d(c3, nc, 1)를 사용합니다.
따라서 각 anchor point는 no = nc + 4 * reg_max개의 출력을 생성합니다. 사전 정의된 anchor를 제거하면 조정해야 하는 hyperparameter에서 anchor box의 크기와 종횡비가 제외됩니다.
Distribution Focal Loss (DFL)#
YOLOv8과 YOLO11은 4개의 box 좌표 각각을 단일 scalar가 아니라 reg_max = 16개 bin에 대한 distribution으로 회귀합니다(Generalized Focal Loss의 적분 형식). DFL 모듈은 4 * reg_max개의 box 채널을 (4, reg_max)로 reshape하고, reg_max개 bin에 softmax를 적용한 뒤 예상 bin index를 계산합니다. 즉, 각 bin index에 softmax 확률을 가중하고 합산하여 예측 좌표를 얻습니다. 이는 가중합이 단일 dot product가 되도록 bin index arange(reg_max)을 weight로 사용하는 고정 1x1 convolution으로 구현됩니다.
YOLO26: NMS-free, DFL-free#
YOLO26은 헤드가 직접 읽는 두 개의 YAML parameter를 설정합니다.
end2end: True—Detect은 branch를 one-to-one head(one2one_cv2/one2one_cv3)로 deep-copy합니다. 이 head는 객체당 하나의 예측을 생성하므로 Non-Maximum Suppression (NMS) post-processing 단계를 제거합니다. export 및 migration 세부 정보는 End-to-End Detection guide를 참조하십시오.reg_max: 1— bin이 하나이면self.dfl은nn.Identity()및no = nc + 4이 되며, 헤드는 좌표를 직접 회귀합니다. 따라서 export된 ONNX graph에는 DFL 연산이 나타나지 않습니다.
다섯 가지 모델 크기(n/s/m/l/x)에서 YOLO26은 YOLO26 paper에 보고된 바와 같이 1.711.8ms의 T4 TensorRT latency에서 COCO 기준 40.957.5 mAP를 달성합니다.
버전별 요약#
| 버전 | 백본 블록 | Spatial pooling | Attention | Detection head | DFL |
|---|---|---|---|---|---|
| YOLOv3 | Darknet-53 (Bottleneck) | base config에 없음 | 없음 | 원본: 앵커 기반; u 변형: 앵커 프리 | 아니요 / 예 (u) |
| YOLOv5 | C3 (CSP) | SPPF | 없음 | 원본: 앵커 기반; u 변형: 앵커 프리 | 아니요 / 예 (u) |
| YOLOv8 | C2f | SPPF | 없음 | 앵커 프리, decoupled | 예 (reg_max=16) |
| YOLO11 | C3k2 | SPPF | C2PSA | 앵커 프리, decoupled | 예 (reg_max=16) |
| YOLO26 | C3k2 | SPPF + shortcut | C2PSA | 앵커 프리, NMS-free (end2end) | 제거됨 (reg_max=1) |
모델별 세부 정보, 성능 표, 사용 예제는 YOLOv3, YOLOv5, YOLOv8, YOLO11, YOLO26의 개별 페이지를 참조하십시오.
아키텍처 직접 확인하기#
model.info() method는 레이어, parameter 및 FLOPs 요약을 출력하며, 파싱된 모듈 목록은 model.model.model에서 확인할 수 있습니다.
from ultralytics import YOLO
# Load a pretrained model
model = YOLO("yolo11n.pt")
# Fuse Conv + BatchNorm layers so counts match the published specs
model.fuse()
# Print a summary: layers, parameters, gradients, GFLOPs
model.info()
# Inspect the detection head (the last module in the network)
head = model.model.model[-1]
print(type(head).__name__, "| reg_max:", head.reg_max, "| end2end:", head.end2end)세 세대에 걸쳐 snippet을 실행하면 변경 사항을 수치로 확인할 수 있습니다. 이는 ultralytics 패키지에서 실제로 fusion된 모델을 실행한 출력이며, 각 model page에 게시된 parameter 및 FLOPs 수와 일치합니다.
| 모델 | 레이어 | 파라미터 | GFLOPs | reg_max | end2end | DFL 레이어 |
|---|---|---|---|---|---|---|
| YOLOv8n | 72 | 3,151,904 | 8.7 | 16 | False | DFL |
| YOLO11n | 100 | 2,616,248 | 6.5 | 16 | False | DFL |
| YOLO26n | 122 | 2,408,932 | 5.5 | 1 | True | Identity |
YOLO26n은 reg_max=1, end2end=True 및 Identity DFL 레이어를 보고합니다. 이는 NMS-free 및 DFL-free 헤드의 아키텍처적 특징입니다.
Parameter 및 FLOPs 값은 각 Conv과 해당 batch normalization 레이어를 병합하는 fused 모델(model.fuse())에 대해 보고됩니다. 이는 게시된 사양과 일치합니다. 새로 로드한 checkpoint는 fusion 전이므로 약간 더 높은 수치를 보고합니다.
결론#
버전이 거듭되면서 YOLO 아키텍처는 한 단계씩 변경되었습니다. 백본은 Darknet-53에서 C3, C2f, C3k2 기반 CSP 블록과 C2PSA attention으로 변경되었고, 넥은 FPN + PAN 구조를 유지하면서 SPP가 SPPF로 변경되었으며, 헤드는 앵커 기반에서 앵커 프리 방식으로, 이후 YOLO26의 NMS-free 및 DFL-free end-to-end 설계로 변경되었습니다.
사용자 지정 아키텍처를 정의하려면 Model YAML Configuration Guide를 참조하거나 model pages에서 모델을 비교하십시오. 질문이 있으면 GitHub 또는 Discord에서 문의하십시오.
FAQ#
YOLO 모델에는 stride 8, 16, 32에서 이미지의 특징을 추출하는 백본, FPN 및 PAN을 사용하여 이러한 특징을 여러 스케일에 걸쳐 융합하는 넥, 그리고 바운딩 박스와 클래스 점수를 예측하는 헤드가 있습니다. YOLOv3부터 YOLO26까지 모든 Ultralytics YOLO 모델은 이 세 단계 설계를 따릅니다.
C2f(YOLOv8)은 융합 convolution 이전에 모든 내부Bottleneck—n + 2feature map의 출력을 연결하는 CSP 블록인 반면, 이전C3은 2개만 전달합니다.C3k2(YOLO11 및 YOLO26)는C2f의 하위 클래스이며,c3k플래그가 설정되면 각Bottleneck을C3k블록(C3의 커널 크기를 구성할 수 있는 변형)으로 대체할 수 있습니다. 두 블록 모두block.py에 정의되어 있습니다.YOLO11은 YOLOv8에 세 가지 구조적 변경을 적용합니다.
C2fbackbone 및 neck 블록을C3k2로 대체하고,SPPF이후에C2PSAself-attention 블록을 삽입하며, head의 classification branch를 더 가벼운 depthwise-separable convolution으로 전환합니다. 두 모델 모두 box regression과 classification을 위한 분리된 branch가 있는 anchor-free 및 decoupledDetecthead와reg_max=16DFL regression을 유지하므로, 이러한 변경은 detection interface를 재설계하지 않고 parameter 및 FLOPs 수를 줄이는 동시에 정확도를 높입니다.최신 Ultralytics YOLO 모델은 anchor-free입니다. YOLOv8, YOLO11 및 YOLO26은 box regression과 classification을 위한 별도의 branch가 있는 anchor-free 및 decoupled
Detecthead를 사용합니다. 기존 YOLOv3과 YOLOv5는 anchor-based였지만, Ultralytics는 이를 YOLOv8과 동일한 anchor-free head를 config에서 사용하는 YOLOv3u 및 YOLOv5u 변형으로 제공합니다.예 — YOLO26은
end2end=True을 설정합니다. 이에 따라Detect는 각 객체에 대해 하나의 prediction만 생성하는 one-to-one head를 사용하며, 이전 모델에 필요했던 비최대 억제 후처리 단계를 제거합니다. 자세한 내용은 종단 간 탐지 가이드를 참조하십시오.DFL은 각 box 좌표를
reg_max개 bin에 대한 softmax distribution으로 회귀합니다(YOLOv8 및 YOLO11에서는 기본값이 16개). 그런 다음 단일 scalar를 예측하는 대신 기댓값을 좌표로 사용합니다. YOLO26은reg_max=1을 설정하므로 DFL layer는 항등 연산이 되고, head는 좌표를 직접 회귀하며, 내보낸 ONNX 또는 TensorRT graph에는 DFL op가 표시되지 않습니다.Python에서 모델을 로드하고
model.info()을 호출하면 layer, parameter 및 GFLOPs 요약을 확인할 수 있습니다. 파싱된 layer는model.model.model에 있으며, 예를 들어model.model.model[-1]는Detecthead로서reg_max및end2end와 같은 attribute를 제공합니다. 전체 아키텍처는 모델의 YAML configuration file에 정의되어 있습니다.