Skip to main content
The Inference facade replaces the multi-step manual pipeline (Backbone + mask provider
  • SlideInference + writer) with a single, reusable object. The constructor is the pipeline config; the methods do the work. It caches tissue masks, organizes outputs into a structured workspace, and can serialize its config for reproducibility.

Configure the pipeline

Pick your backend — the rest of the guide is identical for both.
from bioptimus.inference import Inference
from bioptimus.models.types import Models

infer = Inference(
    model_name=Models.H1,
    api_url="http://localhost:8080",
    tissue=True,
    mask_threshold=0.5,
    output_path="/data/output",
    experiment="h1-embedding-demo",
    run=1,
    description="H1 embeddings with tissue masking",
)

Run the pipeline

infer.tissue(wsi_path)                 # generate (or load cached) tissue mask
result_path = infer.embed(wsi_path)    # -> <workspace>/h1/embeddings/<slide>.zarr
infer.save(wsi_path, patches=True)     # export tile CSV (+ optional patch PNGs)
The tissue mask is cached to <workspace>/tissue/<slide>.npy and reused automatically on later calls.

Reproducibility

The config is auto-saved to <workspace>/config.yaml on first use. Reconstruct the exact pipeline later:
infer.save_config()
infer2 = Inference.from_config(config_path)   # same workspace; cached masks reused
The same object works across multiple slides — call infer.embed([s1, s2]) rather than creating a new Inference per slide. For full cohorts with bulk RNA, see Cohorts.

Workspaces & variants

Your workspace is the directory where all outputs are written. It’s resolved from the config you pass:
<output_path>/<experiment>/run_<run>/<variant>/
Only output_path is required; experiment, run, and variant are appended when set:
def workspace(self) -> Path:
    """Resolved experiment workspace root directory."""
    root = self._output_path
    if self._experiment:
        root = root / self._experiment
    if self._run is not None:
        root = root / f"run_{self._run}"
    if self._variant:
        root = root / self._variant
    return root
variant (a string) adds a final sub-folder so you can keep multiple runs side by side — useful for experiments (e.g. comparing mask thresholds or model versions) without overwriting earlier outputs:
infer = Inference(model_name=Models.H1, api_url="http://localhost:8080",
                  output_path="/data/output", experiment="tcga_coad", run=1,
                  variant="mask_0.5")
# -> /data/output/tcga_coad/run_1/mask_0.5/
A populated workspace looks like:
<output_path>/<experiment>/run_<run>/<variant>/
  config.yaml
  tissue/<slide>.npy
  h1/embeddings/<slide>.zarr
  h1/tiles/<slide>.csv