Snakemake 执行:运行你的第一条流水线

写好了 Snakefile,接下来就是让它跑起来。这部分其实最直接,但也是坑最多的地方。我刚开始用 Snakemake 时,觉得就一句 snakemake 完事,结果动不动就报错,还不清楚哪里出了问题。后来才明白,执行命令背后藏着好几个关键模式——特别是 dry-run 和 DAG 图,几乎是我每次写新流水线必用的调试工具。

snakemake 命令基础

Snakemake 的命令格式很简单:

snakemake [选项] [目标文件或规则]

默认情况下,Snakemake 会在当前目录找 Snakefile,然后执行第一条规则(通常是 rule all)。你可以直接指定一个目标文件,比如:

snakemake results/sample1.bam

这会只构建 results/sample1.bam,不会管其他样本。我个人习惯是先写一个 rule all 把所有最终结果列进去,然后只敲 snakemake,省心。

一句话总结:Snakemake 会根据目标文件反向推导需要执行的所有规则,只运行必要的步骤。

Dry-run 模式:先模拟再执行

你写了一个复杂的 Snakefile,里面有几十个规则、几百个通配符。你敢直接跑吗?我不敢。这时候 dry-run 就派上用场了。

snakemake -n

加上 -n 或 --dry-run,Snakemake 会模拟执行,打印出每一步要做什么,但不会真的创建或删除文件。我每次修改完 Snakefile 都先跑一次 dry-run,检查规则顺序和输入文件是否对。

配合 -p 参数(打印执行的 shell 命令)效果更好:

snakemake -n -p

输出会显示每个规则对应的具体命令,方便你检查通配符是否展开正确。

Dry-run 不会校验输入文件是否存在,但它能快速帮你发现 DAG 结构问题,比如循环依赖或者缺少某个规则的输出。

生成依赖图

Snakemake 最酷的功能之一,就是可以自动生成 DAG(有向无环图)的 DOT 文件。用 Graphviz 渲染出来,你就能直观看到流水线的执行顺序和依赖关系。

snakemake --dag | dot -Tpng > dag.png

如果安装了 Graphviz,直接运行上面命令就能得到一张 PNG 图。我常用 --forceall 把整个 DAG 都画出来,即使某些步骤已经完成:

snakemake --dag --forceall | dot -Tpng > full_dag.png

还有一种更轻量的方式,用 snakemake --rulegraph 生成规则级别的图(不展开样本):

snakemake --rulegraph | dot -Tpng > rulegraph.png

依赖图是我调试流水线的“X 光片”。有一次我发现 DAG 里多了个不该存在的边,原来是某个规则写了相同的输出文件名,Snakemake 自动合并了——还好提前看到。

如果输出文件很多,--dag 可能会生成超大的图。建议先用 snakemake -n --quiet 看看总规则数,再决定要不要画全部样本的 DAG。

常见执行场景与参数

除了 -n 和 --dag,还有几个参数我几乎天天用:

参数作用我的常用场景
-j N并行执行 N 个任务服务器有 32 核,snakemake -j 30,留两个核给系统
-p打印所有 shell 命令想看规则到底跑了什么脚本
-k遇到错误继续执行后续规则批量处理 100 个样本,某个样本报错,不想重跑整个队列
--rerun-incomplete重新运行输出不完整的任务上次运行被中断,用这个自动补全
--cluster提交到集群(如 SLURM)snakemake -j 100 --cluster "sbatch -t 60"

嗯,这里要注意 --rerun-incomplete 是 Snakemake 7 之后的默认行为,但早期版本需要显式加,记一下。

我的避坑经验

我曾经踩过一个坑:写了一个 Snakefile,在本地 dry-run 完全正常,但上了集群跑就报“MissingInputException”。查了半天,发现是集群上某个参考文件路径写错了,而 dry-run 不检查输入文件是否存在。所以现在我的习惯是:

  1. 先在本地用 -n 检查 DAG 结构。
  2. 再用 touch 创建几个占位输入文件,实际跑一小部分(snakemake -j 1 --resources mem_gb=8 限制资源)。
  3. 最后才提交集群全量跑。

另外,--force 和 --forceall 的区别也容易搞混。--force 只强制重新运行指定的目标,--forceall 会强制重新运行所有上游规则。我曾经用 --forceall 修改了一个参数,结果把整个流水线从原始数据开始重跑了一遍,白白浪费一天计算时间。

记住:先 dry-run,再看 DAG,最后才 snakemake -j。这三步能帮你省掉 90% 的调试时间。

本章小结

执行 Snakemake 流水线并不只是敲个命令。dry-run 让你安全预览,依赖图让你看清全局,再加上集群参数和错误处理,你就能灵活控制整个流程。把这张图记住,以后写 Snakefile 会顺手很多。

Snakemake 执行流程 snakemake 命令 解析 Snakefile 构建 DAG Dry-run? 实际执行 ( -j ) 生成依赖图 生成输出文件 否 是 说明 • Dry-run 模式预览执行计划 • 依赖图帮助检查 DAG 结构 • 实际执行可并行、容错