Skip to navigation

Benchmarks

View as Markdown

BioNeMo Inference Runtime (BioIR) measured against two OSS PyTorch baselines on every GPU it is tested on. These are the numbers a run of the published procedure should reproduce; they are not peak performance, and no attempt was made to tune any configuration per GPU.

Both baselines are reported for every measurement, and the pair is the point. Against OSS PyTorch eager, BioIR leads on every datacentre GPU and model here — 2.4x at worst. On GB10 it leads overall on every model, 1.14x at worst, but Protenix there falls to parity above 512 residues (0.98x and 0.99x). Against OSS torch.compile the answer depends on the architecture: 2.3-6.3x on Ampere, Hopper and Ada, 2.3-5.2x on Blackwell, and 1.4-2.4x on GB10. Either baseline quoted alone overstates the result in one direction or understates it in the other, so figures below 1.00x are printed rather than dropped.

torch.compile is ahead on one individual measurement: the largest OpenFold2 multimer input, 1734 residues on GB10, at 0.94x. On Boltz-2, OpenFold3 and OpenFold2 multimer the margin narrows with length on GB10, and on Boltz-2 and OpenFold3 on Blackwell too, so long inputs there are the case to check before quoting a single figure.

GB10 is a desktop part and reads like one: 128 GB of LPDDR5x at 273 GB/s shared between CPU and GPU, an order of magnitude under HBM. It runs the same spec 13-26x slower than an H100, and BioIR’s lead over both baselines is narrowest there. It is reported because it is a supported target, not as a comparison against the datacentre parts above it.

Speedup against input size on H100

Per-sample speedup against input size, all four models on H100. The dashed line is parity; crosses mark the largest input measured. The curves are far from flat — high on the smallest inputs, where launch and dispatch overhead dominates and BioIR has less of it, lowest in the few-hundred-residue range, then climbing with length as the fused kernels start to matter. That shape is why every table below is broken out by residue count, and why an overall geomean alone is not enough to quote.

Contents

Measurements

Hardware

LabelDeviceSMMemoryPower limitDriver
h100NVIDIA H100 80GB HBM39080 GiB700 W580.105.08
h200NVIDIA H20090140 GiB700 W595.58.03
a100NVIDIA A100 80GB PCIe8080 GiB300 W595.58.03
b200NVIDIA B200100179 GiB1000 W595.58.03
b300NVIDIA B300 SXM6 AC103269 GiB1100 W595.58.03
gb200NVIDIA GB200100185 GiB1200 W595.58.03
gb300NVIDIA GB300103278 GiB1400 W595.58.03
l40sNVIDIA L40S8945 GiB350 W595.58.03
l40NVIDIA L408945 GiB300 W595.58.03
l4NVIDIA L48922 GiB72 W595.58.03
rtx6000adaNVIDIA RTX 6000 Ada Generation8948 GiB300 W595.58.03
gb10NVIDIA GB10121——595.58.03

One GPU per measurement, one process, no replicas. Absolute latencies move with clocks, power limit and thermal headroom; the ratios are what should be comparable. Below 256 residues, host-side launch and dispatch dominate OSS latency, so OSS results there, and the speedups against them, also vary with CPU speed.

What Is Compared

Three backends fold the same inputs on the same GPU in the same container:

NameWhat it is
BioIRThis runtime: fused kernels, CUDA graphs, torch.compile where it applies
OSS torch.compileThe reference implementation under torch.compile
OSS PyTorch eagerThe reference implementation, unmodified

The OSS side runs its own inference script: eager always, and torch.compile additionally when it passes a dynamic-shape probe. Protenix has no compile path, which is why its compile column is empty.

Units

Speedup is OSS forward / BioIR forward per sample; above 1 favours BioIR. Every figure is a geometric mean of per-sample speedups, not a ratio of totals, so each sample counts equally regardless of how long it runs. n is the sample count and differs by model.

Speedups are broken out by input size in residues because the spread is wide — Boltz-2 on GB200 is 3.72x below 512 residues and 1.82x above 1024 against OSS torch.compile. The overall geomean alone hides a factor of two.

Peak memory is torch.cuda.max_memory_allocated over the run. Accuracy is OpenStructure lDDT over every sample and DockQ over the subset with a supported protein interface.

Boltz-2

GPUvs OSS torch.compilevs OSS PyTorch eager<512 res512-1024 res>1024 resn
h1003.81x6.35x3.79x / 5.71x3.67x / 6.44x4.01x / 7.11x17
h2004.33x6.19x4.58x / 5.98x3.90x / 5.98x4.57x / 6.72x17
a1003.64x5.39x4.16x / 6.06x3.41x / 5.03x3.34x / 5.07x17
b2002.65x3.91x3.34x / 4.38x2.36x / 3.56x2.30x / 3.82x17
b3002.72x4.41x3.38x / 5.87x2.41x / 3.59x2.41x / 4.00x17
gb2002.28x3.40x3.72x / 5.41x1.68x / 2.57x1.82x / 2.73x17
gb3003.14x4.72x4.68x / 7.03x2.44x / 3.67x2.62x / 3.96x17
l40s3.79x5.59x4.16x / 5.52x3.48x / 5.37x3.76x / 5.96x17
l402.73x4.19x3.86x / 5.22x2.42x / 3.53x2.08x / 3.94x17
l43.29x5.07x3.30x / 4.21x3.36x / 5.83x3.05x / 5.84x14
rtx6000ada3.16x4.61x4.45x / 6.11x2.55x / 3.76x2.73x / 4.20x17
gb101.71x2.75x2.05x / 2.48x1.70x / 3.35x1.37x / 2.46x17

Bucket cells are OSS torch.compile / OSS PyTorch eager. Below 1.00x means the baseline was faster.

Forward Latency

GPUBioIROSS torch.compileOSS PyTorch eager
h1003.35 s12.74 s21.27 s
h2003.15 s13.64 s19.51 s
a1007.90 s28.73 s42.55 s
b2003.63 s9.61 s14.20 s
b3003.52 s9.57 s15.53 s
gb2004.91 s11.17 s16.69 s
gb3003.44 s10.79 s16.23 s
l40s8.33 s31.58 s46.57 s
l4010.93 s29.83 s45.77 s
l416.97 s55.83 s86.00 s
rtx6000ada10.09 s31.92 s46.52 s
gb1043.76 s74.62 s120.48 s

Geomean of the per-sample forward time, over the samples the ratios above are taken over. Quote these when comparing two releases: a ratio that moved does not say which side did.

Peak Allocated Memory

GPUBioIROSS torch.compileOSS PyTorch eagerBioIR / compile
h10020.34 GiB32.27 GiB32.27 GiB0.63x
h20020.34 GiB32.27 GiB32.27 GiB0.63x
a10020.30 GiB32.25 GiB32.25 GiB0.63x
b20019.59 GiB32.27 GiB32.27 GiB0.61x
b30019.59 GiB32.27 GiB32.27 GiB0.61x
gb20019.59 GiB32.27 GiB32.27 GiB0.61x
gb30019.59 GiB32.27 GiB32.27 GiB0.61x
l40s20.30 GiB32.25 GiB32.25 GiB0.63x
l4020.30 GiB32.25 GiB32.25 GiB0.63x
l415.30 GiB16.44 GiB16.44 GiB0.93x
rtx6000ada20.30 GiB32.25 GiB32.25 GiB0.63x
gb1019.59 GiB32.27 GiB32.27 GiB0.61x

Below 1.00x means BioIR allocates less than the baseline; above 1.00x means it allocates more.

Accuracy

GPUlDDTDockQn lDDTn DockQ
h1000.667 / 0.665 / 0.6640.611 / 0.606 / 0.601179
h2000.667 / 0.664 / 0.6630.611 / 0.609 / 0.617179
a1000.662 / 0.660 / 0.6630.613 / 0.608 / 0.610179
b2000.663 / 0.661 / 0.6630.613 / 0.611 / 0.610179
b3000.669 / 0.660 / 0.6640.606 / 0.601 / 0.605179
gb2000.665 / 0.665 / 0.6620.610 / 0.615 / 0.607179
gb3000.669 / 0.667 / 0.6650.608 / 0.614 / 0.611179
l40s0.664 / 0.667 / 0.6660.603 / 0.612 / 0.615179
l400.666 / 0.666 / 0.6640.613 / 0.607 / 0.611179
l40.668 / 0.638 / 0.6380.608 / 0.620 / 0.625179
rtx6000ada0.663 / 0.665 / 0.6630.613 / 0.616 / 0.608179
gb100.666 / 0.662 / 0.6670.604 / 0.604 / 0.611179

Each cell is BioIR / OSS torch.compile / OSS PyTorch eager. lDDT is scored over every sample; DockQ covers the subset with a supported protein interface, which is why its count is lower. The three should agree — a speedup that moved them would not be the same answer.

OpenFold3

GPUvs OSS torch.compilevs OSS PyTorch eager<512 res512-1024 res>1024 resn
h1006.27x8.20x7.69x / 8.96x5.17x / 7.41x6.18x / 8.33x17
h2005.63x7.93x6.93x / 8.57x4.66x / 7.21x5.49x / 8.07x17
a1004.78x6.27x6.11x / 7.98x3.99x / 5.39x4.41x / 5.62x17
b2004.26x5.44x5.81x / 6.78x3.57x / 4.88x3.63x / 4.77x17
b3004.64x6.09x6.80x / 8.74x3.80x / 5.08x3.73x / 4.92x17
gb2003.70x4.47x6.47x / 7.00x3.00x / 3.58x2.44x / 3.40x17
gb3005.21x6.57x8.99x / 10.28x4.22x / 5.30x3.49x / 4.96x17
l40s5.54x6.63x6.99x / 8.77x5.03x / 5.96x4.72x / 5.39x17
l405.00x6.04x6.93x / 8.81x4.32x / 5.12x4.02x / 4.67x17
l44.39x5.60x4.39x / 5.60x— / —— / —6
rtx6000ada4.81x5.99x7.49x / 9.71x3.96x / 4.87x3.58x / 4.31x17
gb102.36x2.89x2.30x / 3.08x2.72x / 3.25x2.04x / 2.33x17

Bucket cells are OSS torch.compile / OSS PyTorch eager. Below 1.00x means the baseline was faster.

Forward Latency

GPUBioIROSS torch.compileOSS PyTorch eager
h1002.78 s17.44 s22.81 s
h2002.66 s14.97 s21.09 s
a1006.22 s29.69 s38.98 s
b2003.22 s13.71 s17.51 s
b3003.05 s14.15 s18.59 s
gb2004.34 s16.06 s19.39 s
gb3002.97 s15.49 s19.53 s
l40s6.28 s34.78 s41.62 s
l407.92 s39.58 s47.78 s
l43.42 s15.01 s19.16 s
rtx6000ada7.26 s34.92 s43.51 s
gb1036.39 s85.71 s105.25 s

Geomean of the per-sample forward time, over the samples the ratios above are taken over. Quote these when comparing two releases: a ratio that moved does not say which side did.

Peak Allocated Memory

GPUBioIROSS torch.compileOSS PyTorch eagerBioIR / compile
h10022.14 GiB29.49 GiB29.49 GiB0.75x
h20022.14 GiB29.49 GiB29.49 GiB0.75x
a10022.10 GiB29.47 GiB29.47 GiB0.75x
b20021.39 GiB29.49 GiB29.49 GiB0.73x
b30021.39 GiB29.49 GiB29.49 GiB0.73x
gb20021.39 GiB29.49 GiB29.49 GiB0.73x
gb30021.39 GiB29.49 GiB29.49 GiB0.73x
l40s22.10 GiB29.47 GiB29.47 GiB0.75x
l4022.10 GiB29.47 GiB29.47 GiB0.75x
l411.53 GiB8.40 GiB8.40 GiB1.37x
rtx6000ada22.10 GiB29.47 GiB29.47 GiB0.75x
gb1021.39 GiB29.49 GiB29.49 GiB0.73x

Below 1.00x means BioIR allocates less than the baseline; above 1.00x means it allocates more.

Accuracy

GPUlDDTDockQn lDDTn DockQ
h1000.617 / 0.616 / 0.6190.533 / — / —179
h2000.617 / 0.617 / 0.6120.533 / — / —179
a1000.616 / 0.616 / 0.6180.533 / — / —179
b2000.618 / 0.616 / 0.6140.535 / — / —179
b3000.618 / 0.619 / 0.6170.532 / — / —179
gb2000.613 / 0.606 / 0.6130.531 / — / —179
gb3000.614 / 0.619 / 0.6180.530 / — / —179
l40s0.617 / 0.617 / 0.6150.544 / — / —179
l400.617 / 0.622 / 0.6180.535 / — / —179
l40.575 / 0.407 / 0.4070.529 / — / —147
rtx6000ada0.614 / 0.621 / 0.6070.533 / — / —179
gb100.611 / 0.620 / 0.6190.538 / — / —179

Each cell is BioIR / OSS torch.compile / OSS PyTorch eager. lDDT is scored over every sample; DockQ covers the subset with a supported protein interface, which is why its count is lower. The three should agree — a speedup that moved them would not be the same answer.

OpenFold2 / AlphaFold2

Monomer

GPUvs OSS torch.compilevs OSS PyTorch eager<512 res512-1024 res>1024 resn
h1006.08x5.70x4.81x / 4.39x6.26x / 6.32x9.14x / 7.82x15
h2005.98x6.02x4.67x / 4.70x6.27x / 6.70x8.88x / 7.97x15
a1004.11x4.05x3.60x / 3.68x4.07x / 4.10x5.49x / 4.81x15
b2004.49x4.79x3.76x / 3.89x4.35x / 5.10x6.77x / 6.40x15
b3004.21x4.41x3.19x / 3.16x4.34x / 5.03x6.95x / 6.57x15
gb2004.06x3.85x4.04x / 3.38x3.58x / 3.90x5.24x / 4.85x15
l40s3.09x2.64x2.64x / 2.46x2.84x / 2.63x4.97x / 3.04x15
l402.93x2.63x2.76x / 2.74x2.59x / 2.47x4.24x / 2.76x15
l42.40x2.42x1.91x / 2.12x3.02x / 2.77x— / —12
rtx6000ada3.07x2.88x3.03x / 3.10x2.66x / 2.70x4.19x / 2.82x15
gb101.60x1.47x1.27x / 1.39x2.03x / 1.71x1.61x / 1.22x15

Bucket cells are OSS torch.compile / OSS PyTorch eager. Below 1.00x means the baseline was faster.

Forward Latency

GPUBioIROSS torch.compileOSS PyTorch eager
h1001.39 s8.44 s7.91 s
h2001.28 s7.66 s7.72 s
a1003.56 s14.65 s14.43 s
b2001.42 s6.38 s6.81 s
b3001.44 s6.07 s6.35 s
gb2001.92 s7.79 s7.39 s
l40s4.43 s13.69 s11.70 s
l405.20 s15.25 s13.68 s
l48.93 s21.46 s21.64 s
rtx6000ada4.76 s14.61 s13.70 s
gb1026.95 s43.24 s39.61 s

Geomean of the per-sample forward time, over the samples the ratios above are taken over. Quote these when comparing two releases: a ratio that moved does not say which side did.

Peak Allocated Memory

GPUBioIROSS torch.compileOSS PyTorch eagerBioIR / compile
h10029.69 GiB15.27 GiB15.27 GiB1.94x
h20029.69 GiB15.27 GiB15.27 GiB1.94x
a10029.67 GiB15.25 GiB15.25 GiB1.95x
b20018.77 GiB15.27 GiB15.27 GiB1.23x
b30018.77 GiB15.27 GiB15.27 GiB1.23x
gb20018.77 GiB15.27 GiB15.27 GiB1.23x
l40s29.67 GiB15.25 GiB15.25 GiB1.95x
l4029.67 GiB13.00 GiB13.00 GiB2.28x
l416.17 GiB13.00 GiB13.00 GiB1.24x
rtx6000ada29.67 GiB15.25 GiB15.25 GiB1.95x
gb1023.56 GiB15.27 GiB15.27 GiB1.54x

Below 1.00x means BioIR allocates less than the baseline; above 1.00x means it allocates more.

Accuracy

GPUlDDTDockQn lDDTn DockQ
h1000.434 / 0.426 / 0.432— / — / —15—
h2000.434 / 0.421 / 0.426— / — / —15—
a1000.434 / 0.422 / 0.422— / — / —15—
b2000.434 / 0.429 / 0.433— / — / —15—
b3000.434 / 0.427 / 0.426— / — / —15—
gb2000.433 / 0.432 / 0.429— / — / —15—
l40s0.432 / 0.431 / 0.426— / — / —15—
l400.434 / 0.419 / 0.433— / — / —15—
l40.481 / 0.424 / 0.417— / — / —15—
rtx6000ada0.434 / 0.420 / 0.418— / — / —15—
gb100.434 / 0.421 / 0.424— / — / —15—

Each cell is BioIR / OSS torch.compile / OSS PyTorch eager. lDDT is scored over every sample; DockQ covers the subset with a supported protein interface, which is why its count is lower. The three should agree — a speedup that moved them would not be the same answer.

Multimer

GPUvs OSS torch.compilevs OSS PyTorch eager<512 res512-1024 res>1024 resn
h1005.27x6.03x— / —4.82x / 5.58x5.76x / 6.51x4
h2005.25x6.09x— / —4.80x / 5.65x5.75x / 6.57x4
a1003.17x3.66x— / —3.00x / 3.51x3.35x / 3.82x4
b2004.06x4.84x— / —3.51x / 4.26x4.70x / 5.49x4
b3004.10x4.89x— / —3.42x / 4.19x4.90x / 5.72x4
gb2002.94x3.46x— / —2.55x / 3.04x3.39x / 3.93x4
gb3004.16x4.90x— / —3.49x / 4.17x4.96x / 5.75x4
l40s2.74x3.03x— / —2.56x / 2.84x2.94x / 3.23x4
l402.30x2.54x— / —2.16x / 2.41x2.45x / 2.68x4
rtx6000ada2.32x2.61x— / —2.20x / 2.51x2.45x / 2.70x4
gb101.43x1.57x— / —1.72x / 1.90x1.19x / 1.30x4

Bucket cells are OSS torch.compile / OSS PyTorch eager. Below 1.00x means the baseline was faster.

Forward Latency

GPUBioIROSS torch.compileOSS PyTorch eager
h1003.74 s19.71 s22.54 s
h2003.49 s18.31 s21.23 s
a10011.49 s36.40 s42.05 s
b2003.68 s14.97 s17.81 s
b3003.52 s14.43 s17.24 s
gb2004.82 s14.15 s16.67 s
gb3003.36 s14.00 s16.48 s
l40s13.82 s37.90 s41.90 s
l4017.58 s40.43 s44.65 s
rtx6000ada16.88 s39.24 s44.01 s
gb1093.66 s133.90 s147.23 s

Geomean of the per-sample forward time, over the samples the ratios above are taken over. Quote these when comparing two releases: a ratio that moved does not say which side did.

Peak Allocated Memory

GPUBioIROSS torch.compileOSS PyTorch eagerBioIR / compile
h10018.01 GiB14.04 GiB14.04 GiB1.28x
h20018.01 GiB14.04 GiB14.04 GiB1.28x
a10017.99 GiB14.02 GiB14.02 GiB1.28x
b20016.31 GiB14.04 GiB14.04 GiB1.16x
b30016.31 GiB14.04 GiB14.04 GiB1.16x
gb20016.31 GiB14.04 GiB14.04 GiB1.16x
gb30016.31 GiB14.04 GiB14.04 GiB1.16x
l40s17.99 GiB14.02 GiB14.02 GiB1.28x
l4017.99 GiB11.84 GiB11.84 GiB1.52x
rtx6000ada17.99 GiB14.02 GiB14.02 GiB1.28x
gb1021.43 GiB14.04 GiB14.04 GiB1.53x

Below 1.00x means BioIR allocates less than the baseline; above 1.00x means it allocates more.

Accuracy

GPUlDDTDockQn lDDTn DockQ
h1000.784 / 0.736 / 0.7660.603 / 0.601 / 0.61044
h2000.784 / 0.762 / 0.7610.603 / 0.591 / 0.60644
a1000.777 / 0.750 / 0.7770.597 / 0.617 / 0.62044
b2000.783 / 0.766 / 0.7740.607 / 0.610 / 0.60644
b3000.783 / 0.756 / 0.7790.607 / 0.609 / 0.62044
gb2000.783 / 0.768 / 0.7620.607 / 0.600 / 0.61044
gb3000.783 / 0.768 / 0.7740.607 / 0.635 / 0.62144
l40s0.780 / 0.783 / 0.7660.609 / 0.613 / 0.60044
l400.782 / 0.754 / 0.7670.602 / 0.608 / 0.60244
rtx6000ada0.782 / 0.769 / 0.7660.602 / 0.622 / 0.60844
gb100.780 / 0.756 / 0.7730.602 / 0.613 / 0.62544

Each cell is BioIR / OSS torch.compile / OSS PyTorch eager. lDDT is scored over every sample; DockQ covers the subset with a supported protein interface, which is why its count is lower. The three should agree — a speedup that moved them would not be the same answer.

Protenix

GPUvs OSS torch.compilevs OSS PyTorch eager<512 res512-1024 res>1024 resn
h100—5.37x— / 6.85x— / 4.45x— / 5.04x17
h200—5.03x— / 6.46x— / 4.21x— / 4.61x17
a100—3.90x— / 5.93x— / 3.10x— / 3.12x17
b200—3.54x— / 4.82x— / 2.96x— / 3.04x17
b300—4.27x— / 7.04x— / 3.23x— / 3.28x17
gb300—4.59x— / 7.78x— / 3.44x— / 3.43x17
l40s—3.74x— / 5.36x— / 3.17x— / 2.96x17
l40—3.06x— / 5.43x— / 2.32x— / 2.14x17
l4—3.00x— / 3.53x— / 2.67x— / 2.64x14
rtx6000ada—3.16x— / 5.88x— / 2.31x— / 2.19x17
gb10—1.14x— / 1.51x— / 0.98x— / 0.99x17

Bucket cells are OSS torch.compile / OSS PyTorch eager. Below 1.00x means the baseline was faster.

Forward Latency

GPUBioIROSS torch.compileOSS PyTorch eager
h1004.59 s—24.64 s
h2004.44 s—22.34 s
a10011.44 s—44.64 s
b2004.99 s—17.69 s
b3004.67 s—19.94 s
gb3004.40 s—20.16 s
l40s12.27 s—45.87 s
l4016.67 s—51.00 s
l426.11 s—78.40 s
rtx6000ada15.03 s—47.50 s
gb10120.09 s—137.41 s

Geomean of the per-sample forward time, over the samples the ratios above are taken over. Quote these when comparing two releases: a ratio that moved does not say which side did.

Peak Allocated Memory

GPUBioIROSS torch.compileOSS PyTorch eagerBioIR / compile
h10027.57 GiB—35.16 GiB—
h20027.57 GiB—35.16 GiB—
a10027.55 GiB—35.14 GiB—
b20033.19 GiB—35.16 GiB—
b30033.19 GiB—35.16 GiB—
gb30033.19 GiB—35.16 GiB—
l40s27.55 GiB—35.14 GiB—
l4027.55 GiB—35.14 GiB—
l417.42 GiB—17.78 GiB—
rtx6000ada27.55 GiB—35.14 GiB—
gb1033.19 GiB—35.16 GiB—

Below 1.00x means BioIR allocates less than the baseline; above 1.00x means it allocates more.

Accuracy

GPUlDDTDockQn lDDTn DockQ
h1000.658 / — / 0.6500.591 / — / 0.545179
h2000.657 / — / 0.6500.591 / — / 0.568179
a1000.659 / — / 0.6490.599 / — / 0.541179
b2000.659 / — / 0.6480.590 / — / 0.562179
b3000.658 / — / 0.6540.589 / — / 0.549179
gb3000.659 / — / 0.6530.589 / — / 0.555179
l40s0.660 / — / 0.6520.600 / — / 0.552179
l400.657 / — / 0.6480.589 / — / 0.548179
l40.635 / — / 0.6090.581 / — / 0.515158
rtx6000ada0.658 / — / 0.6500.601 / — / 0.554179
gb100.658 / — / 0.6520.601 / — / 0.552179

Each cell is BioIR / OSS torch.compile / OSS PyTorch eager. lDDT is scored over every sample; DockQ covers the subset with a supported protein interface, which is why its count is lower. The three should agree — a speedup that moved them would not be the same answer.

RFProteína

RFProteína is a design model rather than a folding model, so it runs on its own harness and these figures are not comparable with the tables above. The unit is milliseconds per sampling step on one h100, batch 1, 50 sampling steps, a mid-peak recycling schedule for 170 trunk passes, and self-conditioning disabled, across thirty sequence lengths from 64 to 1024 residues.

Each side is configured as it would be deployed rather than forced into a common mould: the OSS implementation uses static torch.compile and pads every input up to a released compile anchor, while BioIR runs the native length unpadded, with exact-shape CUDA graphs through 512 residues and eager execution above. Compilation, capture and warmup are outside the timed region.

BioIR is faster at all thirty shapes, with a median speedup of 2.03x over a range of 1.28x to 3.35x.

ResiduesOSS pads toBioIR modeOSSBioIRSpeedup
64128CUDA graph233.6974.023.16x
128128CUDA graph225.74103.162.19x
256256CUDA graph436.60272.561.60x
512512CUDA graph1195.36767.431.56x
769896eager2983.93889.793.35x
10241024eager2895.811489.111.94x

Fourteen of the thirty measured shapes carry the pattern; six representative rows are shown. Read the extremes with care. The largest speedups sit immediately after an OSS compile anchor — 769 residues padded to 896 gives 3.35x — where much of the gain is padding waste on the OSS side rather than BioIR being faster. Each row is a single timed rollout after warmup rather than a median of repeats, so individual rows carry run-to-run noise. The sweep also predates the removal of a short-sequence triangle-multiplication path, so rows below 384 residues understate current BioIR performance, and it predates the upstream thinking-mode schedules, so its fixed 50-step, 170-pass budget is not what a default run executes today: the default is thinking_medium, 60 steps over 185 trunk passes. Latency per sampling step stays the comparable unit; total design time scales with the mode’s trunk-pass count.

Peak allocated memory is lower for BioIR at long lengths, 10.74 against 15.56 GiB at 1024 residues, while peak reserved memory is higher, 38.69 against 33.62 GiB. That reflects caching-allocator behaviour under graph capture rather than live tensor footprint, so deployments sized on reserved memory should note the difference.

Design quality is reported separately in RFProteína architecture, because the comparison is distributional rather than a per-sample score.

Reproducing

These numbers are not tied to a build artifact: they come from main, on one GPU, with public inputs and upstream baselines at pinned tags. The procedure is the bench-perf-oss agent skill — point an agent at it rather than following steps by hand. It installs BioIR and each pinned baseline in isolation, runs one warmup and one timed forward per sample, scores the output, and aggregates the geomeans above.

Have these ready first; the skill cannot supply them:

  • One NVIDIA GPU on driver 580 or newer. The container ships a CUDA 13.2 build of PyTorch. On a 535 driver it runs only through the forward-compatibility shim, and measuring on that path produced silent hangs and SIGFPE crashes part-way through a sweep — wrong numbers, not merely slow ones. Check the ECC counters are zero while you are there.
  • NGC_API_KEY exported, for the MSA Search NIM. rebuild_dataset.py builds the dataset-0.3.0 inputs from RCSB and that endpoint rather than downloading a release; the structures need no credential at all (--structures-only). Free key at build.nvidia.com. Every structure is checked against the coordinates that were measured. When RCSB has since revised an entry’s coordinates (7PV5 in September 2026), the script takes the measured version from the wwPDB versioned archive instead.
  • HF_TOKEN exported. OpenFold3’s checkpoint is gated and an anonymous fetch returns 401. Registering is free. Checkpoint staging generally is Model Weights.
  • A built extension, per Development Workflow.

When a ratio does not match, suspect the baseline environment before the code. The most common cause by far is an upstream package resolved against a different torch than BioIR’s, at which point the ratio compares two PyTorch builds rather than two implementations.


Container nvcr.io/nvidia/pytorch:26.05-py3 · driver 580.105.08–610.57.04 · measured 2026-10-14