022

Uni-Mol 教程:分子表征、性质预测与 Docking 的统一框架

Uni-Mol 把分子表征、性质预测与对接统一在一个框架里。这篇给出各任务的使用方式与评估建议。

Uni-Mol 提供了一套统一的接口:同一个预训练模型既能给出分子表示、也能做性质预测、还能做对接。配套的 unimol_tools 让使用门槛大幅降低。

三类用法

用法 输入 输出 典型场景
表示提取 SMILES 分子/原子级向量 作为下游模型的特征
性质预测 SMILES + 标签 微调后的预测模型 QSAR、ADMET
对接 蛋白口袋 + 配体 结合姿势 104《Uni-Mol Docking》

表示提取

pip install unimol_tools

from unimol_tools import UniMolRepr

clf = UniMolRepr(data_type="molecule", remove_hs=False)
smiles = ["CC(=O)Nc1ccc(O)cc1", "CCO", "c1ccccc1"]
reprs = clf.get_repr(smiles, return_atomic_reprs=True)

X = reprs["cls_repr"]              # 分子级表示
atomic = reprs["atomic_reprs"]     # 原子级表示
print(len(X), len(X[0]))

# ---- 用于下游任务 ----
import numpy as np
import lightgbm as lgb

X = np.array(X)
model = lgb.LGBMRegressor(n_estimators=800, verbose=-1)
model.fit(X_train, y_train)

# 【最实用的做法:与其它特征拼接】
from rdkit import Chem
from rdkit.Chem import rdFingerprintGenerator, Descriptors

gen = rdFingerprintGenerator.GetMorganGenerator(radius=2, fpSize=2048)

def combined_features(smiles_list):
    unimol = np.array(UniMolRepr(data_type="molecule")
                      .get_repr(smiles_list)["cls_repr"])
    ecfp, desc = [], []
    for s in smiles_list:
        m = Chem.MolFromSmiles(s)
        ecfp.append(np.array(gen.GetFingerprint(m)) if m else np.zeros(2048))
        desc.append([Descriptors.MolWt(m), Descriptors.MolLogP(m),
                     Descriptors.TPSA(m), Descriptors.NumHDonors(m),
                     Descriptors.NumHAcceptors(m),
                     Descriptors.NumRotatableBonds(m)] if m else [0] * 6)
    return np.hstack([unimol, np.array(ecfp), np.array(desc)])

# 【为什么拼接常常更好】:
#   不同表示捕捉不同的信息
#   Uni-Mol: 三维环境;ECFP: 子结构;
#   描述符: 全局性质
#   → 交给树模型自己选
#   → 成本低(表示只需算一次)

性质预测的微调

from unimol_tools import MolTrain, MolPredict

# train.csv 需要有 SMILES 列与目标列
clf = MolTrain(
    task="regression",             # 或 classification / multiclass
    data_type="molecule",
    epochs=20,
    learning_rate=1e-4,
    batch_size=16,
    early_stopping=5,
    metrics="rmse",
    split="scaffold",              # 【务必用骨架划分,见 051】
    save_path="./exp",
    smiles_col="SMILES",
    target_cols=["TARGET"],
)
clf.fit(data="train.csv")

# 预测
predictor = MolPredict(load_model="./exp")
y_pred = predictor.predict(data="test.csv")

# 【必做的对照实验】:
#   同样的数据、同样的划分,
#   用 ECFP + LightGBM 跑一遍
#   → 【如果 Uni-Mol 打不过它,就用基线】
#
#   典型情况:
#     数据 < 1000    基线常常更好
#     数据 1000~5000 各有胜负
#     数据 > 5000    Uni-Mol 可能有优势
#     依赖三维的性质 Uni-Mol 优势更明显(见 142)

# 【多种子评估】:
import numpy as np
scores = []
for seed in range(5):
    clf = MolTrain(task="regression", split="scaffold", seed=seed, ...)
    clf.fit(data="train.csv")
    scores.append(evaluate(clf, test_data))
print(f"RMSE = {np.mean(scores):.3f} ± {np.std(scores):.3f}")
# 【提升必须超过 2 倍标准差才算显著】

Uni-Mol Docking

# Uni-Mol Docking V2 相对 V1 大幅提升了物理有效性
#   → 加入了物理约束损失与几何精修(见 104)

# 使用(具体接口以官方文档为准):
#   输入:蛋白口袋(PDB)+ 配体(SDF/SMILES)
#   输出:预测的结合姿势
#
# 【与传统对接的定位差异】:
#   速度:Uni-Mol Docking 更快(GPU)
#   物理有效性:V2 有明显改善但仍需检查
#   亲和力:不提供(与所有此类方法一样)
#
# 【必需的后处理】(与所有深度学习对接方法一样):
#   1) PoseBusters 物理检查(见 096)
#   2) smina --minimize 局部优化(见 100)
#   3) smina --score_only 独立打分
#   4) 相互作用核对(见 108)
#   5) 与 Vina/GNINA 交叉验证(见 346)

# 【在线体验】:
#   Bohrium 平台提供了 Uni-Mol Docking 的在线服务(见 294)
#   → 适合快速试用,不适合批量与敏感数据

使用中的注意事项

  • 三维模型对构象敏感Uni-Mol 需要三维构象作为输入,而构象生成方式会影响结果——必须固定构象生成流程(工具、参数、随机种子),否则结果不可复现(见 049《构象生成入门》);
  • 计算成本:比二维模型慢数倍,大规模筛选时是实际约束;
  • 预训练数据的重叠测试集分子可能已在预训练数据中——评估时应检查;
  • 输入质量:质子化态、立体化学要正确;
  • 版本固定:不同版本的模型权重与接口可能不同。

什么时候用 Uni-Mol

场景 建议
小数据(< 1000)的性质预测 先用 ECFP + LightGBM
依赖三维结构的性质 Uni-Mol 有优势
作为额外特征拼接 推荐——成本低收益稳
大规模筛选 考虑速度成本
对接 与 Vina/GNINA 对比后决定
需要原子级表示 Uni-Mol 提供

关键要点

  • 把 Uni-Mol 表示与 ECFP、描述符拼接是成本最低、收益最稳的用法;
  • 微调时必须用骨架划分并与 ECFP + LightGBM 基线比较
  • 三维模型对构象敏感——必须固定构象生成流程,否则结果不可复现;
  • Docking V2 的物理有效性明显改善,但后处理检查仍不可省

延伸资源