1import numpy as np
2import onnxruntime as ort
3
4# Load model
5sess = ort.InferenceSession("scrfd_10g_320_batch.onnx",
6 providers=["TensorrtExecutionProvider", "CUDAExecutionProvider"])
7
8# Batch inference
9batch = np.random.randn(16, 3, 320, 320).astype(np.float32)
10outputs = sess.run(None, {"input.1": batch})
11
12# outputs[0-2]: scores per FPN level (stride 8, 16, 32)
13# outputs[3-5]: bboxes per FPN level
14# outputs[6-8]: keypoints per FPN level
1# Same frame processed alone vs in batch = identical results
2single_output = sess.run(None, {"input.1": frame[np.newaxis, ...]})
3batch[7] = frame
4batch_output = sess.run(None, {"input.1": batch})
5
6max_diff = np.max(np.abs(single_output[0] - batch_output[0][7]))
7# max_diff < 1e-5 ✓
These models were re-exported from InsightFace's PyTorch source using MMDetection with proper dynamic_axes:
1dynamic_axes = {
2 "input.1": {0: "batch"},
3 "score_8": {0: "batch"},
4 "score_16": {0: "batch"},
5 # ... all outputs
6}