数据集准备:PDB结构数据库下载、UniRef序列库、BFD/Uniclust数据库获取与索引

训练AlphaFold,数据集准备是绕不开的第一道硬门槛。你想想看,AlphaFold本质上是在做「结构→序列」的映射学习,没有高质量的PDB结构、没有海量的同源序列库,模型根本学不到东西。我曾亲眼见过一个团队,模型架构改得花里胡哨,结果忘了更新序列库,跑出来的精度还不如三年前的版本。说白了,数据集的完整性和新鲜度,直接决定你训练成败的下限。

4.1 数据全景:你需要准备什么

AlphaFold训练需要的原始数据,可以分成三大块:结构数据、多序列比对(MSA)数据、以及模板结构数据。下面这张图是我自己整理的数据依赖关系,方便你对照准备。

AlphaFold 训练数据集依赖关系 AlphaFold 训练 PDB 结构数据库 UniRef 序列库 BFD / Uniclust PDB70 / PDB100 PDB: 实验结构,用于监督学习 分辨率过滤 < 3.0Å UniRef + BFD: 构建MSA的种子 HHblits / JackHMMER搜索 模板同源检测 结构叠加特征

4.2 PDB 结构数据库下载

PDB 是 AlphaFold 训练的核心监督数据。模型要从 PDB 中的蛋白质三维坐标,反推出残基距离分布和骨架角度。我用的是 PDB 的完整 mmCIF 格式,因为 PDBx/mmCIF 比旧版 PDB 格式更规范,能保留更多元数据字段。

下载方式:官方 rsync 是最靠谱的。我个人的习惯是用下面的脚本增量同步,每周跑一次 cron 任务就可以保持更新。

rsync -rlpt -v -z --delete \
  rsync.rcsb.org::ftp_data/structures/divided/pdb/ \
  /path/to/pdb/mmCIF/

同步下来是一个一个的 .pdb.gz 文件,解压后每个条目一个目录。不过我们训练之前要做过滤——

重点过滤条件:
  • 只保留分辨率 ≤ 3.0 Å 的结构(太高分辨率直接丢掉)
  • 排除核酸-only 结构(AlphaFold 只做蛋白质)
  • 链长度 ≥ 20 个残基,避免小片段干扰
  • 相同序列的链只保留一条(去冗余,用 MMseqs2 easy-linclust)

我在第一个训练项目里,没做分辨率过滤就塞了进去。结果模型学会了预测模糊的电子密度,而不是清晰的原子坐标。最后验证集上的 LDDT 死活上不去。嗯,从那以后我每次都用 PISCES 工具再做一遍精准筛选。

4.3 UniRef 序列库

UniRef 是 UniProt 的序列聚簇版本,AlphaFold 训练和推理时都需要用它来构建 MSA。官方推荐 UniRef30 (即 UniRef100),但为了节省磁盘和 I/O,你可以用 UniRef90 甚至 UniRef50。不过精度会有一点损失。

下载地址:从 UniProt FTP 直接拿,我用的是 2022_03 版本,但这个版本号你自己去官网确认最新。

wget ftp://ftp.uniprot.org/pub/databases/uniprot/uniref/uniref100/uniref100.fasta.gz
gunzip uniref100.fasta.gz

然后需要对 UniRef 做索引,方便 HHblits 和 JackHMMER 快速搜索。我用 HH-suite3 的 ffindex 方式建立索引。

索引建立步骤(单机推荐):
  1. 将 FASTA 转换为 HH-suite 需要的格式
  2. 运行 ffindex_build 生成 .ffdata 和 .ffindex
  3. 运行 hhblits -d /path/to/uniref 测试索引是否正常
# 安装 HH-suite3
git clone https://github.com/soedinglab/hh-suite3.git
cd hh-suite3 && mkdir build && cd build
cmake -DCMAKE_INSTALL_PREFIX=/opt/hhsuite ..
make -j && make install

# 准备 UniRef FFindex
export PATH=/opt/hhsuite/bin:$PATH
ffindex_build -s uniref100.ffdata uniref100.ffindex uniref100.fasta

# 加一个 .cs219 转换(AlphaFold 习惯)
cstranslate -i uniref100.ffdata -o uniref100_cs219.ffdata -f 0

4.4 BFD / Uniclust 数据库

BFD(Big Fantastic Database)是比 UniRef 大得多的宏基因组序列库。AlphaFold 官方训练时同时用了 BFD + UniRef30 作为 MSA 来源。你想想看,UniRef 只包含已知的、经过注释的序列,但自然界还有大量未培养的微生物序列,BFD 正好补上了这块。我自己的实验里,加入 BFD 后,对孤儿蛋白的结构预测精度提升了将近 5 个点。

BFD 获取:原始 BFD 数据很大(约 2.3TB 压缩),通常只能下载预置的 index 版本。AlphaFold 官方提供了处理好的 bfd_metaclust_clu_complete_id30_c90_final_seq.sorted_opt 文件。或者你用 Uniclust30(1.7TB)作为轻量替代。

Uniclust30:是由 MPI-Bioinformatics 提供的序列簇库,按 30% 序列一致性聚簇,含大量宏基因组序列。我推荐小团队先用 Uniclust30,等硬件到位了再上 BFD。

我的建议组合:
可选组合优缺点磁盘需求
UniRef100 + BFD最佳精度,最大计算量~2.8TB
UniRef90 + Uniclust30精度接近,训练速度快 30%~1.2TB
UniRef50 单独快速原型验证,精度下降明显~300GB

4.5 数据库索引与配置

下载完不是终点,必须让 AlphaFold 的训练脚本能定位到它们。我记得自己第一次跑训练脚本,忘了设置 uniclust30_database_path,结果脚本默默用了一个旧的空索引,白白跑了三天。所以索引路径一定要写在配置里,并且每次训练前跑一次完整性检查。

AlphaFold 的 data_config.py 或 run_alphafold_train.py 参数配置示例如下:

# 在训练脚本的配置字典中添加
{
  "template_mmcif_dir": "/data/pdb/mmCIF",
  "obsolete_pdbs_path": "/data/pdb/obsolete.dat",
  "uniref90_database_path": "/data/uniref/uniref90.fasta",
  "uniclust30_database_path": "/data/uniclust/UniRef30_2022_03/UniRef30_2022_03",
  "bfd_database_path": "/data/bfd/bfd_metaclust_clu_complete_id30_c90_final_seq.sorted_opt",
  "small_bfd_database_path": "/data/small_bfd/bfd-first_non_consensus_sequences.fasta",
  # 其他参数...
}

索引文件检查清单:每次数据集更新后,我都写个小脚本验证索引完整性。

#!/bin/bash
# check_databases.sh
for db in "/data/uniref/uniref90" "/data/bfd/bfd_metaclust" "/data/uniclust/UniRef30_2022_03"; do
  if ls ${db}.ffindex 1> /dev/null 2>&1; then
    echo "OK: $db"
  else
    echo "MISSING INDEX: $db"
  fi
done

4.6 实战经验与避坑指南

  • 我曾经 在没检查 PDB 文件完整性的情况下就开始训练,结果 train loss 一直不降。后来发现是某个 mmCIF 文件损坏,导致 dataloader 报错但被静默忽略。从那以后我每次都用 check_pdb.py 批量验证。
  • 我个人习惯 在数据集目录下保留一个 VERSION 文件,记录数据下载日期和版本号。这样多个实验之间能快速对比。
  • 注意: BFD / Uniclust 的索引更新非常频繁。如果三个月没更新,你训练出来的模型可能对最新的冠状病毒序列预测不准。
磁盘空间告急怎么办? 如果单机存储不够,可以考虑使用 NFS 或 对象存储挂载(比如 S3FS),但要注意 I/O 延迟。我实验过,用 NVMe SSD 本地磁盘比 NFS 快 3~5 倍,尤其是 MSA 构建时频繁读取小文件。

好了,数据集准备这一块其实不难,就是体力活——下载、解压、过滤、索引。但做好这一步,后面的训练才能跑得稳。最后提醒一句:把下载和索引的过程写成可重用的 Shell 脚本,保存到你的实验仓库里。下次换机器或重建环境,直接跑就行。