Xenium、CosMx、Stereo-seq和CODEX把空间组学推到百万细胞后,许多课题组遇到的第一个问题已不是“能不能画图”,而是邻居图构建、特征矩阵和嵌入训练能否在有限显存中稳定完成。更容易踩坑的是:看到某个百万细胞案例只用了十几GB显存,就按细胞数线性外推自己的项目,结果细胞更少却先爆显存。
2026年预印本方法SpaLP(Spatial Local Pooling)针对超大规模空间组学嵌入,支持空间图谱构建、niche识别、表达重建、多切片整合、跨平台及多组学整合。官方仓库公布了逐数据集资源表:212.8万细胞、329个特征的跨平台任务,在NVIDIA A800 80GB上峰值显存21.96GB、CPU内存36GB、运行约62秒;而123.6万细胞、1000个基因的CosMx任务反而使用30.15GB显存。这正说明资源由“细胞数×特征数×邻居图”共同决定。

官方资源表里最值得看的四组数字
| 数据场景 | 细胞/点位 | 输入特征 | 峰值显存 | 运行时间 |
|---|---|---|---|---|
| 跨平台整合 | 2,127,707 | 329基因 | 21.96GB | 1分02秒 |
| CosMx | 1,236,281 | 1,000基因 | 30.15GB | 1分03秒 |
| Xenium | 1,355,849 | 379基因 | 15.89GB | 47秒 |
| CODEX | 1,395,992 | 43蛋白 | 5.29GB | 25秒 |
这些结果来自A800-SXM4-80GB和32核Xeon Platinum 8462Y+,并非所有GPU的固定表现。相同细胞规模下,输入特征从43个蛋白增加到数百或上千基因,特征矩阵、梯度与中间张量都会放大;KNN参数和切片数量也会影响空间邻接及批次整合成本。不能只问“有多少细胞”,还要同时问“每个细胞保留多少特征、建多少邻居、整合多少批次”。
先把输入对象做对,再谈GPU
SpaLP接收AnnData对象,二维坐标必须放在adata.obsm['spatial'],预处理后的特征矩阵放在adata.obsm['feat']。原始count建议先总量归一化、log1p和scale;已经对数转换的表达或蛋白数据只需按教程进行scale。对于超过3000基因的平台,官方建议选择前2000或3000个高变基因;小于2000基因的靶向面板则可保留全部基因。
import scanpy as sc
import SpaLP
adata = sc.read_h5ad("sample.h5ad")
assert "spatial" in adata.obsm
sc.pp.highly_variable_genes(adata, n_top_genes=2000, flavor="seurat_v3")
adata = adata[:, adata.var.highly_variable].copy()
sc.pp.normalize_total(adata, inplace=True)
sc.pp.log1p(adata)
sc.pp.scale(adata)
adata.obsm["feat"] = adata.X
print(adata.n_obs, adata.n_vars, adata.obsm["spatial"].shape)
真正运行前还应检查坐标是否含缺失值、细胞ID是否唯一、不同切片的坐标单位是否一致、稀疏矩阵有没有被无意转成dense。百万细胞×2000基因若以float32稠密存储,单个矩阵理论上就接近8GB,复制、标准化和写回obsm会产生额外峰值;这也是“模型显存够了,Python进程却被系统杀掉”的常见原因。
一套可执行的资源画像方法
不要直接把全量数据送上GPU。先从10万、50万和100万细胞做三级抽样,保持真实平台比例和组织区域,分别记录预处理峰值内存、KNN时间、GPU峰值、训练时间和输出大小。随后固定细胞数,把特征数从500提高到1000、2000,观察显存增长;最后再改变KNN的k值。只有把三个维度拆开,才能知道瓶颈来自细胞、特征还是图结构。
建议用/usr/bin/time -v记录CPU内存,用nvidia-smi --query-compute-apps=used_memory定时采样显存,并保存软件版本、随机种子、输入h5ad校验值和最终参数。若显存不足,可以减少高变基因数量、降低单次整合规模或转CPU验证流程;但降维和拆批会影响生物学分辨率与跨切片关系,不能只为“跑通”而不做结果对照。
不能忽视h5ad之外的临时空间
空间数据从原始矩阵到模型输入通常会经历过滤、归一化、高变基因选择、scale和邻居搜索。每一步都可能产生副本,尤其是把稀疏矩阵写入obsm['feat']或调用会返回dense结果的函数时。服务器磁盘规划应同时考虑原始h5ad、处理后h5ad、临时矩阵、模型输出与日志,不能按最终文件大小一比一分配。建议把只读原始数据放在容量盘,把可重建缓存和临时对象放在本地NVMe,并给每个任务独立目录。
多切片整合还要防止样本不均衡。一张切片有100万细胞,另外几张只有数万细胞时,简单随机抽样会让大切片主导资源测试和嵌入结构。三级试跑应按切片、区域与细胞类型分层抽样,同时记录每片细胞数和坐标范围。正式整合前,先在单切片上验证输入和空间邻居,再增加跨切片关系;这样出现异常时,才能区分数据问题、图构建问题和显存问题。
如果需要团队多人重复分析,最好把环境写成固定的Conda锁定文件或容器,输出中保留pip freeze、代码提交号与参数JSON。Jupyter适合探索,但百万细胞正式任务应由脚本或调度器启动,设置退出码、日志、资源上限和完成标记,避免浏览器断开后无法判断任务状态。
GPU不是唯一选择,但CPU路径也有代价
官方给出一个CPU案例:198,248个Stereo-seq点位、2000基因,在8462Y+上使用8.9GB内存,运行12分25秒;GPU显存记为0。它说明没有高显存GPU仍可完成部分任务,但不能由此推断百万级数据也会等比例扩展。CPU路径更适合流程预检、较小数据或GPU暂不可用的场景,大规模多切片仍需实测墙钟时间和内存。
当数据达到300万细胞以上,官方另提供840万细胞整合教程。此时服务器价值不只是“显卡更大”,还包括足够的主内存、本地NVMe工作盘、稳定Jupyter环境、长任务日志与多用户资源隔离。把原始h5ad、预处理缓存、邻居图和最终嵌入分目录保存,可减少失败重跑时的重复计算。
跑得快,不等于空间结论已经可靠
SpaLP输出嵌入可用于聚类、niche识别、重建与跨平台映射,但结果仍受分割质量、基因面板交集、批次组成、空间邻居定义和聚类分辨率影响。百万细胞任务尤其要检查稀有区域是否被大群体淹没、不同切片是否过度混合、已知解剖结构是否保留,以及不同随机种子的结果是否稳定。
目前SpaLP论文仍是预印本,官方资源数字主要来自A800环境。将其迁移到不同GPU、CUDA、PyTorch或CPU平台时应重新验证;嵌入和重建结果也不能代替组织学标注、病理复核或实验验证。
把规模和面板带来,先判断显存花在哪里
如果你的空间组学项目已经到几十万或数百万细胞,可先整理平台、切片数、总细胞数、每片细胞数、基因/蛋白面板、现有h5ad大小、目标任务和可用GPU。云生信可以先判断预处理、邻居图还是嵌入阶段更可能成为瓶颈,再分别确认服务器环境部署与交接、算力租用自运行,或按约定范围完成整合与质控;三种方式的交付边界分别确认。
资料来源: SpaLP预印本;SpaLP官方GitHub。
