Skip to main content

UniVI

PyPI PyPI downloads conda-forge conda-forge downloads Python Docs Paper License: MIT

UniVI integrates single-cell modalities measured in the same cells (RNA, surface protein, chromatin accessibility, DNA methylation, and others) into one latent space. Each modality has its own encoder and decoder, so a trained model can align cells across assays, predict one modality from another, map new single-modality datasets onto a multimodal reference, and generate cells.

UniVI architecture, training objective, and evaluation

Documentation, tutorials, and API reference: univi.readthedocs.io

Installation

pip install univi                      # or: conda install -c conda-forge univi
pip install "univi[tutorials]"         # adds Jupyter and scikit-misc for the tutorials

UniVI requires PyTorch. If import torch fails, or you need a specific CUDA build, install PyTorch first from pytorch.org.

Quickstart

Train on paired RNA + ATAC from 10x Multiome PBMCs (downloaded and cached on first use), then embed held-out cells and predict their gene expression from chromatin accessibility:

import torch
import univi.datasets as uds
from univi import ModalityConfig, TrainingConfig, UniVIConfig, UniVIMultiModalVAE, UniVITrainer
from univi.evaluation import cross_modal_predict, encode_adata, evaluate_alignment
from univi.preprocessing import ATACPreprocessor, RNAPreprocessor, split_by_label
from univi.workflows import make_loader, save_reference

device = "cuda" if torch.cuda.is_available() else "cpu"

# 1. Paired data: one AnnData per modality, same cells in the same order
data = uds.pbmc_multiome_10k()
rna, atac = data["rna"], data["atac"]

# 2. Split, then fit preprocessing on training cells only
split = split_by_label(rna.obs["cell_type"], train_fraction=0.8, val_fraction=0.1, seed=0)
rna_prep = RNAPreprocessor(n_hvg=2000, scale=True).fit(rna[split["train"]])
atac_prep = ATACPreprocessor(n_components=101, drop_first=True).fit(atac[split["train"]])
parts = {k: {"rna": rna_prep.transform(rna[i]), "atac": atac_prep.transform(atac[i])}
         for k, i in split.items()}
train, val, test = parts["train"], parts["val"], parts["test"]

# 3. One encoder/decoder per modality, a shared 30-dimensional latent space
cfg = UniVIConfig(
    latent_dim=30, beta=1.25, gamma=4.35, encoder_dropout=0.1, decoder_dropout=0.05,
    kl_anneal_start=50, kl_anneal_end=85, align_anneal_start=75, align_anneal_end=110,
    modalities=[
        ModalityConfig("rna", train["rna"].n_vars, [512, 256, 128], [128, 256, 512], likelihood="gaussian"),
        ModalityConfig("atac", train["atac"].n_vars, [128, 64], [64, 128], likelihood="gaussian"),
    ],
)
model = UniVIMultiModalVAE(cfg)

# 4. Train with early stopping on the validation cells
UniVITrainer(
    model,
    train_loader=make_loader(train, batch_size=256, shuffle=True, drop_last=True),
    val_loader=make_loader(val, batch_size=1024),
    train_cfg=TrainingConfig(n_epochs=400, lr=1e-3, weight_decay=1e-4, device=device,
                             early_stopping=True, patience=50, best_epoch_warmup=110),
).fit()

# 5. Embed each modality, measure alignment, predict RNA from ATAC
z_rna = encode_adata(model, test["rna"], modality="rna", latent="modality_mean", device=device)
z_atac = encode_adata(model, test["atac"], modality="atac", latent="modality_mean", device=device)
labels = test["rna"].obs["cell_type"].astype(str).to_numpy()
metrics = evaluate_alignment(Z1=z_rna, Z2=z_atac, labels_source=labels, labels_target=labels)
print("FOSCTTM:", metrics["foscttm_mean"], "label transfer:", metrics["label_transfer_acc"])

rna_from_atac = cross_modal_predict(model, test["atac"], src_mod="atac", tgt_mod="rna", device=device)

# 6. Save weights + configuration + fitted preprocessing as a reusable reference
save_reference("multiome_reference", model, preprocessors={"rna": rna_prep, "atac": atac_prep})

The quickstart notebook runs the same steps with plots and explanations.

What you can do with UniVI

Task Tutorial
Integrate paired RNA + ATAC; check alignment; predict one modality from another Quickstart
CITE-seq: fused embeddings, protein prediction, denoising, per-cell modality weights CITE-seq
Map RNA-only or ATAC-only data onto a reference; transfer labels; flag unfamiliar cells Query mapping
Add cell-type or genotype heads to a trained reference, with partial labels Heads and refinement
Denoise, generate cells, run in-silico perturbations Generation
Three or more modalities; count, methylation (beta-binomial) and other likelihoods Custom modalities

Every tutorial opens in Google Colab. The user guide covers data preparation, likelihood and hyperparameter choices, evaluation metrics, and saving models.

Reproducing the Genome Research analyses

The notebooks that produced every figure of the article are in notebooks/GR_manuscript_reproducibility/, with parameter files in parameter_files/ and a driver script in scripts/revision_reproduce_all.sh. The article was prepared against release v0.4.7 (pip install univi==0.4.7, or envs/univi_v0.4.7_env.yml). The reproduction guide maps each figure to its notebook and dataset.

Processed datasets download with univi.datasets (uds.list_datasets() shows what is available); the annotated Multiome PBMC data are on Zenodo.

Citation

Ashford AJ, Enright T, Somers J, Nikolova O, Demir E. Unifying multimodal single-cell data with a mixture-of-experts β-variational autoencoder framework. Genome Research (2026). doi:10.1101/gr.281431.125

@article{Ashford2026UniVI,
  title   = {Unifying multimodal single-cell data with a mixture-of-experts
             {$\beta$}-variational autoencoder framework},
  author  = {Ashford, Andrew J. and Enright, Trevor and Somers, Julia
             and Nikolova, Olga and Demir, Emek},
  journal = {Genome Research},
  year    = {2026},
  doi     = {10.1101/gr.281431.125},
  url     = {https://doi.org/10.1101/gr.281431.125}
}

Repository layout

univi/        the Python package
docs/         documentation source; tutorials are the notebooks in docs/tutorials/
notebooks/    archived analysis notebooks for the Genome Research article
parameter_files/, scripts/   JSON configurations and command-line entry points
envs/         conda environment files (including the v0.4.7 environment used for the article)
tests/        unit tests and tutorial execution tests

Contributing and support

Questions and bug reports are welcome as GitHub issues; please include the UniVI version (python -c "import univi; print(univi.__version__)") and a minimal example. See CONTRIBUTING.md for the development setup.

UniVI is released under the MIT License.

Metadata

Release files for univi 1.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for univi 1.1.0
File Size Uploaded
univi-1.1.0.tar.gz 141.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for univi 1.1.0
File Interpreter ABI Platform
univi-1.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 285.2 kB

Release files / univi-1.1.0.tar.gz

Download URL univi-1.1.0.tar.gz
Size 141.9 kB
Tags Source
SHA-256 checksum
How to use checksums
89081e785c5fdbf13f2efdcd69bf9505793c6158b6e029cfddf859256997ec3a
BLAKE2b-256 checksum
How to use checksums
326a5f8f9058d0b14f7f574c321ef0eed6df82d537a44a061e37f137ec61d0c9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.14

Release files / univi-1.1.0-py3-none-any.whl

Download URL univi-1.1.0-py3-none-any.whl
Size 143.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9c3def6b713d6ab78abb43eeab5e3c10b6a248e806756da709c309d1093fe5d4
BLAKE2b-256 checksum
How to use checksums
88d59483f04314a240852c6ec946b3348d9463d30e177160df858663c7f3169e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.14

Release history Release notifications | RSS feed

1.2.1

2 release files

1.2.0

2 release files

This release

1.1.0 This release

2 release files

1.0.0

2 release files

0.5.0

2 release files

0.4.7

2 release files

0.4.6

2 release files

0.4.5

2 release files

0.4.4

2 release files

0.4.3

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.9

2 release files

0.3.8

2 release files

0.3.7

2 release files

0.3.6

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.9

2 release files

0.2.8

2 release files

0.2.7

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.9

2 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page