在化学信息学和计算化学领域,数据驱动模型正在加速改变分子设计与合成路径规划的流程。但很多模型在公开基准上表现很好,进入真实实验室却频频失效。本文从 onepot-Bench 0 出发,围绕“实验室感知”这一核心理念,拆解计算化学基准测试的设计思路、评估维度与落地避坑要点,并给出可直接运行的代码示例与工程建议。
1. 背景与核心概念
1.1 计算化学基准测试为什么重要
在机器学习加速化学研发的今天,基准测试已经不只是学术榜单那么简单。无论是逆合成分析、反应条件预测、一锅法反应规划,还是分子性质预测,研究人员都需要一套统一的测试标准,用来回答一个基本问题:这个模型到底行不行?
传统基准测试的做法,通常是收集大量公开反应数据集,切分成训练集、验证集和测试集,然后让模型在测试集上给出预测结果,再统计准确率。这种方式在数据层面很干净,却忽略了一个关键事实:化学反应发生在真实实验室里,而不是字符串或图结构里。一个在标准数据集上准确率很高的模型,可能完全无法处理实验室中常见的底物浓度差异、溶剂纯度波动、温度控制偏差等现实约束。
正是这种“数据干净、现实复杂”的矛盾,催生了所谓实验室感知(lab-aware)基准测试的研究方向。onepot-Bench 0 就是这类思路下的一个具体实践。
1.2 onepot-Bench 0 解决什么问题
从名称来看,onepot-Bench 0 面向的核心场景是“一锅法反应”的建模与评估。一锅法反应在药物合成和精细化工中非常常见,它的特点是:多个化学转化在同一容器中连续进行,中间步骤不进行分离纯化。这种策略能显著减少操作步骤、降低物料损耗、提升总产率,但也给计算模型带来了额外挑战。
传统基准任务通常把反应视为“一步变换”,输入反应物和试剂,输出产物。而一锅法场景要求模型在更长的决策序列上做预测,不仅需要判断每一步的化学可行性,还要考虑步骤之间的兼容性,比如上一阶段的催化剂是否会影响下一步反应、中间体的稳定性是否足够支撑到下一步操作。
onepot-Bench 0 的定位,就是为这类序列决策型化学任务提供一个更贴近实验现实、也更能暴露模型短板的评估框架。
1.3 lab-aware 的含义拆解
所谓 lab-aware,直译是“实验室感知”,它强调基准测试的设计不能脱离实验过程的真实约束。对比传统基准,它有以下几个明显差异:
- 输入不仅包含分子结构,还包含试剂、溶剂、温度、时间、催化剂等实验条件。
- 输出不只是一步反应的预测结果,而是覆盖完整操作序列的决策路径。
- 评估指标不仅看化学结构是否合理,还要看整体方案是否具备实际可操作性。
- 数据划分需要避免泄漏,即同一反应类型或同一反应底物不能同时出现在训练集和测试集中。
换句话说,lab-aware 基准测试试图回答的不是“模型能否拟合已知数据”,而是“模型给出的结果能否在实验室里被真正执行”。
2. 基准设计与数据体系
2.1 一锅法反应建模的难点
一锅法反应建模相比常规反应预测,存在三个层面的难点。
第一,状态空间的累积误差。在多步反应中,每一步模型的预测误差都会向后传递。如果第一步预测的中间体就不准确,后续所有步骤的预测都会失去意义。传统基准测试通常只评估单步预测,无法体现这种误差传播效应。
第二,条件变量的相互作用。一锅法反应中,试剂、溶剂和催化剂的选择往往互相制约。比如某个碱性条件有利第一步反应,但会抑制第二步反应的催化剂活性。模型需要学习这些跨步骤的相互依赖关系,而普通反应数据集很难提供足够的标注信息。
第三,评价指标的片面性。只看产物结构是否正确,会忽略很多实际因素:总步数是否最短?中间体是否需要极端条件?催化剂是否昂贵?这些都会影响一锅法路线在真实工业场景中的可行性。
2.2 基准数据集的构建原则
onepot-Bench 0 在数据集构建上,应该有意识地与普通反应数据库区分开。参考当前计算化学基准测试的主流做法,其数据构建通常遵循以下几个原则:
- 从公开反应数据库中筛选包含多步连续操作、且明确标注“一锅法”或“one-pot”的反应记录。
- 对反应条件字段进行结构化解析,统一溶剂、试剂、催化剂等实体的表示方式。
- 使用标准化分子表示,如 SMILES、InChI 或分子指纹,并在训练测试划分时避免结构相似性泄漏。
- 引入实验可操作性标注,例如反应时间、温度区间、是否需要惰性气体保护等。
这些原则背后的核心思想是:基准测试不应该只服务算法的性能比拼,更要反馈到真实实验设计中去,帮助化学家判断哪些计算结果是值得尝试的。
2.3 数据划分与泄漏控制
数据泄漏是化学机器学习基准测试里最容易踩的坑。很多模型在测试集上分数很高,训练测试数据之间存在明显的分子结构重合,测试成绩自然虚高。真实场景中,我们需要面对的是从未见过的新分子、新反应条件组合。
因此,在 onepot-Bench 0 这样的基准体系中,数据划分至少要考虑以下两个维度:
- 结构相似性划分:根据分子骨架或者指纹相似度将数据分成不重叠的簇,保证同一骨架的分子不会同时出现在训练集和测试集中。
- 反应类型划分:同一类反应在不同条件下可能表现出很大差异,划分时应该避免同一反应类型的数据同时出现在训练和测试中,否则模型只需要记忆模板就能得高分。
实际落地时,这两种划分往往结合使用。先按反应类型分组,再对组内分子做相似度聚类,最终实现更严格的数据隔离。
3. 环境准备与实验工具链
3.1 计算环境推荐
无论你是初次接触计算化学基准测试,还是在已有项目中引入 lab-aware 评估流程,环境配置都应该尽量做到清晰、可复现。下面是一个常见的实验环境组合,实际操作时请结合团队基础设施调整版本。
- 操作系统:Linux(Ubuntu 20.04 / 22.04)或 Windows 10 以上
- Python 版本:3.8 以上,推荐 3.10
- 分子处理库:RDKit 2023.9 或更高版本
- 机器学习框架:PyTorch 2.x 或 TensorFlow 2.x
- 数据科学库:pandas、numpy、scikit-learn
- 可视化工具:matplotlib、seaborn(用于结果分析)
以上版本并非固定要求,如果使用 conda 管理环境,建议直接创建一个独立虚拟环境,避免与已有项目冲突。
3.2 安装核心依赖
这里给出一个基于 conda 和 pip 的安装流程。假设你已经安装了 conda,可以按下面步骤操作:
conda create -n onepot-bench python=3.10 -y conda activate onepot-bench pip install rdkit pandas numpy scikit-learn matplotlib pip install torch --index-url https://download.pytorch.org/whl/cu118PyTorch 的安装命令需要根据你的 CUDA 版本选择,如果只做 CPU 推理,可以去掉 index-url 参数,直接安装 CPU 版本。RDKit 也可以通过 conda 安装:
conda install -c conda-forge rdkit -y安装完成后,可以用下面的命令验证环境是否正常:
import rdkit from rdkit import Chem mol = Chem.MolFromSmiles('c1ccccc1') print(mol.GetNumAtoms())如果能输出 6,说明 RDKit 安装正常。
3.3 项目目录结构
为了让实验代码清晰可维护,建议采用下面的项目目录结构:
onepot-bench-practice/ ├── data/ │ ├── raw/ │ └── processed/ ├── src/ │ ├── data_preprocessing.py │ ├── evaluator.py │ ├── baselines.py │ └── utils.py ├── results/ │ ├── logs/ │ └── metrics/ ├── tests/ │ └── test_evaluator.py └── README.md这样的目录结构可以很好地区分原始数据、处理逻辑、评估代码和实验结果,方便后续复现和团队协作。
4. 数据集构建与预处理实战
4.1 数据格式约定
在 onepot-Bench 0 的基准框架下,一条完整的反应记录通常包含以下核心字段:
reaction_id:反应唯一标识reactants:反应物 SMILES,多组分用.分隔reagents:试剂 SMILES,多组分用.分隔products:产物 SMILESsolvents:溶剂名称或 SMILEStemperature:反应温度(摄氏度)time:反应时长catalyst:催化剂信息steps:步骤数量,一锅法反应中通常大于 1step_details:分步描述,JSON 结构,包含每一步的反应物、试剂、条件等
实际数据集可能来自不同来源,字段命名会有差异,但上述字段基本覆盖了一锅法反应建模所需的核心信息。
4.2 分子标准化处理
分子结构标准化是预处理阶段最重要的一步。不同数据库对同一分子的 SMILES 写法可能不同,如果不做标准化,会导致数据稀疏和模型学习困难。下面是一段基于 RDKit 的标准化函数:
from rdkit import Chem from rdkit.Chem import rdMolDescriptors def standardize_smiles(smiles): """ 对 SMILES 字符串进行标准化,包括去盐、去溶剂、规范连接表。 参数: smiles: 原始 SMILES 字符串 返回: 标准化后的 SMILES 字符串 """ if smiles is None: return None mol = Chem.MolFromSmiles(smiles) if mol is None: return None # 去掉盐和溶剂分子,保留主成分 mol = Chem.RemoveHs(mol) # 规范化并返回 canonical SMILES canonical_smiles = Chem.MolToSmiles(mol, canonical=True) return canonical_smiles使用这个函数时,需要注意:RemoveHs只会移除显式氢,并重新计算化合价;对于包含配位键或复杂金属有机物的分子,RDKit 的标准解析可能不完整,建议在预处理阶段增加错误捕获和日志记录。
4.3 一锅法序列切分
一锅法反应的关键特征是分步连续操作。在构建模型训练数据时,我们需要将整条反应序列切分为多个过渡态,以便模型能够逐件学习。下面是一个简化的切分逻辑:
import json def parse_step_details(step_details_str): """ 解析分步反应详情,返回结构化字典列表。 """ try: details = json.loads(step_details_str) return details except Exception as e: print(f"解析失败: {e}") return [] def split_reaction_sequence(reaction_record, max_steps=5): """ 将一条多步一锅法反应记录切分为多个逐步预测的样本。 参数: reaction_record: 原始反应记录字典 max_steps: 最大支持步骤数 返回: 逐步样本列表,每个样本包含前序状态和当前步目标 """ step_details = parse_step_details(reaction_record.get('step_details', '[]')) if len(step_details) == 0: return [] samples = [] intermediate_state = reaction_record['reactants'] for step in step_details[:max_steps]: sample = { 'current_state': intermediate_state, 'step_conditions': step.get('conditions', {}), 'target': step.get('products', '') } samples.append(sample) # 更新中间状态 intermediate_state = step.get('products', intermediate_state) return samples这段代码实现了两个关键点:一是把多步反应切分为逐步数据,二是构建了“当前状态”到“目标产物”的映射。这样处理之后,模型可以基于逐步数据进行训练,同时也保留了完整反应序列用于整体评估。
4.4 数据质量控制
数据质量直接影响基准测试的可信度。预处理时需要注意几个常见问题:
- SMILES 解析失败,说明数据源存在格式问题,需要记录并过滤。
- 反应前后原子数不守恒,说明反应信息不完整,需要人工复核。
- 同一反应在不同数据库中的表示不一致,需要通过
reaction_id或 InChIKey 去重。 - 实验条件字段缺失严重,比如没有温度或时间,需要标记为未知,不能直接填充默认值。
通过严格的数据质量控制,才能保证后续评估结果有实际参考价值。
5. 基线模型设计
5.1 基于模板的基线
在引入复杂模型之前,一个基于反应规则模板的强基线会绑定视角比较。模板类方法在有机化学领域历史悠久,通常称作反应产物预测模型。其核心思想是:从训练数据中提取反应中心并生成反应模板,推理时匹配模板并应用变换。
下面是一个简化的模板匹配思路:
def extract_reaction_template(reactant_smiles, product_smiles): """ 基于反应前后分子差异提取反应中心。 这里只做核心逻辑示意,实际项目中应使用 RDChiral 或类似工具。 """ # 解析分子 rxn = Chem.ReactionFromSmarts( f"{reactant_smiles}>>{product_smiles}" ) # 提取反应中心(伪代码,实际需用 RDChiral) template = "" return template这类方法可解释性强,但覆盖度有限。对于训练集中没有出现过的反应类型,模板法很难给出有效预测。
5.2 基于 Transformer 的序列基线
当前比较流行的做法,是将反应预测建模为 SMILES 字符串到 SMILES 字符串的序列生成任务。以分子翻译模型(Molecular Transformer)为例,它的输入是反应物 SMILES 加特殊标记,输出是产物 SMILES。
下面是一个模型调用流程的简单示意:
import torch from transformers import AutoTokenizer, AutoModelForSeq2SeqLM def load_molecular_transformer(model_name="your-model-path"): """ 加载预训练的分子翻译模型。 生产环境建议使用 Chemformer 或 MegaMolBART 等公开权重。 """ tokenizer = AutoTokenizer.from_pretrained(model_name) model = AutoModelForSeq2SeqLM.from_pretrained(model_name) return tokenizer, model def predict_product(tokenizer, model, reactants_smiles): """ 对给定反应物做产物预测。 """ # 拼接反应物输入 input_text = f"{reactants_smiles}>>" inputs = tokenizer(input_text, return_tensors="pt") with torch.no_grad(): outputs = model.generate( **inputs, max_length=512, num_beams=10, num_return_sequences=10 ) candidates = tokenizer.batch_decode(outputs, skip_special_tokens=True) return candidates实际部署时,需要根据 onepot-Bench 0 的数据格式对输入序列做适配,比如在反应物 SMILES 中加入条件前缀,使模型能够感知温度和溶剂信息。
5.3 实验室约束的解码
单纯使用 beam search 生成候选产物,不一定会考虑实验可行性。一个有效的优化手段,是在解码阶段引入约束解码,过滤掉那些使用训练集中从未出现过的极端条件组合的候选方案。比如,如果候选方案需要 300 摄氏度以上的反应条件,而数据集中的大部分反应都在 0-150 摄氏度范围内,那么这个候选就应该降低排序分数。
这个思路可以通过重写模型的得分函数实现,在 score 中加入一个条件合理性惩罚项。
6. 评估指标体系
6.1 基础准确率指标
onepot-Bench 0 的核心评估度量,仍然会包括 top-k 准确率。这个指标的含义是:模型给出的前 k 个预测中,是否包含正确的产物或正确的下一步操作。计算公式比较简单:
def top_k_accuracy(predictions, ground_truth, k=5): """ 计算 top-k 准确率。 参数: predictions: 列表,每个元素是一组候选 SMILES ground_truth: 列表,每个元素是标准答案 SMILES k: 考虑前几个候选 返回: 准确率值 """ if len(predictions) != len(ground_truth): raise ValueError("预测结果与标准答案数量不一致") correct = 0 total = len(predictions) for candidates, truth in zip(predictions, ground_truth): truth_canonical = standardize_smiles(truth) if truth_canonical is None: total -= 1 continue candidate_set = [standardize_smiles(c) for c in candidates[:k]] if truth_canonical in candidate_set: correct += 1 return correct / total if total > 0 else 0.0这里需要注意的是,与字符串精确匹配相比,化学有效性等价于等价。因为同一个产物可能有多个合法写法,所以统一先做规范的 SMILES 标准化,再比较字符串,才是可行的做法。
6.2 化学合理性指标
准确率不是唯一标准。一个预测在数学上是正确匹配,在化学上却可能完全无法反应。因此,lab-aware 基准测试还需要引入化学合理性指标。比较常见的有:
- 原子守恒率:反应前后各元素原子数是否守恒。
- 价键合理性:产物中的每个原子是否满足常见的化合价规则。
- 反应条件分布:预测结果的条件组合是否落在已有反应条件的合理区间内。
下面是一段计算原子守恒率的代码:
from rdkit.Chem import rdMolDescriptors def check_atom_conservation(reactants_smiles, products_smiles): """ 检查反应前后原子种类和数量是否一致。 """ reactants = Chem.MolFromSmiles(reactants_smiles) products = Chem.MolFromSmiles(products_smiles) if reactants is None or products is None: return False r_dict = rdMolDescriptors.CalcMolFormula(reactants) p_dict = rdMolDescriptors.CalcMolFormula(products) return r_dict == p_dict需要说明的是,不完全守恒并不一定说明反应非法,因为一锅法反应数据里有时会包含未完整标注的组成部分。因此这个指标更适合作为辅助参考。
6.3 步骤级评估与全局评估
onepot-Bench 0 的评测还应该兼顾“逐步正确率”和“整条路线成功率”。
步骤级评估关注的是模型在每一个中间步骤的预测能力,这个维度适合定位模型具体在哪一步容易出错。全局评估则关注完整反应路线的可行性,即模型是否能够生成从起始反应物到最终产物的、每一步都合理且整体一致的操作序列。
实现上,可以分别统计每个步骤的正确率,同时设定“全步正确才算这条路线成功”的严格标准。
6.4 实验可行性评估
实验可行性是整个基准测试里最核心、也最难量化的维度。一个可行的做法是构建规则集,从多个角度打分。比如,温度范围、压力要求、试剂毒性、反应时间、催化剂成本,每项都设一个合理区间。
def evaluate_experimental_feasibility(route, feasibility_rules): """ 根据可操作规则集对合成路线进行打分。 参数: route: 包含所有步骤条件信息的完整路线字典 feasibility_rules: 规则列表,每条规则是函数 返回: 总分,范围 0-1 """ total_score = 0.0 rule_num = len(feasibility_rules) if rule_num == 0: return 1.0 for rule in feasibility_rules: score = rule(route) total_score += score return total_score / rule_num这套打分机制完全可以扩展为更复杂的约束满足模型,也可以接入实验 LIMS 数据做动态校准。
7. 完整评估流程实战
7.1 测试集准备
下面我们用一个完整的示例,演示从测试集加载到评估报告生成的流程。为了方便演示,这里使用一个简化的内存数据集。
# 示例测试数据 test_records = [ { "reaction_id": "OPB00001", "reactants": "CCO.CC(=O)O", "products": "CCOC(C)=O", "temperature": "25-30", "time": "2h", "steps": 1 }, { "reaction_id": "OPB00002", "reactants": "c1ccccc1Br", "products": "c1ccccc1C#N", "reagents": "CN", "temperature": "80-100", "time": "6h", "steps": 1 } ]实际使用时,建议将数据存为 CSV 或 JSON 文件,从 data 目录读取。
7.2 定义评估器
为了方便复用,把评估逻辑封装成一个 Evaluator 类。
class OnepotEvaluator: def __init__(self, top_k_list=(1, 3, 5)): self.top_k_list = top_k_list def evaluate(self, predictions, ground_truth_records): """ 对模型预测结果进行多维度评估。 参数: predictions: 模型输出的候选列表 ground_truth_records: 标注数据 返回: 包含各项指标的字典 """ metrics = {} # 基础准确率 for k in self.top_k_list: acc = top_k_accuracy(predictions, [r['products'] for r in ground_truth_records], k=k) metrics[f'top_{k}_accuracy'] = acc # 原子守恒率 conservation_count = 0 valid_num = 0 for pred_candidates, record in zip(predictions, ground_truth_records): for candidate in pred_candidates[:1]: if check_atom_conservation(record['reactants'], candidate): conservation_count += 1 valid_num += 1 break metrics['atom_conservation_rate'] = conservation_count / valid_num if valid_num > 0 else 0.0 # 步骤成功率(单步示例,多步需要扩展) step_success = 0 for pred_candidates, record in zip(predictions, ground_truth_records): truth = standardize_smiles(record['products']) candidates = [standardize_smiles(c) for c in pred_candidates] if truth in candidates: step_success += 1 metrics['step_success_rate'] = step_success / len(ground_truth_records) return metrics这个评估器只是一个起点。真实使用时,你可以把实验可行性规则也接入进来,扩展成一个更完整的评估框架。
7.3 生成评估报告
评估结果的呈现要直观、可比较。推荐使用表格形式汇总指标,并用 matplotlib 或 seaborn 绘制指标对比图。
import json def generate_report(metrics, output_path): """ 将评估指标写入 JSON 文件,方便后续分析。 """ with open(output_path, 'w', encoding='utf-8') as f: json.dump(metrics, f, ensure_ascii=False, indent=2) for key, value in metrics.items(): print(f"{key}: {value:.4f}" if isinstance(value, float) else f"{key}: {value}")7.4 实际运行预期
如果模型是随机猜测,top-1 准确率会非常低,通常小于 1%。如果模型只是记住训练集中的所有反应模板,但划分严格的话,top-5 准确率也只能做到中等水平。真正有实力的 lab-aware 模型,应该同时具备较高准确率、高原子守恒率和明确的实验可行性分数。
这里有一个很多开发者容易忽略的点:准确率最高不代表模型最好,一定要结合后续的人工复核和可行性评估去看整体指标。
8. 常见问题与排查思路
8.1 SMILES 解析失败
问题现象:预处理时Chem.MolFromSmiles返回None。
常见原因:SMILES 写法不规范,包含非标准原子符号或非法价键。
解决思路:
- 使用标准化工具对 SMILES 做规整处理。
- 过滤掉解析失败的样本,并在日志中记录原因。
- 如果是手写测试数据,建议使用 ChemDraw 等工具生成 SMILES。
8.2 训练集和测试集结构泄漏
问题现象:验证集 top-10 准确率很高,但在外部数据集上效果明显下降。
常见原因:数据划分时没有考虑分子骨架相似性,同一结构的分子分散到了不同集合。
解决思路:基于 Bemis-Murcko 骨架聚类,将同一骨架的分子划分到同一集合中,或者使用 Butina 聚类进行分组划分。
8.3 多步累积误差
问题现象:逐步准确率不错,但整条路线成功率极低。
常见原因:每一步的预测误差逐步累积,越到后面偏差越大。
解决思路:
- 在训练时引入轨迹级损失函数,不只优化单步准确率。
- 在推理时使用序列级 beam search,而不是在每个步骤独立采样。
- 增加回溯机制,当某一步候选方案可行性过低时,回退到上一步重新决策。
8.4 资源消耗过大
问题现象:Transformer 模型训练需要大量 GPU 显存,普通开发机无法运行。
解决思路:
- 先使用预训练模型,在目标任务上做轻量微调,而不是完整训练。
- 控制输入序列长度,对冗长的 SMILES 做裁剪或片段化处理。
- 如果只是研究评估指标,可以使用模板法做基线,不一定要跑大规模模型。
下面汇总一下常见问题:
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| SMILES 解析失败 | 格式不规范 | 标准化过滤并记录日志 |
| 验证集虚高 | 数据泄漏 | 按骨架聚类划分 |
| 路线成功率低 | 误差累积 | 轨迹级训练与 beam search |
| GPU 内存不足 | 序列过长 | 预训练+微调,限制输入长度 |
| 指标有高有低 | 指标口径不一致 | 统一评估器,标准化 SMILES |
9. 最佳实践与工程建议
9.1 数据版本管理
计算化学数据集迭代速度很快,建议使用 DVC(Data Version Control)或类似工具管理数据版本。每次修改预处理逻辑,都生成新版本数据并记录变更说明,这样评估结果才可追溯。
9.2 评估流程标准化
团队内部应该统一评估器,避免不同成员各自实现评估逻辑导致指标不可对比。建议将评估器做成 Python 包,所有实验统一调用。
9.3 可复现性配置
训练模型时,需要固定随机种子和数据读取顺序。涉及 GPU 时,还需要设置torch.backends.cudnn.deterministic = True,尽可能保证相同代码和相同环境下结果一致。
9.4 多模型纵向对比
记录模型结构和超参之外,还需要写出评估时所用的候选生成数量。因为num_beams=10和num_beams=50的 top-10 准确率天然不同,只有在同一条件下对比才有意义。
9.5 安全与合规注意
涉及化学反应方案时,特别是面向工业环境的数据分析,务必关注化学品安全、知识产权和合规使用边界。评估和数据集发布,应当只使用公开或已授权的数据,并对可能涉及敏感方向的内容严格把关。任何反应条件推荐,只用于评估与学习研究,不应在未经验证的情况下直接放大到生产实验。
9.6 从模型分数到实验验证的闭环
lab-aware 基准测试的最终目的,是在模型评估和湿实验验证之间建立闭环。建议在评测阶段增加“人工复核”环节,让有经验的合成化学家对 top-k 候选方案做小规模抽样验证。这不仅能发现数据标注问题,还能让评测指标更接近真实场景需求。
10. 总结与学习路线
onepot-Bench 0 所代表的 lab-aware 基准测试方向,核心价值在于把计算模型的评估从“数据拟合”拉向“实验可行”。它把一个真实的问题摆到桌面上:模型给出的预测,到底能不能进实验室跑一遍?
在这个过程中,我们需要掌握的核心能力包括:分子数据的标准化与清洗、一锅法反应序列的切分与建模、多维度评估指标的实现、数据泄漏控制,以及把模型输出转为可执行实验方案的综合判断。
如果你准备上手这个方向,建议按照以下路线逐步深入:
- 第一阶段:用 RDKit 熟悉分子数据基础操作,掌握 SMILES 解析、标准化、骨架提取。
- 第二阶段:阅读常用的反应数据集格式,尝试做反应模板提取。
- 第三阶段:跑通一个分子翻译基线模型,掌握 beam search 评估流程。
- 第四阶段:在评估器中加入原子守恒、条件合理性、实验可行性等指标,建立自己的 lab-aware 评估体系。
- 第五阶段:结合化学家反馈,迭代数据预处理和评估规则。
计算化学的机器学习远没有到一锤定音的阶段。模型榜单高分的意义,只有放到实验室验证里才能被真正检验。这也是为什么理解和用好 lab-aware 基准测试比单纯跑通一个模型更重要。