2. 蛋白序列数据获取与预处理工程

蛋白序列语言模型的训练效果,很大程度上取决于输入语料的质量与一致性。UniProt、Pfam、PDB 是三类最常用的数据源,但它们的数据形态、覆盖范围和用途差异明显:UniProt 提供大规模氨基酸序列与注释,Pfam 提供基于隐马尔可夫模型的家族划分与结构域边界,PDB 提供实验解析的三维结构及其对应序列。工程上通常不是“选一个”,而是按训练目标组合使用,并在接入阶段就统一标识、去重和过滤规则。

数据源接入:先明确“要什么”,再决定“怎么取”

UniProt 的接入一般通过 REST API 或 FTP 批量下载。若目标是构建通用蛋白语言模型语料,推荐使用 UniProtKB/Swiss-Prot(人工审阅、质量高)与 UniProtKB/TrEMBL(自动注释、规模大)的组合。以 Swiss-Prot 为例,可通过 https://rest.uniprot.org/uniprotkb/stream?query=reviewed:true&format=fasta 流式获取 FASTA;若需注释字段,则改用 format=tsv 并指定 fields=accession,sequence,length,organism,reviewed 等列。Pfam 通常下载 Pfam-A.hmm 与 Pfam-A.seed,前者用于 hmmscan 扫描结构域,后者用于家族序列比对。PDB 则通过 https://files.rcsb.org/ 获取 pdb_seqres.txt 或按条目下载 .cif,再用 gemmi、Bio.PDB 提取链序列。

接入阶段最容易埋下隐患的是标识体系不统一:UniProt 用 accession(如 P12345),PDB 用 4HHB_A,Pfam 用 PF00069。建议在入库时建立一张映射表,至少保留 source、source_id、uniprot_accession、pdb_id、pfam_id、sequence_hash 六个字段,后续所有清洗与版本管理都围绕这张表进行。

序列清洗:从原始记录到可训练序列

原始 FASTA 中常见的问题包括:小写字母、X/B/Z/U/O 等非标准氨基酸、* 终止符、空白行、重复 header、以及长度极端序列。清洗流程建议按以下顺序执行,避免顺序颠倒导致误删:

  1. 去空白与统一大小写:去除行首尾空白,将序列统一转为大写。
  2. 非标准氨基酸处理:U(硒代半胱氨酸)和 O(吡咯赖氨酸)在部分物种中具有生物学意义,可保留或映射为 C/K;B、Z、X 通常视为未知,建议直接剔除或截断所在区域。
  3. 终止符与非法字符:删除 *、-、数字及标点;若序列中出现内部 *,说明该条目可能为多肽链拼接,应整条丢弃。
  4. 长度过滤:语言模型通常设置 min_len=50、max_len=2000。过短序列信息量不足,过长序列会显著增加显存与注意力计算成本;超过上限的可截断或分块。
  5. 去冗余:先用精确哈希(如 SHA-256)去除完全重复序列;再用 CD-HIT 或 MMseqs2 以 identity=0.9、coverage=0.8 聚类,每个簇保留一条代表序列。若训练集面向家族泛化,可进一步降到 identity=0.5。
去冗余阈值不是越低越好。阈值过低会丢失家族内多样性,导致模型对同源蛋白的表示过于粗糙;阈值过高则保留大量近重复序列,使训练集分布偏斜。建议先用 identity=0.9 做基础去重,再根据验证集表现决定是否收紧。

数据集版本管理:让每次训练可追溯

预处理不是一次性动作,而是随数据源更新反复执行的过程。建议采用“原始层—清洗层—训练层”三层目录,并用 DVC 或 Git LFS 管理大文件,用 manifest.json 记录每层的来源、参数与统计量。一个可用的 manifest 示例:

{
  "version": "2025-03-01",
  "sources": ["uniprot_sprot", "pfam_a", "pdb_seqres"],
  "filters": {"min_len": 50, "max_len": 2000, "allowed_aa": "ACDEFGHIKLMNPQRSTVWY"},
  "dedup": {"method": "mmseqs2", "identity": 0.9, "coverage": 0.8},
  "counts": {"raw": 572000, "after_clean": 548300, "after_dedup": 312400},
  "sequence_hash": "sha256:9f2c..."
}

每次重新生成数据集时,版本号、过滤参数和最终序列哈希必须同步更新。这样当模型指标异常时,可以快速定位是数据源变化、过滤阈值调整还是去冗余策略改动导致的。

蛋白序列数据接入与预处理流水线 UniProt Swiss-Prot / TrEMBL FASTA / TSV Pfam Pfam-A.hmm / seed 家族与结构域 PDB pdb_seqres / .cif 实验结构序列 标识映射表 accession / pdb_id pfam_id / seq_hash 序列清洗与过滤 大小写统一 去空白 / 转大写 非标准氨基酸 U/O 保留,B/Z/X 剔除 长度过滤 50 ≤ len ≤ 2000 精确去重 SHA-256 哈希 聚类去冗余 MMseqs2 id=0.9 cov=0.8 数据集版本管理(manifest.json) 原始层 raw 572,000 条 来源与下载日期 清洗层 clean 548,300 条 过滤参数与统计 训练层 train 312,400 条 去冗余后 + 哈希 版本号、过滤参数与序列哈希同步更新,保证每次训练可追溯

完成上述流程后,建议对最终训练集做一次分布检查:统计序列长度直方图、氨基酸频率、以及各数据源占比。若发现某类氨基酸频率异常偏高(例如 X 残留),说明清洗规则仍有漏洞;若 Swiss-Prot 与 TrEMBL 比例严重失衡,则需在采样阶段做加权。只有数据层稳定,后续的 tokenizer 训练与模型预训练才有可靠基础。