大数跨境

BioEmu2 全流程教程与测试 |微软开源发布的全原子生物分子结构与动力学模型

BioEmu2 全流程教程与测试 |微软开源发布的全原子生物分子结构与动力学模型 AI4Peptide
2026-11-08
2
导读:BioEmu2 是微软 Microsoft Research AI for Science 发布的全原子生物分

BioEmu2 是微软 Microsoft Research AI for Science 发布的全原子生物分子结构与动力学模型,代码和预览版权重已公开。输入蛋白、核酸、小分子等组分,它可以生成结构、采样多种构象,也可以从一个已有构象出发,预测一段时间后的结构。

工具发布页面

本文在 Linux + conda + NVIDIA RTX 4080 SUPER 上实测了两个体系:腺苷酸激酶 ADK 和 肌红蛋白。每个体系先生成 8 个初始候选,选一个作为起点,再推进 4 条轨迹:每条推进 20 次、每次 50 ns,加上起点共 21 帧,覆盖 1 μs 模型时间。下文依次介绍安装、YAML 输入、MSA、运行参数,以及多轨迹动画和接触热图的制作与解读。

code :https://github.com/microsoft/bioemu2

1 认识 BioEmu2

1.1 能做什么

一句话概括:输入分子组成,输出三维结构,并给出它可能怎样运动。

输入可以是蛋白、核酸、小分子等,支持单个分子和多链复合物;蛋白还可以额外提供 MSA 和接触信息。输出是全原子坐标,可用来查看折叠、结构域运动、结合口袋和分子间接触。

研究中我们通常关心三件事:结构长什么样、哪些部位会动、加入另一条链或配体后有没有变化。BioEmu2 把结构预测、多构象采样和时间推进放进了同一个模型。本文的 ADK 案例观察结构域和残基接触的变化,肌红蛋白案例观察血红素口袋和配体接触。

1.2 工作原理

BioEmu2 是约 5 亿参数的全原子扩散模型。训练数据包括 PDB 实验结构、AFDB 等预测结构,以及微软生成的分子动力学轨迹。前两类数据让模型学会"结构长什么样",轨迹数据让模型学会"结构怎么变"。

生成一个结构大致分三步:

1.编码分子信息。读取序列、化学组分、MSA 和可选的接触条件,算出一组表示。同一体系的表示可以缓存复用。
2.从噪声中去噪。从带噪声的原子坐标出发,反复修正,逐步得到合理的构象。
3.按任务切换条件。结构预测追求单个可靠结构;平衡采样追求构象多样;时间推进则额外输入起始构象和时间间隔。

时间推进的思路很直接:给定当前构象和时间间隔,模型采样"这段时间之后可能的构象"。每次调用只返回一个未来构象;把它作为下一次的起点反复调用,就串成一条轨迹。同一起点配合不同的随机噪声,就能得到多条轨迹。

模型不会输出这 50 ns 内的中间过程。

1.3 主要功能

功能
用途
入口与注意点
结构预测
从分子组成生成候选结构
bioemu2 predict-structure
;适合先得到一个结构
平衡构象采样
为同一体系生成多个独立构象
bioemu2 sample-equilibrium
;样本编号不代表时间先后
时间推进
从已有构象预测一段时间后的构象,连续调用即得轨迹
bioemu2 propagate
、EmuSession.propagate();官方建议间隔取训练覆盖的 1–1000 ns
复合物与配体
同时建模多条蛋白链、核酸和小分子
在 system YAML 中定义各组分、链和必要的化学键

使用方式:BioEmu2 先根据给定序列生成结构,再从初始结构出发,采样一段时间后可能的构象。按本文设置,每次推进 50 ns,反复执行,直到达到设定时间。

1.4 本文流程

两个案例走同一套流程:

定义分子组成 → 准备 MSA → 生成并筛选初始候选 → 从同一起点推进 4 条轨迹 → 分析接触、制作动画

每条轨迹 21 帧,覆盖 1 μs。第 6 节提供一个分析 skill,装进 agent 后可以直接处理这些结果。

2 安装

2.1 环境与目录

项目
本次环境
系统
Linux x86_64
GPU
RTX 4080S
NVIDIA 驱动
580.126.09
Python
3.12.16
BioEmu2
0.1.0rc0

软件、权重和缓存放在 ~/program/bioemu2,输入和结果放在 ~/work/bioemu2_tutorial_20261103,推理使用独立的 bioemu2 conda 环境。

# 创建软件与任务目录
mkdir -p ~/program/bioemu2
mkdir -p ~/work/bioemu2_tutorial_20261103/{inputs/msa,results,analysis}

2.2 创建 conda 环境

仓库支持 Python 3.12–3.14,官方基准和本文都用 3.12。uv 用来安装 Python 依赖。

# 创建并激活独立环境
source ~/miniconda3/etc/profile.d/conda.sh
conda create -n bioemu2 -c conda-forge python=3.12 pip uv -y
conda activate bioemu2

2.3 下载源码并安装依赖

源码固定到本次使用的 commit,确保输入格式和默认参数与实测一致。RTX 4080 SUPER 的计算能力为 8.9,满足官方 cuda 扩展的要求。

# 下载源码并切换到本次实测版本
git clone https://github.com/microsoft/bioemu2.git ~/program/bioemu2/bioemu2
cd ~/program/bioemu2/bioemu2
git checkout 06be369dd555849165a737472d42d936959e46fc

# 安装 CUDA 扩展和作图依赖
export UV_CACHE_DIR=~/program/bioemu2/cache/uv
uv pip install -e '.[cuda]' matplotlib pillow

3 权重与运行资源

本文使用 bioemu2-preview,Hugging Face revision 固定为 dd4b0c1b69984b68edcb6200a544213be4d75242。

先在终端中设置缓存目录。后面的 Python 代码按顺序放在同一个 Python 会话或 Notebook 中执行。

# 激活环境并设置缓存目录
conda activate bioemu2
export HF_HOME=~/program/bioemu2/cache/huggingface
export HF_HUB_CACHE=~/program/bioemu2/cache/huggingface/hub
export BIOEMU2_MSA_CACHE=~/program/bioemu2/cache/msa
export BIOEMU2_CCD_CACHE=~/program/bioemu2/cache/ccd
export BIOEMU2_TEMPLATE_CACHE=~/program/bioemu2/cache/templates
export BIOEMU2_EMBEDS_CACHE=~/program/bioemu2/cache/embeddings

模型支持首次加载时自动下载权重。

from pathlib import Path
from huggingface_hub import snapshot_download

model_dir = snapshot_download(
    repo_id="microsoft/bioemu2",
    revision="dd4b0c1b69984b68edcb6200a544213be4d75242",
    allow_patterns="checkpoints/bioemu2-preview/*",
)
checkpoint = Path(model_dir) / "checkpoints/bioemu2-preview/checkpoint.ckpt"

官方源连接不稳定时,可在启动 Python 前设置镜像:

export HF_ENDPOINT=https://hf-mirror.com

MSA 来自公共 ColabFold 服务,HEM、NBN、SO4 等化学组分定义由程序按需下载并缓存,不需要在服务器上部署完整数据库。

4 输入准备与关键参数

4.1 两个体系

ADK 直接使用官方的 ake.yaml:一条 214 aa 的蛋白链,不含配体。肌红蛋白以官方 myoglobin_101m.yaml 为基础,包含 154 aa 蛋白、SO4、HEM 和 NBN。

案例
组成
观察内容
ADK
A 链,214 aa,大肠杆菌单链腺苷酸激酶
各轨迹中 NMP、LID 的相对运动和残基接触变化
肌红蛋白
A 链 154 aa;B 链 SO4;C 链 HEM;D 链 NBN
口袋与配体的相对位置,以及配体与残基的接触变化

补充说明:

•4AKE 的默认 biological assembly 有两条蛋白链,所以直接使用官方单链 YAML。
•肌红蛋白序列与 101M 的沉积序列 一致,保留了该构建体的 F46V、D122N 突变;按本文从 1 开始的编号,对应 V47、N123。
•NBN 是正丁基异腈。
•references/ 中的实验 CIF 只用于核对输入;轨迹起点由模型采样得到。

4.2 YAML 输入

entities 列出各个组分:蛋白写完整序列,配体写 CCD 编码,asym_ids 指定链名。在 ~/work/bioemu2_tutorial_20261103 目录下,将下面两份配置分别保存为 inputs/adk.yaml 和 inputs/myoglobin.yaml,后面的代码直接读取它们。

ADK:inputs/adk.yaml

# E. coli adenylate kinase (AKE, PDB 4AKE) System.
entities:
  - entity_type: protein
    asym_ids:
      - A
    sequence: MRIILLGAPGAGKGTQAQFIMEKYGIPQISTGDMLRAAVKSGSELGKQAKDIMDAGKLVTDELVIALVKERIAQEDCRNGFLLDGFPRTIPQADAMKEAGINVDYVLEFDVPDELIVDRIVGRRVHAPSGRVYHVKFNPPKVEGKDDVTGEELTTRKDDQEETVRKRLVEYHQMTAPLIGYYSKEAEAGNTKYAKVDGTKPVAEVRADLEKILG
    mods: []
bonds: []

肌红蛋白:inputs/myoglobin.yaml

# 101M composition; no extra contact conditioning.
entities:
- entity_type: protein
  sequence: MVLSEGEWQLVLHVWAKVEADVAGHGQDILIRLFKSHPETLEKFDRVKHLKTEAEMKASEDLKKHGVTVLTALGAILKKKGHHEAELKPLAQSHATKHKIPIKYLEFISEAIIHVLHSRHPGNFGADAQGAMNKALELFRKDIAAKYKELGYQG
  asym_ids: A
- entity_type: ligand
  ccd_code: SO4
  asym_ids: B
- entity_type: ligand
  ccd_code: HEM
  asym_ids: C
- entity_type: ligand
  ccd_code: NBN
  asym_ids: D
字段
含义
entity_type
组分类型,本文用到 protein 和 ligand
sequence
完整蛋白序列,残基从 1 开始编号
asym_ids
链 ID,可写一个链名或一个列表
ccd_code
化学组分编号;HEM、NBN、SO4 的原子和化学键由 CCD 提供
mods
 / bonds
修饰和额外化学键;ADK 中为空

肌红蛋白输入没有加 contacts,也没有声明额外的共价键或金属配位键。

4.3 准备 MSA

BioEmu2 默认从公共 ColabFold 服务获取 MSA。下面依次处理两个蛋白:已有 A3M 时直接读取,没有时查询公共服务,然后保存到 inputs/msa/。

# 获取MSA
from bioemu2 import get_msa, load_system_and_contacts

task = Path.home() / "work/bioemu2_tutorial_20261103"

for case in ("adk", "myoglobin"):
    system, _ = load_system_and_contacts(task / "inputs" / f"{case}.yaml")
    msa_path = task / "inputs/msa" / f"{case}.a3m"
    msa = get_msa(system, source=msa_path) if msa_path.exists() else get_msa(system)
    msa_path.write_text(msa.a3m())
    print(case, "A3M records:", len(msa))

两个体系都只有一条蛋白链,不涉及 paired MSA。MSA 深度如下;当前版本的预处理默认最多使用前 4,092 行。

案例
下载的 A3M 记录数
实际使用的行数
ADK
16,866
4,092
肌红蛋白
1,170
1,170

4.4 关键参数

先分清几组概念:

•采样数是生成多少个候选;batch size 是每批同时算几个。
•推进次数是一条轨迹往前走几步;去噪步数是生成每个构象时内部迭代几次。本文推进 20 次、每次 50 ns,每次使用官方默认的 200 个去噪步。

四条轨迹从同一个起点出发,之后各自使用不同的随机噪声。

参数
本文设置
说明
num_starts
8
先生成 8 个平衡模式候选,按规则选出起点
num_trajectories
4
同一起点复制 4 份,分别推进
num_steps
20
每条轨迹推进 20 次,含起点共 21 帧
lag_time_ns
50
相邻两帧的模型时间间隔;20 次合计 1 μs
batch_size
4
每批同时算 4 个构象;显存不足就调小,并换一个结果目录
seed
ADK 20261103;肌红蛋白 20261104
固定随机数;第 k 步使用 seed + 1000 + k
采样器与去噪步数
edm
,200 步
官方默认值

起点怎么选:

•先用官方 high_quality 检查蛋白几何;
•肌红蛋白另外要求 H94 NE2 到 HEM FE 的距离在 1.5–3.0 Å 之间。
•选第一个通过的候选。这个距离窗口只用于挑选起点,推进过程中不添加任何配位键或约束。

5 实际运行

两例共用下面这段代码,按顺序完成读取输入 → 生成候选 → 选择起点 → 连续推进 → 保存轨迹。准备好前面的 YAML、MSA 和 checkpoint 后,在同一个 Python 会话中继续执行。

# 示例代码
import mdtraj as md
import numpy as np
from bioemu2 import (
    EmuSession, check_physicality, join_trajectory_steps,
    load_model, save_frames,
)

num_starts = 8
num_trajectories = 4
num_steps = 20
lag_time_ns = 50
batch_size = 4
model = load_model(checkpoint_path=checkpoint)

for case, seed in [("adk", 20261103), ("myoglobin", 20261104)]:
    system, contacts = load_system_and_contacts(task / "inputs" / f"{case}.yaml")
    msa = get_msa(system, source=task / "inputs/msa" / f"{case}.a3m")
    emu = EmuSession(system, model=model, mode="equilibrium", msa=msa, contacts=contacts)
    out = task / "results" / case

    # 生成初始候选,保留必要的蛋白几何筛选
    candidates = emu.sample(num_samples=num_starts, batch_size=batch_size, seed=seed)
    report = check_physicality(candidates, system=system)
    save_frames(candidates, out / "starting_candidates", physicality=report)
    eligible = report.passed.copy()

    # 肌红蛋白额外筛选 His94 NE2–HEM FE 距离,MDTraj 的 nm 转为 Å
    if case == "myoglobin":
        his = next(a.index for a in system.topology.atoms
                   if a.residue.chain.chain_id == "A"
                   and a.residue.resSeq == 94 and a.name == "NE2")
        fe = next(a.index for a in system.topology.atoms
                  if a.residue.chain.chain_id == "C" and a.name == "FE")
        distance = md.compute_distances(candidates, [[his, fe]], periodic=False)[:, 0] * 10
        eligible &= (distance >= 1.5) & (distance <= 3.0)

    selected = int(np.flatnonzero(eligible)[0])
    print(case, "起点候选:", selected + 1)
    step_frames = [candidates[[selected] * num_trajectories]]

    # 每次同时推进四条轨迹;本次输出作为下一次输入
    for step in range(1, num_steps + 1):
        frames = emu.propagate(
            step_frames[-1],
            lag_time_ns=lag_time_ns,
            batch_size=batch_size,
            seed=seed + 1000 + step,
        )
        step_frames.append(frames)

    # 将按步骤排列的构象整理为四条轨迹;时间自动设为 ps
    trajectories = join_trajectory_steps(step_frames, lag_time_ns=lag_time_ns)
    for i, trajectory in enumerate(trajectories, 1):
        report = check_physicality(trajectory, system=system)
        folder = out / f"trajectory_{i:02d}"
        save_frames(trajectory, folder, physicality=report)
        np.savez_compressed(folder / "coordinates.npz", xyz=trajectory.xyz, time=trajectory.time)

step_frames 中每一项都包含四条轨迹在同一步的构象;join_trajectory_steps() 将它们拆成四条时间有序的轨迹,并设置 0、50、100……1000 ns 对应的时间。physicality.json 记录每帧的几何检查结果,全部推进帧都会保存。

配套材料中已经包含完整的 results/。直接分析可进入第 6 节;自己重新计算时,先按第 7.3 节保留已有结果。

5.1 ADK:四条轨迹与残基接触

ADK 使用随机种子 20261103,选择第一个通过蛋白几何筛选的候选作为四条轨迹的共同起点。

结果:8 个初始候选都通过了几何检查,选第 1 个作为起点。4 条轨迹都推进到 1 μs,80 个推进端点全部通过 high_quality 检查。

图 1|ADK 多轨迹动画。灰色为 CORE,紫色为 NMP(30–59),金色为 LID(122–159),四条轨迹都按 CORE 对齐。21 个原始帧经插值扩展为 201 帧,以 25 fps 播放,Display t 标出插值位置。可以看到 NMP、LID 和环区在各条轨迹中的位置变化,整体折叠保持稳定。

ADK 接触占有率与差值热图

图 2|ADK 残基接触。左图统计 50–500 ns,中图统计 550–1000 ns,右图为两者之差(后减前)。占有率范围 0–1,差值色阶 −0.4–0.4;细线标出 CORE、NMP、LID 的边界,灰色格子是被排除的自身和相邻残基。

下表列出两组变化最大的接触,以及一组 CORE/NMP 边界附近的接触(编号对应输入序列):

接触对
前半程
后半程
差值
Phe109–Gly198
47.5%
80.0%
+32.5 个百分点
Leu107–Lys195
37.5%
7.5%
−30.0 个百分点
Ile29–Met34
55.0%
82.5%
+27.5 个百分点

这说明在本次轨迹中,部分局部接触发生了调整。完整数据和每条轨迹单独计算的差值在 analysis/adk/ 中,可以进一步检查某个变化是否在多条轨迹中方向一致。

5.2 肌红蛋白:四条轨迹与配体接触

肌红蛋白由上面的循环接着计算,使用随机种子 20261104,推进参数与 ADK 相同。起点额外要求 His94 NE2–FE 距离位于 1.5–3.0 Å;这一筛选只影响起点选择,不会在推进过程中添加配位键或约束。

结果:8 个初始候选都通过了几何检查,His94 NE2–FE 距离也都在 1.5–3.0 Å 内。选第 1 个候选为起点,距离为 2.44 Å;80 个推进端点全部通过几何检查。

图 3|肌红蛋白多轨迹动画。蛋白为灰色半透明 cartoon,HEM 为紫色,NBN 为金色,SO4 为青色。四条轨迹按蛋白 Cα 对齐,使用相同的视角和缩放,便于比较口袋和配体的相对位置。动画同样是 201 帧、25 fps 的插值展示;热图只使用原始帧。

肌红蛋白配体接触占有率与差值热图

图 4|肌红蛋白配体–残基接触。每个面板从上到下依次为 HEM、NBN、SO4,横轴为蛋白残基编号。前两个面板是占有率(0–1),差值面板为 −0.3–0.3。SO4 的接触比较分散,HEM 和 NBN 集中在口袋附近。

接触对
前半程
后半程
差值
HEM–Leu33
40.0%
62.5%
+22.5 个百分点
HEM–Phe139
77.5%
95.0%
+17.5 个百分点
NBN–Leu30
15.0%
30.0%
+15.0 个百分点
SO4–Glu106
17.5%
2.5%
−15.0 个百分点

另外,HEM–His94 和 NBN–His65 在两个时间窗口中都是 100% 接触。按原子距离复核,80 个推进端点的 His94 NE2–FE 距离为 1.97–2.43 Å,中位数 2.18 Å。这些结果只描述本次轨迹中的口袋几何和接触情况,没有用来计算解离速率或结合自由能。

6 用 skill 制作动画和接触热图

我们把分析流程打包成了 bioemu2-analysis skill。把它放进支持 SKILL.md 的 agent 技能目录后,完成运行后直接给 agent 指明结果在哪、要分析什么,它就会调用附带的脚本完成接触分析、轨迹对齐和动画制作。

6.1 skill 内容

下载 BioEmu2 分析 skill:

网盘链接: https://pan.baidu.com/s/1z0MFl5_rlH1g0ZRqq6c7Hw?pwd=4jah 

提取码: 4jah 

bioemu2-analysis/
  SKILL.md                      # agent 的使用说明与统计约定
  agents/openai.yaml            # 显示名称与默认调用提示
  scripts/
    analyze.py                  # 读取坐标、接触统计、热图和对齐
    render_chimerax.py           # 统一视角与平滑过渡帧
    compose_animation.py         # 并排 GIF/MP4
    requirements.txt            # 分析与合成所需依赖
  references/
    data-contract.md            # 输入、单位、JSON 配置和输出定义
    workflow.md                 # 命令、依赖与核验方法
  assets/
    adk.json                    # 本文 ADK 的配置
    myoglobin.json              # 本文肌红蛋白的配置

输入为同一次输出中的 topology.cif 和 samples.xtc,也支持本文保存的 coordinates.npz。轨迹条数和帧数不限,但并排展示的轨迹必须原子组成、顺序和帧数一致,时间轨迹的时间点也要一致。处理新体系时,修改链、配体、对齐区域、接触阈值和时间窗口即可,不要照搬 ADK 的结构域编号。

6.2 安装与使用

直接将压缩包发给 agent 然后说安装这个 skill。

处理自己的体系时,换成实际路径,让 agent 根据拓扑生成 JSON 配置。

对齐方式可以参考本文:ADK 按 CORE 的 Cα 对齐,以保留 NMP、LID 的相对运动;肌红蛋白按蛋白 Cα 对齐。

其他蛋白默认按全部蛋白 Cα 对齐,也可以指定一个稳定的结构域。

7 输出、耗时与重新运行

7.1 结果目录

XTC 用于常见的分子可视化软件;NPZ 保留浮点坐标,供接触统计读取。

results/adk/                         # myoglobin 使用相同结构
  starting_candidates/
    topology.cif                    # 第一个初始候选
    samples.xtc                     # 全部 8 个初始候选
    physicality.json                # 初始候选的几何检查
  trajectory_01/ … trajectory_04/
    topology.cif                    # 拓扑和第一帧坐标
    samples.xtc                     # 21 帧时间有序轨迹
    coordinates.npz                 # xyz 为 nm,time 为 ps
    physicality.json                # 每个原始帧的几何检查

topology.cif 只含第一帧坐标,读取完整轨迹要同时加载 samples.xtc。每例共 4×21=84 帧,其中 4 个 t=0 是同一个起点,真正新增的推进端点是 80 个,热图基于这 80 帧。

7.2 耗时与显存

本机实测,batch_size=4。每次推进同时生成四条轨迹的下一帧。

项目
ADK
肌红蛋白
建模原子数
1,655
1,274
首次计算模型表示
7.9 秒
3.3 秒
生成 8 个初始候选
33.9 秒
28.8 秒
20 次推进合计
333.7 秒
259.5 秒
每次推进耗时中位数
16.56 秒
12.92 秒
从加载模型到写完结果
390.6 秒(6.51 分钟)
305.6 秒(5.09 分钟)
本进程显存峰值(2 秒采样)
7,444 MiB
3,976 MiB
PyTorch 张量分配峰值
5,181 MiB
2,993 MiB
推进端点几何检查
80 / 80 通过
80 / 80 通过

8 参考资料

1.BioEmu2 官方仓库:https://github.com/microsoft/bioemu2
2.BioEmu2 模型卡:https://github.com/microsoft/bioemu2/blob/06be369dd555849165a737472d42d936959e46fc/MODEL_CARD.md
3.定义分子体系:https://github.com/microsoft/bioemu2/blob/06be369dd555849165a737472d42d936959e46fc/docs/system.md
4.使用 MSA:https://github.com/microsoft/bioemu2/blob/06be369dd555849165a737472d42d936959e46fc/docs/msa.md
5.官方 ADK 多轨迹示例:https://github.com/microsoft/bioemu2/blob/06be369dd555849165a737472d42d936959e46fc/examples/simulate_a_trajectory.py
6.4AKE 实验参考:https://www.rcsb.org/structure/4AKE
7.101M 实验参考:https://www.rcsb.org/structure/101M


【声明】内容源于网络
0
0
AI4Peptide
专注探索人工智能在多肽药物设计与研发中的应用,定期发布相关的前沿研究、技术解析和行业动态,迎接未来智能药物研发的新时代。
内容 79
粉丝 0
AI4Peptide 专注探索人工智能在多肽药物设计与研发中的应用,定期发布相关的前沿研究、技术解析和行业动态,迎接未来智能药物研发的新时代。
总阅读4.3k
粉丝0
内容79