3. 工作流语言与描述模型

在生物信息分析中,一个典型任务往往包含几十个步骤:从原始 FASTQ 质控、比对、去重、变异检测,到注释与报告生成。把这些步骤串起来的方式有很多种,从最朴素的 Shell 脚本,到声明式的 WDL/CWL,抽象层次差异巨大。理解这些差异,是选择合适工作流引擎的前提。

我们可以从三个维度来刻画一种工作流描述模型:依赖表达方式(隐式还是显式)、执行环境抽象(本地、集群、容器、云)、可复现与可移植能力。下面逐一分析五种主流方案。

Shell 脚本:最直接的命令串联

Shell 脚本本质上是一串按顺序执行的命令。依赖关系靠书写顺序隐式表达,没有任务图,也没有断点续跑。例如:

fastp -i raw_R1.fq -I raw_R2.fq -o clean_R1.fq -o clean_R2.fq
bwa mem -t 8 ref.fa clean_R1.fq clean_R2.fq | samtools sort -o sorted.bam
samtools index sorted.bam
gatk MarkDuplicates -I sorted.bam -O dedup.bam -M metrics.txt

它的优点是零学习成本、调试直观;缺点是任何一步失败后重跑都要从头开始,中间文件命名、参数、环境全靠人工维护,换一台机器或换一个样本几乎必然出错。Shell 适合一次性探索、小规模数据或作为其他引擎内部调用的“胶水”。

Make:基于文件时间戳的依赖引擎

Make 引入了“目标—依赖—命令”的规则模型,通过文件时间戳判断是否需要重建。它第一次让“只重跑变化部分”成为可能:

sorted.bam: clean_R1.fq clean_R2.fq ref.fa
	bwa mem -t 8 ref.fa clean_R1.fq clean_R2.fq | samtools sort -o $@

dedup.bam: sorted.bam
	gatk MarkDuplicates -I $< -O $@ -M metrics.txt

Make 的抽象层次高于 Shell,但它的依赖模型是“文件级”的,对通配符、多样本批量、集群调度支持很弱。当样本数从 1 个变成 500 个时,Makefile 会迅速变得难以维护。因此 Make 更适合工具构建、小型固定流程,而非大规模组学分析。

Snakemake:面向生物信息的 Python 化规则引擎

Snakemake 保留了 Make 的规则思想,但用 Python 语法描述,天然支持通配符、多样本展开和集群提交。一个多样本比对规则可以写成:

rule bwa_map:
    input:
        "data/{sample}.R1.fq",
        "data/{sample}.R2.fq",
        "ref/genome.fa"
    output:
        "mapped/{sample}.bam"
    threads: 8
    shell:
        "bwa mem -t {threads} {input} | samtools sort -o {output}"

其中 {sample} 是通配符,Snakemake 会根据目标文件自动推导需要展开的样本集合。它支持 --dry-run 预览执行计划、--rerun-incomplete 断点续跑、--cluster 提交到 Slurm/SGE,也能通过 conda 或容器固定软件环境。Snakemake 的抽象层次适中,学习曲线平缓,特别适合单实验室、以 Python 为技术栈、需要在 HPC 上跑多样本流程的团队。

Nextflow:面向数据流的可移植执行模型

Nextflow 采用数据流(dataflow)编程模型,用 process 定义计算单元,用 channel 传递数据。它最突出的能力是“一次编写,多处运行”:同一份脚本可以在本地、Slurm、AWS Batch、Google Cloud 之间切换,只需改配置文件。例如:

process align {
    container 'biocontainers/bwa:0.7.17'
    cpus 8
    input:
    tuple val(sample), path(reads)
    output:
    path("${sample}.bam")
    script:
    """
    bwa mem -t 8 ref.fa $reads | samtools sort -o ${sample}.bam
    """
}

Nextflow 内置对容器、Conda、模块系统的支持,配合 nf-core 社区已有大量经过验证的流程可直接复用。它的抽象层次较高,适合跨机构协作、云上弹性伸缩、需要严格版本控制的中大型项目。代价是需要理解 channel、operator 等概念,调试门槛高于 Snakemake。

WDL / CWL:面向互操作的声明式标准

WDL(Workflow Description Language)和 CWL(Common Workflow Language)是两种独立的声明式标准,目标都是让流程描述与执行引擎解耦。WDL 由 Broad Institute 主导,语法接近自然语言,配合 Cromwell 引擎可在本地、集群或 Terra 云平台运行;CWL 更强调与 Unix 工具和容器生态的兼容,被多个欧洲项目采用。二者都要求显式声明输入、输出、运行时资源,天然适合需要跨平台共享、审计和长期维护的临床或联盟级流程。缺点是编写相对繁琐,社区工具链不如 Nextflow 活跃。

五种工作流描述模型的抽象层次与适用场景 抽象层次 / 可移植性 适用规模与协作复杂度 → Shell 脚本 顺序执行 · 无依赖图 Make 文件时间戳依赖 Snakemake Python 规则 · 通配符 Nextflow 数据流 · 容器 · 云 WDL / CWL 声明式 · 跨引擎标准 选择依据:数据规模 · 团队技术栈 · 执行环境(本地/HPC/云)· 可复现要求 · 社区生态

如何选择:从实际约束出发

选择工作流语言时,不要先问“哪个最先进”,而应先明确约束条件。如果只是跑几个样本、验证一个想法,Shell 或 Make 足够;如果样本数上百、需要在 Slurm 集群上批量提交、团队以 Python 为主,Snakemake 是性价比最高的选择;如果项目需要跨机构共享、在云上弹性运行、或直接复用 nf-core 流程,Nextflow 更合适;如果流程要作为标准交付给临床或联盟伙伴、需要严格审计和跨引擎执行,WDL/CWL 的声明式约束反而成为优势。

一个实用的判断顺序是:先看执行环境(本地/HPC/云)→ 再看样本规模与重跑频率→ 再看团队已有技术栈→ 最后看是否需要跨机构互操作。多数情况下,Snakemake 和 Nextflow 覆盖了生物信息分析 80% 以上的实际需求,Shell 和 Make 作为底层补充,WDL/CWL 则在标准化场景中不可替代。

实践建议:无论选择哪种引擎,都应把软件版本、参考基因组版本、关键参数写入流程描述文件本身,而不是散落在命令行历史中。这是从“能跑”走向“可复现”的第一步。