Ultralytics YOLO26의 엔드투엔드(End-to-End) 탐지 이해하기
소개
If you're upgrading to YOLO26 from an earlier model like YOLOv8 or YOLO11, one of the biggest changes you'll notice is the removal of Non-Maximum Suppression (NMS). Traditional YOLO models produce thousands of overlapping predictions that need a separate NMS post-processing step to filter down to final detections. This adds latency, complicates export graphs, and can behave inconsistently across different hardware platforms.
YOLO26은 다른 접근 방식을 취합니다. 외부 필터링 없이 모델에서 직접 최종 탐지 결과를 출력합니다. 이를 **엔드투엔드 object detection**이라고 하며, 모든 YOLO26 모델에서 기본적으로 활성화되어 있습니다. 그 결과 배포 파이프라인이 더 단순해지고, 지연 시간이 줄어들며, CPU에서 최대 43% 더 빠른 추론이 가능합니다.
이 가이드에서는 무엇이 변경되었는지, 코드를 업데이트해야 하는지, 어떤 내보내기 형식이 엔드투엔드 추론을 지원하는지, 그리고 이전 YOLO 모델에서 원활하게 마이그레이션하는 방법을 안내합니다.
이러한 아키텍처 변화의 동기에 대한 더 깊은 내용은 YOLO26이 NMS를 제거한 이유와 배포 방식의 변화에 관한 Ultralytics 블로그 포스트를 참조하십시오.
- Ultralytics API나 CLI를 사용하시나요? 변경할 필요가 없습니다. 모델 이름을
yolo26n.pt로 바꾸기만 하면 됩니다. - Using custom inference code (ONNX Runtime, TensorRT, etc.)? Update your post-processing — detection output is now
(N, 300, 6)inxyxyformat, no NMS required. Other tasks append extra data (mask coefficients, keypoints, or angle). - 내보내기(Export)를 하시나요? 대부분의 형식은 엔드투엔드 출력을 기본적으로 지원합니다. 하지만 일부 형식(NCNN, RKNN, PaddlePaddle, ExecuTorch, IMX, Edge TPU)은 지원되지 않는 연산자 제약(예:
torch.topk)으로 인해 자동으로 기존 출력 방식으로 돌아갑니다.
엔드투엔드 탐지의 작동 원리
YOLO26은 학습 중 듀얼 헤드 아키텍처를 사용합니다. 두 헤드는 동일한 백본과 넥을 공유하지만, 다음과 같이 서로 다른 방식으로 출력을 생성합니다.
| 헤드 | 목적 | 탐지 출력 | 후처리 |
|---|---|---|---|
| One-to-One (기본값) | 엔드투엔드 추론 | (N, 300, 6) | 신뢰도 임계값만 적용 |
| One-to-Many | 기존 YOLO 출력 | (N, nc + 4, 8400) | NMS 필요 |
위의 형상은 탐지를 위한 것입니다. 다른 작업은 탐지당 추가 데이터를 원-투-원 출력에 추가합니다.
| 태스크 | 엔드투엔드 출력 | 추가 데이터 |
|---|---|---|
| 탐지(Detection) | (N, 300, 6) | — |
| 세그멘테이션 | (N, 300, 6 + nm) + proto (N, nm, H, W) | nm 마스크 계수 (기본값 32) |
| 포즈 | (N, 300, 57) | 17 키포인트 × 3 (x, y, 가시성) |
| OBB | (N, 300, 7) | 회전 각도 |
학습 중에 두 헤드는 동시에 실행됩니다. 원-투-매니 헤드는 더 풍부한 학습 신호를 제공하고, 원-투-원 헤드는 깔끔하고 중복되지 않는 예측을 생성하도록 학습합니다. 추론 및 내보내기 중에는 기본적으로 원-투-원 헤드만 활성화되며, 이미지당 최대 300개의 탐지 결과를 [x1, y1, x2, y2, confidence, class_id] 형식으로 생성합니다.
model.fuse()를 호출하면 더 빠른 추론을 위해 Conv + BatchNorm 레이어가 결합되며, 엔드투엔드 모델의 경우 원-투-매니 헤드도 제거되어 모델 크기와 FLOPs가 줄어듭니다. 듀얼 헤드 아키텍처에 대한 자세한 내용은 YOLO26 모델 페이지를 참조하십시오.
코드를 변경해야 하나요?
Ultralytics Python API 또는 CLI 사용 시
변경할 필요가 없습니다. 표준 Ultralytics Python API 또는 CLI를 사용하는 경우 모든 것이 자동으로 작동합니다. 예측, 검증, 내보내기 모두 엔드투엔드 모델을 즉시 지원합니다.
from ultralytics import YOLO
# Load a YOLO26 model
model = YOLO("yolo26n.pt")
# Predict — no NMS step, no code changes
results = model.predict("image.jpg")사용자 정의 추론 코드 사용 시
네, 출력 형식이 다릅니다. YOLOv8이나 YOLO11을 위해 사용자 정의 후처리 로직을 작성했다면(예: ONNX Runtime 또는 TensorRT로 추론 실행 시), 새로운 출력 형상을 처리하도록 업데이트해야 합니다.
| YOLOv8 / YOLO11 | YOLO26 (엔드투엔드) | |
|---|---|---|
| 탐지 출력 | (N, nc + 4, 8400) | (N, 300, 6) |
| 박스 형식 | xywh (중심 x, 중심 y, 너비, 높이) | xyxy (좌상단 x, 좌상단 y, 우하단 x, 우하단 y) |
| 레이아웃 | 앵커당 박스 좌표 + 클래스 점수 | [x1, y1, x2, y2, conf, class_id] |
| NMS 필요 | 예 | 아니요 |
| 후처리 | NMS + 신뢰도 필터 | 신뢰도 필터만 적용 |
세그멘테이션, 포즈, OBB 작업의 경우, YOLO26은 각 탐지에 작업별 데이터를 추가합니다. 위의 출력 형상 표를 참조하십시오.
여기서 N은 배치 크기이고 nc는 클래스 수(예: COCO의 경우 80)입니다.
엔드투엔드 모델을 사용하면 후처리가 훨씬 간단해집니다. 예를 들어 ONNX Runtime을 사용할 때 다음과 같습니다.
import onnxruntime as ort
# Load and run the exported end-to-end model
session = ort.InferenceSession("yolo26n.onnx")
output = session.run(None, {session.get_inputs()[0].name: input_tensor})
# End-to-end output: (batch, 300, 6) → [x1, y1, x2, y2, confidence, class_id]
detections = output[0][0] # first image in batch
detections = detections[detections[:, 4] > conf_threshold] # confidence filter — that's it!원-투-매니 헤드로 전환하기
기존 YOLO 출력 형식이 필요한 경우(예: 기존의 NMS 기반 후처리 코드를 재사용해야 하는 경우), end2end=False로 설정하여 언제든지 원-투-매니 헤드로 전환할 수 있습니다.
from ultralytics import YOLO
model = YOLO("yolo26n.pt")
# Prediction with NMS (traditional behavior)
results = model.predict("image.jpg", end2end=False)
# Validation with NMS
metrics = model.val(data="coco.yaml", end2end=False)
# Export without end-to-end
model.export(format="onnx", end2end=False)내보내기 형식 호환성
대부분의 내보내기 형식은 ONNX, TensorRT, CoreML, OpenVINO, TFLite, TF.js, MNN을 포함하여 엔드투엔드 추론을 즉시 지원합니다.
다음 형식은 엔드투엔드를 지원하지 않으며 자동으로 원-투-매니 헤드로 돌아갑니다: NCNN, RKNN, PaddlePaddle, ExecuTorch, IMX, Edge TPU.
TensorRT는 엔드투엔드를 지원하지만, TensorRT ≤10.3.0에서 int8=True로 내보낼 때는 자동으로 비활성화됩니다.
정확도와 속도 간의 절충
엔드투엔드 탐지는 정확도에 최소한의 영향만 주면서 상당한 배포 이점을 제공합니다.
| 지표 | 엔드투엔드 (기본값) | 원-투-매니 + NMS (end2end=False) |
|---|---|---|
| CPU 추론 속도 | 최대 43% 더 빠름 | 베이스라인 |
| mAP 영향 | ~0.5 mAP 낮음 | YOLO11과 동등하거나 우수함 |
| 후처리 | 신뢰도 필터만 적용 | 전체 NMS 파이프라인 |
| 배포 복잡성 | 최소화 | NMS 구현 필요 |
대부분의 실무 환경에서 ~0.5 mAP 차이는 무시할 수 있는 수준이며, 특히 속도와 단순함의 이득을 고려하면 더욱 그렇습니다. 최대 정확도가 가장 중요한 우선순위라면, 언제든 end2end=False를 사용하여 원-투-매니 헤드로 돌아갈 수 있습니다.
모든 모델 크기(n, s, m, l, x)에 대한 자세한 벤치마크는 YOLO26 성능 지표를 참조하십시오.
YOLOv8 또는 YOLO11에서 마이그레이션하기
기존 프로젝트를 YOLO26으로 업그레이드하는 경우, 원활한 전환을 위한 빠른 체크리스트입니다.
- Ultralytics API / CLI 사용자: 변경 불필요. 모델 이름을
yolo26n.pt(또는yolo26n-seg.pt,yolo26n-pose.pt,yolo26n-obb.pt)로 업데이트하십시오. - 사용자 정의 후처리 코드: 새로운 출력 형상을 처리하도록 업데이트하십시오. 탐지의 경우
(N, 300, 6), 그 외 세그멘테이션, 포즈, OBB는 작업별 데이터를 포함합니다. 또한 박스 형식이xywh에서xyxy로 변경된 점을 유의하십시오. - 내보내기 파이프라인: 대상 형식에 대해 위의 형식 호환성 섹션을 확인하십시오.
- TensorRT + INT8: 엔드투엔드 지원을 위해 TensorRT 버전이 10.3.0보다 높은지 확인하십시오.
- FP16 내보내기: 모든 출력을 FP16으로 유지해야 하는 경우
end2end=False로 내보내십시오. output0이 FP32로 유지되는 이유를 참조하십시오. - iOS / CoreML: 엔드투엔드가 완벽하게 지원됩니다. Xcode 미리보기 기능이 필요한 경우
end2end=False와nms=True를 사용하십시오. - 엣지 디바이스 (NCNN, RKNN): 이 형식들은 자동으로 원-투-매니로 돌아가므로, 온디바이스 파이프라인에 NMS를 포함하십시오.
FAQ
end2end=True와 nms=True를 함께 사용할 수 있나요?
No. These options are mutually exclusive. If you set nms=True on an end-to-end model during export, it will be automatically forced to nms=False with a warning. The end-to-end head already handles duplicate filtering internally, so external NMS is unnecessary.
하지만 end2end=False와 nms=True를 조합하는 것은 유효한 설정이며, 내보내기 그래프에 기존 NMS를 포함시킵니다. 이는 CoreML 내보내기 시 Xcode의 미리보기 기능을 탐지 모델과 직접 사용할 수 있게 해주므로 유용할 수 있습니다.
엔드투엔드 모델에서 max_det 파라미터는 무엇을 제어하나요?
max_det 파라미터(기본값: 300)는 원-투-원 헤드가 이미지당 출력할 수 있는 최대 탐지 수를 설정합니다. 추론 또는 내보내기 시점에 조정할 수 있습니다.
model.predict("image.jpg", max_det=100) # fewer detections, slightly faster
model.export(format="onnx", max_det=500) # more detections for dense scenes기본 YOLO26 체크포인트는 max_det=300으로 학습되었습니다. 이 값을 늘릴 수는 있지만, 원-투-원 헤드는 학습 중에 최대 300개의 깔끔한 탐지 결과를 생성하도록 최적화되었으므로 그 이상으로 탐지할 경우 품질이 낮아질 수 있습니다. 이미지당 300개 이상의 탐지가 필요하다면 더 높은 max_det 값으로 재학습하는 것을 고려하십시오.
내보낸 ONNX 모델 출력이 (1, 300, 6)인데 맞나요?
네, 그것이 탐지를 위한 예상 엔드투엔드 출력 형식입니다: 배치 크기 1, 최대 300개의 탐지, 각각은 [x1, y1, x2, y2, confidence, class_id]라는 6개의 값을 가집니다. 단순히 신뢰도 임계값으로 필터링하기만 하면 되며, NMS는 필요하지 않습니다.
다른 작업의 경우 출력 형상이 다릅니다:
| 태스크 | 출력 형상 | 설명 |
|---|---|---|
| Detection | (1, 300, 6) | [x1, y1, x2, y2, conf, class_id] |
| Segmentation | (1, 300, 38) + (1, 32, 160, 160) | 6개의 박스 값 + 32개의 마스크 계수, 그리고 프로토타입 마스크 텐서 |
| 포즈(Pose) | (1, 300, 57) | 6개의 박스 값 + 17개의 키포인트 × 3 (x, y, 가시성) |
| OBB | (1, 300, 7) | 6개의 박스 값 + 1개의 회전 각도 |
내보낸 모델이 엔드투엔드(end-to-end)인지 확인하려면 어떻게 해야 합니까?
Ultralytics Python API를 사용하거나 내보낸 ONNX 모델 메타데이터를 직접 검사하여 확인할 수 있습니다:
from ultralytics import YOLO
model = YOLO("yolo26n.onnx")
model.predict(verbose=False) # run predict to setup predictor first
print(model.predictor.model.end2end) # True if end-to-end is enabled또는 출력 형상을 확인하십시오. 엔드투엔드 탐지 모델은 (1, 300, 6)을 출력하고, 기존 모델은 (1, nc + 4, 8400)을 출력합니다. 다른 작업 형상에 대해서는 출력 형상 FAQ를 참조하십시오.
세그멘테이션, 포즈, OBB 작업에서 엔드투엔드가 지원됩니까?
네, 지원됩니다. 모든 YOLO26 작업 변형인 탐지, 세그멘테이션, 포즈 추정, 그리고 회전 객체 탐지 (OBB)는 기본적으로 엔드투엔드 추론을 지원합니다. 모든 작업에서 end2end=False 대체 모드도 사용 가능합니다.
각 작업은 기본 탐지 출력에 작업별 데이터를 추가합니다:
| 태스크 | 모델 | 엔드투엔드 출력 |
|---|---|---|
| Detection | yolo26n.pt | (N, 300, 6) |
| Segmentation | yolo26n-seg.pt | (N, 300, 38) + 프로토 (N, 32, 160, 160) |
| 포즈(Pose) | yolo26n-pose.pt | (N, 300, 57) |
| OBB | yolo26n-obb.pt | (N, 300, 7) |