Ultralytics YOLO26におけるEnd-to-End検出の理解
はじめに
もしYOLO26からYOLOv8やYOLO11のような以前のモデルにアップグレードする場合、最も大きな変更点の1つは(NMS) が削除されたことです。従来のYOLOモデルでは、数千もの重複する予測が生成され、最終的な検出結果に絞り込むために個別のNMS後処理ステップが必要でした。これによりレイテンシが増加し、エクスポートグラフが複雑になり、ハードウェアプラットフォーム間で一貫性のない挙動を示す可能性がありました。
YOLO26は異なるアプローチをとります。モデルから直接最終的な検出結果を出力するため、外部でのフィルタリングは不要です。これはEnd-to-End物体検出と呼ばれ、すべてのYOLO26モデルでデフォルトで有効になっています。その結果、デプロイメントパイプラインが簡素化され、レイテンシが低下し、CPU上での推論速度が最大43%向上します。.
本ガイドでは、何が変更されたのか、コードの更新が必要かどうか、どのエクスポート形式がEnd-to-End推論をサポートしているか、そして古いYOLOモデルからスムーズに移行する方法について解説します。
このアーキテクチャの変更の背後にある動機の詳細については、YOLO26がなぜNMSを削除したのかに関するUltralyticsブログ記事.
- Ultralytics APIまたはCLIを使用していますか? 変更は不要です。モデル名を
yolo26n.pt. - カスタム推論コード(ONNX Runtime、TensorRTなど)を使用していますか? 後処理を更新してください。検出出力は現在
(N, 300, 6)内のxyxy形式であり、NMSは不要です。その他のタスクでは、追加のデータ(マスク係数、キーポイント、または角度)が付加されます。 - エクスポートしていますか? ほとんどの形式はEnd-to-End出力をネイティブでサポートしています。ただし、一部の形式(NCNN、RKNN、PaddlePaddle、ExecuTorch、IMX、Edge TPU)は、サポートされていない演算子の制約(例:
torch.topk).
End-to-End検出の仕組み
YOLO26はデュアルヘッドアーキテクチャ の間にトレーニング を使用します。両方のヘッドは同じバックボーンとネックを共有していますが、異なる方法で出力を作成します。
| ヘッド | 目的 | 検出出力 | 後処理 |
|---|---|---|---|
| One-to-One (デフォルト) | End-to-End推論 | (N, 300, 6) | 信頼度しきい値のみ |
| One-to-Many | 従来のYOLO出力 | (N, nc + 4, 8400) | NMSが必要 |
上記の形状は検出に対するものです。他のタスクでは、検出ごとにデータを追加してOne-to-One出力を拡張します。
| タスク | End-to-End出力 | 追加データ |
|---|---|---|
| 検出 | (N, 300, 6) | — |
| Segmentation | (N, 300, 6 + nm) + proto (N, nm, H, W) | nm マスク係数(デフォルト32) |
| Pose | (N, 300, 57) | 17キーポイント × 3 (x, y, 可視性) |
| OBB | (N, 300, 7) | 回転角度 |
トレーニング中、両方のヘッドが同時に動作します。One-to-Manyヘッドはより豊かな学習信号を提供し、One-to-Oneヘッドは重複のないクリーンな予測を作成するように学習します。推論中(推論とexport)は、デフォルトでOne-to-Oneヘッドのみがアクティブになり、画像ごとに最大300個の検出を形式で出力します。[x1, y1, x2, y2, confidence, class_id].
を呼び出すと、model.fuse()はConv + BatchNormレイヤーを畳み込んで推論を高速化し、End-to-EndモデルではOne-to-Manyヘッドも削除してモデルサイズとFLOPsを削減します。デュアルヘッドアーキテクチャの詳細については、YOLO26モデルページ.
コードを変更する必要がありますか?
Ultralytics Python APIまたはCLIを使用している場合
変更は不要です。 標準のUltralytics Python APIやPythonを使用すれば、すべて自動的に動作します。予測, 検証、およびexportはすべて、End-to-Endモデルをそのまま処理できます。
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や最適化のための最大ワークスペースサイズをGiB単位で設定し、メモリ使用量と性能のバランスをとります。で推論を実行する場合など)、新しい出力形状を処理するように更新する必要があります。
| YOLOv8 / YOLO11 | YOLO26 (End-to-End) | |
|---|---|---|
| 検出出力 | (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)。End-to-Endモデルでは、後処理は非常にシンプルになります。例えば、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!One-to-Manyヘッドへの切り替え
従来のYOLO出力形式が必要な場合(例えば、既存のNMSベースの後処理コードを再利用する場合)、いつでもOne-to-Manyヘッドに切り替えることができます。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)エクスポート形式の互換性
ほとんどの Distribution Focal Loss (DFL) の削除により、モデルのはEnd-to-End推論をそのままサポートしており、ONNX, 最適化のための最大ワークスペースサイズをGiB単位で設定し、メモリ使用量と性能のバランスをとります。, CoreML, OpenVINO, TFLite, TF.js、およびMNN.
以下はサポートしていません(End-to-End非対応であり、自動的にOne-to-Manyヘッドにフォールバックします):NCNN, RKNN, PaddlePaddle, ExecuTorch, IMX、およびEdge TPU.
最適化のための最大ワークスペースサイズをGiB単位で設定し、メモリ使用量と性能のバランスをとります。はEnd-to-Endをサポートしていますが、自動的に無効化されます以下でエクスポートする場合int8=TrueTensorRT ≤10.3.0の場合。
精度と速度のトレードオフ
End-to-end検出は、以下のパフォーマンスに最小限の影響で、デプロイにおける大きな利点を提供します。精度:
| メトリクス | End-to-End (デフォルト) | One-to-Many + NMS (end2end=False) |
|---|---|---|
| CPU推論速度 | 最大43%高速化 | ベースライン |
| mAPへの影響 | ~0.5 mAPの低下 | YOLO11と同等以上 |
| 後処理 | 信頼度フィルタのみ | 完全なNMSパイプライン |
| デプロイの複雑性 | 最小限 | NMSの実装が必要 |
ほとんどの現実的なアプリケーションにおいて、~0.5のmAPの差は無視できるレベルであり、特に速度とシンプルさの向上を考慮すると顕著です。最大の精度が最優先である場合は、いつでもone-to-manyヘッドに切り替えることができます。end2end=False.
トレーニング、検証、エクスポートの手順については、YOLO26パフォーマンス指標(すべてのモデルサイズ:n, s, m, l, xのベンチマーク詳細はこれらを参照してください)。
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: end-to-endサポートにはTensorRTのバージョンが10.3.0を超えていることを確認してください。
- FP16エクスポート: すべての出力をFP16にする必要がある場合は、以下でエクスポートしてください
end2end=False— 参照なぜoutput0がFP32のままなのか - iOS / CoreML: End-to-endは完全サポートされています。Xcode Previewのサポートが必要な場合は、以下を使用してください。
end2end=Falseとnms=True - エッジデバイス (NCNN, RKNN): これらのフォーマットは自動的にone-to-manyにフォールバックするため、デバイス上のパイプラインにNMSを含めてください。
FAQ
end2end=Trueとnms=Trueを同時に使用できますか?
いいえ。これらのオプションは排他的です。もしnms=Trueをend-to-endモデルに対して以下で使用すると、export警告付きで自動的に強制されます。nms=FalseEnd-to-endヘッドは既に重複フィルタリングを内部で処理しているため、外部のNMSは不要です。
しかし、end2end=False とnms=True の組み合わせは有効な構成です — これは伝統的なNMSをエクスポートグラフに焼き込みます。これはCoreMLエクスポートに役立ちます。なぜなら、XcodeのPreview機能で検出モデルを直接使用できるようになるからです。
end-to-endモデルにおいてmax_detパラメータは何を制御しますか?
このmax_detパラメータ(デフォルト: 300)は、one-to-oneヘッドが画像ごとに出力できる検出の最大数を設定します。推論時またはエクスポート時に調整可能です:
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。この値を増やすことは可能ですが、one-to-oneヘッドはトレーニング中に最大300件のクリーンな検出を行うよう最適化されているため、その制限を超える検出は品質が低下する可能性があります。画像あたり300件以上の検出が必要な場合は、より高いmax_det値での再トレーニングを検討してください。
エクスポートしたONNXモデルの出力が(1, 300, 6)なのですが、これは正しいですか?
はい、それが検出における期待されるend-to-endの出力形式です:バッチサイズの1、最大300件の検出、各6つの値[x1, y1, x2, y2, confidence, class_id]。自信値(confidence threshold)でフィルタリングするだけで完了です — NMSは不要です。
他のタスクでは、出力形状が異なります:
| タスク | 出力形状 | デフォルト |
|---|---|---|
| 検出 | (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あるいは、出力形状を確認してください。end-to-end検出モデルは以下を出力し、(1, 300, 6)、従来のモデルは以下を出力します。(1, nc + 4, 8400)。他のタスクの形状については、出力形状FAQ.
セグメンテーション、ポーズ、OBBタスクでend-to-endはサポートされていますか?
はい。すべてのYOLO26タスクバリエーション — 検出, セグメンテーション, 姿勢推定、および指向性物体検出(OBB) — はデフォルトでend-to-end推論をサポートしています。end2end=Falseフォールバックもすべてのタスクで利用可能です。
各タスクは、基本の検出出力にタスク固有のデータを拡張します:
| タスク | モデル | End-to-End出力 |
|---|---|---|
| 検出 | yolo26n.pt | (N, 300, 6) |
| Segmentation | yolo26n-seg.pt | (N, 300, 38) + proto (N, 32, 160, 160) |
| Pose | yolo26n-pose.pt | (N, 300, 57) |
| OBB | yolo26n-obb.pt | (N, 300, 7) |