FastCSP 端到端晶体结构预测实战:从 SMILES 到分子晶体能量景观的完整工作流
【免费下载链接】ocpFAIR Chemistry's library of machine learning methods for chemistry项目地址: https://gitcode.com/GitHub_Trending/oc/ocp
导读
本文以 FastCSP 官方示例(src/fairchem/applications/fastcsp/example/)为主线,完整讲解一条SMILES → 构象生成 → 晶体结构生成 → ML 弛豫 → 能量修正 → 过滤去重 → 实验比对 → 振动自由能的端到端晶体结构预测(Crystal Structure Prediction, CSP)流水线。读者将掌握fastcsp-confgen与fastcsp两个 CLI 的用法、两个 YAML 配置文件中全部关键参数的语义与默认值、七阶段工作流的依赖关系与断点续跑机制,以及如何把示例规模(冒烟测试级)扩展到生产级吞吐(10–100 倍算力规模)。
示例概述:两个 JACS 测试集分子
示例针对 FastCSP JACS 测试集中的两个分子晶体:
- XULDUD:半刚性双环氧杂茚(semi-rigid bicyclic oxaindene),实验上有 2 个多晶型(refcode 为
XULDUD01、XULDUD); - WIDBAO:柔性噻唑啉-硫酮(flexible thiazoline-thione),实验上有 1 个多晶型(refcode 为
WIDBAO)。
该示例被定位为冒烟测试(smoke test)或可复制粘贴的起点:规模足够小、可在合理时间内跑通全部七个阶段,同时保留完整的生产级工作流结构,是理解 FastCSP 全流程的最佳入门素材。示例涉及的全部文件位于src/fairchem/applications/fastcsp/example/目录:
| 文件 | 用途 |
|---|---|
| molecules.csv | 共享输入:name,smiles,conformers_path,refcode,z,spg。fastcsp-confgen只读取name+smiles(忽略其他列);fastcsp读取name,conformers_path,refcode,z,spg(忽略其他列) |
| confgen_config.yaml | 构象生成配置(SMILES → 每个分子的 XYZ 文件) |
| fastcsp_config.yaml | 七阶段 CSP 工作流配置 |
| genarris_base.conf | Genarris 模板,被fastcsp_config.yaml引用 |
molecules.csv:一条 CSV 驱动两个工具
CSV 是整条流水线的"契约"文件,两个 CLI 各取所需字段:
name,smiles,select_for_fastcsp,conformers_path,refcode,z,spg XULDUD,C1CC2=COC=C12,1,conformers/conformers_fastcsp/XULDUD/,"XULDUD01,XULDUD","[1, 2, 4]","[[1],[2],[14]]" WIDBAO,CN(C)C(=S)N1C(=S)Sc2ccccc12,2,conformers/conformers_fastcsp/WIDBAO/,WIDBAO,"[2, 4]","[[14, 2, 4]]"各列含义:
name:分子标识,贯穿整个输出目录树;smiles:SMILES 字符串,仅fastcsp-confgen使用;select_for_fastcsp:可选列,控制每个分子有多少个(能量最低的)弛豫构象被镜像进conformers_fastcsp/子目录(XULDUD 取 1 个,WIDBAO 取 2 个);conformers_path:指向fastcsp第一阶段输入的构象目录(相对root解析);refcode:实验晶体 CCDC refcode,多个用逗号分隔(如"XULDUD01,XULDUD"),供evaluate阶段使用;z:每个分子允许的分子数(Z),如 XULDUD 为[1, 2, 4];spg:每个 Z 值对应的空间群编号列表(嵌套列表),如 XULDUD 为[[1],[2],[14]],即 Z=1 时只用 SG 1,Z=2 时用 SG 2,Z=4 时用 SG 14;WIDBAO 的[[14, 2, 4]]表示三种 Z 共享同一组空间群。
从 confgen 源码 的结构看,CSV 中凡是与CONF_GEN_DEFAULTS/RELAX_DEFAULTS中键名相同的列,还会成为按行(per-molecule)覆盖项,优先级为默认值 < YAML 配置 < CSV 列,每个 worker 在任务启动时会打印最终解析后的配置——这为按分子精细调参提供了入口。
动手前必须替换的占位符
两个 YAML 配置中都含有尖括号占位符,默认状态下没有任何路径是可移植的,必须逐一替换:
<PROJECT_ROOT>:所有输出落盘的绝对路径。必须在confgen_config.yaml和fastcsp_config.yaml中设为同一个值,这样工作流才能找到<PROJECT_ROOT>/conformers/conformers_fastcsp/<name>/*.xyz(该路径与molecules.csv的conformers_path列一致);<PATH_TO_GENARRIS>:安装了 Genarris 3.0 的 Python 环境(仅在generate阶段使用);<PATH_TO_MPIRUN>:对 Genarris 环境可见的 MPI 启动器(如mpirun);<PATH_TO_EXPERIMENTAL_CIFS>:存放<refcode>.cif文件的目录(evaluate阶段需要;没有实验参考数据可跳过);<YOUR_PARTITION>:每个阶段slurm:块的 SLURM 分区;- (可选)
<PATH_TO_CSD_PYTHON>:装有 CCDC Python API 的环境,仅在把evaluate.method从pymatgen切换为csd时需要。
第一步:从 SMILES 生成起始构象
fastcsp-confgen -c example/confgen_config.yaml该命令读取 molecules.csv(此阶段只需要name和smiles两列;可选的select_for_fastcsp列控制每个分子有多少构象被镜像进conformers_fastcsp/子目录),每个分子提交一个 SLURM 任务,最终写出:
<PROJECT_ROOT>/conformers/ ├── conformers_fastcsp/ # 按 select_for_fastcsp 精选的子集 │ ├── XULDUD/ │ │ └── XULDUD_conf_00_relaxed.xyz │ └── WIDBAO/ │ ├── WIDBAO_conf_00_relaxed.xyz │ └── WIDBAO_conf_01_relaxed.xyz ├── conformers_generated/ # 全部 RDKit 生成的(弛豫前) ├── conformers_relaxed/ # 全部 UMA 弛豫后的幸存者 ├── summaries/ # 每个分子的 .json 摘要 └── slurm/ # submitit 日志这些构象经过UMA-omol 力场 BFGS 弛豫、去重(Butina 聚类 + 能量门控)、以及energy_window能量窗口裁剪。完整的逐分子处理管线见 confgen/README.md,其核心步骤为:
- 种子池生成:
generate_conformers用四种互补策略(ETKDGv3 + MMFF、ETKDGv3 随机坐标 + MMFF、无 MMFF 的 ETKDGv3、均匀随机扭转)嵌入约initial_pool_size个构象,并剔除原子碰撞与连接性改变的几何; - 弛豫前 RMSD 聚类:此时能量为零,能量门控失效,直接对最佳 RMSD 做 Butina 聚类,先廉价丢弃近重复种子,避免浪费 UMA 计算;
- UMA 单点能:对预聚类池做单点能计算,输出到
conformers_generated/<name>/; - UMA 弛豫:使用 fastcsp 的
relax_atoms驱动(孤立分子、fix_symmetry=false、relax_cell=false),丢弃失败的弛豫,再做连接性检查,剔除键图改变的构象; - 弛豫后聚类 + 能量窗口:以
cluster_energy_thresh门控的 Butina 聚类,再用energy_window封顶,输出到conformers_relaxed/<name>/; - FastCSP 子集:若
select_for_fastcsp > 0,将该数量的最低能量弛豫构象复制进conformers_fastcsp/<name>/(弛豫池为空时才回退用conformers_generated/,不混用)。
值得注意的设计是立体化学不是独立阶段:从输入 SMILES 一次性计算 CIP 签名,用于(a)在每个*_confs.csv中标记每个构象的stereo_changed、stereo_diff列;(b)在第 5 步优先选择立体化学正确的簇代表。
confgen 配置文件逐项解析
confgen_config.yaml 是示例实际的构象生成配置,其键名与说明如下:
root: <PROJECT_ROOT> # 输出根目录(与 fastcsp_config.yaml 保持一致) molecules: molecules.csv # 与 fastcsp 工作流共享的单一 CSV rdkit: initial_pool_size: 40 # RDKit ETKDG 种子池大小 seed: 42 # 随机种子 rmsd_thresh: 0.25 # Butina 聚类半径(Å) cluster_energy_thresh: 1.5 # kJ/mol;能量差超过该值的构象对跳过 RMSD 比较 include_hydrogens: true # RMSD 是否包含全部原子(false = 仅重原子) output_format: xyz # fastcsp 可读 xyz/sdf/mol relax: calculator: uma_sm_1p1_omol # 使用 omol(分子)任务而非 omc optimizer: BFGS fmax: 0.05 # 力收敛阈值(eV/Å) max_steps: 100 # 最大优化步数 write_traj: false # 是否写 ASE 轨迹 energy_window: 40.0 # 最终弛豫池的能量上限(kJ/mol) slurm: # 每个分子的 SLURM 数组任务 timeout_min: 240 gpus_per_node: 1 cpus_per_task: 8 mem_gb: 32 # partition: <YOUR_PARTITION> # array_parallelism: 8关键参数说明:
rmsd_thresh与cluster_energy_thresh联合决定 Butina 去重的"相邻判定":先看能量差,若两构象能量差 ≥ 1.5 kJ/mol 直接视为不同,否则再比较 RMSD;include_hydrogens决定 RMSD 是在全原子还是重原子子集上计算,直接影响柔性分子的去重灵敏度;energy_window是弛豫后池子的能量封顶,超出最低能量 40 kJ/mol 的构象被裁掉,控制进入 CSP 的构象数量;calculator: uma_sm_1p1_omol表示用 UMA 的 omol(孤立分子/气相)任务变体做构象弛豫,与后续晶体弛豫用的uma_sm_1p1_omc明确区分。
该阶段还支持按分子覆盖:initial_pool_size、seed、rmsd_thresh、cluster_energy_thresh、include_hydrogens、output_format、calculator、optimizer、fmax、max_steps、energy_window、select_for_fastcsp均可作为 CSV 列逐行覆盖。此外 confgen 运行是可续的——conformers_generated/或conformers_relaxed/子目录非空的分子会被跳过。
第二步:运行晶体结构预测工作流
同一个 molecules.csv 驱动 Stage 1:其conformers_path列指向<PROJECT_ROOT>/conformers/conformers_fastcsp/<name>/。按顺序运行全部 7 个阶段:
fastcsp -c example/fastcsp_config.yaml \ -s generate process_generated relax \ compute_conformer_corrections filter evaluate compute_free_energy- 第 4、6、7 阶段是可选的——去掉其中任意一个,工作流仍可端到端运行;
- 自动续跑:失败后重新执行同一条命令,会从第一个未完成的阶段自动恢复。
七阶段在源码中的落地
从 core/workflow/main.py 的编排逻辑可以看到每个阶段的实际调用链与输出目录:
| 阶段 | 配置块 | 输入 → 输出 | 关键实现 |
|---|---|---|---|
| 1. generate | genarris | →generated_structures/ | generate.py 中run_genarris_jobs,为每个分子生成 Genarris SLURM 作业 |
| 2. process_generated | pre_relaxation_filter | generated_structures/→raw_structures/ | process_generated.py 读取 Genarris 输出、去重并写 parquet |
| 3. relax | relax | raw_structures/→relaxed/<run_name>/raw_structures/ | relax.py 用 UMA 做 ML 弛豫 |
| 4. compute_conformer_corrections(可选) | conformer_corrections | 改写raw_structures/(默认原地) | conformer_correction.py |
| 5. filter | post_relaxation_filter | →relaxed/<run_name>/filtered_structures/ | filter.py 能量过滤 + 最终去重 |
| 6. evaluate(可选) | evaluate | →relaxed/<run_name>/matched_structures_*/ | eval.py,pymatgen 或 CSD API |
| 7. compute_free_energy(可选) | free_energy | →relaxed/<run_name>/free_energy/ | free_energy.py 准谐波振动自由能 |
main函数还会在启动时把config.yaml与molecules.csv复制到root下存档,并通过 logging.py 的detect_restart检测是否续跑;阶段列表会被reorder_stages_by_dependencies按依赖重排,保证即使-s参数乱序也能正确执行。
fastcsp 配置文件逐项解析
fastcsp_config.yaml 是七阶段工作流的实际配置。下面按阶段逐块说明参数(示例值 + 语义):
Stage 1:Genarris 结构生成
genarris: mpi_launcher: <PATH_TO_MPIRUN> # 例如 /public/apps/openmpi/.../bin/mpirun python_cmd: <PATH_TO_GENARRIS>/bin/python # 装有 Genarris 的 Python genarris_cli: <PATH_TO_GENARRIS>/cli.py genarris_base_config: genarris_base.conf # 本目录下的兄弟文件 # (可选)计算节点环境初始化,会前置到每个 slurm.sh # env_setup: # - "source /etc/profile.d/modules.sh || true" # - "module load openmpi/3.1.1/gcc.7.3.0" # mpi_extra_args: "--oversubscribe --bind-to none --mca btl self,vader,tcp" vars: num_structures_per_spg: 10 # 小规模冒烟测试;生产建议 500+ read_z_from_file: true # 从 molecules.csv 按分子读取 Z read_spg_from_file: true # 从 molecules.csv 按分子读取空间群 slurm: job-name: example_genarris nodes: 1 ntasks-per-node: 20 time: 240 # partition: <YOUR_PARTITION>Genarris 模板 genarris_base.conf 定义了生成器的核心行为,其中多处???占位符由工作流在运行时填充(如name、molecule_path、Z、num_structures_per_spg、spg_distribution_type),关键控制项包括:
[generation]:max_attempts_per_spg = 100000000、tol = 0.01、unit_cell_volume_mean = predict、volume_mult = 1.5、generation_type = crystal、natural_cutoff_mult = 1.2,控制晶体生成的空间群采样密度与晶胞体积;[symm_rigid_press]:sr = 0.85、method = BFGS、tol = 0.01,控制对称性刚体加压弛豫;[workflow]:tasks = ['generation', 'symm_rigid_press']定义生成后紧接着的弛豫任务链。
read_z_from_file: true/read_spg_from_file: true使得每个分子的 Z 与空间群列表直接来自 CSV 的z、spg列,无需在配置中硬编码。
Stage 2:弛豫前去重
pre_relaxation_filter: assign_groups: true # 运行去重 blocker 并分配 group_index remove_duplicates: true # 每组只保留一个(代表 = 最接近组中位密度的结构) ltol: 0.3 # 晶格容差 stol: 0.4 # 位点容差(Å) angle_tol: 5 # 角度容差(°) bin_by_conf: true # 去重 bin 键加入 conf_id bin_by_z: true # 加入 Z bin_by_spg: true # 加入 spg_generated density_tol: 0.05 # 便宜的 |Δρ| 预过滤,先于 sm.fit npartitions: 1 # SLURM 数组大小(parquet 分区数) slurm: job-name: example_pre_relax_dedup cpus_per_task: 1 mem_gb: 100 time: 240Stage 3:UMA ML 弛豫
relax: calculator: uma_sm_1p1_omc # 有机分子晶体推荐使用 omc 任务 optimizer: BFGS fmax: 0.01 # 力收敛阈值(eV/Å) max_steps: 1000 # 最大步数 fix_symmetry: false # 弛豫时是否固定晶体对称性 relax_cell: true # 是否允许晶胞弛豫 write_traj: false slurm: num_ranks: 1 # GPU 任务数 array_parallelism: 1 timeout_min: 240从 relax.py 的CHECKPOINTS结构可以确认,calculator取值来自预训练 UMA 检查点键(如uma_sm_1p1_omc、uma_sm_1p1_omol、uma_sm_1p2_omc、uma_sm_1p2_omol),其中omc 变体面向有机分子晶体(organic molecular crystals),官方注释明确推荐。弛豫输出目录名<calculator>_<optimizer>_<fmax>_<steps>_...会把这三个超参数编码进去(示例中为uma_sm_1p1_omc_bfgs_0.01_1000_relaxcell)。
Stage 4(可选):逐构象片段能量修正
conformer_corrections: corrector_calculator: uma_sm_1p1_omol # 气相分子任务,作为 corrector separate_output: false # true 时写入镜像子目录而非原地改写 slurm: num_ranks: 20 timeout_min: 240该阶段是两级单点能方案:对每个 PBC 解缠绕的分子,分别用弛豫计算器和 corrector 计算器做单点能,然后计算
energy_corrected = energy_relaxed - sum_z E_original + sum_z E_corrector即用更精确的气相分子模型修正晶体中每个分子的片段能量贡献,默认原地改写raw_structures/下的 parquet。实现细节见 conformer_correction.py 的apply_conformer_corrections。
Stage 5:弛豫后过滤与去重
post_relaxation_filter: remove_problematic: true # 丢弃未收敛 / 连接性改变的 assign_groups: true # 去重 blocker + group_index remove_duplicates: true # 每组保留一个(代表 = energy_relaxed 最低者) energy_cutoff: 20 # 高于全局最低点 20 kJ/mol 的裁掉 density_min_cutoff: 0.5 # 弛豫密度下限(g/cm³) density_max_cutoff: 3.0 # 弛豫密度上限(g/cm³) ltol: 0.2 stol: 0.3 angle_tol: 5 slurm: job-name: example_post_relax_dedup cpus_per_task: 40 mem_gb: 100 time: 240注意此处容差比弛豫前更紧(ltol 0.3→0.2、stol 0.4→0.3),因为弛豫后的结构更接近物理合理状态。去重时代表结构的选择策略也与 Stage 2 不同:弛豫前取"最接近组中位密度"者,弛豫后取"energy_relaxed 最低"者(见 filter.py 与 deduplicate.py)。
Stage 6(可选):实验结构评估
evaluate: target_xtals_dir: <PATH_TO_EXPERIMENTAL_CIFS> # {refcode}.cif 文件目录 method: pymatgen # "pymatgen"(无需许可证)或 "csd"(需 CCDC API) pymatgen: match_params: # 透传给 pymatgen StructureMatcher ltol: 0.2 stol: 0.3 angle_tol: 5 slurm: job-name: example_eval_pymatgen cpus_per_task: 20 mem_gb: 50 time: 240 # csd: # python_cmd: <PATH_TO_CSD_PYTHON>/bin/python # 装有 CSD API 的环境 # num_cpus: 40XULDUD 需要XULDUD.cif、XULDUD01.cif(对应两个实验多晶型),WIDBAO 需要WIDBAO.cif。没有实验参考数据时可以直接删除整个块。eval.py 支持两种匹配器:pymatgen(StructureMatcher,无许可证要求)与csd(CCDC API,通过子进程分块流式调用)。评估输出目录后缀matched_structures_pmg_l0.2_s0.3_a5直接编码了匹配容差。
Stage 7(可选):振动自由能(准谐波)
free_energy: calculator: uma_sm_1p1_omc input_directory: filtered_structures # 默认;对全部过滤后的结构计算 match_only: false # true 时(配合 input_directory: matched_structures) # 只计算与实验匹配的结构 quasiharmonic: true # 准谐波近似(体积扫描) t_min: 0 t_max: 500 t_step: 10 # 温度网格(K) structures_per_job: 5 # 每个 SLURM 任务处理的结构数 compute_dos: false # 是否额外计算声子态密度 slurm: job-name: example_free_energy gpus_per_node: 1 cpus_per_task: 10 mem_gb: 50 time: 480该阶段对每个过滤后的结构做有限差分声子计算,输出 Helmholtz/Gibbs 自由能、熵、热容等热力学量在t_min..t_max..t_step温度网格上的数组,以及准谐波附加量(体模量、热膨胀系数、Grüneisen 参数)。match_only: true要求输入目录含match列(即matched_structures),否则会直接抛KeyError。
全局日志
logging: level: INFO # DEBUG / INFO / WARNING / ERROR console: true # 除 FastCSP.log 外同时输出到 stdout第三步:检查结果
作为参考,官方在 scavenge 队列上端到端运行约2.5 小时:
| 阶段 | 墙钟时间(scavenge 队列) | 输出 |
|---|---|---|
| generate | ~2 min | 7 个 Genarris 数组任务 |
| process_generated | ~1 min | 3 个去重任务 |
| relax | ~50 min | 10 个 GPU rank,覆盖 12 个 parquet |
| compute_conformer_corrections | ~1 min | 4 个 GPU rank(仅重打分) |
| filter | ~2 min | 2 个分子共 111 个过滤后结构 |
| evaluate | ~4 s | 2 个 pymatgen matcher 任务 |
| compute_free_energy | ~1h 35 min | 56 个 GPU 任务(每个任务 2 个结构) |
(注:该耗时仅供参考,取决于具体集群与队列资源,不应视为保证值。)
输出目录结构
<PROJECT_ROOT>/ ├── FastCSP.log # 工作流日志 ├── config.yaml # fastcsp_config.yaml 的副本 ├── molecules.csv # 输入 CSV 的副本 │ ├── generated_structures/ # Stage 1(Genarris 原始输出) │ ├── XULDUD/<conf>/Z<z>/structures.json # 每个 (mol, conf, Z, SG) 任务一个 JSON │ └── WIDBAO/<conf>/Z<z>/structures.json │ ├── raw_structures/ # Stage 2(处理后、去重前) │ └── <mol>/<conf>/partition_id=*/*.parquet │ ├── slurm/ # 工作流编排器的 submitit 日志 │ └── relaxed/ └── uma_sm_1p1_omc_bfgs_0.01_1000_relaxcell/ # <calculator>_<optimizer>_<fmax>_<steps>_... ├── raw_structures/ # Stage 3+4(弛豫后 + 修正后) │ └── <mol>/<conf>/partition_id=*/*.parquet ├── slurm/ # Stage 3 各 rank 的 submitit 日志 ├── slurm_conformer_corrections/ # Stage 4 各 rank 的 submitit 日志 ├── filtered_structures/ # Stage 5(每个分子一个 parquet) │ ├── XULDUD.parquet │ └── WIDBAO.parquet ├── matched_structures_pmg_l0.2_s0.3_a5/ # Stage 6(evaluate;后缀 = 容差) │ ├── XULDUD.parquet │ └── WIDBAO.parquet └── free_energy/ # Stage 7(每个分子一个 parquet) ├── XULDUD.parquet └── WIDBAO.parquet关键 parquet 列
最终每个分子的 parquet(filtered_structures/<mol>.parquet及其下游产物)同时携带CIF(cif_generated、cif_relaxed)与逐结构指标。每一行都有唯一的structure_id,形如mol=<name>::conf=<conf_id>::z=<Z>::spg=<SG>::hash=<12hex>,可据此回溯到轨迹 / SLURM 日志 / 实验匹配结果。
需要重点关注的列:
| 列名 | 阶段 | 含义 |
|---|---|---|
energy_relaxed_per_molecule | 3 | UMA-omc 弛豫能量(kJ/mol/分子) |
density_relaxed,volume_relaxed | 3 | 弛豫后晶胞(g/cm³、ų) |
optimizer_converged,optimizer_steps | 3 | BFGS 是否达到fmax、用了多少步 |
validity.crystal_relaxed.* | 3 | 3 个布尔量:correct_z、molecule_matches_reference、connectivity_unchanged |
correction.e_fragments_{original,corrector}_per_molecule | 4 | 用弛豫与 corrector 计算器得到的每分子片段单点能(kJ/mol) |
energy_corrected_per_molecule | 4 | energy_relaxed - sum_z E_original + sum_z E_corrector(每分子) |
validity.conformer_corrections.applied | 4 | 仅当该行两次单点能扫描都成功时为True |
group_index | 5 | 去重簇 id(-1= 保留的孤立结构或被过滤掉) |
pymatgen_match,pymatgen_rmsd | 6 | 仅当该行匹配到某个refcode时才非空 |
temperatures,free_energy,gibbs_free_energies,entropy,heat_capacity,heat_capacity_P | 7 | t_min..t_max..t_step网格上的数组(Helmholtz / Gibbs / S / C_v / C_p) |
bulk_modulus_P,thermal_expansion_coefficients,gruneisen_parameters | 7 | 准谐波附加量(同网格数组);compute_dos=true时还有phonon_dos |
validity.crystal_relaxed.*三个布尔量来自 structure.py 的check_correct_z、check_molecule_matches_reference、check_connectivity_unchanged,分别校验分子数 Z 是否正确、分子是否与参考键图匹配、弛豫前后连接性是否保持不变。
快速检视脚本
import pandas as pd df = pd.read_parquet( "<PROJECT_ROOT>/relaxed/<run_name>/filtered_structures/XULDUD.parquet" ) top = df.nsmallest(5, "energy_corrected_per_molecule") print( top[ [ "structure_id", "z", "spg_generated", "energy_corrected_per_molecule", "density_relaxed", ] ] ) # 与实验 refcode 匹配上的预测结构 mdf = pd.read_parquet( "<PROJECT_ROOT>/relaxed/<run_name>/matched_structures_pmg_l0.2_s0.3_a5/XULDUD.parquet" ) print( mdf[mdf["pymatgen_match"].notna()][ ["structure_id", "pymatgen_match", "pymatgen_rmsd"] ] )nsmallest(5, "energy_corrected_per_molecule")直接给出能量景观中排名前 5 的候选结构;matched_structures目录下的查询则揭示哪些预测结构复现了实验多晶型以及 RMSD 偏离程度。
扩展到生产规模
该示例按冒烟测试规模设计——在num_structures_per_spg: 25时预期不会有实验匹配命中。生产级运行的规模大约是示例的 10–100 倍:
| 旋钮 | 示例 | 生产 |
|---|---|---|
genarris.vars.num_structures_per_spg | 25 | 500–2000 |
relax.slurm.num_ranks | 10 | 1000–3000 |
pre_relaxation_filter.npartitions | 4 | 500–5000 |
free_energy.structures_per_job | 2 | 5–20 |
(注意:示例中的 fastcsp_config.yaml 实际将num_structures_per_spg设为 10、npartitions设为 1、structures_per_job设为 5,README 表格给出的是另一组冒烟规模参考值;两者都属于"小规模"范畴,迁移到生产时应以官方表格的 500+ 起步。)
每个slurm:块都接受partition、mem、cpus_per_task、gpus_per_node、array_parallelism、time等标准字段。关于工作流支持的全部旋钮,core/configs/example_config.yaml 提供了逐项带注释的完整参考,其要点包括:
genarris.vars中的Z、spg_distribution_type("standard"或显式空间群编号列表)、num_structures_per_spg(默认 500)、read_z_from_file/read_spg_from_file;- 去重相关:
density_bin_size、energy_bin_size、density_tol、energy_tol、apply_niggli_filter等廉价预过滤器,以及bin_by_conf/bin_by_z/bin_by_spg对 bin 键的扩展(bin 键越大,桶越小、去重越快,但跨 bin 边界的重复可能漏检); free_energy的atom_disp(有限差分位移,默认 0.01 Å)、min_lengths(声子计算最小超胞边长,默认 15.0 Å)、energy_cutoff、max_structures等 workload 控制项。
总结
FastCSP 示例演示了一条从 SMILES 出发、不依赖实验晶体信息的全自动晶体结构预测流水线:fastcsp-confgen先用 RDKit + UMA 生成并精修气相构象,fastcsp再依次执行 Genarris 晶体生成、弛豫前去重、UMA-omc 弛豫、可选片段能量修正、弛豫后过滤去重、可选实验比对与可选振动自由能计算,最终产出每个候选结构带唯一structure_id、CIF 与全套能量/热力学指标的 parquet 数据集。借助"共享 CSV + 两级 YAML 配置 + 阶段依赖自动重排 + 断点续跑"的设计,这套冒烟测试可以平滑扩展到 500–2000 个结构/空间群、数千 GPU rank 的生产规模。建议读者以本示例为起点跑通流程后,再对照 core/configs/example_config.yaml 的完整参数参考逐项调优。
【免费下载链接】ocpFAIR Chemistry's library of machine learning methods for chemistry项目地址: https://gitcode.com/GitHub_Trending/oc/ocp
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考