To the Editor — Methods for analyzing single-cell data1,2,3,4 perform a core set of computational tasks. These tasks include dimensionality reduction, cell clustering, cell-state annotation, removal of unwanted variation, analysis of differential expression, identification of spatial patterns of gene expression, and joint analysis of multi-modal omics data. Many of these methods rely on likelihood-based models to represent variation in the data; we refer to these as ‘probabilistic models’. Probabilistic models provide principled ways to capture uncertainty in biological systems and are convenient for decomposing the many sources of variation that give rise to omics data5.

Despite the appeal of probabilistic models, several obstacles impede their community-wide adoption. The first obstacle, coming from the perspective of the end user, relates to the difficulty of implementing and running such models. Because probabilistic models are often implemented using Python machine-learning libraries, users are often required to interact with interfaces and objects that are lower level in nature than those used in popular environments for single-cell data analysis like Bioconductor6, Seurat7 or Scanpy8.

A second obstacle relates to the development of new probabilistic models. From the perspective of developers, there are many necessary routines to implement in support of a probabilistic model, including data handling, tensor computations, training routines that handle device management (for example, GPU (graphic processing unit) computing), and the underlying optimization, sampling and numerical procedures. Although higher level machine-learning packages that automate some of these routines (for example, PyTorch Lightning9 or Keras10) are becoming popular, they do not work seamlessly with single-cell omics data.

To address these limitations, we present scvi-tools (https://scvi-tools.org/), a Python library for deep probabilistic analysis of single-cell omics data. From the end user’s perspective (Supplementary Note 1), scvi-tools offers standardized access to methods for many single-cell data analysis tasks, such as integration of single-cell RNA sequencing (scRNA-seq) data (scVI11 or scArches12), annotation of single-cell profiles (CellAssign13 or scANVI14), deconvolution of bulk spatial transcriptomics profiles (Stereoscope15 or DestVI16), doublet detection (Solo17) and multi-modal analysis of CITE-seq (cellular indexing of transcriptomes and epitopes by sequencing) data (totalVI18).

In the broader analysis pipeline, scvi-tools sits downstream of initial quality control (QC)-driven preprocessing and generates outputs that may be further interpreted via general single-cell analysis tools (Fig. 1a). At its core, scvi-tools implements several key functionalities that are accessible across data modalities, such as differential analysis and dataset integration. All 14 models (Supplementary Table 1) currently implemented in scvi-tools interact with Scanpy through the annotated dataset (AnnData19) format, and the models share a consistent user interface (Fig. 1b). The scvi-tools library also has an interface with R such that each model may be used in Seurat or Bioconductor pipelines.

Fig. 1: User perspective of scvi-tools.
figure 1

a, Overview of single-cell omics analysis pipeline with scvi-tools. Datasets may contain multiple layers of omic information, along with metadata at the cell and feature levels. QC and preprocessing are done with popular packages like Scanpy, Seurat and Scater. Subsequently, datasets can be analyzed with scvi-tools, which contains implementations of probabilistic models that offer a range of capabilities for various omics. Finally, results are further investigated or visualized, typically through a nearest neighbors graph, and through environments like VISION or cellxgene or by directing back to Scanpy or Seurat. b, Left, overview of the functionality of models implemented in scvi-tools covers core single-cell analysis tasks. Right, each model has a simple and consistent user interface; the code snippet shown applies scVI to a dataset read from a h5ad file and then performs dimensionality reduction and differential expression.

We also illustrate two new features of scvi-tools applicable to several types of omics data. The first feature offers the ability to remove unwanted variation due to multiple nuisance factors simultaneously, including both discrete (for example, batch category) and continuous (for example, percent mitochondrial reads) factors. In Supplementary Note 2, we apply this in the context of an scRNA-seq dataset of Drosophila wing development that suffered from nuisance variation due to cell cycle, sex and replicate. The second feature extends several scvi-tools integration methods to iteratively integrate new ‘query’ data into a pretrained ‘reference’ model via the recently proposed scArches neural network architecture surgery12. This feature is particularly useful for incorporating new samples into an analysis without having to reprocess the entire set of samples. Supplementary Note 3 presents a case study of applying this approach with totalVI by projecting data from patients with COVID-19 into an atlas of immune cells.

From the perspective of a methods developer, scvi-tools offers a set of building blocks that make it easy to implement new models and modify existing models with minimal code overhead (Fig. 2a,b and Supplementary Note 4). These building blocks use popular libraries, such as AnnData12, PyTorch20, PyTorch Lightning9 and Pyro21, and facilitate probabilistic model design with neural network components and GPU acceleration. This allows method developers to primarily focus on developing probabilistic models instead of on data management, model training and user-interface code. We demonstrate how these building blocks can be used for efficient model development through a reimplementation of Stereoscope, in which we demonstrate a substantial reduction in code complexity (Fig. 2c–e and Supplementary Note 5). This example demonstrates the broad scope of analyses that may be powered by scvi-tools.

Fig. 2: The scvi-tools API for developers and reimplementation of Stereoscope.
figure 2

a, For every probabilistic method implemented in scvi-tools, users interact with a high-level ‘model’ object. The model relies on several lower level components for training a model and analyzing data. The ‘module’, which must be implemented, systematically encapsulates the probabilistic specification of the method. The rest of the lower level components rely on precoded objects in scvi-tools, such as AnnDataLoader for loading data from AnnData objects, TrainingPlan for updating the parameters of the module, and Mixin classes for downstream analyses. b, The creation of a new module in scvi-tools involves three key steps. First, the generative model and inference procedure are mathematically specified. Second, users may either choose from our wide range of precoded neural network architectures and distributions or implement their own with PyTorch. Finally, those elements are combined together and organized into a class that inherits from the abstract class BaseModuleClass (note: presentation is pseudocode). The generative method maps latent variables to the data-generating distribution. The inference method maps input data to the variational distribution (specific to variational inference). The loss method specifies the objective function for the training procedure, here the evidence lower bound (and specifically depicted for a variational autoencoder (VAE)). c, Overview of the Stereoscope method. Stereoscope takes as input a spatial transcriptomics dataset, as well as a single-cell RNA sequencing dataset, and outputs the proportion of cell types in every spot. d, Short description of the steps required to reimplement Stereoscope into the codebase. For each of the two models of Stereoscope, we created a module class as well as a model class. e, Average cyclomatic code complexity and total number of source code lines for each of scvi-tools implementation and the original implementation.

On the scvi-tools documentation website, we feature the application programming interface (API) reference of each model, as well as tutorials describing the functionality of each model and its interaction with other single-cell tools. We also make these tutorials available via Google Colab, which provides a free computing environment and GPU and can even support large-scale analyses.

In the development of scvi-tools, we aimed to bridge the gap that exists between the single-cell software ecosystem and the contemporary machine-learning frameworks for constructing and deploying this class of models. Thus, developers can now expect to build models that are immediately accessible to end users in the single-cell community while continuing to rely on popular machine-learning libraries. On our documentation website, we provide a series of tutorials on building a model with scvi-tools, walking through the steps of data management, module construction and model development. We also built a template repository on GitHub that enables developers to quickly create a Python package that uses unit testing, automated documentation and popular code styling libraries. This repository demonstrates how the scvi-tools building blocks can be used for external model deployment. We anticipate that most models built with scvi-tools will be deployed in this way as independent packages while adhering to standard API and coding conventions, which will make them more readily accessible for new users.

As scvi-tools remains under active development, end users can expect that scvi-tools will continually evolve, adding support for new models, new workflows and new features. We anticipate that these resources will serve the single-cell community by facilitating the prototyping of new models, creating a standard for the deployment of probabilistic analysis software and enhancing the scientific discovery pipeline.