Meet YOLO26: next-gen vision AI.

Link to this sectionTìm hiểu về End-to-End Detection trong Ultralytics YOLO26#

Link to this sectionGiới thiệu#

Nếu bạn đang nâng cấp lên YOLO26 từ một model cũ hơn như YOLOv8 hoặc YOLO11, một trong những thay đổi lớn nhất mà bạn sẽ nhận thấy là việc loại bỏ Non-Maximum Suppression (NMS). Các model YOLO truyền thống tạo ra hàng ngàn dự đoán chồng chéo, đòi hỏi một bước hậu xử lý NMS riêng biệt để lọc ra các kết quả phát hiện cuối cùng. Điều này làm tăng độ trễ, làm phức tạp các biểu đồ xuất (export graphs) và có thể hoạt động không nhất quán trên các nền tảng phần cứng khác nhau.

YOLO26 áp dụng một cách tiếp cận khác. Nó xuất ra các kết quả phát hiện cuối cùng trực tiếp từ model — không cần lọc bên ngoài. Đây được gọi là end-to-end object detection và được bật theo mặc định trong tất cả các model YOLO26. Kết quả là một pipeline triển khai đơn giản hơn, độ trễ thấp hơn và inference nhanh hơn tới 43% trên CPU.

Hướng dẫn này sẽ giúp bạn nắm bắt những thay đổi, liệu bạn có cần cập nhật code của mình không, những định dạng xuất nào hỗ trợ end-to-end inference và cách di chuyển mượt mà từ các model YOLO cũ hơn.

Để có cái nhìn sâu hơn về động lực đằng sau sự thay đổi kiến trúc này, hãy xem bài blog của Ultralytics về lý do tại sao YOLO26 loại bỏ NMS.

Tóm tắt nhanh
  • Bạn đang sử dụng Ultralytics API hoặc CLI? Không cần thay đổi gì cả — chỉ cần đổi tên model của bạn thành yolo26n.pt.
  • Bạn đang sử dụng code inference tùy chỉnh (ONNX Runtime, TensorRT, v.v.)? Hãy cập nhật phần hậu xử lý của bạn — đầu ra phát hiện hiện là (N, 300, 6) ở định dạng xyxy, không cần NMS. Các tác vụ khác sẽ đính kèm thêm dữ liệu (hệ số mask, keypoints, hoặc góc).
  • Đang xuất (export)? Hầu hết các định dạng hỗ trợ xuất end-to-end một cách tự nhiên. Tuy nhiên, một vài định dạng (NCNN, RKNN, PaddlePaddle, ExecuTorch, IMX, Edge TPU, và QNN) sẽ tự động quay lại đầu ra truyền thống do các ràng buộc về toán tử không được hỗ trợ (ví dụ: torch.topk). Các pipeline Hailo HEF được biên dịch từ ONNX với các script cụ thể của Hailo, vì vậy hãy xác minh phần detection head và cấu hình NMS cho model của bạn.

Link to this sectionCách thức hoạt động của End-to-End Detection#

YOLO26 sử dụng kiến trúc dual-head (hai đầu) trong quá trình training. Cả hai đầu đều chia sẻ chung backbone và neck, nhưng tạo ra đầu ra theo các cách khác nhau:

HeadMục đíchĐầu ra phát hiệnHậu xử lý
One-to-One (mặc định)End-to-end inference(N, 300, 6)Chỉ ngưỡng tin cậy (Confidence threshold)
One-to-ManyĐầu ra YOLO truyền thống(N, nc + 4, 8400)Yêu cầu NMS

Các shape ở trên dành cho detection. Các tác vụ khác mở rộng đầu ra one-to-one với dữ liệu bổ sung cho mỗi kết quả phát hiện:

Tác vụEnd-to-End OutputDữ liệu bổ sung
Phát hiện(N, 300, 6)
Phân đoạn Instance(N, 300, 6 + nm) + proto (N, nm, H, W)nm hệ số mask (mặc định 32)
Pose(N, 300, 57)17 keypoints × 3 (x, y, độ hiển thị)
OBB(N, 300, 7)Góc xoay

Trong quá trình training, cả hai head đều chạy đồng thời — head one-to-many cung cấp tín hiệu học tập phong phú hơn, trong khi head one-to-one học cách tạo ra các dự đoán sạch, không chồng chéo. Trong quá trình inferenceexport, chỉ head one-to-one hoạt động theo mặc định, tạo ra tối đa 300 kết quả phát hiện mỗi ảnh ở định dạng [x1, y1, x2, y2, confidence, class_id].

Khi bạn gọi model.fuse(), nó sẽ gộp các lớp Conv + BatchNorm để inference nhanh hơn và, trên các model end-to-end, cũng loại bỏ head one-to-many — làm giảm kích thước model và FLOPs. Để biết thêm chi tiết về kiến trúc dual-head, hãy xem trang model YOLO26.

Link to this sectionTôi có cần thay đổi code của mình không?#

Link to this sectionSử dụng Ultralytics Python API hoặc CLI#

Không cần thay đổi. Nếu bạn sử dụng Ultralytics Python API hoặc CLI tiêu chuẩn, mọi thứ sẽ hoạt động tự động — prediction, validation, và export đều xử lý các model end-to-end ngay lập tức.

Không cần thay đổi code với Ultralytics API
from ultralytics import YOLO

# Load a YOLO26 model
model = YOLO("yolo26n.pt")

# Predict — no NMS step, no code changes
results = model.predict("image.jpg")

Link to this sectionSử dụng Custom Inference Code#

Có, định dạng đầu ra khác biệt. Nếu bạn đã viết logic hậu xử lý tùy chỉnh cho YOLOv8 hoặc YOLO11 (ví dụ, khi chạy inference với ONNX Runtime hoặc TensorRT), bạn sẽ cần cập nhật nó để xử lý shape đầu ra mới:

YOLOv8 / YOLO11YOLO26 (end-to-end)
Đầu ra phát hiện(N, nc + 4, 8400)(N, 300, 6)
Định dạng Boxxywh (tâm x, tâm y, chiều rộng, chiều cao)xyxy (x trên-trái, y trên-trái, x dưới-phải, y dưới-phải)
Bố cụcTọa độ Box + điểm số class trên mỗi anchor[x1, y1, x2, y2, conf, class_id]
Yêu cầu NMSKhông
Hậu xử lýNMS + lọc độ tin cậyChỉ lọc độ tin cậy

Đối với các tác vụ segmentation, pose, và OBB, YOLO26 đính kèm dữ liệu cụ thể của tác vụ vào mỗi kết quả phát hiện — xem bảng shape đầu ra ở trên.

Trong đó Nbatch sizenc là số lượng class (ví dụ: 80 cho COCO).

Với các model end-to-end, việc hậu xử lý trở nên đơn giản hơn nhiều — ví dụ, khi sử dụng 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!

Link to this sectionChuyển sang Head One-to-Many#

Nếu bạn cần định dạng đầu ra YOLO truyền thống (ví dụ, để tái sử dụng code hậu xử lý dựa trên NMS hiện có), bạn có thể chuyển sang head one-to-many bất cứ lúc nào bằng cách đặt end2end=False:

Sử dụng head one-to-many cho đầu ra dựa trên NMS truyền thống
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)

Link to this sectionKhả năng tương thích định dạng xuất#

Hầu hết các định dạng xuất đều hỗ trợ end-to-end inference ngay lập tức, bao gồm ONNX, TensorRT, CoreML, OpenVINO, TFLite, TF.js, và MNN.

Các định dạng sau không hỗ trợ end-to-end và sẽ tự động quay lại head one-to-many: NCNN, RKNN, PaddlePaddle, ExecuTorch, IMX, Edge TPU, và Qualcomm QNN.

Điều gì xảy ra khi end-to-end không được hỗ trợ

Khi bạn xuất sang một trong các định dạng này, Ultralytics sẽ tự động chuyển sang head one-to-many và ghi nhật ký cảnh báo — không cần thao tác thủ công. Điều này có nghĩa là bạn sẽ cần NMS trong pipeline inference của mình cho các định dạng này, giống như với YOLOv8 hoặc YOLO11.

Đối với Hailo HEF, bước biên dịch diễn ra bên ngoài model.export(format=...) sau khi xuất ONNX. Sử dụng nhật ký Hailo DFC, script model .alls và JSON NMS khớp với model phát hiện chính xác của bạn; nếu biểu đồ YOLO26 end-to-end không được hỗ trợ bởi toolchain Hailo của bạn, hãy xuất model ONNX với end2end=False và biên dịch head phát hiện truyền thống.

TensorRT + INT8

TensorRT hỗ trợ end-to-end, nhưng nó sẽ tự động bị tắt khi xuất với int8=True trên TensorRT 10.3.0 trên JetPack 6.

Link to this sectionĐánh đổi giữa độ chính xác và tốc độ#

End-to-end detection mang lại những lợi ích triển khai đáng kể với tác động tối thiểu lên độ chính xác:

Chỉ sốEnd-to-End (mặc định)One-to-Many + NMS (end2end=False)
Tốc độ CPU InferenceNhanh hơn tới 43%Baseline
Tác động mAPThấp hơn ~0.5 mAPBằng hoặc vượt qua YOLO11
Hậu xử lýChỉ lọc độ tin cậyPipeline NMS đầy đủ
Độ phức tạp khi triển khaiTối thiểuYêu cầu triển khai NMS

Đối với hầu hết các ứng dụng thực tế, sự khác biệt ~0.5 mAP là không đáng kể, đặc biệt khi cân nhắc đến tốc độ và sự đơn giản. Nếu độ chính xác tối đa là ưu tiên hàng đầu, bạn luôn có thể quay lại head one-to-many bằng cách sử dụng end2end=False.

Xem thông số hiệu năng YOLO26 để biết các benchmark chi tiết cho tất cả các kích thước model (n, s, m, l, x).

Link to this sectionDi chuyển từ YOLOv8 hoặc YOLO11#

Nếu bạn đang nâng cấp một dự án hiện có lên YOLO26, đây là danh sách kiểm tra nhanh để đảm bảo quá trình chuyển đổi suôn sẻ:

  • Người dùng Ultralytics API / CLI: Không cần thay đổi — chỉ cần cập nhật tên model thành yolo26n.pt (hoặc yolo26n-seg.pt, yolo26n-pose.pt, yolo26n-obb.pt)
  • Code hậu xử lý tùy chỉnh: Cập nhật để xử lý shape đầu ra mới — (N, 300, 6) cho phát hiện, cộng với dữ liệu cụ thể của tác vụ cho segmentation, pose, và OBB. Cũng lưu ý việc thay đổi định dạng box từ xywh sang xyxy
  • Pipeline xuất: Kiểm tra phần khả năng tương thích định dạng ở trên cho định dạng đích của bạn
  • TensorRT + INT8: Trên JetPack 6, TensorRT 10.3.0 tự động tắt end-to-end với int8=True — hãy sử dụng phiên bản TensorRT khác để giữ nguyên end-to-end
  • Xuất FP16: Nếu bạn cần tất cả các đầu ra ở định dạng FP16, hãy xuất với end2end=False — xem tại sao output0 vẫn ở FP32
  • iOS / CoreML: End-to-end được hỗ trợ đầy đủ. Nếu bạn cần hỗ trợ Xcode Preview, hãy sử dụng end2end=False với nms=True
  • Thiết bị Edge (NCNN, RKNN): Các định dạng này tự động quay lại one-to-many, vì vậy hãy bao gồm NMS trong pipeline trên thiết bị của bạn

Link to this sectionCâu hỏi thường gặp#

Link to this sectionTôi có thể sử dụng end2end=True và nms=True cùng nhau không?#

Không. Các tùy chọn này loại trừ lẫn nhau. Nếu bạn đặt nms=True trên một model end-to-end trong quá trình export, nó sẽ tự động bị buộc thành nms=False kèm theo một cảnh báo. Head end-to-end đã tự xử lý việc lọc trùng lặp, vì vậy NMS bên ngoài là không cần thiết.

Tuy nhiên, end2end=False kết hợp với nms=True là một cấu hình hợp lệ — nó tích hợp NMS truyền thống vào biểu đồ xuất. Điều này có thể hữu ích cho các lần xuất CoreML vì nó cho phép bạn sử dụng chức năng Preview trong Xcode trực tiếp với model phát hiện.

Link to this sectionTham số max_det kiểm soát điều gì trong các mô hình end-to-end?#

Tham số max_det (mặc định: 300) thiết lập số lượng phát hiện tối đa mà phần đầu one-to-one có thể xuất ra trên mỗi hình ảnh. Bạn có thể điều chỉnh tham số này tại thời điểm suy luận hoặc xuất mô hình:

model.predict("image.jpg", max_det=100)  # fewer detections, slightly faster
model.export(format="onnx", max_det=500)  # more detections for dense scenes

Lưu ý rằng các checkpoint YOLO26 mặc định được huấn luyện với max_det=300. Mặc dù bạn có thể tăng giá trị này, phần đầu one-to-one đã được tối ưu hóa trong quá trình huấn luyện để tạo ra tối đa 300 phát hiện chính xác, vì vậy các phát hiện vượt quá giới hạn đó có thể có chất lượng thấp hơn. Nếu bạn cần hơn 300 phát hiện mỗi ảnh, hãy cân nhắc huấn luyện lại với giá trị max_det cao hơn.

Link to this sectionMô hình ONNX đã xuất của tôi có đầu ra (1, 300, 6) — điều đó có đúng không?#

Có, đó là định dạng đầu ra end-to-end mong đợi cho tác vụ phát hiện: batch size là 1, tối đa 300 phát hiện, mỗi phát hiện có 6 giá trị [x1, y1, x2, y2, confidence, class_id]. Bạn chỉ cần lọc theo ngưỡng confidence là xong — không cần NMS.

Đối với các tác vụ khác, hình dạng đầu ra sẽ khác:

Tác vụHình dạng đầu raMô tả
Detection(1, 300, 6)[x1, y1, x2, y2, conf, class_id]
Segmentation(1, 300, 38) + (1, 32, 160, 160)6 giá trị khung hình + 32 hệ số mặt nạ, cộng với một tensor mặt nạ nguyên mẫu
Pose(1, 300, 57)6 giá trị khung hình + 17 điểm đặc trưng × 3 (x, y, khả năng hiển thị)
OBB(1, 300, 7)6 giá trị khung hình + 1 góc xoay

Link to this sectionLàm thế nào để kiểm tra xem mô hình đã xuất của tôi có phải là end-to-end hay không?#

Bạn có thể kiểm tra bằng Ultralytics Python API hoặc bằng cách kiểm tra trực tiếp metadata của mô hình ONNX đã xuất:

Kiểm tra xem mô hình có phải là end-to-end không
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

Ngoài ra, hãy kiểm tra hình dạng đầu ra — các mô hình phát hiện end-to-end xuất ra (1, 300, 6), trong khi các mô hình truyền thống xuất ra (1, nc + 4, 8400). Để biết hình dạng của các tác vụ khác, hãy xem FAQ về hình dạng đầu ra.

Link to this sectionEnd-to-end có được hỗ trợ cho các tác vụ phân đoạn đối tượng (instance segmentation), ước tính tư thế (pose) và OBB không?#

Có. Các biến thể tác vụ kiểu phát hiện của YOLO26 — phát hiện, phân đoạn đối tượng, ước tính tư thế, và phát hiện vật thể theo hướng (OBB) — đều hỗ trợ suy luận end-to-end theo mặc định. Tùy chọn dự phòng end2end=False cũng có sẵn trên các tác vụ này.

Mỗi tác vụ mở rộng đầu ra phát hiện cơ sở với dữ liệu đặc thù của tác vụ:

Tác vụMô hìnhEnd-to-End Output
Detectionyolo26n.pt(N, 300, 6)
Instance Segmentationyolo26n-seg.pt(N, 300, 38) + proto (N, 32, 160, 160)
Poseyolo26n-pose.pt(N, 300, 57)
OBByolo26n-obb.pt(N, 300, 7)

Bình luận