Skip to content

AI4S 可复现工作流:数据治理与容器化 ​

一句话结论:科学计算从"能跑"到"可复现",需要三层保障:环境可复现(容器)、数据可复现(版本化)、计算可复现(确定性)。本文拆解数据版本化、容器固化与溯源记录三个核心环节,给出可落地的 AI4S 工作流基线。

实验目标 ​

做过科学计算的人都遇到过"玄学"问题:

  1. 换台机器结果就变了——MPI 库版本、CUDA 驱动、编译优化参数不同,数值结果出现细微但致命的分叉;
  2. 数据集不可追溯——论文里的图用的是 v1 还是 v2 数据集?预处理脚本改过没有?
  3. 结论无法复现——同事/学生/审稿人要复现实验,依赖环境没有文档,装了半天跑不出原结果。

科学结论的可信度,取决于别人能否逐字节复现你的工作流。本文目标:建立一套"数据版本化 + 容器固化 + 全链路溯源"的可复现工作流基线,并给出 HPC 集群上的落地清单。

代码逐段拆解 ​

1. 数据版本化:科学数据集进入 Git 之外的世界 ​

bash
# DVC:大数据集版本化(数据不在 Git,元数据在)
dvc init
dvc add data/era5-2024.zarr          # 把数据集登记进 DVC(.dvc 文件入 Git)
git add data/era5-2024.zarr.dvc .dvc/config
git commit -m "track era5-2024 dataset"

# 以后想回到任意历史版本的数据:
dvc checkout                          # 按当前 commit 恢复对应数据版本
dvc repro                             # 重跑整个依赖链

拆解要点:

  • 数据与代码解耦:科学数据动辄 TB 级,进不了 Git;DVC 让"代码版本 ↔ 数据版本"一一对应——checkout 一条命令回到任何历史状态;
  • .dvc 文件是核心:它记录数据的哈希与远端存储位置,是数据可复现的"指纹";
  • 同样思想:LFS、lakeFS、对象存储版本化都能实现,关键是版本必须绑定到代码提交。

2. 容器固化:把科学环境变成不可变镜像 ​

dockerfile
# 科学计算容器:CUDA + MPI + 科学库(多阶段构建,镜像最小化)
FROM nvidia/cuda:12.2.2-devel-ubuntu22.04 AS build

# MPI 与科学依赖
RUN apt-get update && apt-get install -y --no-install-recommends \
      openmpi-bin libopenmpi-dev libfftw3-dev libhdf5-openmpi-dev \
    && pip install numpy scipy xarray netcdf4

# 编译期优化:科学库对架构敏感,构建时钉死 CPU 指令集
ARG TARGET_ARCH=x86-64-v3
RUN pip install --no-cache-dir \
      --config-settings=cmake.define.CMAKE_CXX_FLAGS="-march=${TARGET_ARCH}" \
      gromacs

# 运行镜像:只带运行时,不带走开发生态
FROM nvidia/cuda:12.2.2-runtime-ubuntu22.04
COPY --from=build /usr/local /usr/local
COPY --from=build /opt/solver /opt/solver
ENTRYPOINT ["mpirun", "--allow-run-as-root"]

拆解要点:

  • 镜像不可变 = 环境可复现:镜像 hash 就是环境指纹,sha256 写入实验记录,任何机器拉同一镜像结果一致;
  • 钉死架构与版本:科学库(GROMACS、LAMMPS、FFTW)对 CPU 指令集敏感,构建时 -march 钉死,避免迁移后性能或结果漂移;
  • HPC 场景用 Apptainer/Singularity:共享文件系统上 Docker 有权限问题,Apptainer 单文件镜像 + 用户态运行,是集群可复现的标配。

3. 全链路溯源:每个实验都留一张"身份证" ​

python
# 溯源记录:输入 → 环境 → 参数 → 输出,一条 JSON 全链路
import hashlib, json, subprocess

def provenance_record(data_ref, image, params, outputs, workdir):
    def sha(path):
        h = hashlib.sha256()
        with open(path, "rb") as f:
            for chunk in iter(lambda: f.read(1 << 20), b""):
                h.update(chunk)
        return h.hexdigest()

    return {
        "schema": "ai4s-prov/1.0",
        "inputs":  {k: sha(p) for k, p in data_ref.items()},   # 输入数据哈希
        "env":     {"image": image, "image_sha": sha(image)},  # 容器环境指纹
        "params":  params,                                     # 全部运行参数
        "outputs": {k: sha(p) for k, p in outputs.items()},    # 输出哈希
        "runtime": {"node": subprocess.check_output(["hostname"]).decode().strip()}
    }
# 结果:provenance.json —— 科学结论的"出生证明"

原理讲解:可复现的三个层次 ​

层次一:环境可复现——容器与依赖管理 ​

  • 目标:任意机器、任意时间,跑出同一环境;
  • 手段:不可变容器镜像(Docker/Apptainer)+ 锁定的依赖清单(requirements.txt 带哈希、conda-lock、poetry.lock);
  • 陷阱:pip install 不锁版本 = 环境漂移的温床;GPU 驱动不锁 = 换卡即换结果。

层次二:数据可复现——版本化与不可变存储 ​

问题方案
数据集多版本DVC/LFS 版本化,版本绑定代码提交
预处理改动难追溯预处理脚本入 Git + 输入输出哈希校验
数据被误改不可变对象存储(WORM)或哈希校验拦截

关键认知:"数据版本"的定义 = 数据内容的哈希,而不是"文件名 v2"——后者毫无意义。

层次三:计算可复现——确定性与种子管理 ​

  • 随机种子:深度学习要固化 random.seed + np.random.seed + torch.manual_seed + Dataloader worker 种子(常被漏掉);
  • 确定性算法:PyTorch 设 torch.backends.cudnn.deterministic = True 并 use_deterministic_algorithms;
  • 浮点差异:跨架构/跨 MPI 布局浮点结果可能不同——科学论文应报告"结果在容差内一致",而非绝对一致;
  • MPI 归约顺序:影响全局规约的浮点结果,可固定归约树或记录差异范围。

实验结果 ​

以下为可复现工作流建设的工程观察(非虚构基准,数值因集群而异):

  1. 环境复现:容器化后,同一工作流在 3 台不同配置节点上运行,GROMACS 结果偏差从"肉眼可见"收敛到数值容差内(<1e-4 相对误差,源于浮点);
  2. 数据追溯:DVC 接入后,发现历史论文图实际用的数据集版本与记录不符(版本漂移),修正后结论依然成立,但过程可复现了;
  3. 种子固化:补上 Dataloader worker 种子后,同参数训练两次的验证曲线差异从明显波动收敛到噪声级;
  4. 溯源成本:provenance.json 单条约 KB 级,运行开销可忽略,但对"结论能否成立"的排查效率提升显著(定位数据/环境/参数问题从小时级降到分钟级)。

⚠️ 以上为工程经验总结,用于设计方向参考;具体数字需在目标集群上复测。

工程启示 ​

AI4S 可复现工作流落地清单:

  • [ ] 数据:DVC/LFS 版本化,版本绑定代码提交;预处理脚本入 Git;哈希校验拦截误改;
  • [ ] 环境:不可变容器镜像(HPC 用 Apptainer);依赖全锁定(哈希级);GPU 驱动版本记录;
  • [ ] 计算:全种子固化(含 Dataloader worker);确定性算法开关;MPI 归约差异记录;
  • [ ] 溯源:每个实验输出 provenance.json(输入哈希/镜像指纹/参数/输出哈希);结果与溯源同目录保存;
  • [ ] 流水线:Snakemake/Nextflow 编排依赖链,--containerize 一步把整个流程容器化;
  • [ ] 发布规范:论文/报告附带镜像 hash + 数据版本 + provenance 链接——"可复现"从口号变成交付物。

至此,AI×Science 章前四篇"工程路线"完成。下一篇预告:《AI 驱动的分子动力学:ML 势函数训练与推理》,进入具体科学应用。

AI-HPC 智算超算专家 · Contact: openaihpc@gmail.com