2. NCBI BLAST工具介绍:命令行BLAST、BLAST+新特性、常用参数

说到BLAST,这玩意儿在生信领域算得上是“老黄牛”了。从90年代初诞生到现在,几乎每个做序列比对的同行都跟它打过交道。我自己从硕士阶段就开始用,那时候还是经典的 blastall 命令行。后来NCBI推出了BLAST+,我一开始还不太适应,但用顺手之后,真香。

这一节我们就来聊聊BLAST工具本身。说白了,你得先把“武器”弄明白,后面讲GPU加速才有意义。

2.1 BLAST的历史与演变

可能有人觉得“BLAST不就是一个比对工具吗?”嗯,其实这里面有几个版本的变化,值得了解一下。

版本 核心命令 特点 我个人怎么看
传统BLAST blastall, formatdb 功能集成在单个程序里,靠参数切换 当年用起来挺方便的,但代码维护是个噩梦
BLAST+ blastn, blastp, makeblastdb 程序拆分、模块化、支持多线程 我建议新手直接学BLAST+,别走弯路
提示: 虽然老版本的 blastall 在一些老服务器上还能见到,但NCBI早就停止维护了。我见过的坑是:有人用conda安装时没注意版本,装了个legacy blast,跑出来的结果格式跟预期不一样。排查了半天才发现是工具版本问题。

2.2 BLAST+新特性

BLAST+相比老版本,改动还挺大的。我挑几个最关键的说说。

2.2.1 模块化设计

老版本一个 blastall 扛所有活,参数多得能写两页。BLAST+ 直接拆成了多个独立程序:

  • blastn —— 核酸vs核酸
  • blastp —— 蛋白vs蛋白
  • blastx —— 核酸翻译后vs蛋白
  • tblastn —— 蛋白vs核酸翻译库
  • tblastx —— 核酸翻译vs核酸翻译

你想想看,这样做的好处是什么?每个程序只做一件事,参数更清晰,出问题也好定位。我在搭建自动化流程时,用 blastn 和 blastp 分别处理不同任务,脚本写起来舒服多了。

2.2.2 数据库构建命令统一

老版本用 formatdb,BLAST+ 换成了 makeblastdb。用法基本一致,但多了几个实用选项:

makeblastdb -in my_sequences.fasta -dbtype nucl -out my_db -parse_seqids
注意: -parse_seqids 这个参数建议加上。我遇到过客户拿来的数据库没加这个选项,后面做 blastdbcmd 按序列ID提取子序列时直接报错。加了也就多几秒建库时间,别省。

2.2.3 多线程支持

老版本的BLAST是单线程的,一个比对任务只能用一个CPU核心。BLAST+ 引入了 -num_threads 参数,可以并行加速。这在服务器上特别管用。

blastn -db nt -query reads.fasta -out results.txt -num_threads 8

嗯,这里要注意:多线程加速不是线性的。我记得测过一次,8线程大概比单线程快4-5倍,再往上加核收益就逐渐变平了。不过这已经是很大的改进了。

2.3 常用参数详解

BLAST+ 的参数很多,但真正日常高频使用的也就那么十几个。我挑几个最容易踩坑的讲。

2.3.1 -evalue(期望阈值)

这个参数控制比对的“严格程度”。evalue 越小,结果越严格。默认值通常是10,但说实话,10这个值真的很宽松。我处理宏基因组数据的时候,默认10能打出几十万个结果,里面一堆假阳性。

场景 推荐evalue 说明
寻找近缘同源 1e-5 到 1e-10 严格,减少假阳性
远缘同源检测 1e-2 到 10 宽松,但小心错误匹配
短序列比对(如引物) 100 到 1000 短序列本身统计显著性低,需要放宽
经验: 我曾经在分析RNA-seq数据时,直接用默认evalue 10跑blastn,结果把细菌污染序列也当成“显著比对”输出了一大堆。后来把evalue降到1e-5,干净多了。如果你不确定,先从1e-5开始试,再根据结果调整。

2.3.2 -word_size

这个词大小参数决定了BLAST用来“锚定”比对的种子长度。蛋白质比对默认是3,核酸比对默认是11(BLAST+默认是28,但这取决于程序)。

为什么这个参数重要?word_size 越小,越能找到短而弱的匹配,但计算量会暴增。我试过把核酸比对的word_size从28降到11,运行时间直接翻了5倍。

# 较快的设置(默认)
blastn -db nt -query seq.fa -word_size 28

# 敏感但更慢的设置
blastn -db nt -query seq.fa -word_size 11
小技巧: 如果你在做跨物种的远源比对,可以适当降低word_size提高灵敏度。但如果只是比对高度同源的序列,保持默认值就好,别自己找麻烦。

2.3.3 其他常用参数一览

参数 作用 我常用的默认值
-outfmt 输出格式,常用6(表格)或10(CSV) 6
-max_target_seqs 每个query最多返回的匹配数 20
-perc_identity 最低序列一致性 90(同物种);70(跨物种)
-culling_limit 限制每个subject的hit数量 1
BLAST+ 核心参数与性能权衡 query序列 + 数据库 参数:-evalue, -word_size, -perc_identity 控制比对灵敏度与严格程度 性能影响 - word_size↓ → 计算量↑ - evalue↓ → 过滤更多候选 - num_threads↑ → 并行加速 结果质量 - word_size↓ → 灵敏度↑ - evalue↓ → 假阳性↓ - perc_identity↓ → 召回率↑ 比对结果(表格/XML) 权衡: 速度快 ↔ 灵敏度高 需要根据任务选择

2.4 命令行比对示例

聊了这么多理论,咱们上手跑个实际的例子。假设你有一个包含几千条16S rRNA序列的fasta文件,想跟NCBI的16S数据库比对:

# 第一步:建库(假设你已经下载了16S数据库)
makeblastdb -in 16S_ribosomal_RNA.fasta -dbtype nucl -out 16S_db -parse_seqids

# 第二步:比对
blastn -db 16S_db -query unknown_bacteria.fasta \
       -out results.txt \
       -outfmt 6 \
       -evalue 1e-5 \
       -word_size 28 \
       -num_threads 8 \
       -max_target_seqs 5
我个人的习惯: 每次做完比对,先别急着往下分析。看一眼 results.txt 里有多少条“0 evalue”的匹配,以及那些evalue刚好在边界上的结果。如果边界附近结果特别多,说明你的evalue设置可能太松了。我曾经有一次就是没看这一步,直接进了下游分析,结果发现很多低质量匹配把结果搞乱了。

2.5 避坑指南:你可能会遇到的情况

这些是我自己在不同项目里踩过的坑,写出来希望你能绕开:

  • 数据库版本不一致: 新旧版BLAST的数据库格式不兼容。你用BLAST+建了库,就不能用旧版本的blastall来读。反之亦然。
  • 内存不足: 大型数据库(比如nt)建库时需要大量内存。我曾经在只有8GB内存的机器上建nt库,直接OOM(内存溢出)了。可以用 -max_file_sz 限制输入文件大小,或者换台内存更大的机器。
  • 输出格式混淆: -outfmt 0 是默认的对齐视图(含文字描述),看起来清晰但解析麻烦。做自动化流程时,我99%的情况都用 -outfmt 6 或 10,方便用脚本处理。
  • 参数命名变化: 老版本 -p 指定程序类型,新版本直接用不同命令名。写教程或脚本时注意区分。

好了,BLAST工具本身就说这么多。记住:工具是死的人是活的。参数调优这事儿,说白了就是经验活。多跑几次,多看看结果,你自然就知道怎么调了。