‹ Back to Benchmarks

GPU ResNet-50 inference: OpenNN vs PyTorch vs TensorFlow

OpenNN reaches a five-run median of 107,229 samples/s in fp32 and 176,990 samples/s in bf16 on an NVIDIA GeForce RTX 4080. In the same forward-only ResNet-50 workload, that is 1.232x and 1.418x PyTorch throughput, respectively.

Results are medians across five runs, with the standard deviation reported for every framework. This benchmark uses ResNet-50 v1.5 with CIFAR geometry and 32×32 CIFAR-10 inputs; it does not represent ImageNet-resolution inference.

Contents

Introduction

ResNet-50 remains a useful test of convolution, normalization, residual connections, and repeated GPU kernel execution. The CIFAR-10 adaptation keeps the ResNet-50 v1.5 bottleneck structure while using the smaller spatial geometry required by 32×32 images.

This benchmark compares sustained fp32 and bf16 forward-pass throughput in OpenNN, PyTorch, and TensorFlow. It measures the optimized inference path of each framework rather than preprocessing, model construction, or cold start.

Benchmark application

Item Configuration
Dataset CIFAR-10
Input 32×32 RGB images
Model ResNet-50 v1.5 bottleneck, CIFAR geometry
Batch size 128
Precisions fp32 and bf16
Runs 5 per framework and precision
Timed work Forward inference only
Metrics Median samples/s and milliseconds/batch; higher throughput is better

Reference computer

Component Value
CPU Intel Core i9-12900K
GPU NVIDIA GeForce RTX 4080, 16 GB
NVIDIA driver 595.71.05
Python 3.12.3
PyTorch 2.13.0+cu130
TensorFlow 2.21.0
OpenNN 9.0.0
Run ID 20260714T124333Z

Methodology

All three frameworks use the same CIFAR-10 input geometry, ResNet-50 v1.5 bottleneck topology, batch size, precision, and forward-only timing scope. Five successful runs are recorded for each framework and precision. The tables report the median throughput and batch time, plus the standard deviation of throughput across runs.

  • OpenNN keeps inputs on the GPU and uses its captured resident-output inference path.
  • PyTorch runs in evaluation mode under no_grad with PT_FAST=1, channels-last tensors, TF32 for fp32, and torch.compile(mode="reduce-overhead"). This is PyTorch’s compile-plus-CUDA-Graphs inference path.
  • TensorFlow runs with training=False under XLA and uses its bf16 policy for the bf16 cell.

Dataset preparation, process startup, model construction, host-to-device setup, and file loading are outside the measured region. GPU synchronization is included before timing is finalized.

Results

GPU ResNet-50 inference throughput
Higher is better
RTX 4080 · CIFAR-10 geometry · batch 128 · five-run medians
fp32
OpenNN
107.2k samples/s
PyTorch
87.0k samples/s
TensorFlow
52.8k samples/s
bf16
OpenNN
177.0k samples/s
PyTorch
124.8k samples/s
TensorFlow
80.8k samples/s
Five successful runs per framework and precision. The table reports exact medians, standard deviations, and batch times.
Precision Framework Median throughput Standard deviation Median batch time OpenNN speedup
fp32 OpenNN 107,229 samples/s 374 samples/s 1.194 ms 1.000x
fp32 PyTorch 87,038 samples/s 496 samples/s 1.471 ms 1.232x
fp32 TensorFlow 52,801 samples/s 763 samples/s 2.424 ms 2.031x
bf16 OpenNN 176,990 samples/s 598 samples/s 0.723 ms 1.000x
bf16 PyTorch 124,814 samples/s 1,739 samples/s 1.026 ms 1.418x
bf16 TensorFlow 80,778 samples/s 3,319 samples/s 1.585 ms 2.191x

OpenNN leads PyTorch by 23.2% in fp32 and 41.8% in bf16. Against TensorFlow, the corresponding leads are 103.1% and 119.1%.

Discussion

The five-run result separates the fp32 paths clearly: OpenNN records 107.2k samples/s with a standard deviation of 374 samples/s, while PyTorch reaches 87.0k samples/s and TensorFlow processes 52.8k samples/s in the same cell.

The bf16 path raises OpenNN throughput to 177.0k samples/s, a 1.65x increase over its own fp32 result. OpenNN also retains the highest throughput in this precision, reaching 1.418x PyTorch and 2.191x TensorFlow.

Relative dispersion is lowest for OpenNN in both cells: 0.35% in fp32 and 0.34% in bf16. PyTorch records 0.57% and 1.39%, while TensorFlow records 1.45% and 4.11%. These values describe repeatability in this five-run sample; they do not by themselves identify which runtime mechanism causes the difference.

The small CIFAR spatial geometry makes launch scheduling and framework overhead more visible than an ImageNet-resolution workload. The results therefore support this exact CIFAR-10 deployment shape and should not be generalized to 224×224 ResNet-50 without a separate measurement.

Conclusions

  • OpenNN reaches 107,229 ± 374 samples/s in fp32 and 176,990 ± 598 samples/s in bf16.
  • OpenNN is 1.232x PyTorch in fp32 and 1.418x PyTorch in bf16.
  • OpenNN is 2.031x TensorFlow in fp32 and 2.191x TensorFlow in bf16.
  • Five-run dispersion remains below 0.4% for OpenNN in both precision cells.
  • The result applies to ResNet-50 v1.5 with CIFAR-10 geometry and batch size 128.

Reproducing

The canonical runner is docs/benchmarks/throughput/resnet50/run_resnet50_infer.py:

python docs/benchmarks/throughput/resnet50/run_resnet50_infer.py \
  --dataset cifar10 --batch 128 --runs 5 --precision both

The immutable result artifact is docs/benchmarks/results/gpu-resnet50-inference-speed-cifar10-20260714T124333Z.json.

References