1. WDL入门:从零到上手

说实话,我第一次接触WDL是在处理一批基因组测序数据的时候。那时候每天手动跑流程,一个样本就要敲十几条命令,还得盯着日志怕哪步挂掉。后来团队引入WDL,我最初还挺排斥——又得学新东西?但真正用起来之后,我只想说一句:为什么不早点用它?

这一章,我们聊聊WDL是什么、从哪来、能干什么,以及怎么把它装到你电脑上。

1.1 WDL的发展历史

WDL(Workflow Description Language)是Broad Institute牵头开发的。2014年左右吧,他们内部做生物信息学分析时发现一个痛点:每次对接不同工具、不同环境,脚本都得重写。你想想看,光是对齐软件就有BWA、Bowtie、STAR...每个的输入格式、参数结构都不一样。

于是,一个专门描述数据科学工作流的语言就诞生了。它的设计原则很明确:

  • 可读性强——人类能一眼看懂这个流程在干什么
  • 可移植性高——本地能跑,集群能跑,云上也能跑
  • 标准化——社区有统一的语法和语义

到了2018年,WDL被正式提交给OpenWDL社区管理。从那以后,版本迭代更快了。我记得1.0发布时大家还挺兴奋,因为终于不用自己写自定义运行时处理了。

现在最新的稳定版是1.1,2.0也在开发中。我个人的建议是:新项目直接用1.1,兼容性好,功能也够用。

版本 发布时间 核心变化 我的看法
draft-2 2016 最早的可用版本,定义基本结构 现在别用了,兼容性问题多
1.0 2018 加入Input/Output声明、标准化运行时 还算能用,但建议升级
1.1 2020 改进类型系统、支持可空类型、结构化输出 目前首选版本
2.0(开发中) 预计2024+ 完全重构类型系统、增强并发支持 观望中,别用在生产环境

1.2 核心概念:工作流、任务、调用

WDL的核心其实只有三个东西:Workflow(工作流)、Task(任务)、Call(调用)。说白了,就像搭积木。你定义一堆小任务,然后在一个工作流里按顺序或并行调用它们。

Task 是最小执行单元。它定义了三样东西:

  • 输入什么(Input)
  • 跑什么命令(Command)
  • 输出什么(Output)

Workflow 是编排器。它把任务串起来,管理数据流转。一个最简单的WDL脚本长这样:

version 1.1

workflow my_first_workflow {
  input {
    File my_file
  }
  call my_task {
    input:
      infile = my_file
  }
  output {
    File result = my_task.outfile
  }
}

task my_task {
  input {
    File infile
  }
  command {
    cp ~{infile} output.txt
  }
  output {
    File outfile = "output.txt"
  }
}

你看,结构非常清晰。Workflow 定义流程,Task 定义具体操作。我个人习惯把 Task 放在文档底部,Workflow 放在前面,这样读的人一眼就能看到核心逻辑。

Call 就是调用。你可以按顺序调、并行调、甚至在条件/循环里调。后面章节会展开讲,这里先有个概念就行。

关键区别:Task 定义“怎么做”,Workflow 定义“做什么”。别把它们混在一起。

1.3 应用场景

WDL 天然适合数据密集型的工作流。我接触最多的场景包括:

  1. 生物信息学处理:基因组比对、变异检测、RNA-seq定量。这个领域是WDL的主战场。
  2. 数据ETL:从不同源拉数据、清洗、合并、输出结构化文件。WDL 比手写Python脚本好维护得多。
  3. 模型训练预处理:特征工程、数据划分、格式转换。配合Docker使用,环境依赖问题基本消灭。
  4. 批处理作业:定时跑报表、批量压缩文件、自动化校验。我曾经帮运营团队把一个每周手动跑3小时的流程,改成WDL + Cron 自动跑,节约了大量人力。

一个小建议:如果你日常工作里经常需要“先把A结果传给B,B处理完再给C,然后汇总”,那WDL就适合你。

1.4 环境搭建

搭建WDL环境不像搭深度学习环境那么麻烦。你只需要两个东西:

  • 一个WDL的解析/运行引擎
  • 一个后端执行器(本地或集群)

目前最流行的引擎是MinimWDL和Cromwell。MinimWDL适合学习和本地测试,Cromwell适合生产环境。

咱们先装MinimWDL:

pip install miniwdl

# 验证是否安装成功
miniwdl --version

如果没报错,你就已经有了一个完整的WDL执行环境。拿上面那个脚本试试:

miniwdl run my_first_workflow.wdl -i inputs.json

Inputs.json 长这样:

{
  "my_first_workflow.my_file": "data/sample.txt"
}

嗯,这里有个坑要注意。文件名路径不要用波浪号~开头,有些引擎不解析。我刚开始就因为这个浪费了半小时。

如果你打算用Cromwell(生产环境推荐),下载JAR包就行:

wget https://github.com/broadinstitute/cromwell/releases/download/87/cromwell-87.jar

# 运行
java -jar cromwell-87.jar run my_first_workflow.wdl

警告:Cromwell 需要Java 11+,而且对内存有要求。默认只给512MB,跑大数据任务时会OOM。我建议至少分配2GB:

java -Xmx2g -jar cromwell-87.jar run my_first_workflow.wdl

说到引擎选型,我自己的经验总结如下表:

引擎 适合场景 安装难度 性能 推荐指数
MinimWDL 学习、本地测试、小数据 低(pip一行搞定) 中等 ⭐⭐⭐⭐
Cromwell 生产环境、集群、大数据 中(需下载JAR) 高 ⭐⭐⭐⭐⭐
dxWDL DNAnexus云平台专属 低(仅限云上) 不可比 ⭐⭐⭐

1.5 知识体系总览

为了让你对本章内容有个全局印象,我用一张SVG图画出WDL的骨架。你就把它当作一本小型地图册的目录页。

第1章:WDL入门 —— WDL 脚本的骨架结构 发展历史 核心概念 应用场景 环境搭建 2014诞生 OpenWDL Workflow Task / Call 生物信息 ETL/批处理 核心:Workflow + Task 一切从这开始 先装MinimWDL 生产环境用Cromwell

1.6 总结:你该带走的知识点

这一章的内容,说多不多,说少不少。但我觉得核心就三条:

  • WDL是什么:一个专门写数据工作流的语言,重点是描述数据怎么流动、执行什么操作,而不是每一步的低层实现细节。
  • 怎么装:pip install miniwdl 就已经能跑了。别纠结选引擎,先动手写一个“Hello World”级别的WDL脚本再说。
  • 怎么用:分开写 Task 和 Workflow,保持代码结构清晰。不要在Task里塞工作流的逻辑,也不要在Workflow里定义具体的命令。

一句话记住:WDL 让你不用再关心“这个命令在哪台机器上跑、跑完了怎么给下一个步骤”,你只需要关心“数据从哪来、经过什么处理、输出什么结果”。