Post-processing API
Post-processing helpers for raw model outputs — greedy NMS in numpy.
Streaming inference on the platform applies NMS server-side when the
model is registered with NMS parameters, but single-shot infer()
results, custom decode heads and app-side re-filtering still need a local
implementation. Apps currently hand-roll one whenever scores and boxes
arrive separately.
Pure numpy, no accelerator — the vectorised IoU matrix is already memory-bound at the sizes detector heads produce. When ai-runtime exposes its create-time NMS registration over the service layer (see docs/proposals/sdk-hardware-routing.md), prefer that and keep this for client-side filtering.
from neoruntime_ipc_sdk.postprocess import nms
keep = nms(boxes_xyxy, scores, iou_threshold=0.45, class_ids=cls)
boxes, scores = boxes[keep], scores[keep]
- neoruntime_ipc_sdk.postprocess.nms(boxes, scores, iou_threshold=0.5, class_ids=None)[source]
Greedy non-maximum suppression.
- Parameters:
- Returns:
Indices of the kept boxes, in descending-score order.
- Return type:
Functions
nms
- neoruntime_ipc_sdk.postprocess.nms(boxes, scores, iou_threshold=0.5, class_ids=None)[source]
Greedy non-maximum suppression.
- Parameters:
- Returns:
Indices of the kept boxes, in descending-score order.
- Return type:
Examples
Filter overlapping boxes after decoding
import numpy as np
from neoruntime_ipc_sdk import nms
# Candidate boxes (xywh), scores and classes come from the model's
# output-tensor decoding
keep = nms(boxes, scores, iou_threshold=0.45, class_ids=class_ids)
for i in keep:
x, y, w, h = boxes[i]
print(f"{labels[class_ids[i]]} {scores[i]:.2f} @ ({x:.0f},{y:.0f},{w:.0f},{h:.0f})")
Through the accel router (switches to hardware NMS when exposed)
# Software implementation today; once ai-runtime exposes NMS
# registration params the hardware leg takes over automatically —
# see docs/proposals/sdk-hardware-routing.md
from neoruntime_ipc_sdk import get_default_router
keep = get_default_router().run("nms", boxes, scores, iou_threshold=0.45)