Skip to main content

inference

Model inference pipeline utilities.

Decomposes the monolithic initialise_model(data=...) flow into individually callable functions so that each concern (column configuration, dataloader creation, model init, inference) can be used and tested independently.

Module​

Functions​

build_column_config​

def build_column_config(    image_prefix: str = 'Pixel Data',    selected_cols: list[str] | None = None,    selected_cols_prefix: str | None = None,    schema_requirements: Any = 'empty',    batch_transforms: list[dict[str, typing.Any]] | None = None,    image_prefix_batch_transforms: list[dict[str, typing.Any]] | None = None,    auto_convert_grayscale_images: bool = True,) ‑> DataStructure:

Build a DataStructure suitable for ophthalmology inference.

This is a thin wrapper around the DataStructure constructor with sensible defaults matching the GA Trial Bronze task YAML.

Arguments

  • image_prefix: Image column prefix (default "Pixel Data").
  • selected_cols: Explicit list of selected columns. Defaults to ["Columns", "Rows"] when None.
  • selected_cols_prefix: Prefix for selected columns (default same as image_prefix).
  • schema_requirements: Schema requirement level.
  • batch_transforms: Optional batch transforms list.
  • image_prefix_batch_transforms: Optional image-specific batch transforms.
  • auto_convert_grayscale_images: Convert grayscale to RGB (default True).

Returns A DataStructure instance.

create_inference_dataloader​

def create_inference_dataloader(    datasource: FileSystemIterableSource,    schema: BitfountSchema,    datastructure: DataStructure,    batch_size: int | None = None,) ‑> Any:

Create a test-only dataloader for inference, bypassing BitfountDataBunch.

This reproduces the subset of BitfountDataBunch.__init__ that is relevant for inference:

  1. datastructure.set_training_column_split_by_semantic_type(schema)
  2. data_factory.create_dataset(... data_split=TEST, splitter=_InferenceSplitter)
  3. data_factory.create_dataloader(dataset, batch_size)

No train/validation splits are created.

Arguments

  • datasource: The datasource to iterate over.
  • schema: A BitfountSchema (should already have features populated via BitfountSchema.add_dataframe_features).
  • datastructure: A DataStructure (from build_column_config).
  • batch_size: Batch size for the dataloader.

Returns A BitfountDataLoader wrapping the test dataset.

flush_inference_timers​

def flush_inference_timers(model: Any) ‑> None:

Report the trailing window of every inference phase timed against model.

For a caller that owns the end of the inference loop. Without it the final partial window is discarded, which for a short run is every sample it has.

inference_timer_name​

def inference_timer_name(base: str, model: Any) ‑> str:

Return the timer name for phase base as measured against model.

Qualified by the model's own name, not type(model).__name__: every v1 Hub model is rebuilt by maybe_convert_bitfount_model_class_to_v2 as a class literally called Converted, so the plain class name is the same string for every one of them and would pool the fovea and GA distributions back together

  • the exact thing the qualification exists to prevent. The conversion keeps the original name on __converted_cls_name__ for this reason.

Arguments

  • base: One of the INFERENCE_*_TIMER_NAME constants.
  • model: The model the phase ran against; its name qualifies the timer.

init_model_for_inference​

def init_model_for_inference(model: Any) ‑> None:

Initialise a model for inference without binding any data.

Calls model.initialise_model() with no datasource so that the model's internal create_model() and weight-loading logic runs, but no BitfountDataBunch or dataloaders are created.

After this call you can assign model.test_dl directly and run model._pl_trainer.test().

Arguments

  • model: A Bitfount model instance (already has weights loaded via deserialize).

run_inference​

def run_inference(    model: Any,    datasource: FileSystemIterableSource,    schema: BitfountSchema,    datastructure: DataStructure,    batch_size: int | None = None,) ‑> PredictReturnType:

End-to-end inference: init model, build dataloader, predict.

Composes init_model_for_inference, create_inference_dataloader, and the model's prediction machinery into a single call.

Arguments

  • model: A Bitfount model instance with weights loaded.
  • datasource: The datasource to run inference on.
  • schema: A populated BitfountSchema.
  • datastructure: A configured DataStructure.
  • batch_size: Batch size for inference.

Returns PredictReturnType (preds + keys).

Notes Some Hub models aggregate a whole forward batch into a single prediction (e.g. exam-level ophthalmology models). Run at a batch size

1, they emit fewer predictions than input records, tripping the "predictions vs keys" contract check. Since we cannot edit those models (they are fetched from the Hub), we run optimistically at the requested batch_size and, only if that contract fails, transparently retry the same chunk at one record per forward batch — the size at which no model can collapse per-record results. Well-behaved models never hit the retry, so they keep their throughput.