Recursive AI

Performance against ONNX Runtime

All onemodel docs

Latency and peak memory of this library against ONNX Runtime 1.31.1 on CPU, measured for the 1.0 release with bench/Bar (method: bench-method.md). Each cell is ours / ONNX Runtime: below 1 means we are faster or smaller. ONNX Runtime runs at ORT_ENABLE_ALL with the same thread count as ours. Fast mode, optimization level All, median of 3 repetitions, one process per row and engine.

Machines:

  • x64: AMD Ryzen 9 7950X3D (Zen 4; AVX2, AVX-512, AVX-512 VNNI), 32 logical processors, Linux. "All" is 32 threads.
  • arm64: Apple M2 (4 performance and 4 efficiency cores), macOS. "All" is 8 threads.

Batch N is 32 for the text encoders and 8 for the convolutional models. The Whisper encoder and decoder and the DBNet text detector were measured at batch 1 only, and the CRNN and DBNet OCR models in fp32 only.

Latency, ours / ONNX Runtime

ModelTypeBatchx64 1 threadx64 allarm64 1 threadarm64 all
MiniLM-L6fp3211.180.761.040.86
MiniLM-L6fp32321.070.681.100.68
BERT-basefp3211.090.771.071.02
BERT-basefp32321.180.661.121.00
ResNet-50fp3211.421.161.150.76
ResNet-50fp3281.361.901.120.79
MobileNetV3-Largefp3211.490.740.820.70
MobileNetV3-Largefp3281.490.870.820.82
Whisper-small encoderfp3211.230.521.411.05
Whisper-small decoderfp3211.120.541.070.82
CRNN (text lines)fp3211.531.401.261.25
CRNN (text lines)fp3281.694.481.491.79
DBNet (text detection)fp3212.381.731.521.67
MiniLM-L6int8 dynamic12.330.771.361.36
MiniLM-L6int8 dynamic322.060.961.331.12
BERT-baseint8 dynamic12.441.201.241.06
BERT-baseint8 dynamic322.141.261.180.95
ResNet-50int8 QDQ11.380.361.460.96
ResNet-50int8 QDQ81.280.341.391.20
MobileNetV3-Largeint8 QDQ11.230.401.490.90
MobileNetV3-Largeint8 QDQ81.190.271.430.81
Whisper-small encoderint8 dynamic11.900.681.781.28
Whisper-small decoderint8 dynamic12.841.121.501.08

Where it is slower, and why

  • int8 matrix products on x64 at one thread (MiniLM, BERT, Whisper int8, about 2 to 2.8 times). .NET 10 exposes the x86 integer dot-product instructions only in their VEX forms (AVX-VNNI), which the test CPU does not have, so the int8 kernels use vpmaddwd on 16-bit operands, half the multiply-adds per instruction of a VNNI kernel (docs/int8.md). On CPUs with AVX-VNNI, and on arm64 with its dot-product instructions, the gap is smaller.
  • CRNN at batch 8 with many threads. The recurrent layers step through time on one thread at small batches, so extra threads only help the convolutional front end.
  • DBNet and other very small models (about 1 to 2 ms per call): fixed per-call costs weigh more.
  • ResNet-50 at batch 8 on 32 x64 threads: convolution scaling across both core complexes of the test CPU.

Peak memory, ours / ONNX Runtime

Peak resident memory is at most 1.40 times ONNX Runtime's on every row on x64 (largest: Whisper decoder fp32 1.40, Whisper decoder int8 1.31, BERT-base fp32 1.29) and below 1 on most int8 and batch-N rows. On arm64 the Whisper decoder fp32 is 1.53 times at one thread (1714 MB against 1122 MB) and 1.45 times at 8; every other arm64 row is at most 1.36 times. Steady-state runs allocate no managed memory per call.

Load time

Session creation (import, graph passes, weight packing) is reported per row in the raw results and is not gated.