Scvi Tools
AnthropicOfficialPublished by Anthropic
- Skill
- Tool integration
- Data and AI
- Apache-2.0
- Low risk
- Has scripts
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
scvi-tools provides a suite of probabilistic models designed for the analysis of single-cell data, including scRNA-seq, scATAC-seq, and multi-modal datasets. It leverages variational autoencoders to handle batch correction, data integration, label transfer, and dimensionality reduction. This skill serves as a guide for utilizing specific models like scVI, scANVI, totalVI, PeakVI, MultiVI, DestVI, and veloVI, offering standardized workflows, CLI scripts for pipeline automation, and best practices for data preparation and model training.
What it does
- Performs batch correction and data integration across different experimental conditions.
- Supports multi-modal analysis for CITE-seq and multiome (RNA+ATAC) data.
- Enables label transfer and reference mapping between query and reference datasets.
- Facilitates spatial transcriptomics deconvolution and RNA velocity estimation.
- Provides modular Python scripts for common analysis pipelines.
- Offers guidance on model selection based on specific data types and research goals.
When to use it
- When integrating multiple single-cell datasets with significant batch effects.
- When analyzing multi-modal data such as CITE-seq or joint RNA+ATAC profiles.
- When performing reference-based label transfer or query-to-reference mapping.
- When conducting deep learning-based dimensionality reduction for clustering and visualization.
- When working with spatial transcriptomics or RNA velocity data.
Advantages
- Standardized approach to complex single-cell deep learning workflows.
- Modular scripts allow for reproducible and scalable analysis pipelines.
- Comprehensive model selection guide for diverse genomic data types.
- Built-in support for advanced tasks like batch correction and multi-modal integration.
- Clear documentation on data preparation requirements for probabilistic models.
Usage examples
- “How do I integrate two scRNA-seq datasets using scVI?”
- The agent provides the workflow for preparing the AnnData objects, selecting highly variable genes, setting up the model with batch keys, and training the scVI model.
- “I have CITE-seq data, which model should I use?”
- The agent identifies totalVI as the appropriate model and directs the user to the corresponding reference file for multi-modal integration.
- “How can I map my new scRNA-seq query data to an existing reference?”
- The agent explains the use of scArches for query-to-reference mapping and provides the necessary steps to configure the model.
- “What are the requirements for input data before training a model?”
- The agent outlines the necessity of raw integer count data, the importance of highly variable gene selection, and how to correctly set up the AnnData object.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/anthropics/scvi-tools/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip scvi-tools.zip -d .agents/skills
Documentation by Anthropic
scvi-tools Deep Learning Skill
This skill provides guidance for deep learning-based single-cell analysis using scvi-tools, the leading framework for probabilistic models in single-cell genomics.
How to Use This Skill
Identify the appropriate workflow from the model/workflow tables below
Read the corresponding reference file for detailed steps and code
Use scripts in
scripts/to avoid rewriting common codeFor installation or GPU issues, consult
references/environment_setup.mdFor debugging, consult
references/troubleshooting.md
When to Use This Skill
When scvi-tools, scVI, scANVI, or related models are mentioned
When deep learning-based batch correction or integration is needed
When working with multi-modal data (CITE-seq, multiome)
When reference mapping or label transfer is required
When analyzing ATAC-seq or spatial transcriptomics data
When learning latent representations of single-cell data
Model Selection Guide
| Data Type | Model | Primary Use Case |
|---|---|---|
| scRNA-seq | scVI | Unsupervised integration, DE, imputation |
| scRNA-seq + labels | scANVI | Label transfer, semi-supervised integration |
| CITE-seq (RNA+protein) | totalVI | Multi-modal integration, protein denoising |
| scATAC-seq | PeakVI | Chromatin accessibility analysis |
| Multiome (RNA+ATAC) | MultiVI | Joint modality analysis |
| Spatial + scRNA reference | DestVI | Cell type deconvolution |
| RNA velocity | veloVI | Transcriptional dynamics |
| Cross-technology | sysVI | System-level batch correction |
Workflow Reference Files
| Workflow | Reference File | Description |
|---|---|---|
| Environment Setup | references/environment_setup.md | Installation, GPU, version info |
| Data Preparation | references/data_preparation.md | Formatting data for any model |
| scRNA Integration | references/scrna_integration.md | scVI/scANVI batch correction |
| ATAC-seq Analysis | references/atac_peakvi.md | PeakVI for accessibility |
| CITE-seq Analysis | references/citeseq_totalvi.md | totalVI for protein+RNA |
| Multiome Analysis | references/multiome_multivi.md | MultiVI for RNA+ATAC |
| Spatial Deconvolution | references/spatial_deconvolution.md | DestVI spatial analysis |
| Label Transfer | references/label_transfer.md | scANVI reference mapping |
| scArches Mapping | references/scarches_mapping.md | Query-to-reference mapping |
| Batch Correction | references/batch_correction_sysvi.md | Advanced batch methods |
| RNA Velocity | references/rna_velocity_velovi.md | veloVI dynamics |
| Troubleshooting | references/troubleshooting.md | Common issues and solutions |
CLI Scripts
Modular scripts for common workflows. Chain together or modify as needed.
Pipeline Scripts
| Script | Purpose | Usage |
|---|---|---|
prepare_data.py | QC, filter, HVG selection | python scripts/prepare_data.py raw.h5ad prepared.h5ad --batch-key batch |
train_model.py | Train any scvi-tools model | python scripts/train_model.py prepared.h5ad results/ --model scvi |
cluster_embed.py | Neighbors, UMAP, Leiden | python scripts/cluster_embed.py adata.h5ad results/ |
differential_expression.py | DE analysis | python scripts/differential_expression.py model/ adata.h5ad de.csv --groupby leiden |
transfer_labels.py | Label transfer with scANVI | python scripts/transfer_labels.py ref_model/ query.h5ad results/ |
integrate_datasets.py | Multi-dataset integration | python scripts/integrate_datasets.py results/ data1.h5ad data2.h5ad |
validate_adata.py | Check data compatibility | python scripts/validate_adata.py data.h5ad --batch-key batch |
Example Workflow
# 1. Validate input data
python scripts/validate_adata.py raw.h5ad --batch-key batch --suggest
# 2. Prepare data (QC, HVG selection)
python scripts/prepare_data.py raw.h5ad prepared.h5ad --batch-key batch --n-hvgs 2000
# 3. Train model
python scripts/train_model.py prepared.h5ad results/ --model scvi --batch-key batch
# 4. Cluster and visualize
python scripts/cluster_embed.py results/adata_trained.h5ad results/ --resolution 0.8
# 5. Differential expression
python scripts/differential_expression.py results/model results/adata_clustered.h5ad results/de.csv --groupby leidenPython Utilities
The scripts/model_utils.py provides importable functions for custom workflows:
| Function | Purpose |
|---|---|
prepare_adata() | Data preparation (QC, HVG, layer setup) |
train_scvi() | Train scVI or scANVI |
evaluate_integration() | Compute integration metrics |
get_marker_genes() | Extract DE markers |
save_results() | Save model, data, plots |
auto_select_model() | Suggest best model |
quick_clustering() | Neighbors + UMAP + Leiden |
Critical Requirements
Raw counts required: scvi-tools models require integer count data
adata.layers["counts"] = adata.X.copy() # Before normalization scvi.model.SCVI.setup_anndata(adata, layer="counts")HVG selection: Use 2000-4000 highly variable genes
sc.pp.highly_variable_genes(adata, n_top_genes=2000, batch_key="batch", layer="counts", flavor="seurat_v3") adata = adata[:, adata.var['highly_variable']].copy()Batch information: Specify batch_key for integration
scvi.model.SCVI.setup_anndata(adata, layer="counts", batch_key="batch")
Quick Decision Tree
Need to integrate scRNA-seq data?
├── Have cell type labels? → scANVI (references/label_transfer.md)
└── No labels? → scVI (references/scrna_integration.md)
Have multi-modal data?
├── CITE-seq (RNA + protein)? → totalVI (references/citeseq_totalvi.md)
├── Multiome (RNA + ATAC)? → MultiVI (references/multiome_multivi.md)
└── scATAC-seq only? → PeakVI (references/atac_peakvi.md)
Have spatial data?
└── Need cell type deconvolution? → DestVI (references/spatial_deconvolution.md)
Have pre-trained reference model?
└── Map query to reference? → scArches (references/scarches_mapping.md)
Need RNA velocity?
└── veloVI (references/rna_velocity_velovi.md)
Strong cross-technology batch effects?
└── sysVI (references/batch_correction_sysvi.md)Key Resources
Files
- ATTRIBUTION.mdAdded by AutoGineer932 B
- LICENSE.txt10.0 KiB
- SKILL.md7.2 KiB
- references/atac_peakvi.md9.3 KiB
- references/batch_correction_sysvi.md10.2 KiB
- references/citeseq_totalvi.md10.1 KiB
- references/data_preparation.md6.2 KiB
- references/environment_setup.md6.3 KiB
- references/label_transfer.md10.2 KiB
- references/multiome_multivi.md8.9 KiB
- references/rna_velocity_velovi.md8.6 KiB
- references/scarches_mapping.md10.8 KiB
- references/scrna_integration.md9.6 KiB
- references/spatial_deconvolution.md11.2 KiB
- references/troubleshooting.md10.8 KiB
- scripts/cluster_embed.pyScript6.3 KiB
- scripts/differential_expression.pyScript6.7 KiB
- scripts/integrate_datasets.pyScript6.9 KiB
- scripts/model_utils.pyScript17.0 KiB
- scripts/prepare_data.pyScript5.1 KiB
- scripts/train_model.pyScript11.3 KiB
- scripts/transfer_labels.pyScript7.2 KiB
- scripts/validate_adata.pyScript11.9 KiB
references/troubleshooting.md
Troubleshooting Guide for scvi-tools
This reference provides a consolidated guide for diagnosing and resolving common issues across all scvi-tools models.
Quick Diagnosis
| Symptom | Likely Cause | Quick Fix |
|---|---|---|
| "X should contain integers" | Normalized data in X | Use layer="counts" in setup |
| CUDA out of memory | GPU memory exhausted | Reduce batch_size, use smaller model |
| Training loss is NaN | Bad data or learning rate | Check for all-zero cells/genes |
| Batches not mixing | Too few shared features | Increase HVGs, check gene overlap |
| Over-correction | Too aggressive integration | Use scANVI with labels |
| Import error | Missing dependencies | pip install scvi-tools[all] |
Data Format Issues
Issue: CITE-seq protein data from Seurat is CLR-normalized
Cause: Seurat's NormalizeData(normalization.method = "CLR") transforms raw ADT counts. totalVI requires raw integer counts for protein data.
Symptoms:
Protein values are not integers
Protein values contain negative numbers
Model training produces poor results
Solution:
# Check if protein data is normalized
protein = adata.obsm["protein_expression"]
print(f"Min value: {protein.min()}") # Should be 0 if raw counts
print(f"Contains integers: {np.allclose(protein, protein.astype(int))}")
# If importing from Seurat, use the raw counts assay, not the normalized one
# In R/Seurat, export the RNA assay's counts slot, not the data slot
# GetAssayData(seurat_obj, assay = "ADT", slot = "counts")Issue: "layer not found" or "X should contain integers"
Cause: scvi-tools requires raw integer counts, not normalized data.
Solution:
# Check if X contains integers
import numpy as np
print(f"X max: {adata.X.max()}")
print(f"Contains integers: {np.allclose(adata.X.data, adata.X.data.astype(int))}")
# If normalized, recover from raw
if hasattr(adata, 'raw') and adata.raw is not None:
adata = adata.raw.to_adata()
# Or use existing counts layer
adata.layers["counts"] = adata.X.copy()
scvi.model.SCVI.setup_anndata(adata, layer="counts")Issue: Sparse matrix errors
Cause: Incompatible sparse format or dense array expected.
Solution:
from scipy.sparse import csr_matrix
# Convert to CSR format (most compatible)
if hasattr(adata.X, 'toarray'):
adata.X = csr_matrix(adata.X)
# Or convert to dense if small enough
if adata.n_obs * adata.n_vars < 1e8:
adata.X = adata.X.toarray()Issue: NaN or Inf values in data
Cause: Missing values or corrupted data.
Solution:
import numpy as np
# Check for issues
X = adata.X.toarray() if hasattr(adata.X, 'toarray') else adata.X
print(f"NaN count: {np.isnan(X).sum()}")
print(f"Inf count: {np.isinf(X).sum()}")
print(f"Negative count: {(X < 0).sum()}")
# Replace NaN/Inf with 0
X = np.nan_to_num(X, nan=0, posinf=0, neginf=0)
X = np.clip(X, 0, None) # Ensure non-negative
adata.X = csr_matrix(X)Issue: batch_key or labels_key not found
Cause: Column name mismatch in adata.obs.
Solution:
# List available columns
print(adata.obs.columns.tolist())
# Check for similar names
for col in adata.obs.columns:
if 'batch' in col.lower() or 'sample' in col.lower():
print(f"Potential batch column: {col}")GPU and Memory Issues
Issue: CUDA out of memory
Cause: Model or batch doesn't fit in GPU memory.
Solutions (try in order):
# 1. Reduce batch size
model.train(batch_size=64) # Default is 128
# 2. Use smaller model architecture
model = scvi.model.SCVI(
adata,
n_latent=10, # Default is 10-30
n_layers=1 # Default is 1-2
)
# 3. Subset to fewer genes
sc.pp.highly_variable_genes(adata, n_top_genes=1500)
adata = adata[:, adata.var['highly_variable']].copy()
# 4. Clear GPU cache between models
import torch
torch.cuda.empty_cache()
# 5. Use CPU if GPU is too small
model.train(accelerator="cpu")Issue: No GPU detected
Cause: CUDA not installed or version mismatch.
Diagnosis:
import torch
print(f"CUDA available: {torch.cuda.is_available()}")
print(f"PyTorch version: {torch.__version__}")
print(f"CUDA version: {torch.version.cuda}")Solution:
# Check system CUDA
nvidia-smi
nvcc --version
# Reinstall PyTorch with matching CUDA
pip install torch --index-url https://download.pytorch.org/whl/cu118 # For CUDA 11.8
# Or
pip install torch --index-url https://download.pytorch.org/whl/cu121 # For CUDA 12.1Issue: Memory error with large datasets
Cause: Dataset too large for system RAM.
Solutions:
# 1. Process in chunks (for very large data)
# Subsample for initial exploration
adata_sample = adata[np.random.choice(adata.n_obs, 50000, replace=False)].copy()
# 2. Use backed mode for AnnData
adata = sc.read_h5ad("large_data.h5ad", backed='r')
# 3. Reduce gene count aggressively
adata = adata[:, adata.var['highly_variable']].copy()Training Issues
Issue: Training loss is NaN
Cause: Numerical instability, bad data, or learning rate issues.
Solutions:
# 1. Check for problematic cells/genes
sc.pp.filter_cells(adata, min_genes=200)
sc.pp.filter_genes(adata, min_cells=3)
# 2. Remove cells with zero counts
adata = adata[adata.X.sum(axis=1) > 0].copy()
# 3. Use gradient clipping (built into scvi-tools)
model.train(max_epochs=200, early_stopping=True)Issue: Training doesn't converge
Cause: Insufficient epochs, poor hyperparameters, or data issues.
Solutions:
# 1. Train longer
model.train(max_epochs=400)
# 2. Check training curves
import matplotlib.pyplot as plt
plt.plot(model.history['elbo_train'])
plt.plot(model.history['elbo_validation'])
plt.xlabel('Epoch')
plt.ylabel('ELBO')
plt.legend(['Train', 'Validation'])
# 3. Adjust model size for data size
# Small data (<10k cells): smaller model
model = scvi.model.SCVI(adata, n_latent=10, n_layers=1, dropout_rate=0.2)
# Large data (>100k cells): can use larger model
model = scvi.model.SCVI(adata, n_latent=30, n_layers=2)Issue: Overfitting (validation loss increases)
Cause: Model too complex or trained too long.
Solutions:
# 1. Enable early stopping
model.train(early_stopping=True, early_stopping_patience=10)
# 2. Add regularization
model = scvi.model.SCVI(adata, dropout_rate=0.2)
# 3. Reduce model complexity
model = scvi.model.SCVI(adata, n_layers=1)Integration Issues
Issue: Batches don't mix
Cause: Too few shared features, strong biological differences, or technical issues.
Solutions:
# 1. Check gene overlap between batches
for batch in adata.obs['batch'].unique():
batch_genes = adata[adata.obs['batch'] == batch].var_names
print(f"{batch}: {len(batch_genes)} genes")
# 2. Use more HVGs
sc.pp.highly_variable_genes(adata, n_top_genes=4000, batch_key="batch")
# 3. Train longer
model.train(max_epochs=400)
# 4. Increase latent dimensions
model = scvi.model.SCVI(adata, n_latent=50)Issue: Over-correction (biological signal lost)
Cause: Model removes too much variation.
Solutions:
# 1. Use scANVI with cell type labels
scvi.model.SCANVI.from_scvi_model(scvi_model, labels_key="cell_type")
# 2. Reduce model capacity
model = scvi.model.SCVI(adata, n_latent=10)
# 3. Use categorical covariates instead of batch_key
scvi.model.SCVI.setup_anndata(
adata,
layer="counts",
categorical_covariate_keys=["batch"] # Less aggressive than batch_key
)Issue: One batch dominates clusters
Cause: Unbalanced batch sizes or incomplete integration.
Solutions:
# 1. Check batch distribution
print(adata.obs['batch'].value_counts())
# 2. Subsample to balance
from sklearn.utils import resample
balanced = []
min_size = adata.obs['batch'].value_counts().min()
for batch in adata.obs['batch'].unique():
batch_data = adata[adata.obs['batch'] == batch]
balanced.append(batch_data[np.random.choice(len(batch_data), min_size, replace=False)])
adata_balanced = sc.concat(balanced)Model-Specific Issues
scANVI: Poor label transfer
Solutions:
# 1. Check label distribution
print(adata.obs['cell_type'].value_counts())
# 2. Use Unknown for low-confidence cells
adata.obs.loc[adata.obs['prediction_score'] < 0.5, 'cell_type'] = 'Unknown'
# 3. Train scVI longer before scANVI
scvi_model.train(max_epochs=300)
scanvi_model = scvi.model.SCANVI.from_scvi_model(scvi_model, labels_key="cell_type")
scanvi_model.train(max_epochs=100)totalVI: Noisy protein signal
Solutions:
# 1. Use denoised protein values
_, protein_denoised = model.get_normalized_expression(return_mean=True)
# 2. Check isotype controls
# Isotype controls should have low expression
for i, name in enumerate(adata.uns["protein_names"]):
if 'isotype' in name.lower():
print(f"{name}: mean={adata.obsm['protein_expression'][:, i].mean():.1f}")PeakVI: Poor clustering
Solutions:
# 1. Use more variable peaks
from sklearn.feature_selection import VarianceThreshold
selector = VarianceThreshold(threshold=0.05)
adata = adata[:, selector.fit(adata.X).get_support()].copy()
# 2. Binarize data
adata.X = (adata.X > 0).astype(np.float32)MultiVI: Different cell counts between modalities
Solutions:
# Ensure same cells in same order
common_cells = adata_rna.obs_names.intersection(adata_atac.obs_names)
adata_rna = adata_rna[common_cells].copy()
adata_atac = adata_atac[common_cells].copy()DestVI: Poor deconvolution
Solutions:
# 1. Check gene overlap
common_genes = adata_ref.var_names.intersection(adata_spatial.var_names)
print(f"Common genes: {len(common_genes)}") # Should be >1000
# 2. Use tissue-matched reference
# Reference should contain all cell types expected in spatial data
# 3. Check reference quality
print(adata_ref.obs['cell_type'].value_counts())Version Compatibility
scvi-tools 1.x vs 0.x API changes
Key differences:
# 0.x API
scvi.data.setup_anndata(adata, ...)
# 1.x API (current)
scvi.model.SCVI.setup_anndata(adata, ...)Check versions
import scvi
import scanpy as sc
import anndata
import torch
print(f"scvi-tools: {scvi.__version__}")
print(f"scanpy: {sc.__version__}")
print(f"anndata: {anndata.__version__}")
print(f"torch: {torch.__version__}")Recommended versions (as of late 2024)
scvi-tools>=1.0.0
scanpy>=1.9.0
anndata>=0.9.0
torch>=2.0.0Getting Help
Check documentation: https://docs.scvi-tools.org/
GitHub issues: https://github.com/scverse/scvi-tools/issues
Discourse forum: https://discourse.scverse.org/
Tutorials: https://docs.scvi-tools.org/en/stable/tutorials/index.html
When reporting issues, include:
scvi-tools version (
scvi.__version__)Python version
Full error traceback
Minimal reproducible example
Requirements and compatibility
Written for: Claude Code, Claude apps
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs Python
Security
What our scanner noticed· Low risk
- Instructions that use the network
- Scripts that your agent may run
This skill includes scripts that your agent may run. Read them before you use it.
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Published by
- Anthropic
- Publisher
- Anthropic (Official)
- Source
- anthropics/knowledge-work-plugins · bio-research/skills/scvi-tools · commit e050c2e
- Licence
- Apache License 2.0 (redistribution allowed)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Anthropic.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download scvi-tools.zip