Uni-Parser v1.5.0
返回全部文章
MolParser 2.0

MolParser 2.0:端到端分子识别升级,全面支持 E-SMILES 2.0 规范

MolParser 2.0: End-to-End Molecular Recognition Upgrade with Full E-SMILES 2.0 Support

Uni-Parser 1.5 正式发布 MolParser 2.0,延续端到端 OCSR 技术路线,全面升级至 E-SMILES 2.0 语法,支持十余类复杂分子和Markush结构绘图的序列化表示。

MolParser 2.0:端到端分子识别升级,全面支持 E-SMILES 2.0 规范

从几何检测到端到端序列化

在光学化学结构识别(Optical Chemical Structure Recognition, OCSR)领域,业界主要存在两条技术范式:基于原子-键检测(Atom-Bond Pipeline)和端到端序列化(End-to-End OCSR)。

为什么选择端到端路线?

  • 传统 Atom-Bond 方案虽然能输出携带二维坐标的 .mol 格式,但是该格式难以直接被下游 LLM / Agent 理解和处理,仍需进行SMILES转换。但在执行图论重构与序列化转译时,极易因微小像素间距漂移导致连通性判定错误,产生“视觉上看似闭环、实际拓扑已断开”的致命假象。而端到端模型直接在隐空间建模化学键拓扑语义,从根本上杜绝了几何拼接失效和转换SMILES的失败。
  • 端到端路线将复杂的 2D 分子网格压缩为高密度的线性字符串,极大降低了表征冗余度。生成的标准化文本可以直接无缝注入多模态模型(MLLM)或化学专用大语言模型(LLM)的上下文窗口,提升下游二次推理、分子性质预测与逆合成设计的吞吐效率。直接序列化表示是更适合大模型和agent应用的 1D 表示。

从 MolParser 到 MolParser 2.0

传统 SMILES 与 Mol 格式在表征能力上存在显著边界,为此,我们在 MolParser 工作中设计并提出了 E-SMILES (Extended-SMILES)语法体系。该体系为文献与专利中常见的环上任意位点取代(Regio-uncertain Attachment)、子结构复制与聚合度(SRU)及复杂马库什(Markush)结构,提供了精准、规范的序列化表示。我们的工作首次证实:在真实文献及手写分子等严苛场景下,端到端 OCSR 模型的性能完全可以达到乃至超越基于规则的 Atom-Bond 流程;不仅展现出持续突破的精度上限,在推理吞吐量上亦具备数量级优势,极为契合大规模化学文献挖掘工程。

在本次 MolParser 2.0 更新中,我们延续并深化了这一技术路线,正式引入全新的 E-SMILES 2.0 规范。该升级进一步拓宽了 OCSR 算法的识别边界与表达维度,实现了对海量文献与专利中绘图风格各异、拓扑结构高度复杂的 Markush 分子更全面、更深度的解析支持。

MolParser-2.0-GA(General Availability,正式可用版)发布

相比 Uni-Parser 1.4.0 版本中的 MolParser-2.0-preview,新版 Uni-Parser 带来的 MolParser-2.0-GA,首次引入了OCSR模型的自进化机制,模型能力可以随推理数目的增加而不断提升。在 BioVista OCSR Benchmark 上 MolParser-2.0-GA 取得了新的 SOTA(准确率从测试版的 84.5% 提升至正式版的 85.7%)。针对 Atom-Bond 方法难以处理的各类复杂立体异构结构,新版本表现显著改善;同时,Markush、基团缩写、SRU等识别能力也在自进化中得到明显增强。此外,新版本进一步完善了 E-SMILES 后处理与 Markush 代入的开源配套生态,对药物、化学文献领域Agent的应用提供了坚实的生态基础。

扩展支持范围

E-SMILES(Extended-SMILES)由标准 SMILES 与可选的扩展片段组成,在保持 RDKit-friendly 的同时,为 SMILES 提供 LLM-friendly 的扩展表示:

SMILES<sep>EXTENSION

普通分子(Simple)

普通分子直接使用标准 SMILES 表达,并以 <sep> 结束

图像E-SMILES 表示E-SMILES 2.0 表示
结构示例 simple-01
Cc1cc(Oc2ccc(COc3cc4n(c(=O)n3)CC35CC(CN43)C5)cc2F)ccn1<sep>
Cc1cc(Oc2ccc(COc3cc4n(c(=O)n3)CC35CC(CN43)C5)cc2F)ccn1<sep>

[Updated] 连接点(Dummy Attachment Point)

连接位点使用 <d></d> 表达:

<d>ATOM_INDEX:<dum></d>

其中:

  • ATOM_INDEX 表示连接点对应的原子序号;
  • <dum> 表示该位置为 dummy attachment point,用于表示结构与未展开部分的连接。
图像E-SMILES 表示E-SMILES 2.0 表示
结构示例 attachment-01
*C(O)=O<sep><a>0:<dum></a>
*C(O)=O<sep><d>0:<dum></d>
结构示例 attachment-02
*CCc1ccccc1<sep><a>0:<dum></a>
*CCc1ccccc1<sep><d>0:<dum></d>
结构示例 attachment-03
*CCc1ccccc1F<sep><a>0:<dum></a>
*CCc1ccccc1F<sep><d>0:<dum></d>
结构示例 attachment-04
*CCNC(=O)c1ccccc1<sep><a>0:<dum></a>
*CCNC(=O)c1ccccc1<sep><d>0:<dum></d>

环上不定连接(Ring Attachment / Regio-uncertain Attachment)

当取代基连接于某个环或区域,但具体连接原子不确定时,使用 <r></r> 表达:

<r>RING_INDEX:GROUP</r>

其中:

  • RING_INDEX表示该不定连接所属的环的index(rdkit计算的环序号,从0开始);
  • GROUP 表示连接到该区域的取代基或 Markush 基团;
  • 对于多个环上的不定连接,使用逗号分隔不同环 index,如 <r>RING_INDEX_1,RING_INDEX_2:GROUP</r>,表示该取代基可连接于指定多个环区域中的任意位置;
图像E-SMILES 表示E-SMILES 2.0 表示
结构示例 ring-attachment-01
C1C=CC=CC=1<sep><r>0:R[1]</r><r>0:R[2]</r>
C1C=CC=CC=1<sep><r>0:R[1]</r><r>0:R[2]</r>
结构示例 ring-attachment-02无法表示多环区域不定连接
*1(CC2C*C3=*C(*)=**=C3*2CC1)*<sep><a>0:M[1]</a><r>0,1:R[c]?x</r><a>4:M[6]</a><a>6:M[3]</a><a>8:<dum></a><a>9:M[5]</a><a>10:M[4]</a><a>12:M[2]</a><a>15:<dum></a>

抽象环(Abstract Ring)

无法明确展开具体环结构、仅以抽象环节点表示的结构使用 <c></c> 表达:

<c>ATOM_INDEX:LABEL</c>

其中:

  • ATOM_INDEX 表示抽象环在主体结构中的对应位置;
  • LABEL 表示该抽象环的类型或标识;
  • 抽象环仅保留其作为整体结构单元的连接关系,不展开内部原子和键
图像E-SMILES 表示E-SMILES 2.0 表示
结构示例 abstract-ring-01
*C(NC(*)(*)C(*)(*)*)C(=O)N(*)*<sep><a>0:R[1]</a><a>4:R[3]</a><a>5:R[2]</a><a>7:R[5]</a><a>8:R[4]</a><c>9:B</c><a>13:R[7]</a><a>14:R[6]</a>
*C(NC(*)(*)C(*)(*)*)C(=O)N(*)*<sep><a>0:R[1]</a><a>4:R[3]</a><a>5:R[2]</a><a>7:R[5]</a><a>8:R[4]</a><c>9:B</c><a>13:R[7]</a><a>14:R[6]</a>

Markush分子和缩写基团 (Markush & Abbreviation)

普通 Markush 分子或缩写基团在主体 SMILES 后使用 <a></a> 标记可变取代基:

<a>ATOM_INDEX:GROUP</a>

其中:

  • ATOM_INDEX 表示 Markush 基团连接到主体结构的原子序号;
  • GROUP 表示对应的可变基团,如 R[1]、R[2] 等;
  • 同一结构中可定义多个 Markush 位点,用于表示不同位置的可变取代基。
图像E-SMILES 表示E-SMILES 2.0 表示
结构示例 markush-01
*C(=O)N1CCCN(*)C(*)C1*<sep><a>0:R[1]</a><a>8:R[2]</a><a>10:R[3]</a><a>12:R[5]</a>
*C(=O)N1CCCN(*)C(*)C1*<sep><a>0:R[1]</a><a>8:R[2]</a><a>10:R[3]</a><a>12:R[5]</a>

[New] 特殊Markush (Special Markush)

特殊 Markush 用于表示无法直接映射为普通原子、官能团或标准 R 基的抽象化学片段,例如 DNA、RNA、彩色圆球或其他自定义结构标签。使用 <id>...</id> 表达其自定义标识:

<a>ATOM_INDEX:<id>[LABEL]</id></a>

其中:

  • ATOM_INDEX 表示特殊 Markush 与主体结构连接的原子位置;
  • <id>LABEL</id> 用于记录该抽象片段的语义标签;
  • LABEL 为自由文本标识,例如 DNA、ball(白色圆圈)、blue(蓝色小球) 等;
  • 特殊 Markush 只保留图中给出的抽象身份及连接关系,不对其内部化学结构进行展开或推断。
图像E-SMILES 表示E-SMILES 2.0 表示
结构示例 special-markush-01无法表示特殊Markush取代基
*CC(=O)Nc1c(C#N)c(*)nn1C*<sep><a>0:<id>[blue]</a><a>10:<id>[green]</a><a>14:<id>[green]</a>
结构示例 special-markush-02无法表示特殊Markush取代基
N(C(=O)C(*)NC1N=C(N(*)*)N=C(N(*)*C(=O)N(*)*)N=1)*<sep><a>4:R[1]</a><a>10:R[6]</a><a>11:R[7]</a><a>15:R[2]</a><a>16:R[3]</a><a>20:R[4]</a><a>21:R[5]</a><a>23:<id>[DNA]</a>

[New] 子结构复制(SRU)

对于单个取代基或单个节点的子结构复制支持使用 ?COUNT 表达局部片段的重复次数,其中:

  • ?COUNT 表示其前方局部子结构的复制次数;
  • COUNT 可以为确定数值、范围或变量,例如 ?3、?1-3、?n;
  • ?n 中的实际重复次数可由对应的 Markush 定义给出;
  • 该表示适用于 CH2?n、取代基多重性等局部重复结构。

对于局部骨架片段的子结构复制,无法使用 ?COUNT 无歧义的表示时,需要使用 <g></g> 标记需要整体重复的结构范围,并通过 |Sg:COUNT| 指定重复次数:

<g>[INNER_PORT1:OUTER_PORT1]:[INNER_PORT2:OUTER_PORT2]:|Sg:COUNT|</g>

其中:

  • <g></g> 用于定义需要整体复制的局部结构;
  • [INNER_PORT:OUTER_PORT] 表示该重复结构的一个内外边界连接端口(inner/outer boundary port):

  • INNER_PORT:重复结构(SRU)内部的原子索引;

  • OUTER_PORT:重复结构外部、与该内部原子相连的原子索引;
  • 因此,该表示描述的是从重复结构内部到外部的边界连接关系;
  • 一个局部重复结构通常具有两个边界连接端口,分别定义重复单元的两端。例如:其中 [3:2] 和 [4:5] 分别表示两个内外边界连接端口,即重复单元内部原子 3、4 分别与外部原子 2、5 相连;

text <g>[3:2]:[4:5]:|Sg:20|</g> - COUNT 表示该局部结构的重复次数,可以为变量、确定数值或简单范围,例如 n、m、20 等; - 当整个分子作为一个结构重复单元(structural repeating unit, SRU),并通过其两端连接形成高分子链时,属于 Polymer 的特殊情况,此时直接使用 |Sg:COUNT| 表示整体重复,不再使用 <g></g>。

图像E-SMILES 表示E-SMILES 2.0 表示
结构示例 sru-01
*C(O)c1cc(C(=O)N(*)*)cc(-c2*ccc*2)c1<sep><a>0:CF3</a><a>9:R[3]</a><a>10:R[2]</a><a>14:X</a><a>18:Y</a><r>1:R[1]?1-3</r>
*C(O)c1cc(C(=O)N(*)*)cc(-c2*ccc*2)c1<sep><a>0:CF3</a><a>9:R[3]</a><a>10:R[2]</a><a>14:X</a><a>18:Y</a><r>1:R[1]?1-3</r>
结构示例 sru-02
O=[C](*)[CH2]*[CH2]/C=[C](/O)*<sep><a>2:R[2]</a><a>4:CH2?n</a><a>9:R[1]</a>
O=[C](*)[CH2]*[CH2]/C=[C](/O)*<sep><a>2:R[2]</a><a>4:CH2?n</a><a>9:R[1]</a>
结构示例 sru-03无法表示[片段化的]子结构复制
CCC(NCCC1CCCCCC1)C(C)S<sep><g>[3:2]:[4:5]:|Sg:50|</g>

[Updated] 高分子(Polymer/SRU)

高分子重复单元使用 * 表示与相邻重复单元相连的端点,并通过 <d></d> 标记对应的连接位点:

*CC*<sep><d>0:<dum></d><d>3:<dum></d>|Sg:n|

其中:

  • * 表示高分子重复单元两端的连接点;
  • <d>ATOM_INDEX:<dum></d> 用于标记对应的 dummy attachment point;
  • |Sg:COUNT| 表示重复单元的聚合度或重复次数,高分子不指定重复次数默认为 |Sg:n|;
图像E-SMILES 表示E-SMILES 2.0 表示
结构示例 polymer-01
*OCCOC(=O)c1ccc(C(*)=O)cc1<sep>|Sg:n|
*OCCOC(=O)c1ccc(C(*)=O)cc1<sep><d>0:<dum></d><d>12:<dum></d>|Sg:n|
结构示例 polymer-02
*Oc1ccc(C(=O)Oc2ccc(C(C)(C)c3ccc(S(=O)(=O)c4ccc(OC(=O)c5ccc(*)cc5)cc4)cc3)cc2)cc1<sep>|Sg:n|
*Oc1ccc(C(=O)Oc2ccc(C(C)(C)c3ccc(S(=O)(=O)c4ccc(OC(=O)c5ccc(*)cc5)cc4)cc3)cc2)cc1<sep><d>0:<dum></d><d>34:<dum></d>|Sg:n|
结构示例 polymer-03
*CC1CCC(CNC(=O)C(=O)N*)CC1<sep>|Sg:n|
*CC1CCC(CNC(=O)C(=O)N*)CC1<sep><d>0:<dum></d><d>13:<dum></d>|Sg:m|

[New] 虚拟连接弧(Virtual Arc)

虚拟连接弧(Virtual Arc)使用 <v></v> 标签表示:

<v>[VIRTUALARC_INDEX]:[VIRTUALARC_NAME]:[FROM_ATOM:TO_ATOM]</v>

其中:

  • VIRTUALARC_INDEX 表示虚拟连接弧的索引,从 0 开始,并使用独立于原子和环的索引空间;
  • VIRTUALARC_NAME 表示虚拟连接弧的来源标签,例如 A、Ar 或 M;如果原图中没有对应标签,可以为空;
  • FROM_ATOM 和 TO_ATOM 表示虚拟连接弧两端对应的原子索引,均为基于 Base SMILES 的 0-based atom index;
  • [FROM_ATOM:TO_ATOM] 用于指定虚拟连接弧的两个端点。该连接不表示真实化学键,而是用于表达结构图中的特殊抽象连接关系,例如图中通过大环、跨越结构或其他非标准键线表示的连接;
图像E-SMILES 表示E-SMILES 2.0 表示
结构示例 virtual-arc-01无法表示虚拟连接弧
C=CCCCC1CCC(CC=C)NC1C<sep><v>0:B:[0:10]</v>
结构示例 virtual-arc-02无法表示虚拟连接弧
c1(*)c(N(C)C)*c2n(-c3cn(*)nc3)ncc2c1<sep><v>0:A:[4:5]</v><a>1:R[1]</a><a>6:X</a><a>12:R[2]</a>
结构示例 virtual-arc-03无法表示虚拟连接弧
C=CCC(C(C)*)*<sep><a>6:R[2]</a><a>7:R[1]</a><v>0:A:[0:2]</v><r><v>0:R[3]</r>

[New] 轴手性 (Stereogenic Axis)

手性轴统一使用 <x></x> 标签表示,将原联芳基键的定义泛化为手性轴向量的两端定义点(Terminal Reference Points of Chiral Axis):

<x>[ATOM_1:ATOM_2]:STATE</x>

其中:

  • ATOM_1 和 ATOM_2 表示定义手性轴拓扑跨度的两端关键原子序号,严格遵循 ATOM_1 < ATOM_2;
  • [ATOM_1:ATOM_2] 用于唯一锁定承载轴手性的结构骨架(单键阻转时为该化学键两端原子;多原子累积或正交体系时为主轴两端关键原子);
  • STATE 表示轴手性的绝对构型,取值为:

  • Ra:R 型轴手性(R axial);

  • Sa:S 型轴手性(S axial)
轴手性类型 拓扑 / 阻转本质 轴两端原子定义规则 语法示例
联芳基体系 单键旋转受阻(C-C) 连接两个芳环的 C-C 单键原子序号 <x>[5:12]:Ra</x>
芳基 - 烯基 / 二烯体系 单键旋转受阻(C-C) 芳环碳原子与烯基 α- 碳原子序号 <x>[4:9]:Sa</x>
芳基酰胺 / 酰亚胺体系 单键旋转受阻(C-N) 芳环碳原子与酰胺氮原子序号 <x>[6:7]:Ra</x>
丙二烯 / 累积多烯体系 共线 π 轨道正交累积双键体系 两端的 sp² 碳原子序号 <x>[2:4]:Sa</x>
烷基叉环烷烃 环与双键正交 环内连接原子与双键末端碳原子序号 <x>[3:8]:Sa</x>
螺环化合物 螺原子几何正交 穿过螺原子的主轴线两端最远端原子(对位顶点)序号 <x>[1:10]:Ra</x>
图像E-SMILES 表示E-SMILES 2.0 表示
结构示例 axial-chirality-01无法表示联芳基轴手性
*c1cc(CO*)c(-c2ccc(O*)cc2[C@@H](*)O)c(*)c1*<sep><a>0:OMe</a><a>6:TES</a><a>13:TIPS</a><a>17:R[1]</a><a>20:OMe</a><a>22:OMe</a><x>[7:8]:Ra</x>
结构示例 axial-chirality-02无法表示联芳基轴手性
Nc1ccc2ccccc2c1-c1c(O)ccc2ccccc12<sep><x>[10:11]:Sa</x>

E-SMILES 2.0 工具链与开源生态

Github 开源

E-SMILES 2.0 已在 MolParser 开源仓库 中提供完整的工具与规范支持:

  • 提供 E-SMILES 后处理规范化、格式转换、Markush 代入、以及结构渲染 等基础工具;
  • 提供 E-SMILES Skills,用于帮助 Agent 理解 E-SMILES 2.0 的表示规范与典型案例,可用于 Uni-Parser / MolParser 输出结果的解析、校验、规范化与下游消费;

E-SMILES 后处理

from molparser import utils as mutils

raw = "*c1ccccc1<sep><a>0:CF3</a>"
result = mutils.postprocess_caption(raw)

print(result["smi"])
# FC(F)(F)c1ccccc1
print(result["esmi"])
# FC(F)(F)c1ccccc1<sep>

Markush 代入

from molparser import utils as mutils

# --------------------------------------------
# Example 1:
result = mutils.substitute_markush("*c1ccccc1<sep><a>0:NHR[1]</a>", {"R1": "Me"})
print(result)
# CNc1ccccc1

# --------------------------------------------
# Example 2:
result = mutils.substitute_markush("COCCOC<sep><g>[1:0]:[3:4]:|Sg:n|</g>", {"n": 5})
print(result)
# COCCOCCOCCOCCOCCOC

# --------------------------------------------
# Example 3:
result = mutils.substitute_markush(
    "c1ccccc1<sep><r>0:R[1]?1-3</r>",
    {"R1": "Me"},
)
print(result)
# ['Cc1cc(C)cc(C)c1', 'Cc1ccc(C)c(C)c1', 'Cc1ccc(C)cc1', 'Cc1cccc(C)c1', 'Cc1cccc(C)c1C', 'Cc1ccccc1', 'Cc1ccccc1C']

# --------------------------------------------
# Example 4:
from molparser import utils as mutils

result = mutils.substitute_markush(
    "c1ccc2ccccc2c1<sep><r>0,1:R[1]</r>",
    {"R1": "Me"},
)
print(result)
# ['Cc1ccc2ccccc2c1', 'Cc1cccc2ccccc12']

E-SMILES 分子结构渲染

from molparser import utils as mutils

esmiles = "*c1ccccc1<sep><a>0:R[1]</a>"

svg = mutils.draw(esmiles, output_format="svg")
png = mutils.draw(esmiles, output_format="png")

E-SMILES Skills

仓库同时维护了面向 LLM / Agent 的 E-SMILES Skills,包括:

skills/molparser-extended-smiles/
├── SKILL.md
├── extended-smiles-spec.md
└── figure-index.md

这些 Skills 可直接作为大模型上下文,用于 E-SMILES的识别、校验、规范化、Markush 代入与渲染,从而更方便地消费 Uni-Parser / MolParser 的结构化输出。

Huggingface 开源

欢迎关注 Uni-Parser 团队(DP Technology) 在 Hugging Face 上持续发布的模型与数据:

https://huggingface.co/UniParser

我们将持续为社区提供有价值的开源内容!

主观对比

类型图像MolScribe MolParser 1.0MolParser 2.0
复杂立体结构结构示例 comparison-01结构示例 comparison-02
立体结构错误
结构示例 comparison-03结构示例 comparison-04
特殊Markush结构示例 comparison-05结构示例 comparison-06
无法识别特殊Markush
结构示例 comparison-07
无法识别特殊Markush
结构示例 comparison-08
子结构复制结构示例 comparison-09结构示例 comparison-10
无法识别子结构复制,且结构识别错误
结构示例 comparison-11
无法识别子结构复制
结构示例 comparison-12
高分子结构示例 comparison-13结构示例 comparison-14
无法识别高分子
结构示例 comparison-15
高分子识别错误
结构示例 comparison-16
抽象环结构示例 comparison-17结构示例 comparison-18
无法识别抽象环
结构示例 comparison-19
抽象环误认为是Markush
结构示例 comparison-20
虚拟弧结构示例 comparison-21结构示例 comparison-22
无法识别虚拟弧
结构示例 comparison-23
无法识别虚拟弧
结构示例 comparison-24
环肽结构示例 comparison-25结构示例 comparison-26结构示例 comparison-27结构示例 comparison-28
轴手性结构示例 comparison-29结构示例 comparison-30
无法识别轴手性
结构示例 comparison-31
无法识别轴手性
结构示例 comparison-32
手写分子结构示例 comparison-33结构示例 comparison-34
多处基团和连接关系错误
结构示例 comparison-35
COOR基团识别错误
结构示例 comparison-36