对称性破缺晶体生成:Markovian Jump Diffusion 方法与环境复现指南
2026/9/10 2:52:38 网站建设 项目流程

前阵子看到一篇晶体结构生成方向的论文题目很有意思:Symmetry-Breaking De Novo Crystal Generation via Markovian Jump Diffusion。它不是“套模板生成一个 CIF”的普通练习,而是把生成模型直接放在晶体结构采样上,并且专门瞄准了对称性破缺这一类结构。

如果不做材料科学,光看标题也能抓住三个重点:De Novo表示从零生成,不靠已知模板拼接;Symmetry-Breaking强调低对称结构;Markovian Jump Diffusion是核心生成框架,用于同时处理连续坐标和离散状态。

这类工作对软件工程同学来说,和“一键启动 WebUI”完全不是一回事。它更像一个 AI for Science 研究项目,需要自己搭环境、下载结构数据库、训练或加载 checkpoint、批量采样,再用 pymatgen、ASE 这类工具验证结果。这篇文章我会把任务背景、方法设计、复现思路、测试流程和批量筛选几个环节拆开讲,重点解决三个问题:它到底做了什么、自己想复现时环境怎么搭、生成出来的晶体怎么判断有没有用。

1. 核心能力速览

先给一个总览表。这里的参数不是官方文档复制出来的完整值,因为我目前没有拿到论文最终代码仓库和权重文件的全部细节。更稳妥的说法是:一切以论文原文、代码仓库 release 页面和配置文件为准

能力项说明
任务类型Crystal Generation,无机晶体结构的 de novo 生成
核心方法Markovian Jump Diffusion,连续扩散与离散跳变结合的生成框架
设计重点Symmetry-Breaking,关注高对称原型相之外的对称破缺结构
模型输入通常可包含化学组成、原子数量或初始上下文;具体字段需看原文
模型输出晶格参数、分数坐标、元素种类;可转存为 CIF / POSCAR
是否支持 CPU小规模推理有可能运行,训练和大批量采样不建议
推荐 GPU训练侧建议高显存单卡或集群;推理侧显存取决于模型规模和批量数,需实测
是否支持 API还没有“产品化 API”的说法;如果后续开源,大概率自己用 FastAPI 包一层
是否支持批量任务适合脚本批处理,按 seed 或 batch size 控制采样数量
是否一键启动属于学术项目,基本没有整合包;复现需要手动配置环境
适合人群材料信息学、生成模型、AI4Science 方向研究者和工程同学

这张表的意思很明确:看这篇论文不能抱着“下载双击就能跑”的期待。它的价值更多是算法设计思路和生成范式,而不是现成的用户工具。

2. 它在解决什么问题:为什么晶体生成要专门提“对称破缺”

晶体生成模型的发展,很大程度上是围着“如何把晶体结构约束在一个合法空间里”转的。

晶体结构由晶格、原子位置和元素种类构成。实际材料中有空间群概念,230 种空间群定义了结构的对称限制。早期很多方法会直接利用空间群信息:先把空间群固定,再生成在这个空间群限制下的原子坐标。这样做的优点是生成结果“看起来合理”,不会出现对称性混乱的结构;缺点是过度约束

真实材料有很多有趣性质恰恰来自对称性破缺。举个例子:一个高对称的母相结构,在温度、压力或成分变化后,可能通过原子位移变成对称性更低的畸变结构。铁电材料、钙钛矿中的八面体倾转、Jahn-Teller 畸变,都是这类现象。如果生成器只会固定在某一空间群里挑选输出,它就没有能力覆盖这些真正重要的低对称候选结构。

这篇论文题目里专门放Symmetry-Breaking,说明作者想解决的核心问题是:生成模型不能只在受限空间群里“安全地”找答案,而要能在可能的对称破缺构型空间里完成搜索

再回到De Novo。De novo 生成意味着不需要把已知晶体结构片段拿来拼接,也不依赖一个已有的母相模板。模型给出一组条件,比如化学组成,或者更少的条件,然后从随机状态出发,逐步生成晶格和坐标。这种“从零开始”的生成方式,适合做新材料探索,因为它理论上可以跳出已知原型结构的范围。

所以这件事实际是在回答一个材料科学家非常关心的问题:当模型把“可能的对称破缺构型”也纳入生成空间时,能不能找到更多具有潜在价值的候选结构?

3. 方法核心:Markovian Jump Diffusion 怎么建模晶体

3.1 连续坐标和离散状态怎么统一

扩散模型的思路是:前向过程逐步把数据加噪,让数据分布退化成已知噪声分布;反向过程学习去噪,从噪声一步步还原出数据。图像扩散处理的是连续像素,相对直接。但晶体结构是“连续 + 离散”混合对象:

  • 连续部分:晶格参数、原子分数坐标。
  • 离散部分:每个原子位点上的元素种类、可能出现的缺陷或位点占据。

如果只用一个连续扩散过程处理所有变量,元素种类这类离散信息很难表达好。Markovian Jump Diffusion 的思路是在同一个随机过程中引入两种行为:连续部分的扩散漂移,以及离散部分的马尔可夫跳变。这样模型可以在更新原子坐标的同时,调整离散状态,最终生成一个同时具备合理成分和合理坐标的结构。

为什么这比“先生成元素种类,再生成坐标”更好?因为原子坐标和元素种类会相互影响。某一位置放什么元素,取决于周围原子的种类和距离;反过来,周围坐标也会因为元素类型改变而产生弛豫。联合建模可以把这种耦合关系放进同一个去噪循环里,而不是人为地切成两个独立步骤。

3.2 对称性从哪里来

但这里有个难点:扩散模型生成物理结构时,如果只是单纯拟合数据,很可能生成一堆能量上完全不合理、或者只有局部看起来像晶体的结果。

晶体生成对模型结构有两个天然要求:

  1. 周期性:模型要理解晶格平移对称性,不能把原胞外很远的原子关系当作近邻关系。
  2. 等变性:整体旋转或平移晶体,生成结果的能量和概率不应改变。

常见的实现手段是使用周期图神经网络,在截断半径内建立原子邻居关系,并使用具有等变性的特征更新。如果接触过 e3nn、MACE、NequIP,会比较容易理解这种设计。如果论文代码用到这些库,环境配置时一定要特别留意pytorch_scattere3nn的版本匹配,这是本地复现最容易踩坑的位置。

从题目无法直接看出模型内部用的是什么 Backbone,需要以论文正文实际公式和代码为准。但可以判断的是,一个完整的 MJD 晶体生成流程至少包含:

  • 前向扰动策略:决定连续噪声和离散跳变的强度。
  • 去噪网络:根据当前状态,预测连续坐标的更新方向和离散状态的分布。
  • 采样器:反向迭代产生结构。

3.3 与固定空间群方法的直观区别

直观理解它们的区别,可以看两张“路径”:

固定空间群方法:

  1. 给定或预测空间群。
  2. 在空间群约束下确定 Wyckoff 位置。
  3. 生成满足该空间群的原子排布。

这种路径适合生成“空间中本来就高对称”的晶体,但不容易描述“高对称母相因为畸变变成低对称相”的构型。

对称破缺友好的方法:

  1. 从随机状态出发,同时建模连续坐标和离散状态。
  2. 反向去噪时逐步形成稳定的局域结构。
  3. 最终结构可能是低对称构型,也可能检测出更高空间群。

换句话说,空间群不是前置条件,而是生成结果的某种“事后属性”。这种设计更贴近真实材料中“对称性不是硬性约束,而是能量最低化之后涌现出的规律”这一物理直觉。

4. 数据准备与评估指标

4.1 数据来源

材料晶体生成模型通常依赖无机晶体结构数据库训练。常见来源包括:

  • Materials Project:开放 API,需注册获取 API Key,结构化数据比较规范。
  • ICSD:无机晶体结构数据库,覆盖面广,但部分数据需要授权。
  • OQMD:计算材料数据平台,关注热力学性质。
  • 文献中自带的原子结构数据集。

训练前需要做标准化:统一元素表示、统一晶格表示、处理空间群标签、剔除不合理的结构。由于无法确定论文具体用了哪些数据集,这里不给硬性版本要求。复现时以论文Data Availability和代码仓库README为准。

4.2 生成质量的评估

晶体生成模型只看生成图片式 CIF 是不行的,下面几个维度比较常用。

结构有效性

生成结构是否能通过基本几何检查,比如原子间距是否过近、晶胞体积是否合理、元素组成是否完整。

重复率和多样性

相同条件生成多个样本,如果大部分结果都长一个样,说明模型塌缩了。多样性过低,会导致后续筛选池太小。

空间群统计一致性

把生成结构的空间群分布和训练集分布做对比。理想情况下,生成结果的空间群分布应该和真实材料分布接近。但这里要注意,论文如果强调 Symmetry-Breaking,那么直接把生成结果的空间群映射到固定原型,然后批评它不对称,就不是客观做法。

稳定性初筛

把生成结构用机器学习势或第一性原理方法进行结构弛豫,计算生成结构与真实能量凸包的关系。常见指标是 energy above hull,值越小,表示越接近热力学稳定。

DFT 或高精度验证

对少数高潜力的候选结构做 VASP 等第一性原理验证。由于计算成本高,通常只对批量筛选后的 top 结构执行。

如果在博客或代码笔记里复现这篇论文,评估部分最值得写清楚的是:区分“生成结构长得好看”和“生成结构热力学稳定”。前者可以用解析工具快速算,后者需要昂贵的物理验证。

5. 环境准备与依赖清单

论文级项目依赖的包通常高度定制,建议先建一个干净 Python 环境,再安装依赖。这里给的是通用依赖模板,具体版本以论文仓库为准。

conda create -n mjd-crystal python=3.10 -y conda activate mjd-crystal # PyTorch 版本需要根据本机 CUDA 调整,比如 CUDA 12.1 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121 # 材料结构处理基本工具 pip install pymatgen ase numpy scipy pyyaml # 图神经网络相关,按需安装 pip install e3nn torch_geometric torch_scatter

几点补充:

  • pymatgen负责 CIF、POSCAR 解析和空间群分析,基本必装。
  • ase负责原子结构操作和一些经典势接口。
  • 如果模型使用等变图网络,e3nn大概率会出现在 requirement 中。
  • torch_scatter这类扩展包对 PyTorch 版本非常敏感,不要随意pip install最新版,优先安装和本地 PyTorch 对应的预编译版本。
  • 如果本地没有 NVIDIA 显卡,推理理论可以硬跑 CPU,但速度会慢非常多。训练基本建议单卡显存 24GB 起步,或者使用多卡 DDP。

6. 安装、训练与采样的通用流程

6.1 目录结构

一篇论文如果开源,仓库目录通常可以整理成下面这种结构,方便管理数据、配置、模型和输出:

crystal-gen/ ├── configs/ │ ├── train.yaml │ └── sample.yaml ├── data/ │ └── raw/ ├── datasets/ │ ├── crystal_dataset.py │ └── tokenizer.py ├── models/ │ ├── eq_net.py │ └── heads.py ├── diffusion/ │ ├── noise_schedule.py │ ├── jump_process.py │ └── sampler.py ├── scripts/ │ ├── train.py │ └── sample.py └── outputs/ ├── ckpt/ └── structures/

训练和采样入口不一定就叫train.py,不同仓库差异很大。拿到仓库后可以先看READMEconfigs文件夹,优先理解命令行参数和 checkpoint 加载方式,再跑小规模实验。

6.2 训练启动示例

假设仓库使用 PyTorch 和配置系统,启动训练的通用形式是:

# 单卡训练 python scripts/train.py --config configs/train.yaml --gpu 0 # 多卡 DDP 训练 torchrun --nproc_per_node=4 scripts/train.py --config configs/train.yaml

训练第一步建议不要直接上全量数据。可以先在几百条结构上跑 20 个 step,确认数据加载、模型 forward、loss 计算和 checkpoint 保存都正常。这样能避免显存报错后才发现是数据管线问题。

6.3 采样启动示例

采样流程通常是:

python scripts/sample.py \ --ckpt outputs/ckpt/last.ckpt \ --num_samples 10 \ --batch_size 10 \ --outdir outputs/structures

如果没有官方脚本,也可以自己写一个任务级采样逻辑。下面是一段示意代码,只表达流程,不针对某个具体模型:

import os import torch def run_sampling(model, num_samples=16, batch_size=4, outdir="outputs/structures"): os.makedirs(outdir, exist_ok=True) model.eval() with torch.no_grad(): for start in range(0, num_samples, batch_size): batch_seeds = list(range(start, min(start + batch_size, num_samples))) # 返回 Structure 列表,接口以实际模型为准 structures = model.sample(seeds=batch_seeds) for seed, structure in zip(batch_seeds, structures): filename = os.path.join(outdir, f"sample_{seed:04d}.cif") structure.to(filename) print(f"saved {filename}") if __name__ == "__main__": model = load_model() run_sampling(model)

这种设计的好处是:采样数量不再依赖 GPU 显存一次性容纳全部输出,而是用进度分片的方式控制峰值占用。

7. 功能测试与效果验证

模型跑通之后,不要只看 loss 下降就认为没问题。我们需要建立一套从生成到验证的闭环。

7.1 生成物自动解析

先用 pymatgen 自动读取生成结构:

from pymatgen.core import Structure from pymatgen.symmetry.analyzer import SpacegroupAnalyzer path = "outputs/structures/sample_0000.cif" structure = Structure.from_file(path) print("formula =", structure.composition.reduced_formula) print("lattice =", structure.lattice.parameters) print("num_atoms =", len(structure)) analyzer = SpacegroupAnalyzer(structure, symprec=0.05) print("space_group =", analyzer.get_space_group_symbol()) print("crystal_system =", analyzer.get_crystal_system())

如果代码在执行过程中报错,优先检查 CIF 文件是否缺少元素类型、分数坐标是否越界、晶胞参数是否非法。

7.2 对称性检查

在强调 Symmetry-Breaking 的工作里,直接看生成结构空间群还不够。建议额外比较“初始生成结构”和“弛豫后结构”的空间群差异。如果初始结构是高对称原型,经过局部结构弛豫后变成对称性更低的结构,正说明它抓住了对称破缺的势能面特征。

反过来,如果所有生成结构都能直接匹配训练集中的高对称原型,那么模型可能并没有真正学到低对称区域,只是在重复记忆固定空间群模板。

7.3 用机器学习势做稳定性初筛

结构弛豫不一定要立刻上 VASP。现在有很多可用的机器学习势能模型,比如 CHGNet、M3GNet、MACE。用它们做粗筛,计算速度远高于 DFT。下面是一个 CHGNet 示例:

from chgnet.model.dynamics import StructureRelaxer from pymatgen.core import Structure structure = Structure.from_file("outputs/structures/sample_0000.cif") relaxer = StructureRelaxer() result = relaxer.relax(structure) relaxed_structure = result["final_structure"] relaxed_structure.to(filename="relaxed_sample_0000.cif")

这里必须说明:机器学习势的预测结果只能作为初筛,不能替代真实的 DFT 计算。材料发现流程中,机器学习势筛选后的少数候选结构,仍然需要通过第一性原理验证能量和动力学稳定性。

8. 批量生成与二次筛选

晶体生成真正有价值的场景,不是生成一个结构看看长什么样,而是批量生成一个候选结构库,再通过稳定性、稀有性等指标筛出少数结构。

8.1 批量队列

用不同 seed 控制采样过程,是常见的去重逻辑。每个 seed 生成一个独立随机过程,尽量避免全部输出卡在同一个局部模式里。

import os import json records = [] for seed in range(100): # 单次采样,需要根据模型接口调整 structure = model.sample(seed=seed) filename = f"outputs/structures/seed_{seed:04d}.cif" structure.to(filename) records.append({ "seed": seed, "formula": structure.composition.reduced_formula, "volume": structure.volume, "space_group": SpacegroupAnalyzer( structure, symprec=0.05 ).get_space_group_symbol(), "file": filename }) with open("outputs/manifest.json", "w", encoding="utf-8") as f: json.dump(records, f, ensure_ascii=False, indent=2)

批量任务最好在tmuxscreen中运行,避免终端断开导致采样中断。每个批次结束后写一次 manifest,比全部跑完再写更安全。

8.2 二次筛选

大批量生成后的候选结构,通常按以下几个阶段筛选:

第一阶段,用 pymatgen 做几何检查,剔除明显不合理的结构。第二阶段,用 CHGNet 等机器学习势做结构弛豫,计算能量。第三阶段,计算能量 above hull 或形成能,保留接近凸包的结构。第四阶段,对筛选出的少量结构做 DFT 验证。

需要注意的是,重复度分析不要只看化学式是否相同。同一个化学式完全可能对应不同空间群、不同原子排布。更严谨的做法是使用 pymatgen 的StructureMatcher判断两个结构是否实质相同。

9. 资源占用与性能观察方法

论文没有给出现成的“一键启动包”,因此实际资源占用必须以本机运行结果为准。这里给一套观察方法。

训练阶段最值得关注三个指标:

  1. 模型 forward 和 backward 的显存峰值。
  2. 单 step 耗时。
  3. 数据加载是否是瓶颈。

可以用nvidia-smi -l 1周期性观察显存:

watch -n 1 nvidia-smi

也可以借助psrecord记录模型进程的 CPU 和内存占用:

psrecord $(pgrep -f train.py) --log memory.log --interval 5

采样阶段通常比训练阶段显存压力小,因为不保存梯度和优化器状态。但如果一次性采样数量太多,仍然可能超过显存限制。遇到 OOM 时,优先把 batch_size 调小,而不是换更大显卡。比如从 batch_size 64 降到 8,往往能把峰值显存大幅压低。

如果使用 CPU 推理,速度慢是正常现象。晶体结构的状态空间包含晶格、坐标和元素类别,反推过程每步都要做图卷积或注意力计算,CPU 很难发挥并行效率。更合适的策略是先用小 batch 在 CPU 上验证代码逻辑,再切到 GPU 跑正式实验。

10. 常见问题与排查方法

问题现象可能原因排查方式解决方案
依赖安装失败,比如 torch_scatter 编译报错PyTorch 与扩展包版本不匹配查看本地 PyTorch 版本和 CUDA 版本安装与 PyTorch 匹配的预编译 wheel
Materials Project 数据下载失败API Key 未配置或网络被限制检查环境变量 PMG_API_KEY配置正确的 API Key,确认数据库使用条款
训练 loss 为 NaN学习率过大、数值稳定性不够查看 loss 分段、检查输入是否有 NaN降低学习率、开启混合精度或调整跳变速率
采样结果化学组成错误离散元素状态没有被正确约束检查条件信息是否传入模型调整组成条件编码,或采样后做化学式过滤
显存不足 OOMbatch_size 过大或单结构原子数太多查看 nvidia-smi 的显存占用降低 batch_size、限制最大原子数、使用梯度累积
生成结构原子间距过近去噪网络没有学到足够排斥势可视化几批样本几何分布增加结构合理性 loss 或后处理过滤
采样结果大量重复扩散温度太低或 seed 覆盖不够统计结构去重率调整采样噪声,提高 seed 数量
多卡训练无法启动DDP 初始化失败,端口或通信错误查看 torchrun 日志固定 init_method、检查网卡和端口

11. 最佳实践与合规使用

从实验工程角度看,这类论文复现有几条比较实用的建议。

第一,第一次跑通前,不要追求全部复现,只跑极小数据、极小模型、极少步数,确认整条管线能闭环。很多项目卡在不是模型太差,而是数据预处理或依赖配置的问题。第二,训练集、验证集、测试集要按结构相似性切分,而不是随机切分,否则同一母相结构的畸变版本会同时出现在训练和测试中,造成指标虚高。第三,所有采样结果都要写输出日志和 manifest,记录 seed、生成时间、checkpoint 版本、配置 hash,方便后续回溯。第四,删除模型崩溃产生的异常 CIF。

在合规和边界方面也要单独说明:Materials Project、ICSD 等数据库都有各自的使用条款,不要把授权数据随意二次分发。后续如果要把方法用于“新材料发现”,生成的成分和结构可能涉及专利或知识产权申请,需要做充分的前期检索。使用开源模型和代码时,也要留意模型权重许可证,特别是商用限制。生成结果用于实验合成前,必须经过人工复核和第一性原理验证,不能直接把模型输出当作真实材料稳定性结论。

12. 总结与下一步

这篇论文最有价值的地方,不是“又用了一个生成模型”,而是它把扩散建模的适用范围从一般的图像、文本,推进到了“连续坐标 + 离散状态 + 对称破缺约束”并存的晶体结构空间。对于做材料信息学的人来说,它对应的问题非常明确:怎么让模型既能生成高对称原型相,又不会漏掉真正决定材料性能的低对称畸变相。

从实际操作角度看,最应该先验证的功能有两项:一是模型能否根据给定化学组成稳定地生成符合基本几何约束的结构;二是生成结果在结构弛豫后,空间群是否会出现合理的变化。如果这两点跑通,后面的稳定性和稀有性筛选才有意义。

最容易踩的坑仍然是环境和数据处理。等变图神经网络相关扩展包版本极容易冲突,晶体数据集的切分又直接影响指标可信度。建议所有实验都从极小规模开始,先把生成、保存、解析、弛豫、空间群分析整条链路打通,再放大 batch 数量。

如果后续官方仓库开放代码,建议优先跑一次最小配置,再对比论文给出的消融实验。这类模型真正要关注的不是“这次刷了多少分”,而是它能不能在真实材料搜索场景里稳定产出值得做 DFT 验证的候选结构。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询