目录
前言
GPU服务器和数据传输
scVI环境搭建
scVI实操
前言
除了考虑将哪些因素作为批次效应外,还需要选择适当的数据整合方式。当前有许多单细胞多样本的整合方法,参考国内优秀的单细胞python框架omicverse提供的归类:
在omicverse教程中,作者将这些模型进行全面地探索和对比,这里借用作者提供的结论:在非GPU依赖的数据整合方式中,线性嵌入模型Harmony的表现最好;而深度学习模型(如scVI)表现也非常优秀。如果你有兴趣,可以通过下方链接学习:
# omicverse
# 中文教程
https://single-cell-tutorial.readthedocs.io/zh/latest/preprocess/2-5/
# 英文教程
https://omicverse.readthedocs.io/en/latest/Tutorials-single/t_single_batch/
在笔者的实践中发现,多数情况下scVI的整合能力较其他方法更好,尤其是在大样本数据整合时(如超过10万细胞或多个测序平台),scVI能够更好地消除技术性批次效应,更多保留生物学差异。但是,scVI也有使用场景的限制,最大的问题就是GPU资源的限制。CPU跑深度学习的速度相当感人,但是GPU太贵又买不起,因此scVI一直没有被广泛应用,尤其是细胞数量不多时Harmony的表现力足够优秀。
但是,在单细胞数据暴增、动辄整合上十万上百万细胞的今天,R语言运行速度慢、基于非GPU依赖的整合方式不够给力的问题突出,如何借助GPU对我们的数据实现更好、更快的整合成为了亟待解决的问题。就像共享服务器的发展一般,最近GPU云服务器也开始走入生信人的视野,这篇笔记,我们带大家在租用的GPU服务器上搭建scVI环境,希望读者面对大样本数据时不再恐惧。
本次笔记的代码我们将会全部公开分享。 此外,我们与GPU服务器平台无合作关系,读者可自行选择平台。如果你希望获得本次练习数据,可在公众号后回复20231110获得。
租用GPU服务器
GPU服务器有很多云平台,包括但不限于恒源云、矩池云等平台,其价格也不一,取决于租用的GPU类型、租用内存或硬盘大小等决定,基本大同小异。本次笔记中,我们使用恒源云平台搭建scVI环境。
一、官网登录和注册
# 官网地址
https://gpushare.com/
当然,你也可以选择从小编的邀请链接进入注册(与平台无合作,仅个人邀请),这样可以获得一些代金券等小礼物(够你租GPU跑好几次scVI):
https://gpushare.com/auth/register?user=15*****6841&fromId=5fa7001123bb&source=link
二、使用OSS命令工具进行数据储存和传输
当我们注册登录之后,在右上角可以进入“控制台”。“控制台”是我们最常用的界面,包括了实例的汇总信息,账号信息、储存信息等。
OSS命令工具是恒源云数据储存和传递的重要媒介,可以理解为一个超高速传播的网盘,传输速率最高能达300Mbps/s,仅支持常见的压缩文件传输。OSS命令工具支持Windows、MacOS、Linux等多种平台(暂不支持M1芯片的设备)。接下来,我们在Linux服务器中安装并搭建OSS储存。如果你希望在Windows或MacOS中安装,可以参考以下文档:
# oss 安装官方教程
https://gpushare.com/docs/best_practices/oss/
1.安装oss(本地服务器和恒源云服务器均需要安装)
# 下载
# 如果是非恒源云服务器,这里路径需要自己修改
# 如果是恒源云服务器,可以直接使用该路径
curl -L -o /usr/bin/oss https://gpucloud-static-public-prod.gpushare.com/installation/oss/oss_linux_x86_64
# 更改权限,变成可执行文件
chmod u+x /usr/bin/oss
2.验证安装是否成功
oss version
# version:v1.2.36+prod
# git commit:0759e529f692a8dbca86be24aece46c00abc577d
# go version go1.16.6 linux/amd64
# operating system:darwin, arch:amd64
# build time:2021-08-27-CST/12:01:48
3.数据上传
# 登陆恒源云账号,使用恒源云的账号名与密码,账号名为手机号
# 如果是非中国大陆手机号码,需要加上带 + 的区号
# 重新登录后可能要重新login账号
oss login
# Username:139********
# Password:***********
# 139******** login successfully!
# 在个人数据中创建文件夹
oss mkdir oss://datasets/
# Create folder [oss://] successfully, request id [0000017E0091FBEC9012CBB9E0EBBCE1]
# Create folder [oss://datasets/] successfully, request id [0000017E0091FC1D9012CC094BBD9AF3]
# 上传数据
# 注意,仅支持压缩文件传输
cd ~/resource/practice_data/
zip test.zip lung_atlas_public.h5ad
oss cp test.zip oss://datasets/ # 最后的反斜杠要加上
# 传输很快,实测一般能达到70-80MB/s,与服务器网速有关
# 查看数据
oss ls -s -d oss://datasets/
# Listing objects .
# Folder list:
# oss://datasets/
# Object list:
# oss://datasets/test.zip
# Folder number is: 1
# File number is: 1
4.数据下载
假设我们现在已经把数据从本地或恒源云服务器上传到oss工具,下载同样也很简单,同样是cp命令就可以实现。
注意:/hy-tmp/是数据储存的地方,平台规定数据需要上传到此处,关机后仅保存24小时。
# 在另一个服务器上也需要安装和登录账号
oss login
# 下载个人数据到恒源云的/hy-tmp/目录下
oss cp oss://datasets/test.zip /hy-tmp/
三、创建恒源云GPU实例
从恒源云控制台中,我们找到“创建实例”的蓝色按钮,并进入实例创建界面。在这里,我们需要考虑几个因素:
我们以4060-8G显卡为例,创建一个实例
1.参数选择
2.Pytorch/CUDA/Python版本选择
3.创建成功后,稍等一会儿即可看到登录信息
搭建scVI环境
获得实例后,我们登录服务器并搭建scVI环境
1.登录
方法一:通过终端软件登录
通过复制粘贴恒源云给的登录指令到终端软件即可登录
登录后的提示信息
方法二:通过JupyterLab登录
如果你觉得这样登录麻烦,可以直接点开JupyterLab,打开终端并直接使用。在JupyterLab中打开时,默认进入根目录。
2.配置oss命令工具和传输数据
我们以JupyterLab的终端为例,把数据上传到 /hy-tmp/文件夹。在前面的演示中,我们已经在本地服务器安装了oss命令工具并上传了压缩文件。
你也可以完成环境配置之后再传输数据。
# 安装oss工具,不用更改路径
curl -L -o /usr/bin/oss https://gpucloud-static-public-prod.gpushare.com/installation/oss/oss_linux_x86_64
# 更改权限,变成可执行文件
chmod u+x /usr/bin/oss
# 登录oss
oss login
# 查看,你可以不用下面的 -s -d 参数
oss ls -s -d oss://datasets/
# Listing objects .
# Folder list:
# oss://datasets/
# Object list:
# oss://datasets/test.zip
# Folder number is: 1
# File number is: 1
# 数据下载到 /hy-tmp/
oss cp oss://datasets/test.zip /hy-tmp/
# 对文件进行解压
cd /hy-tmp/
unzip test.zip
# 下载
oss cp oss://datasets/scvi_scripts_data.zip /hy-tmp/
# 解压
cd /hy-tmp/
unzip scvi_scripts_data.zip
3.创建scVI环境
# 我们可以先查看已经安装的软件
# 创建镜像时我们已经选择了pytorch和对应的CUDA,因此不用重复安装
conda list
# 创建和激活环境
conda create -n scvi-env -y
conda activate scvi-env
# 如果你发现选择的 pytorch 错了,也可以通过命令安装
# 但需要你修改 torch 版本和 cuda 版本
# 可以到 pytorch 官网获得对应的命令
# 例如:
# pip install torch==1.13.1+cu116 torchvision==0.14.1+cu116 torchaudio==0.13.1 --extra-index-url https://download.pytorch.org/whl/cu116
# 检查pytorch是否可用
# 进入python
python
# 导入pytorch包
import torch
print(torch.__version__) # 查看版本
print(torch.cuda.is_available()) # True表示可用
# quit() 或 按ctrl+D退出
接下来我们安装单细胞工具和scVI工具包,在此我们借用开头提到的omicverse软件包,它会帮我们把scanpy等常用的单细胞软件都安装好,这个包本身也非常容易安装。
# 如果你不想慢慢等,也可以写个shell脚本丢后台
# 安装omicverse,需要几分钟
pip install -U omicverse
pip install -U numba
# 安装scvi
pip install scvi-tools
# 查看是否能使用
# 进入python
python
# 加载,不报错即可
import scvi
import omicverse as ov
# quit() 或 按ctrl+D退出
我们还需要配置jupyterLab的kernel
# 安装ipykernel
pip install ipykernel
# 配置jupyterlab内核
python -m ipykernel install --user --name=scvi-env --display-name scvi-env
# 查看当前配置的juypter内核
jupyter kernelspec list
这时候我们再打开JupyterLab的启动页就可以看到scvi-env的选项
到这里,我们的scVI环境就搭建好了,可以用自己的数据开始分析,接下来我们用一个示例数据进行操作。
需要补充几点:
查看服务器配置的一些命令:
# 查看实例根目录磁盘使用率
df -h | grep "/$" | awk '{print $5" "$3"/"$2}' # 如果接近上限,及时清理
# 查看 /root 和 /home 目录下面每个目录的大小
du -h --max-depth=1 /root /home
# 查看当前目录下每个目录的大小
du -h --max-depth=1 .
# 查看当前目录下每个文件的大小
ll -h | grep ^- | awk '{print $5"\t"$9}'
scVI实操
scVI的实操并不复杂,按照官方提供的教程即可顺利完成。如果你有一定的python基础,可能会更容易弄明白。
如果你只有一个seurat对象,可以参考小编之前写的《解决Scanpy和Seurat对象的转换问题》,在公众号搜索即可获得。
官方参考教程:
https://docs.scvi-tools.org/en/1.0.2/tutorials/notebooks/harmonization.html
我们通过JupyterLab左侧的目录,进入/hy-tmp/并通过scvi-env新建一个笔记本。
1.载入包和数据
# 设置路径
import os
os.chdir('/hy-tmp/')
# 载入包
import scanpy as sc
print(f"scanpy version: {sc.__version__}")
import scvi
print(f"scvi version: {scvi.__version__}")
# 全局设置
sc.settings.set_figure_params(dpi=80,
dpi_save=300,
facecolor='white',
fontsize=10,
figsize = [5,5])
# 载入数据
adata = sc.read_h5ad('Lung_atlas_public.h5ad')
adata
# 以下代码不运行
# 你也可以通过scVI官方提供的渠道下载
# 但通常网络会有问题
adata = sc.read(
"data/lung_atlas.h5ad",
backup_url="https://figshare.com/ndownloader/files/24539942",
)
# adata信息如下
AnnData object with n_obs × n_vars = 32472 × 15148
obs: 'dataset', 'location', 'nGene', 'nUMI', 'patientGroup', 'percent.mito', 'protocol', 'sanger_type', 'size_factors', 'sampling_method', 'batch', 'cell_type', 'donor'
layers: 'counts'
如果你是自己的数据,需要注意的是layers中是否有counts矩阵,如果没有,你需要按照下面的代码创建。要留意你在前期的处理过程中是否丢失了原始的counts矩阵,及时查看自己的adata.X是否正确。
adata.layers['counts'] = adata.X
此外,由于租用服务器计费和内存偏小的问题,我们尽可能地把前期处理过程放在本地,需要使用scVI整合时尽可能地上传后直接开始。
2.数据预处理
如果你自己的数据已经 进行了预处理,可以跳过。
# 保存原始矩阵
adata.raw = adata
# 寻找高可变基因
sc.pp.highly_variable_genes(
adata,
flavor="seurat_v3",
n_top_genes=2000,
layer="counts",
batch_key="batch",
subset=True,
)
3.scVI模型训练
# adata设置以便scvi模型识别
scvi.model.SCVI.setup_anndata(adata, layer="counts", batch_key="batch")
# 模型参数,一般不用修改
vae = scvi.model.SCVI(adata, n_layers=2, n_latent=30, gene_likelihood="nb")
# 模型训练
vae.train()
# 模型训练输出信息
GPU available: True (cuda), used: True
TPU available: False, using: 0 TPU cores
IPU available: False, using: 0 IPUs
HPU available: False, using: 0 HPUs
LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]
Epoch 246/246: 100%|██████████| 246/246 [15:52<00:00, 3.67s/it, loss=553, v_num=1]
`Trainer.fit` stopped: `max_epochs=246` reached.
Epoch 246/246: 100%|██████████| 246/246 [15:52<00:00, 3.87s/it, loss=553, v_num=1]
可以看到,通过GPU加速后只需要16分钟左右就完成(官网的数据更快,可能是GPU更高级),速度取决于你模型的细胞数量、batch信息的复杂程度等。如果你的模型信息复杂,可能速度比较慢。当然,再慢也没有CPU慢,该示例数据如果使用CPU可能要花费小半天时间。
4.获取cell embedding和画图
我们从训练模型中获取cell embedding并保存在obsm中
# 获取cell embedding
adata.obsm["X_scVI"] = vae.get_latent_representation()
基于X_scVI(替代PCA)进行整合分析
sc.pp.neighbors(adata, use_rep='X_scVI')
sc.tl.umap(adata)
画个图看看
sc.pl.embedding(
adata,
basis="X_umap",
color=["batch", "leiden"],
frameon=False,
ncols=2,
)
adata信息如下
AnnData object with n_obs × n_vars = 32472 × 2000
obs: 'dataset', 'location', 'nGene', 'nUMI', 'patientGroup', 'percent.mito', 'protocol', 'sanger_type', 'size_factors', 'sampling_method', 'batch', 'cell_type', 'donor', '_scvi_batch', '_scvi_labels', 'leiden'
var: 'highly_variable', 'highly_variable_rank', 'means', 'variances', 'variances_norm', 'highly_variable_nbatches'
uns: 'hvg', '_scvi_uuid', '_scvi_manager_uuid', 'neighbors', 'leiden', 'umap', 'batch_colors', 'leiden_colors'
obsm: 'X_scVI', 'X_umap'
layers: 'counts'
obsp: 'distances', 'connectivities'
5.保存
# 加上gzip压缩可以节约一半以上储存空间
adata.write_h5ad('scvi_results.h5ad', compression='gzip')
6.上传至oss
# 压缩打包
zip scvi_scripts_data.zip scvi_results.h5ad Lung_atlas_public.h5ad scvi_pipeline.ipynb
# 上传
oss cp scvi_scripts_data.zip oss://datasets/
恒源云实例镜像保存
当我们完成工作之后,及时选择关机,以节省开支。恒源云会按照最终关机时间,精确到秒来计算。关机后,我们可以通过“创建备份镜像”来保存镜像。下一次开启新的实例时,可以直接通过“备份镜像”来构建,开袋即食,不用从头构建。
保存后,我们新建实例时,就可以从备份镜像中选取。
小结
本次笔记就到这里了,总结一下。如果你对服务器管理或Linux系统操作有一定背景知识,以及有一定的python基础和对scanpy理解,租用服务器和搭建scVI分析环境实际上并不困难,而scVI整体的分析流程也算得上简洁易懂。能够快速地搭建环境也得益于恒源云构建了足够便捷地平台。
当然scVI还有很多高级用途,它本身就提供了一个完整的分析框架,还有提供了半监督聚类的scANVI、参考图谱构建等高级应用,如果你感兴趣,可以通过官方提供的教程去探索。
# 官方教程
https://docs.scvi-tools.org/en/1.0.2/tutorials/notebooks/harmonization.html
未来我们有机会的话,可以讲讲这些高级应用。那么我们下次再见吧!