025

Hugging Face 生物模型区:哪些模型值得药物研发人员关注

Hugging Face 上有大量生物与化学模型。这篇给出筛选值得关注的模型的方法与使用注意事项。

Hugging Face 上托管了大量生物与化学领域的模型。问题不是找不到模型,而是模型太多、质量参差——需要一套筛选方法。

值得关注的模型类别

类别 代表 用途
蛋白语言模型 ESM-2、ProtT5、ProtBERT 蛋白表示与性质预测(见 143《ESM-2 论文精读》144《ProtT5 论文精读》
分子语言模型 ChemBERTa、MolFormer 分子表示(见 145《ChemBERTa 论文精读》147《MolFormer 论文精读》
结构预测 ESMFold 116《ESMFold 论文精读》
分子生成 各类 SMILES 生成模型 158《AI 分子生成模型》
反应预测 Molecular Transformer 类 逆合成
单细胞 scGPT、Geneformer 组学分析
文本挖掘 BioBERT、PubMedBERT、SciBERT 文献信息抽取(见 163《大语言模型与药物发现》

筛选模型的方法

# 【看模型页面的哪些信息】
#
# 1) 【下载量与点赞数】
#    高下载量说明有人在用
#    → 但也可能只是名字响亮
#
# 2) 【是否有对应的论文】
#    有论文 → 至少经过某种形式的审阅
#    没有 → 需要更谨慎
#
# 3) 【模型卡的完整度】
#    □ 训练数据说明清楚吗?
#    □ 【训练数据的时间范围?】
#      → 判断是否与你的测试集重叠
#    □ 评测结果与划分方式?
#    □ 已知的局限性?
#    □ 【许可是什么?】
#
#    【模型卡写得越详细,通常质量越高】
#
# 4) 【最近更新时间】
#    长期未更新的模型可能与新版库不兼容
#
# 5) 【社区讨论区】
#    □ 有人报告问题吗?
#    □ 作者响应吗?
#    → 【这里常常比模型卡更能说明真实情况】
#
# 6) 【是否有官方组织维护】
#    facebook/esm2_*        Meta 官方
#    Rostlab/prot_*         ProtTrans 团队
#    DeepChem/ChemBERTa-*   DeepChem 团队
#    ibm/MoLFormer-*        IBM
#    → 【官方组织的模型通常更可靠】

# 【最重要的一条】:
#   【在自己的数据上验证】
#   → 排行榜与下载量都不能替代这一步

使用的通用模板

from transformers import AutoTokenizer, AutoModel
import torch
import numpy as np

def load_and_embed(model_name, sequences, batch_size=16,
                   max_length=512, trust_remote_code=False):
    """通用的表示提取模板"""
    tokenizer = AutoTokenizer.from_pretrained(
        model_name, trust_remote_code=trust_remote_code)
    model = AutoModel.from_pretrained(
        model_name, trust_remote_code=trust_remote_code).eval()
    if torch.cuda.is_available():
        model = model.cuda()

    out = []
    for i in range(0, len(sequences), batch_size):
        batch = sequences[i:i + batch_size]
        enc = tokenizer(batch, padding=True, truncation=True,
                        max_length=max_length, return_tensors="pt")
        if torch.cuda.is_available():
            enc = {k: v.cuda() for k, v in enc.items()}
        with torch.no_grad():
            h = model(**enc).last_hidden_state
        # 【正确的平均池化:用 attention_mask 排除 padding】
        mask = enc["attention_mask"].unsqueeze(-1).float()
        pooled = (h * mask).sum(1) / mask.sum(1)
        out.append(pooled.cpu().numpy())
    return np.vstack(out)

# 【常见错误】:
#   1) 平均池化时把 padding 位置也算进去
#      → 表示被稀释,长度不同的序列不可比
#   2) 【蛋白模型的输入格式】
#      ProtT5 要求氨基酸间加空格(见 144)
#      ESM 不需要
#      → 【格式错了结果完全无意义,但不会报错】
#   3) 忘记 model.eval()
#      → dropout 仍然激活,结果有随机性
#   4) trust_remote_code=True 的安全风险
#      → 会执行仓库中的代码,只对可信来源使用

评估一个模型是否值得用

# 【标准流程】
#
# 第 1 步:【建立基线】
#   蛋白任务:氨基酸组成 + 理化性质
#   分子任务:ECFP + 描述符
#   模型:LightGBM
#   → 【几分钟就能跑完】
#
# 第 2 步:【提取预训练表示】
#   冻结模型,只提取表示
#   → 喂给同样的 LightGBM
#
# 第 3 步:【同条件比较】
#   同样的数据划分(骨架/时间划分)
#   同样的下游模型
#   多个随机种子
#
# 第 4 步:【判断】
#   提升 > 2 倍标准差 → 有价值
#   否则 → 【用基线,省下部署成本】
#
# 第 5 步:【考虑拼接】
#   把预训练表示与手工特征拼接
#   → 常常比单独用任一种都好
#
# 【一个实用的观察】:
#   多数情况下,预训练表示的价值
#   在【数据量少】时最明显
#   → 数据量 < 500 时值得试
#   → 数据量 > 5000 时收益递减

import numpy as np
from sklearn.model_selection import cross_val_score
import lightgbm as lgb

def compare_representations(reps_dict, y, cv=5):
    """比较多种表示的效果"""
    for name, X in reps_dict.items():
        scores = []
        for seed in range(3):
            m = lgb.LGBMRegressor(n_estimators=500, random_state=seed,
                                  verbose=-1)
            s = cross_val_score(m, X, y, cv=cv,
                                scoring="neg_root_mean_squared_error")
            scores.append(-s.mean())
        print(f"{name:25s} RMSE = {np.mean(scores):.4f} ± {np.std(scores):.4f}")

# 用法:
# compare_representations({
#     "ECFP+描述符(基线)": X_baseline,
#     "ChemBERTa": X_chemberta,
#     "MolFormer": X_molformer,
#     "拼接": np.hstack([X_baseline, X_chemberta]),
# }, y)

使用中的注意事项

  • 数据泄漏的风险预训练模型可能见过你的测试集分子——尤其是从公开数据库来的分子。评估时应检查;
  • 许可差异很大:从完全开放到禁止商用都有,企业使用前必须确认
  • 模型体积与推理成本:大模型需要 GPU,部署复杂度显著增加;
  • 版本固定:模型可能被更新,revision 参数固定到具体 commit 保证可复现;
  • 安全性trust_remote_code=True 会执行仓库中的代码——只对可信来源使用
  • 不同层的表示差异大:应该在验证集上比较不同层(见 144《ProtT5 论文精读》)。

关键要点

  • 优先选官方组织维护、有论文、模型卡完整的模型;讨论区常比模型卡更说明问题;
  • 平均池化必须用 attention_mask 排除 padding;ProtT5 要求氨基酸间加空格;
  • 预训练表示的价值在数据量少时最明显,数据多时收益递减;
  • revision 固定模型版本;trust_remote_code=True 只对可信来源使用。

延伸资源