比对工具选择:STAR vs Hisat2 vs Salmon
RNA-seq 做差异分析,第一步就是比对。说白了,就是把测序得到的 read 贴到参考基因组或者转录本上。这一步选不对工具,后面全白搭。我自己做过几十个 RNA-seq 项目,踩过各种坑,今天就把三个主流工具——STAR、Hisat2、Salmon 的选型逻辑给你讲透。
核心差异:基因组比对 vs 转录本定量
这三个工具不能简单“哪个好哪个差”来评价。它们解决的是不同层面的问题:
- STAR:基于基因组索引的 splice‑aware 比对器。会找到每个 read 在基因组上的精确位置,包括跨越内含子的剪接 junction。结果产出 BAM 文件。
- Hisat2:同样是基因组比对器,但用了层级索引策略,速度比 STAR 快,内存也低不少。也是输出 BAM。
- Salmon:严格来说不是“比对器”,是“准比对器”(quasi‑mapping)。它不找 read 在基因组上的精确坐标,而是直接判断 read 来自哪个转录本 isoform,输出 counts 矩阵和 TPM。没有 BAM。
你想想看,如果你需要做可变剪接分析、融合基因检测、或者看 allele‑specific 表达,那你必须用 STAR 或 Hisat2。如果只是常规基因水平的差异表达,Salmon 又快又准,是我个人最常选的路线。
STAR 是全能型,Hisat2 是轻量型,Salmon 是赛道颠覆者。
你用哪个,取决于你下游还要做什么,以及你的计算资源。
STAR:标杆级精度,但吃资源
STAR 在我项目里出现频率最高。为什么?因为它的 junction 检测太准了。我记得有一次做肿瘤 RNA-seq,要鉴定融合基因,STAR 一次性找到了那个罕见的 BRAF 融合,Hisat2 直接漏掉了。从那以后,只要涉及剪接相关分析,我无脑选 STAR。
STAR 的索引构建非常吃内存。人的基因组你需要至少 30 GB RAM。我当时用 128 GB 服务器跑,索引差不多 10 分钟搞定。机器不够的话,就会 swap 到死机。
# STAR 索引构建(人基因组)
STAR --runThreadN 16 \
--runMode genomeGenerate \
--genomeDir ./STAR_index \
--genomeFastaFiles Homo_sapiens.GRCh38.fa \
--sjdbGTFfile Homo_sapiens.GRCh38.gtf \
--sjdbOverhang 149
# 比对
STAR --genomeDir ./STAR_index \
--readFilesIn sample_R1.fastq sample_R2.fastq \
--runThreadN 16 \
--outSAMtype BAM SortedByCoordinate \
--outFileNamePrefix sample_
优点:
- 精度业内公认最高,特别是在 junction 边界的 read 分配上
- 自带 chimeric detection,融合基因首选
- BAM 文件可以直接进 GATK、samtools 等后续工具
缺点:
- 索引内存消耗大(人的参考基因组需要 30+ GB)
- 比对速度比 Hisat2 慢一些,尤其 read 数大的时候
- 输出文件体积巨大,一个样品 BAM 轻松几十 GB
Hisat2:轻骑兵,适合批量和低配机器
Hisat2 是我在学生时代用得最多的。当时实验室服务器只有 64 GB,跑 STAR 索引会卡。Hisat2 的层级索引(全局索引 + 局部索引)让内存降到了 5 GB 左右,速度反而快了一截。
但要注意,Hisat2 的 junction 检测精度略低于 STAR。我做过一次对比实验,用同一个模拟数据集,STAR 能正确 mapping 的跨内含子 read 比 Hisat2 多出 2~3%。如果你的 read 长度短(比如 50 bp 单端),Hisat2 容易把 read 定位到错误的外显子上。嗯,这里要特别警惕。
# Hisat2 索引构建
hisat2-build -p 16 Homo_sapiens.GRCh38.fa hisat2_index
# 比对
hisat2 -x hisat2_index \
-1 sample_R1.fastq -2 sample_R2.fastq \
-p 16 \
--dta-cufflinks \
-S sample.sam
--dta-cufflinks 或 --dta 参数,让 Hisat2 输出更友好的剪接位点信息。
优点:
- 内存极低(4~5 GB),16 GB 内存的机器也能跑
- 比对速度快,比 STAR 快 1.5~2 倍
- 双端比对一致性不错
缺点:
- 短 read 或低质量数据的 junction 分配偏保守
- 没有内置的 chimeric/fusion 检测模块
- 生成的 SAM 文件大,需要压缩或转 BAM
Salmon:免比对时代的标杆
Salmon 严格来说不算“比对”,它用的是 quasi‑mapping,直接在转录本索引上做 k‑mer 匹配。这就带来两个好处:第一,不再需要 splice‑aware 的基因组索引,省去大量内存;第二,它有自己的一套“偏差校正”模块,能自动修正 GC bias、片段长度 bias、序列偏好 bias。我做过几十个样品的大批量分析,Salmon 跑完一个样品只要十几分钟,资源消耗比 STAR 低一个数量级。
同样,Salmon 默认输出的是 transcript‑level 的 counts,你需要用 tximport 汇总到 gene level 才能喂给 DESeq2 或 edgeR。
# Salmon 索引构建
salmon index -t Homo_sapiens.GRCh38.cdna.all.fa \
-i salmon_index \
-p 16
# 定量(双端)
salmon quant -i salmon_index \
-l A \
-1 sample_R1.fastq -2 sample_R2.fastq \
-p 16 \
--gcBias --seqBias \
-o sample_quant
# 然后用 tximport 整合到 gene 级别
# R 代码片段
library(tximport)
library(DESeq2)
txi <- tximport("sample_quant/quant.sf", type = "salmon", txOut = FALSE)
dds <- DESeqDataSetFromTximport(txi, colData = coldata, design = ~ condition)
优点:
- 速度极快,资源消耗极低
- 内置多种偏差校正,定量结果有时比 STAR 更准确
- 直接输出 counts、TPM、有效长度,下游差异分析一步到位
缺点:
- 无法用于可变剪接等基因组级别分析
- 依赖高质量、完整的转录本参考
- 多样品整合时需要注意“libtype”参数(
-l A自动检测一般够用)
三大工具关键参数对比
| 维度 | STAR | Hisat2 | Salmon |
|---|---|---|---|
| 类型 | 基因组 splice‑aware 比对 | 基因组 splice‑aware 比对 | 转录本准比对 (quasi‑mapping) |
| 输出 | BAM / junction 文件 | SAM/BAM | quant.sf (counts, TPM, 有效长度) |
| 索引内存 (人) | ~30 GB | ~4 GB | ~8 GB |
| 比对速度 (37M 双端) | ~20 min | ~10 min | ~5 min (定量) |
| Junction 精度 | ★★★★★ | ★★★☆☆ | 不适用 |
| 偏差校正 | 无内置 | 无内置 | GC、长度、序列偏好、fragment GC bias |
| 适用场景 | 可变剪接、融合基因、变异检测 | 常规差异表达(资源受限) | 常规差异表达(批量、快速) |
我的选型决策流程
做一个项目之前,我会先问自己三个问题:
- 下游分析需不需要基因组坐标? 如果需要 junction、fusion、ASE → STAR。不需要 → 看第 2 问。
- 机器内存多少? 少于 16 GB → 排除 STAR。用 Hisat2 或 Salmon。
- 样品数量多少? 大于 50 个样品,且没有大量计算资源 → 无脑 Salmon。否则 Hisat2 也可接受。
下面是我脑内的一张决策图,你可以看看:
避坑指南
- 我不建议 在同一个项目中混用两种不同的比对/定量工具。我曾见过有人第一台机器用 STAR,第二台因为资源不够换 Salmon,最后合并 counts 时发现基因表达量系统性偏差,调了很久。
- Salmon 的小陷阱: 如果你用的是双端数据,但插入片段比较极端(比如小于 50 bp),Salmon 的 fragment length distribution 估计会不准,导致 TPM 偏差。加
--fldMean和--fldSD可以手动指定。 - Hisat2 的 --dta-cufflinks 参数 和 STAR 的
--outSAMstrandField intronMotif是给 Cufflinks/StringTie 准备的,如果你不打算用它们做转录本组装,加不加影响不大。 - 永远别信默认参数! 尤其 STAR 的
--outFilterMultimapNmax默认是 10,对于多比对的 read,它可能放过太多 multi‑mapping 导致假阳性。我通常设成 1 或 2,除非你有充足理由需要保留多比对。
quant.sf 里的 EffectiveLength 列是否有意外值(比如 0)。一旦发现有大量 0,说明参考转录本版本有问题,或者 read 长度与索引不匹配。这时候切回 STAR 或者换一个 GRCh38 的参考集。
最终建议
我自己的常规管线是这样配置的:批量 RNA-seq 差异分析(不做剪接)→ Salmon + tximport。需要看剪接 / fusion → STAR + StringTie + rMATS。小项目或者教学演示 → Hisat2,资源友好且容易可视化。你没有必要在某一个工具上“一条路走到黑”,关键看你的数据和你的问题。希望这张决策图和对比表能帮你少走弯路。嗯,就这样,开始跑你的数据吧。