Skip to main content
Whole-slide inference is a pipeline: tiles are read and preprocessed on CPU, then run through the model on GPU, then written to disk. For Bioptimus embedding and prediction models, the GPU forward pass is usually the bottleneck — a few knobs matter a lot, and most others matter little. This page covers the client-side (SDK) knobs; for what’s fixed by the deployment (precision, batching env vars), see the Inference Server’s Performance page.

Quick reference

Batch wait time and CPU preprocess worker count rarely matter once the GPU is the bottleneck — leave them at their defaults unless you’ve confirmed with the check in Is the GPU the bottleneck? that the GPU is not saturated.

Backend-specific knobs

For a cohort (multiple slides) on a single local GPU, keep Inference(..., workers=...) at 1–2 — all slides share the same GPU, so higher values add threads without adding throughput. To use multiple local GPUs, run one process per GPU (CUDA_VISIBLE_DEVICES=<i>) rather than raising workers. See Cohorts.
Tissue masking (mask_threshold) and tile geometry (size/stride) are backend-agnostic — see Preprocessing tuning knobs. For ready-to-copy starting configurations (single slide vs. cohort), see Recommended starting configurations on the Bioptimus SDK page.
As a rough reference, on a single mid-range datacenter GPU, embedding a typical whole slide (a few thousand tissue tiles) with the fp16 checkpoint takes on the order of one to a few minutes; fp32 is a few times slower. Tissue coverage and GPU model shift this substantially — measure your own workload (tiles processed ÷ wall-clock time) rather than relying on this as a guarantee.
Slower than expected, or a run that looks stalled? See Common issues.