Getting Started

Install slide2vec, embed a slide in Python, or save a batch of embeddings from a manifest.

Installation

Python 3.10 or newer is required. Install the package with:

pip install slide2vec

Some presets need additional dependencies; see Installation extras for extras and upstream packages. The fm extra includes dependencies for many foundation models:

pip install "slide2vec[fm]"

Reproducible model environments

The repository also ships a uv.lock file that pins every package for each extra. From a checkout, uv installs the exact locked stack:

uv sync --extra cu128 --extra fm

Use --extra cpu instead of --extra cu128 for CPU-only PyTorch. Add --extra flash-attn for the presets that need FlashAttention (PRISM2 and gigapath-slide); it builds against the locked torch.

The Docker image is built from the same lock. Its SLIDE2VEC_EXTRAS build argument selects the extras, for example docker build --build-arg SLIDE2VEC_EXTRAS="cu128" --build-arg SLIDE2VEC_GROUPS="" . for the base install only.

For gated models, request access from the model’s Hugging Face page in the Model Zoo guide, then authenticate before loading weights:

hf auth login

You can also supply an HF_TOKEN environment variable. The examples below use virchow2, which requires access to its gated weights.

Embed a slide

from hs2p import TilingConfig
from slide2vec import Model, PreprocessingConfig

model = Model.from_preset("virchow2")
preprocessing = PreprocessingConfig(
    tiling=TilingConfig(
        requested_spacing_um=0.5,
        requested_tile_size_px=224,
        tolerance=0.05,
        overlap=0.0,
    ),
)
embedded = model.embed_slide("/path/to/slide.svs", preprocessing=preprocessing)

tile_embeddings = embedded.tile_embeddings  # shape (N, 2560)
x, y = embedded.x, embedded.y               # shape (N,), level-0 pixels

N is the number of selected tiles. embed_slide returns an EmbeddedSlide containing the embeddings, coordinates, and metadata. Its slide_embedding is None for tile encoders such as Virchow2; slide-level presets also produce a slide embedding.

For several slides, embed_slides returns a mapping keyed by sample ID, then annotation label. The default tissue-only run uses the label "tissue":

results = model.embed_slides(
    ["/path/to/slide1.svs", "/path/to/slide2.svs"],
    preprocessing=preprocessing,
)
for sample_id, bags in results.items():
    print(sample_id, bags["tissue"].tile_embeddings.shape)

For path inputs, the sample ID defaults to the filename stem. See Annotation-Aware Sampling for selecting multiple annotation classes.

Choose a model

Browse the Model Zoo guide or list installed presets without loading weights:

from slide2vec import list_models

list_models()           # all presets
list_models("tile")     # one embedding per tile
list_models("slide")    # aggregate tiles into a slide embedding
list_models("patient")  # aggregate a patient's slides

Control preprocessing

PreprocessingConfig holds hs2p’s config dataclasses. Leave tiling unset to take spacing and tile size from the preset. Models with several supported spacings, including Virchow2, need an explicit TilingConfig. To also raise the tissue threshold:

from dataclasses import replace

from hs2p import TilingConfig
from slide2vec import PreprocessingConfig

default_masks = PreprocessingConfig().masks
preprocessing = PreprocessingConfig(
    tiling=TilingConfig(
        requested_spacing_um=0.5,
        requested_tile_size_px=224,
        tolerance=0.05,
        overlap=0.0,
    ),
    masks=replace(default_masks, min_coverage={"tissue": 0.3}),
)
embedded = model.embed_slide("/path/to/slide.svs", preprocessing=preprocessing)

See Preprocessing for readers, segmentation, annotated masks, and previews, or Hierarchical Features to group tiles into regions.

Control execution

By default, runs use all available GPUs, a batch size of 32, and the model’s registered precision. To limit a run to one GPU:

from slide2vec import ExecutionOptions

execution = ExecutionOptions(num_gpus=1, batch_size=32)
embedded = model.embed_slide(
    "/path/to/slide.svs", preprocessing=preprocessing, execution=execution,
)

ExecutionOptions keeps the values you pass: num_gpus and num_preprocessing_workers stay None when left on auto. resolved_num_gpus() and resolved_num_preprocessing_workers() return the counts a run uses on the current machine.

For CPU inference, construct the model with Model.from_preset("virchow2", device="cpu").

ExecutionOptions.precision controls the forward-pass dtype ("fp16", "bf16", "fp32", or None for the model default). output_dtype independently controls feature storage ("fp16" or "fp32"). Left as None, it follows precision: fp16 stores fp16; bf16 and fp32 store fp32. The equivalent CLI config keys are speed.precision and speed.output_dtype. See API Guide for the field reference.

Save a batch to disk

Use Pipeline with a CSV Input Manifest:

sample_id,image_path
slide-1,/data/slide-1.svs
slide-2,/data/slide-2.svs
from slide2vec import ExecutionOptions, Model, Pipeline

pipeline = Pipeline(
    model=Model.from_preset("virchow2"),
    preprocessing=preprocessing,
    execution=ExecutionOptions(output_dir="outputs/run"),
)
result = pipeline.run(manifest_path="/path/to/slides.csv")

The run writes embeddings, coordinate files, and progress records under outputs/run. See Output Layout to load the results, or CLI Guide to run the same workflow from a YAML config.