yolo26-kit
Drop YOLO26 into your existing YOLOv8 pipeline. Bridge library for the NMS-free, end-to-end era.
Why
YOLO26 default ONNX export is end2end=True, producing (N, 300, 6) already-decoded detections. That's great — but it breaks every Triton / DeepStream / OpenCV DNN config that expects YOLOv8-style (1, 4+nc, N). It also leaves you to write letterbox-coord undo math by hand. And some targets (RKNN, certain TFLite quant paths) can't fuse the e2e head, so they ship raw (1, 4+nc, N) you have to decode yourself.
yolo26-kit is a small, pure-functional library that bridges that gap — and nothing else.
Install
# Python — https://pypi.org/project/yolo26-kit/
pip install yolo26-kit # core
pip install "yolo26-kit[ort]" # + ORT wrapper
# TypeScript / JavaScript — https://www.npmjs.com/package/yolo26-kit
npm i yolo26-kit # core
npm i yolo26-kit onnxruntime-web # + ORT wrapper (peer dep)
Export YOLO26 to ONNX
The "happy path" is to export with end2end=True so the ONNX graph emits already-deduplicated (N, 300, 6) detections:
from ultralytics import YOLO
YOLO("yolo26n.pt").export(format="onnx", end2end=True)
# produces yolo26n.onnx with output shape (1, 300, 6)
If you cannot use end2end=True (e.g., quantized TFLite or some NPU runtimes that don't support the e2e head), yolo26-kit auto-detects and runs class-aware NMS for you when decoding raw (1, 4+nc, N) outputs.
Use
Python — e2e default (most users)
import onnxruntime as ort
import yolo26_kit
sess = ort.InferenceSession("yolo26n.onnx")
out = sess.run(None, {"images": pre})[0] # (1, 300, 6)
out = yolo26_kit.normalize_output(out)
dets = yolo26_kit.filter_e2e(out, conf=0.25)
# [{'box': [...], 'score': ..., 'class': ..., 'label': '...'}]
Python — drop into existing YOLOv8 pipeline
out_v8 = yolo26_kit.e2e_to_v8_shape(out) # (1, 84, 300)
# Feed out_v8 to your existing v8 Triton / DeepStream / OpenCV DNN parser.
Python — convenience wrapper (image in, dets in original coords out)
from yolo26_kit import from_ort
decoder = from_ort("yolo26n.onnx")
dets = decoder.predict("bus.jpg", conf=0.25)
TypeScript
import { filterE2E } from "yolo26-kit";
import { fromOrt } from "yolo26-kit/ort";
import * as ort from "onnxruntime-web";
const session = await ort.InferenceSession.create("yolo26n.onnx");
const decoder = fromOrt(session);
const dets = await decoder.predict(canvas, { conf: 0.25 });
Single image at a time (batch=1). Loop in your code if you have multiple frames.
TypeScript — non-e2e raw export
import { decodeDetect, normalizeOutput } from "yolo26-kit";
const out = normalizeOutput(rawTensor);
const dets = decodeDetect(out, [1, 84, 8400], { conf: 0.25, numClasses: 80 });
Decoder auto-routing
The Decoder auto-detects whether the ONNX is e2e (output shape ends in 6) or raw (output shape (1, 4+nc, N)):
- e2e: runs
filter_e2e— already deduped by the model, no NMS. - raw: runs
decode_detectwith class-aware NMS (defaultiou_threshold=0.45).
Override the NMS default if you want raw outputs (e.g., for further post-processing):
decoder.predict("bus.jpg", conf=0.25, nms=False)
await decoder.predict(canvas, { conf: 0.25, nms: false });
What's in the box (v0.1.x)
| Function | Purpose |
|---|---|
filter_e2e / filterE2E |
Filter the default (N, 300, 6) e2e output by confidence + classes + min-area |
decode_detect / decodeDetect |
Decode raw (1, 4+nc, N) non-e2e exports (NPU / quantized targets) |
e2e_to_v8_shape / e2eToV8Shape |
Adapter to drop YOLO26 into legacy YOLOv8 pipelines |
v8_shape_to_e2e / v8ShapeToE2E |
Reverse adapter |
letterbox_unmap / letterboxUnmap |
Undo letterbox padding back to original image coords |
normalize_output / normalizeOutput |
Dtype workaround for upstream YOLO26 fp16 export issue (#23645) |
class_aware_nms / classAwareNMS |
Class-aware non-maximum suppression for raw decoder output |
Decoder.predict() |
Image in → detections in original-image coords out (auto e2e/non-e2e routing) |
Compatibility
| package | version | ultralytics (verified) |
runtime |
|---|---|---|---|
yolo26-kit (PyPI) |
0.1.1 | 8.4.x (yolo26n.pt) | onnxruntime ≥1.17 |
yolo26-kit (npm) |
0.1.3 | 8.4.x (yolo26n.pt) | onnxruntime-web ≥1.20 |
A nightly live-diff workflow installs the latest ultralytics and re-validates fixtures. Drift opens an auto-tagged drift issue.
Status
v1 (this release): Detect task only. e2e + non-e2e paths. Both Python and TypeScript, cross-language equivalent (verified via golden fixtures).
Roadmap: Seg, pose, cls, OBB tasks. Reproduction kit (Docker + COCO train/eval). ONNX schema standardizer. NPU ports (RKNN, Hailo, RDK, Qualcomm SNPE/QNN).
Development
# Python
cd python
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest tests/ -v
mypy src/yolo26_kit
ruff check src tests
# TypeScript
cd js
npm install
npm test
npm run typecheck
npm run lint
Limitations (v0.1.x)
- Single image only: decoders reject
batch > 1. Loop in user code for multi-image inference. Batched decode tracked for v0.2. - Detect task only: seg/pose/cls/OBB queued.
- Browser preprocess uses nearest-neighbor resize for portability. For pixel-perfect parity with PIL bilinear, pre-resize via canvas.
License
Apache-2.0 for the code in this repository. Model weights are not redistributed; users fetch them from the official Ultralytics distribution under its own terms (AGPL-3.0).
See fixtures/LICENSES.md for fixture asset attribution.
Metadata
Release files for yolo26-kit 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| yolo26_kit-0.1.1.tar.gz | 19.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| yolo26_kit-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 36.6 kB
Release files / yolo26_kit-0.1.1.tar.gz
| Download URL | yolo26_kit-0.1.1.tar.gz |
|---|---|
| Size | 19.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0c09684ec00103ccb570a823b089f99495e691a4764ac363700197dbe83809c5
|
|
BLAKE2b-256 checksum How to use checksums |
6466812f51acc786caba2c7412f6ede6dd9a011b14ed4a9a2d32c16edcfee0cc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.11
|
Release files / yolo26_kit-0.1.1-py3-none-any.whl
| Download URL | yolo26_kit-0.1.1-py3-none-any.whl |
|---|---|
| Size | 16.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4f1e6e74d3af948077b330dc0a0293f9ad45d2b8eb0ea3f5ac424291ee8acca8
|
|
BLAKE2b-256 checksum How to use checksums |
6f4da040ecd23bafdbb2bbf42e3b9c63f7c461d1957a423921cb24cd1946b149
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.11
|