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 的物理有效性明显改善,但后处理检查仍不可省。
延伸资源
- Uni-Mol 论文:142《Uni-Mol 论文精读》;Uni-Mol Docking:104《Uni-Mol Docking》;工具部署:187《Uni-Mol》;
- Chemprop:131《Chemprop / D-MPNN 论文精读》;构象生成:049《构象生成入门》;深势科技:316《DP Technology 深势科技》。