UMI 技术原理

说实话,我刚入行做单细胞数据分析那会儿,对 UMI 也是一脸懵。明明同一个基因,PCR 之后读段数量能差几十倍,这到底是真实表达还是技术噪音?后来搞清楚 UMI 的原理,才明白它就是为了解决这个问题的。

什么是 Unique Molecular Identifier

UMI,全称 Unique Molecular Identifier,中文叫“唯一分子标签”。说白了,它就是个随机序列,长度通常在 8-12 bp。在反转录阶段,每个 mRNA 分子都会连上一个独一无二的 UMI。你可以把它想象成给每个转录本发了一张身份证。

为什么要这么干?因为 PCR 扩增效率不固定。同样的模板,有的扩了 100 倍,有的只扩了 10 倍。你只靠读段计数,根本分不清是丰度高还是 PCR 扩得多。UMI 一加,逻辑就变了:只要两个读段拥有相同的 UMI 和基因比对位置,它们就来自同一个原始 mRNA 分子。这就不怕 PCR 带来的偏差了。

我当年第一次处理 10X Genomics 的数据时,看到 FASTQ read 名里那串长长的 barcode 序列,愣是拆了半天才搞明白。嗯,这里有个常见坑:UMI 和细胞 barcode 是两码事,别搞混了。细胞 barcode 标记的是哪个细胞,UMI 标记的是哪个分子。

类别 作用 长度 来源
UMI 标记原始 mRNA 分子 8-12 bp 反转录引物自带
细胞 barcode 标记细胞来源 12-16 bp 液滴或孔板分配

UMI 如何纠正 PCR 扩增偏差

这个问题我用一个例子说明。假设一个细胞里某基因有 3 个原始 mRNA 分子,反转录时分别连上了 UMI-AAA、UMI-AAB、UMI-AAC。PCR 之后,AAA 扩了 50 倍,AAB 扩了 80 倍,AAC 扩了 60 倍。测序得到 190 条 reads。没有 UMI 时你会以为表达量是 190,有 UMI 后你只计数不同的 UMI 种类,结果就是 3。这才是真实分子数。

具体实现上,常见的做法是:

  • 把 reads 比对到参考基因组,确定基因
  • 提取 UMI 序列
  • 按“基因 + UMI”去重,同一个基因下同一个 UMI 只保留一条
  • 统计每个基因的唯一 UMI 数

我记得到有一次项目,用 Smart-seq2 技术,由于建库时没加 UMI,做差异表达分析时,高表达基因的方差被 PCR 噪音撑得特别大,结果根本没法用。后来转成含有 UMI 的实验方案,数据质量肉眼可见地提升。这个教训让我现在看任何单细胞数据集,第一件事就是确认有没有 UMI。

关键要点:UMI 的核心假设是每个原始分子在反转录时都分配到一个不同序列。如果 UMI 长度不够或者初始分子数太多,就可能出现“碰撞” — 两个分子拿到了同样的 UMI。一般建议 UMI 种类数至少是预期分子数的 10 倍以上。

UMI 处理流程概览

下面这张图梳理了从原始分子到定量结果的完整流程,我建议你多看几遍。

UMI 纠正 PCR 偏差流程图 原始 mRNA 分子 反转录添加 UMI (每个分子唯一标签) PCR 扩增 测序获得 Reads UMI + 基因 去重 (只保留唯一组合) 统计唯一 UMI 数 避坑 UMI 长度 ≥ 8 bp 减少碰撞风险 提示 去重前需校正 测序错误

UMI 去重实现举例

我常用的工具是 umi_tools(来自 CGAT 团队),或者 10X 自己的 Cell Ranger。下面给一个简单的 Python 示意代码,帮你理解去重逻辑:

# 假设已经有一个字典: gene_umi_counts
# key: (gene_name, umi_sequence)
# value: read_count

deduped = {}
for (gene, umi), count in gene_umi_counts.items():
    if (gene, umi) not in deduped:
        deduped[(gene, umi)] = 1   # 只记录存在

# 统计每个基因的 unique UMI 数
from collections import Counter
gene_expression = Counter()
for (gene, _), _ in deduped.items():
    gene_expression[gene] += 1

print(gene_expression)

当然,真实数据里 UMI 序列可能会因测序错误而产生少量碱基差异。很多工具会做 UMI 校正,比如按编辑距离合并相似的 UMI。我一般设编辑距离为 1 或 2,太大会误伤真实分子。

实用技巧:处理 UMI 时,提前做一次 fastp 或 cutadapt 的接头去除和低质量过滤,可以明显减少 UMI 上的测序错误。别让脏数据污染你的 UMI 去重逻辑。

常见的 UMI 设计方案

方案 UMI 长度 特点 适用场景
随机 N 碱基 8-12 bp 简单,但可能存在回文或均聚物 大多数建库方案
预先设计校正集 8-10 bp 避免均聚物,平衡 GC 含量 高精度定量(如 CEL-Seq2)
双端 UMI 两端各 8 bp 进一步降低碰撞 超高通量测序

我个人比较推荐用随机 N 碱基 + 后续错误校正,因为实现简单,而且后面的软件支持也最多。不过有些项目设计 UMI 时用了“简并碱基”(比如 N=AT, 不包含 C/G 以避免某些偏好),这时候需要你在 read 处理流程里特别注意识别模式。

警告:如果 UMI 序列中有连续 4 个以上相同碱基(例如 AAAA),在 PCR 时会因为聚合酶滑移而产生错误。建库时最好避免这种序列。很多 UMI 设计软件(如 UMI-tools 的 whitelist 命令)可以帮你过滤掉这类可疑 UMI。

嗯,理解 UMI 是单细胞质控的第一步。后面的章节会详细讲怎么根据 UMI 的分布以及基因数来设阈值,这里先把原理吃透。