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: Optional[list[str]] = 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:
datastructure.set_training_column_split_by_semantic_type(schema)data_factory.create_dataset(... data_split=TEST, splitter=_InferenceSplitter)data_factory.create_dataloader(dataset, batch_size)
No train/validation splits are created.
Arguments
datasource: The datasource to iterate over.schema: ABitfountSchema(should already have features populated viaBitfountSchema.add_dataframe_features).datastructure: ADataStructure(frombuild_column_config).batch_size: Batch size for the dataloader.
Returns
A BitfountDataLoader wrapping the test dataset.
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 viadeserialize).
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 populatedBitfountSchema.datastructure: A configuredDataStructure.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_sizeand, 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.