酶设计真正缺的那一层
酶设计通常被讲成一条生成故事:扩散模型出骨架,反折叠出序列,结构网络再打分。这条故事在迷你蛋白和结合蛋白上已经成立。酶不同。催化要求的是对特定化学键重排的活性,而不是对一个表位的形状互补。PNAS 论文开篇写得很清楚:生成式酶设计的表现,取决于训练数据里有多少已知、野生型的反应性;要把新反应性补进数据,必须先从自然酶库里把它们找出来。
因此,一场酶工程战役的第一个可实验决策往往不是“设计一条全新序列”,而是:给定目标反应,哪一条已有蛋白值得作为进化或理性设计的起点。传统路径用序列相似或 EC 号做代理。论文给出的对照很硬:只用 EC 号前三位给序列排序,测试集 Top-100 命中率只有 27.5%。也就是说,即便已经知道反应属于哪一类,按注释检索仍然会漏掉大多数真正的催化剂。
Horizyn 把问题改写成跨模态检索。反应用分子指纹,蛋白用预训练语言模型的静态嵌入,两侧各经一个 MLP 投影到 512 维 L2 归一化球面,用余弦距离排序。查询可以是反应找酶,也可以是酶找可能催化的反应。它不输出结构,不预测动力学常数,也不生成氨基酸。把它放进酶设计上下文里,正确的位置是战役入口的检索层:为后续的定向进化、活性口袋改造或生成模型微调,提供可合成、可表达的起始序列。
判断:在酶设计里,Horizyn 回答的是“从哪条序列开始”,不是“这条序列会不会折叠、kcat 是多少”。把检索命中写成催化证明,是最常见的误用。
项目身份与证据边界
需要同时看三套不完全重合的对象。
| 对象 | 是什么 | 证据来源 |
|---|---|---|
| Horizyn-1(论文) | Dayhoff Labs 的反应–酶推荐模型;基准集 + 大规模推理模型 + 湿实验 | PNAS 123(12): e2520070123(2026-03-17,开放获取) |
| horizyn 仓库 | 官方 Lightning 实现:训练、评估、对 bundled ~216K ProtT5 嵌入做预测 | /home/qiao/md/horizyn 源码、配置、检查点 |
| 托管 API | 在 6.33M 蛋白上检索,带名称、物种、EC、辅因子、文献过滤 | api.horizyn1.dayhofflabs.com |
论文收稿日期 2025-07-28,接受 2026-02-17,由 KAIST 的 Sang Yup Lee 编辑。作者为 Jason W. Rocks、Dat P. Truong、Dmitrij Rappoport、Samuel Maddrell-Mander、Daniel A. Martin-Alarcon、Toni Lee、Steve Crossan、Joshua E. Goldford。仓库许可证为 PolyForm Noncommercial 1.0.0:学术与非商业可免费使用,商业需另行授权。
版本号不要当成单一事实:pyproject.toml 写 version = "1.0.0",包内 horizyn/__init__.py 写 __version__ = "0.1.0"。这是仓库内部不一致,不是论文勘误。
bioRxiv 预印本为 10.1101/2025.08.21.671639。本报告的论文数字以 PNAS HTML 正文为准。
双编码器:把反应与酶放进同一球面
实现集中在 horizyn/model.py 的 DualContrastiveModel。两侧编码器独立,不共享权重,输出强制 rank-2 且末维相等。
SOTA 配置在 configs/sota.yaml:query_encoder_dims = [2048, 4096, 4096, 512],target_encoder_dims = [1024, 4096, 4096, 512]。MLP 按宽度堆 Linear → 激活 → [LayerNorm] → [Dropout],最后接输出线性层;normalise_output=True 时在 post_nn_layers 追加 NormalizeLayer(F.normalize(p=2, dim=-1, eps=1e-12))。
构造期有一条硬约束:enforce_normalisation=True 时,两个编码器末层必须是 NormalizeLayer,否则抛 ValueError(model.py 约 L367–382)。这不是风格问题。后续损失用余弦距离,几何假设是单位球面;漏掉归一化会让 MLNCE 的配分函数失去意义。
论文消融与这份架构一致,且给出了“不要轻易换表示”的证据:用 rxnfp(反应 Transformer)或 Chemprop(图网络)替换指纹,Top-1 / Top-10 明显下降;ESM-2(650M 与 3B)略差于 ProtT5;微调 ESM-2-650M 或加入三维结构,相对静态嵌入没有实质提升,却显著增加计算。对酶设计用户,这意味着:反应怎么表示,比蛋白编码器是否端到端可训更关键。仓库选择冻结 ProtT5、只训投影 MLP,与论文结论对齐,而不是工程偷懒。
反应侧:指纹、标准化与双向增广
4.1 两种互补指纹
RDKitPlusFingerprintDataset 默认 Morgan、radius=3(ECFP6),use_chirality=True。SOTA 使用 struct 模式:向量对半切开,反应物占前半、产物占后半,同一侧多个分子按位或。这保留“两边各有什么结构”,但不直接编码键的生成与断裂。互补的是 DRFP:对反应物与产物的圆形子结构做对称差,折叠到 1024 维(radius=3, rings=True, root_central_atom=True)。两种指纹经 MergeDataset 按键求交,再 ConcatTensorTransform 拼成 2048 维。求交的含义是:任何一侧指纹失败的反应不会进入训练——脏 SMILES 被默默丢掉,而不是用零向量污染对比池。
4.2 五步标准化
chemistry/standardizer.py 按开关串联:高价态清理 → 去显式氢 → Kekulize(默认关,保留芳香性)→ 去电荷(默认开,并按电荷差回补质子)→ 金属–N/O/F 键断开。SOTA 默认 hypervalent / remove_hs / uncharge / metals = on,kekulize = off。跨 Rhea / UniProt 来源时,这一步决定同一反应会不会被当成两个不同 query。
4.3 双向增广
反应 A>>B 变成正向 _f 与反向 B>>A 的 _r;配对同步翻倍。预测脚本 --bidirectional 对两向编码取均值,与训练增广一致。这使可逆转化(转氨基、氧化还原)在嵌入空间里双向可查。代价也明确:实现是字符串反转,不做化学可逆性判断。ATP 水解这类实际上不可逆的反应,逆方向会作为噪声正样本进入损失。
全批 MLNCE:多标签检索的损失
一个反应常被多个酶催化,一个酶也常有杂泛性。标准 InfoNCE 的“一个 query 一个正样本”假设在这里不成立。FullBatchMLNCELoss(horizyn/losses.py)直接在整个 batch 的距离矩阵上算最大似然噪声对比估计:
第一项拉近正对;第二项对全部 Q×T 配对做 soft 归一化,使正对在对比池里概率最大。β 以 logβ 存储;SOTA 固定 learn_beta=False。训练 batch 为 16,384,每个 step 的对比池就是这一个大矩阵。论文把同一策略称为 in-batch negative sampling,并报告它优于按共享 EC 构造的 hard negative,同时更省计算。论文也承认风险:数据库未标注的真实正对会被当成负例。他们用人为扣掉已知正对的模拟表明,模型对这些“缺失标注”仍保持预测力——这是对杂泛性检索有利的性质,但模拟不等于湿实验。
指标在 horizyn/metrics.py:Top-K hit rate(多标签用 torch.isin)、R-precision、average precision。评估脚本额外报 K∈{1,10,100,1000}。Top-K 之所以被论文当作主指标,是因为它直接对应实验设计:Top-100 就是一次发现战役里准备合成、表达的序列上限。
论文数字、仓库口径与检查点
三套数字不要混用。
| 口径 | 反应 | 蛋白 / 序列 | 反应–酶对 | 用途 |
|---|---|---|---|---|
| PNAS 基准集 | 11,961(Rhea);测试 1,012,按指纹相似度切分 | 216,132(UniProt) | 294,166 | 消融与 Top-K 表(Fig. 1D) |
仓库 data/README.md |
train 10,785 + test 1,012 = 11,797 | 216,132(train 192,769 / test 32,100) | 257,733 + 33,996 = 291,729 | 本地复现用 SOTA 文件 |
| PNAS 推理模型 | ~31,000(多库合并) | ~27M → MMSeqs2 80% 聚类后 ~7M | ~34M → 聚类后 ~9M | 湿实验查询用的 Horizyn-1 |
| 托管 API | 用户提交 SMILES | 6.33M(带注释) | — | 在线筛选,无需 GPU |
蛋白数 216,132 在论文基准与仓库之间对齐。反应数与配对数有小幅差额(11,961 vs 11,797;294,166 vs 291,729)。本报告不把它们收成一个数。Abstract 里的“数百万反应–酶对”指向推理模型的 ~9M 聚类后训练集,不是 294k 基准集。
Top-100 hit rate 76.7%:ECFP6/DRFP + 静态 ProtT5,1,012 测试反应,完整酶库排序。来源:PNAS Fig. 1D 正文。
EC 三位数基线 Top-100 = 27.5%。部分 EC 信息与模型联用再提升约 5–10%。
数据 10% 时 Top-100 仍 > 40%;性能随训练反应数对数增长。论文外推约 10 倍反应规模可使 Top-100 接近 100%——这是标度拟合,不是已训练模型的实测。
README 声称 dev 检查点 Top-1 ≈ 32.4%。仓库未附评估 JSON 或训练日志。本报告撰写时没有运行 scripts/evaluate.py,该数字保持“声称”,不升级为本地复现。
76.7%(Top-100)与 32.4%(Top-1)是不同 K、且可能对应不同筛选库口径。禁止把它们写成同一结果的两种说法。
仓库提供两个检查点,均来自 Zenodo record 20348783。本机文件与 README MD5 一致:
| 文件 | 训练数据 | 用途 | 本机 MD5 |
|---|---|---|---|
horizyn_v1_0_dev.ckpt |
仅 train split(paper-faithful) | 评估、复现指标 | 5b1f938f8b0a82fbe91892a3b4e2bf2c |
horizyn_v1_0_inf.ckpt |
全量(train+test) | 预测;不用于发论文式评估 | cf6775b775287462099ae0681485a6bc |
切分原则写在 data/README.md:按 reaction_id 切,同一反应的全部配对只能落在 train 或 test 一侧。这避免“见过这个反应的别的酶”这种泄漏。论文正文补充:测试 1,012 反应按反应指纹相似度切分,目的是降低近邻反应泄漏,而不只是随机划 ID。
湿实验:孤儿反应、杂泛性、非天然转化
以下全部来自 PNAS Results,不是本仓库的复现实验。仓库只提供检索模型;湿实验在论文实验室完成。
7.1 尼龙降解路径的孤儿转氨酶
Rhea 中的孤儿反应指转化已被观察或推断,但尚未标注催化剂。论文以尼龙降解菌 Arthrobacter sp. KI72 的 6-aminohexanoate aminotransferase(RHEA:58200,EC 2.6.1.116)为第一例。对基因组全部 4,173 条蛋白编码序列查询后,高置信候选为 WP_021472307.1(注释为 GabT,EC 2.6.1.19)与 WP_079941468.1(III 类 PLP 依赖转氨酶,EC 2.6.1.-)。表达纯化后,两者相对未催化对照均显示显著的 6-aminohexanoate 转氨活性。
这两条序列与 E. coli GabT(P22256)分别有 43.3% 与 43.5% 一致。Horizyn-1 在训练集里把 GabT 排为该反应的第一名。纯化后的 GabT 对该孤儿反应的活性高于两条 Arthrobacter 酶,并与其标注底物 4-aminobutyrate(RHEA:23352)相当。论文还测了 β-alanine 与 putrescine 等孤儿 ω-转氨反应,GabT 呈弱杂泛性。含义对酶设计很直接:起始酶不必来自“正确”的 EC 叶子;邻近底物的已知酶往往就是可进化的起点。
7.2 嗜热菌中的杂泛性与未注释激酶
在 Thermus aquaticus 中,作者筛选与训练集序列一致度不超过 50% 的酶(n=382),对 15,814 条 Rhea 反应查询,过滤掉已有 EC 对应反应后得到 818 个分数 >0.80 的杂泛性候选。A0A0N0U829(注释 D-乳酸脱氢酶,EC 1.1.2.4)的第一名与同源模型一致,但同时对 (R)-2-hydroxyglutarate–pyruvate transhydrogenase(RHEA:51608,EC 1.1.99.40)打出高分。偶联乳酸脱氢酶实验显示,仅在该酶存在时 NADH 被消耗,支持转氢酶活性。
未注释蛋白 A0A0N0BLM2 被预测为 dCMP / CMP kinase。LC–MS 多反应监测在酶与 dCMP 孵育 18 小时后检出 dCDP 峰,无酶对照没有对应产物。
7.3 非天然转化与少样本微调
Significance 与 Abstract 还列出第三类场景:非天然生化转化,包括用于非canonical 氨基酸合成的 lysine-driven transamination;并称在代表性不足的反应类上,用少于 10 条额外反应微调即可显著改善。本次抓取未展开该段的完整实验表,因此这里只保留论文摘要级陈述,不补未核对的转化数或滴度。
证据边界:湿实验证明的是“检索排序可以给出可纯化、可测活的候选”,不是“Top-100 命中率等于体外阳性率”。尼龙例子的基因组库只有 4,173 条,与 216K / 7M 筛选库的难度不可互换。
如何接入酶设计流水线
一条诚实的计算酶设计链至少有五段。Horizyn 只覆盖其中的检索与(弱)功能先验:
本地 README 的 qiaogan 附录记录了一条本机协同:ProstT5 反折叠出序列 → embed.py --per_protein 1 得到与 Horizyn 兼容的 1024 维嵌入 → predict.py 做反应匹配。这是本机工作流注释,不是 PNAS 方法、也未经本报告复现。它在工程上说得通:蛋白侧 MLP 只吃 ProtT5 向量,任何能产出同分布嵌入的序列都可以查询。风险同样清楚——设计序列若远离 UniRef50 训练分布,静态嵌入可能把“不像天然酶”编码成低分,而不是把“新活性”编码成高分。
论文自己建议的扩展方向与此互补:性能随反应多样性对数增长;结合主动学习、优先采集新反应类,而不是无限堆相似序列。对想做 de novo 酶的团队,更有杠杆的数据投资是新反应–酶对,不是再训一个更大的蛋白 LM。
8.1 本地预测与托管 API
离线路径检索 bundled 216,132 个嵌入,需要 GPU(官方建议单卡 ≥16 GB)以及 inf 检查点:
托管 API 把筛选库扩到 6.33M,并返回名称、物种、EC、辅因子、文献。密钥用邮箱验证码签发,无需 GPU。限额为每密钥 60 次/分钟、10,000 次/月。OpenAPI 在 /docs。仓库与 API 独立:复现论文用仓库,做发现战役用 API。
训练、评估与预测的工程结构
train.py 加载 YAML,组装 HorizynDataModule + HorizynLitModule + Lightning Trainer。全部数据 in_memory=True:216K × 1024 × 4 字节约 880 MB 蛋白嵌入,指纹再进 InMemoryCache。这是用内存换掉训练期 I/O。
验证被拆成三个 DataLoader,对应 Lightning 对“一个 step 不能扫完 216K 靶标”的妥协:
- 验证损失(配对 batch=16,384)
- 把完整 screening set(train+val+负例,216,132)编码进查找表
- 对每个 query 做全库排序,记录 Top-K
lightning_module.py L263–265 用注释强调:必须用 _screening_target_data,不能用仅含 val 蛋白的 _target_data。闭集小库会把命中率虚高到没有战役意义的数字。
优化器为 AdamW(lr=1e-4,weight_decay=0.01),无学习率调度;max_epochs=100,每 10 个 epoch 验证一次;devices=1。DDP 的 all_gather 分支留在查找表更新里,但训练入口锁单卡。Checkpoint 监控 val/loss,save_top_k=3。
测试在仓库质量上是加分项:tests/unit/ 与 tests/integration/ 合计约 8,100 行,覆盖标准化、指纹、损失、三路验证和 nanodata 冒烟。SOTA 全量评估 test_sota.py 在数据未下载时会跳过——因此 CI 绿不代表 76.7% 被复现。
设计取舍与风险
| 选择 | 换到的东西 | 付掉的代价 |
|---|---|---|
| 全批 MLNCE,batch 16,384 | 多标签、大负样本池 | ≥16 GB 显存;消费级卡几乎跑不了 SOTA |
| 冻结 ProtT5,只训 MLP | 与论文消融一致;复现门槛低 | 新蛋白家族必须自备同分布 1024 维嵌入;无法端到端微调 |
| 双向字符串增广 | 可逆反应样本翻倍 | 不可逆反应的逆方向成为噪声标签 |
| 完整 216K screening | 指标接近真实库检索 | 验证慢;闭集数字不可比 |
| 去电荷时按电荷差补质子 | 跨库电荷表示统一 | NADH/NAD⁺ 这类质子耦合反应可能被改计量 |
| 默认不 Kekulize | 保留芳香性 | 芳香/Kekulé 混源 SMILES 可能分裂为两个 query |
另外三件事实性风险:
- Top-1 未在本报告中复现。 README 的 32.4% 需要一次
evaluate.py才能从“声称”变成“本地数字”。 - 论文基准集与仓库文件计数不完全相等。 发文或做对照时要写明用的是哪一张表。
- 分数不是活性。 余弦相似度排序的是“像不像训练集里的正对”,在分布外反应上可以系统性自信且系统性错。
速览与结论
| 项 | 值 | 状态 |
|---|---|---|
| 论文 | PNAS 123(12) e2520070123,2026-03-17 | 已核 DOI / 日期 |
| 模型 | 双编码器 MLP,512 维 L2 球面 | 与 configs/sota.yaml 一致 |
| 反应表示 | ECFP6 struct 1024 ⊕ DRFP 1024 | 代码 + 论文 Fig. 1D |
| 蛋白表示 | 静态 ProtT5-XL 1024 维 | 仓库不分发 T5 权重 |
| 损失 | FullBatch MLNCE,β=10 | losses.py L240–256 |
| Top-100 | 76.7%(vs EC-3 基线 27.5%) | PNAS 正文;非本机复现 |
| Top-1 | README ≈ 32.4% | 未跑 evaluate.py |
| 湿实验 | 孤儿转氨酶、转氢酶、dCMP kinase | 论文实验室,非仓库 |
| 本地检查点 MD5 | 与 README 一致 | 本机 md5sum 已跑 |
| 托管检索库 | 6.33M 蛋白 | API 文档 |
| 许可证 | PolyForm NC 1.0.0 | 非商业 |
Horizyn 把酶设计里最不像“生成”的那一步做成了可扩展的检索:用反应的化学图变化去问自然酶库。论文用 76.7% 的 Top-100 和几例湿实验说明,这件事在孤儿反应与杂泛性上已经能给出可纯化的候选。仓库则把同一几何——指纹 ⊕ 蛋白 LM ⊕ 全批 MLNCE ——收成可训练、可测试、可离线查询的 Lightning 项目。
它加速的是战役的第一枪。后续的折叠、口袋设计、动力学和工艺放大,仍然要交给别的网络和别的实验。对正在做酶设计的人,合理用法是:用 API 或 inf 检查点拿到 Top-K 起始序列,再进入自己的结构/进化管线;用 dev 检查点复现指标时,坚持完整 216K screening,并自己跑一遍 evaluate.py,不要转抄 README 的 Top-1。
论文:Rocks et al., Dual-encoder contrastive learning accelerates enzyme discovery, Proc. Natl. Acad. Sci. U.S.A. 123(12): e2520070123 (2026). doi:10.1073/pnas.2520070123
预印本:bioRxiv 10.1101/2025.08.21.671639
API:api.horizyn1.dayhofflabs.com/docs
本地审阅路径:/home/qiao/md/horizyn(README、codemap、system_architecture、源码与检查点)