云生信学生物信息学

单细胞分析卡在建图,值得换 GPU 吗?读懂 rapids-singlecell

作者:发布于 2026-11-14约 8 分钟阅读
单细胞计算依赖示意:表达矩阵经预处理和 PCA 生成邻接图,Leiden 聚类与 UMAP 嵌入分别使用这张图;只改聚类分辨率时可以复用已有图。

假设手里已有一份单细胞表达矩阵。第一次跑完聚类后,你想把 Leiden 的分辨率调低一点,看看一个细胞群还会不会拆成两簇。如果邻接图还保存在对象里,只要在原图上重跑聚类就能回答这个问题。要是你改的是参与建图的主成分数,细胞之间的距离会变,才需要重建邻接图,再重跑依赖它的聚类或可视化。

这一区别决定了 GPU 值不值得用。先找出这次分析真正需要重算的步骤,再看它占了多少等待时间。 rapids-singlecell 是 scverse 生态中的 Python 仓库,为 AnnData 对象提供一批可用 NVIDIA GPU 执行的单细胞算法。下面以 v0.18.1 的常用接口为例,从已经得到的“细胞 × 基因”矩阵讲起。比对 FASTQ、识别条形码和生成计数矩阵属于更上游的任务。rapids-singlecell v0.18.1

单细胞计算依赖示意:表达矩阵经预处理和 PCA 生成邻接图,Leiden 聚类与 UMAP 嵌入分别使用这张图;只改聚类分辨率时可以复用已有图。

从表达矩阵到 UMAP,哪些步骤能在 GPU 上做?

在 AnnData 中,adata.X 通常存放当前使用的表达矩阵。对每个细胞求和、对每个基因统计变异,包含大量可并行的数值运算。等到寻找邻居时,计算对象已经变了:用一组主成分代表每个细胞,在这个低维空间里寻找相似的细胞,再把它们连成图。聚类和 UMAP 都能使用这张图,各自回答不同的问题。官方 GPU 函数目录

分析环节 GPU 接口示例 可以得到什么,何时需要重算
质控、归一化 rsc.pp.calculate_qc_metrics、normalize_total、log1p 统计每个细胞的计数与检出基因,或对表达量做归一化和对数变换。质控阈值仍要结合样本、组织和建库方式判断。
高变基因、PCA rsc.pp.highly_variable_genes、rsc.pp.pca 前者筛选特征,后者把表达矩阵压缩为每个细胞的一组坐标。高变基因方法对输入有要求,例如 seurat_v3 使用原始计数;要先弄清 X 和 counts 层各存了什么。
近邻搜索、构图 rsc.pp.neighbors 用 PCA 坐标等表示寻找邻居,保存距离与连接关系。改用另一份表示、调整主成分数或邻居数,都应重新建图。
图聚类 rsc.tl.leiden 在邻接图上划分细胞群,输出每个细胞的簇标签。只比较不同分辨率,可固定同一张图,保存多组标签。
UMAP 嵌入 rsc.tl.umap 根据邻接关系求二维坐标。已有坐标时,按另一个基因、样本或簇标签重新着色,只需重新绘图。

表中函数都有 GPU 实现。一次调用还可能涉及 CPU 调度、数组转换与结果回存。读取 h5ad、写文件、用 Scanpy 画图也应单独计时,尤其是数据放在共享网络盘上时。官方用法与数据转换示例

看一段代码:同一张图上试两种聚类分辨率

下面这个示例从较靠后的环节切入。假设 cells_pca.h5ad 已完成质控、特征选择和 PCA,obsm["X_pca"] 保存了可用的主成分坐标,细胞数大于示例中的邻居数。在已配置兼容 NVIDIA 驱动、CUDA 与 rapids-singlecell 的环境中,可以直接指定这份表示建图。参数用于演示,可按研究设计调整。近邻接口源码 · 安装说明

import scanpy as sc
import rapids_singlecell as rsc

adata = sc.read_h5ad("cells_pca.h5ad")
rsc.pp.neighbors(adata, use_rep="X_pca", n_neighbors=15)

rsc.tl.leiden(adata, resolution=0.5, key_added="leiden_05")
rsc.tl.leiden(adata, resolution=1.0, key_added="leiden_10")

rsc.tl.umap(adata)
sc.pl.umap(adata, color=["leiden_05", "leiden_10"])

两幅图共用一套 UMAP 坐标。颜色边界移动时,你看到的是聚类粒度的影响。如果对象里本来就有按目标参数构建的邻接图,还可以跳过 neighbors。若研究的是处理组和对照组的差异,接下来仍要核对分群是否由某个样本主导、标记基因是否支持该注释;换计算设备无法解决批次混杂。Leiden 实现 · UMAP 实现

显存怎么算?先看矩阵在内存中长什么样

上例建图使用 PCA 坐标。如果从表达矩阵开始做归一化,常见用法是 rsc.get.anndata_to_GPU(adata),默认转换 adata.X。原始计数如果另存在 adata.layers["counts"],可以为确实要用它的步骤单独指定该层。保留在主机内存的备用矩阵越多,越要留意主机内存;把多个大矩阵同时搬上卡,又会抬高显存需求。v0.18.1 数据迁移接口

一个算例能说明为什么 h5ad 文件大小很难直接换算成显存。假设有 10 万个细胞、2 万个基因,每个元素用 4 字节的 float32 表示,那么一份完整的稠密矩阵就是 8 GB。同样细胞数下,若每个细胞只保留 50 个主成分,单份稠密坐标数组就是 20 MB。这里按十进制单位计算,两项都是数组大小的算术示例。真实稀疏表达矩阵还要存非零值和索引,运行时也要放邻接图、临时数组,某些变换还会产生稠密副本。选卡要看目标步骤的峰值显存。

什么时候值得用 GPU?用自己的一个分析问题试出来

你实际在等什么 先做的判断
合并多个样本后,反复调整表示、主成分或邻居数,每轮都要重建图 优先测试 GPU 建图。把同一份 PCA 坐标交给 CPU 和 GPU 两条路线,比较完整一轮花多久。
图和二维坐标已经保存,主要是看标记基因、改配色或核对样本标签 先复用已有图和坐标。只有聚类本身也占去明显时间时,再单测这一段。
每轮都要从远端读文件、传到显卡,只算一步就传回来 把读盘、传输、计算和写回分开计时。若等待集中在读写,先处理数据位置或重复加载。
子集可以跑,全量一到预处理就显存不足 查明是哪一层、哪个操作产生副本或稠密矩阵。分别测不同规模子集,并在目标规模复核;一次小样本跑通还不足以定卡型。

做一次公平的试跑。 固定细胞与基因、输入表示、主成分数、邻居数、距离度量和随机种子,同时记录 CPU 线程数、GPU 型号、软件版本,以及近邻搜索用的是精确算法还是近似算法。记两笔时间:用户真正等的“读入到保存”,以及要优化的“建图到结果就绪”。GPU 执行可能异步,单卡单进程的分段计时应在边界同步设备;首次初始化与后续重复运行分开记录。若平时只跑一次,首次开销也算进这次决定。CuPy 官方计时指南

再看结果是否足以回答原问题。 比如要比较近邻图,就对同一细胞取两条路线各自的近邻名单,用共同邻居数除以邻居数,再分别查看主要细胞群和稀有群。若某个小群只在一种设置下出现,回看它的标记基因、样本来源和邻居构成。UMAP 的整体旋转或翻转本身不说明生物学结论变了。

如果主要等待确实来自可重复的 GPU 计算,而现有机器缺少合适显卡,再考虑租用就有了依据。咨询时带上细胞数、参与计算的特征数、矩阵格式、最慢的步骤;有试跑记录,再补上峰值显存、整轮耗时和预计重复次数。可以据此和云生信确认显卡、主机内存、工作盘及驱动环境,把数据上传和环境准备也算进实际租期。云生信 GPU 科研计算环境与服务器租赁

把知识用于当前任务

把方法直接跑起来

使用单细胞在线分析入口,减少环境配置和重复操作。

打开单细胞工具仍有疑问,联系客服 ↗