第二章:Pipeline运行环境搭建

老实说,我见过太多人在环境搭建这一步栽跟头了。有的项目因为依赖冲突浪费了整整一周,有的因为Python版本不对导致结果全错。今天咱们就聊聊,怎么把运行环境搞利索。

2.1 依赖安装:把坑填平再上路

变异解读Pipeline的依赖,说白了就三大类:Python包、工具软件、数据库。让我按优先级一个个说。

2.1.1 Python核心依赖

我一般把依赖分成「必须装」和「按需装」两类。必须装的包括:

# 核心依赖 (必须安装)
pysam>=0.19.0
pandas>=1.4.0
numpy>=1.22.0
pydantic>=1.9.0
scipy>=1.8.0

# 数据库交互
sqlalchemy>=2.0.0
psycopg2-binary>=2.9.0

# 日志与配置
loguru>=0.6.0
pyyaml>=6.0

有个坑我曾经踩过:pysam 在旧版本里和某些BCFtools版本不兼容。所以你现在看到的 pysam>=0.19.0 这个下限,是我用周末加班换来的教训。

2.1.2 系统级工具

Python包好说,真正麻烦的是系统级工具。举个例子,你要处理VCF文件,就绕不开BCFtools和bedtools。

工具 用途 最低版本 安装方式
BCFtools VCF操作、过滤、统计 1.15 conda / apt / 源码
bedtools BED文件区间运算 2.30 conda / apt / 源码
samtools BAM/SAM处理 1.15 conda / apt / 源码
tabix 索引压缩文件 1.11 一般随BCFtools安装
版本陷阱:BCFtools 1.14 有个已知的bug — 处理多等位基因位点时可能输出错误的VCF头。我排查了整整两天才定位到这个。所以强烈建议直接上1.15+。

2.1.3 数据库与参考基因组

这部分最让我头疼。数据库下载慢、版本对不上、路径写错…这些问题我几乎每个项目都遇到。

# 参考基因组 (GRCh38)
# 建议提前下载,别让Pipeline跑起来才下载
wget https://ftp.ebi.ac.uk/ensembl/pub/release-112/fasta/homo_sapiens/dna/Homo_sapiens.GRCh38.dna.primary_assembly.fa.gz
gunzip Homo_sapiens.GRCh38.dna.primary_assembly.fa.gz
samtools faidx Homo_sapiens.GRCh38.dna.primary_assembly.fa

# ClinVar 数据库 (按月更新)
wget https://ftp.ncbi.nlm.nih.gov/pub/clinvar/vcf_GRCh38/weekly/clinvar_20241201.vcf.gz
tabix -p vcf clinvar_20241201.vcf.gz
我的习惯:单独弄一个 /data/reference/ 目录,把所有参考文件和数据库都放进去。然后在系统环境变量里定义 REF_DIR,这样所有配置文件都能引用同一个变量,改路径时改一处就行。

2.2 虚拟环境:隔离才是王道

你想想看,一个团队里有人用Python 3.8,有人用3.10。一个项目依赖pandas 1.3,另一个必须用pandas 2.0。不隔离的话,迟早会出乱子。

2.2.1 Conda:适合生物信息学

Conda对生物信息学很友好。很多工具 — 比如BCFtools、samtools — 都能直接用conda装,省去了编译的麻烦。

# 创建环境
conda create -n vep_pipeline python=3.10

# 激活环境
conda activate vep_pipeline

# 从environment.yml恢复环境 (推荐)
conda env create -f environment.yml

# 导出当前环境
conda env export > environment.yml

environment.yml 长什么样子?我给你看一个实际项目里用过且能稳定复现的:

name: vep_pipeline
channels:
  - conda-forge
  - bioconda
  - defaults
dependencies:
  - python=3.10
  - pysam=0.19.0
  - pandas=1.4.0
  - bcftools=1.15
  - bedtools=2.30.0
  - samtools=1.15
  - pip
  - pip:
    - pydantic>=1.9.0
    - loguru>=0.6.0
    - pyyaml>=6.0
小心Conda的依赖解析:Conda有时会把环境搞得混乱,特别是当channel优先级没设好时。我的建议:conda-forge 优先级高于 bioconda,defaults 放最后。也别混用pip和conda,除非你像我这样显式用 pip: 节。

2.2.2 venv:轻量但够用

如果你的团队只用Python包,不需要系统工具,那 venv 就足够了。它轻量、快速、无负担。

# 创建虚拟环境
python3 -m venv vep_env

# 激活 (Linux / macOS)
source vep_env/bin/activate

# 激活 (Windows)
vep_env\Scripts\activate

# 安装依赖
pip install -r requirements.txt

# 退出环境
deactivate

这里有个经验:requirements.txt 要锁定精确版本号。别写 pandas>=1.4.0,而是写 pandas==1.4.3。为什么?因为配管线的首要目标是可复现。

# requirements.txt (锁定版本)
pysam==0.19.2
pandas==1.4.3
numpy==1.22.4
pydantic==1.9.2
scipy==1.8.1
loguru==0.6.0
pyyaml==6.0

2.3 容器化:从「我电脑上能跑」到「哪都能跑」

我敢打赌,你听过这句话:「在我电脑上明明能跑啊!」 容器化就是专门解决这个问题的。

2.3.1 Docker:最通用的选择

Docker是我个人最喜欢的方式。一个Dockerfile把整个运行环境固定下来,到哪都一样。

# Dockerfile 示例
FROM continuumio/miniconda3:22.11.1

LABEL maintainer="yourname@institute.edu"
LABEL description="Variant Interpretation Pipeline v2.0"

# 安装系统依赖
RUN apt-get update && apt-get install -y \
    procps \
    wget \
    && rm -rf /var/lib/apt/lists/*

# 复制环境配置
COPY environment.yml /tmp/environment.yml

# 创建Conda环境
RUN conda env create -f /tmp/environment.yml

# 复制管线代码
COPY ./pipeline /opt/pipeline
COPY ./config /opt/config

# 设置工作目录
WORKDIR /opt

# 定义默认命令 (可以用脚本覆盖)
CMD ["python", "pipeline/run.py", "--config", "config/config.yaml"]

构建镜像并运行:

# 构建镜像
docker build -t vep-pipeline:v2.0 .

# 运行 (挂载输入输出目录)
docker run --rm \
    -v /data/input:/input \
    -v /data/output:/output \
    -v /data/reference:/ref \
    vep-pipeline:v2.0 \
    python pipeline/run.py --config config/config.yaml \
    --input /input/sample.vcf.gz \
    --output /output/results.vcf.gz
挂载参考基因组:别把参考基因组打包进镜像里 — 那样镜像会超过10GB。把 /ref 目录挂载进去,既灵活又省空间。我吃过这个亏,后来再也不敢把数据库塞镜像里了。

2.3.2 Singularity:HPC集群的首选

你在大学的超算上跑Pipeline吧?那大概率只能用Singularity(现在叫Apptainer)。它不用root权限,安全且用户友好。

# 把Docker镜像转换成Singularity格式
singularity build vep-pipeline_v2.0.sif docker://your-registry/vep-pipeline:v2.0

# 或者从Dockerfile构建
singularity build --sandbox vep-pipeline_sandbox/ docker://... 

# 运行
singularity exec \
    -B /data/input:/input \
    -B /data/output:/output \
    -B /data/reference:/ref \
    vep-pipeline_v2.0.sif \
    python /opt/pipeline/run.py --config /opt/config/config.yaml

嗯,这里要注意:Singularity的 -B 参数语法和Docker略有不同。如果你从Docker迁移过来,千万别写错了冒号的位置。

2.4 环境搭建的核心逻辑

为了让你对整体流程有个直观感受,我画了张图。它把依赖、环境、容器化之间的关系梳理清楚了:

Pipeline运行环境搭建核心逻辑图 Pipeline 运行环境搭建逻辑图 依赖安装 Python包 (pysam, pandas) 系统工具 (BCFtools, bedtools) 数据库与参考基因组 虚拟环境 Conda (生物信息友好) venv (轻量Python隔离) environment.yml / requirements.txt 容器化 Docker (通用、跨平台) Singularity (HPC集群) 镜像构建与挂载 核心目标 1:可复现 相同环境 → 相同结果 版本锁定 → 杜绝意外 核心目标 2:可移植 本地、服务器、云原生 跨平台无差异运行 核心目标 3:可维护 配置与代码分离 单点修改 → 全局生效 说明 1. 依赖安装是基础,虚拟环境保证隔离,容器化保证一致。 2. 实际项目建议从Conda环境起步,需要分发时再打包为Docker镜像。

2.5 避坑指南:我从失败中学到的

环境搭建这件事,说白了就是「提前把雷踩完」。我把自己踩过的坑分享给你:

  • 不要信任「最新版」 — 我曾经直接用 pip install pysam 装了最新版,结果它和项目里写死的VCF解析逻辑不兼容。后来我乖乖锁版本。
  • 数据库路径写在配置文件里 — 别硬编码在代码中。我在 config.yaml 里用一个 database: 节管理,这样换数据库只用改配置,不变代码。
  • 同一个项目统一Conda还是pip — 混用会导致环境无法被 conda env export 完整恢复。我的经验是:能用conda装的用conda,剩下的统一用pip。
  • HPC集群要提前测试文件挂载 — Singularity镜像里的路径和宿主机的路径可能不一样。我在测试阶段就写一个完整的数据处理脚本,确保跑通再到集群上正式运行。

最佳实践总结:

  1. 开发阶段用Conda环境 & environment.yml 锁定。
  2. 交付或部署阶段用Docker/Singularity镜像。
  3. 所有路径、版本参数写在外部配置文件(YAML/TOML)里,不写死。
  4. 参考基因组、数据库单独维护,不要打包进镜像或环境。

好了,环境搭建这部分就到这。接下来配置文件的写法才是真正见功底的地方 — 变量怎么定义、参数怎么传递、模块怎么分,这些都得提前想清楚。