SciVerseGym User ManualSciVerseGym 用户说明书
English is the primary view. The Chinese view contains the same sections, examples, formulas, tables, and operational guidance. Use this manual to configure MLFF-backed crystal discovery, submit structured actions, train simple BO/RL agents, and interpret formation energy, convex hull, phonons, and rewards.
本手册以英文为主,中文视图包含相同章节、示例、公式、表格和操作说明。你可以用它配置 MLFF 晶体发现环境,提交结构化 action,训练简单 BO/RL agent,并理解形成能、convex hull、 声子和 reward 返回值。
1. Overview1. 项目概览
SciVerseGym is a Gymnasium-style environment for materials discovery. Agents do not emit raw CIF files.
They submit structured crystal-edit actions. The environment applies the edit to the current ASE
Atoms, evaluates the new structure with the configured MLFF or custom calculator, computes
reward, and returns a standard transition.
SciVerseGym 是一个 Gymnasium 风格的材料发现环境。智能体不需要直接输出 CIF 文件,而是提交
结构化晶体编辑 action。环境会把 action 应用到当前 ASE Atoms,再用配置好的
MLFF 或自定义 calculator 评估新结构,计算 reward,并返回标准 transition。
obs, reward, terminated, truncated, info = env.step(action)
mlff_model="sevennet" or another supported MLFF inside gym.make(...). Use calculator=... only for custom or reference-backed calculators.
推荐用法是在 gym.make(...) 中显式传入 mlff_model="sevennet" 或其他支持的 MLFF。只有自定义 calculator 或带 reference 的 calculator 才使用 calculator=...。
2. Install2. 安装
Install the repository in editable mode with development tools:
以 editable 模式安装仓库和开发工具:
python -m pip install -e ".[dev]"
Install built-in MLFF adapters and their optional dependencies:
安装内置 MLFF 适配器和可选依赖:
python -m pip install -e ".[dev,mlff]"
3. Jupyter From Zero3. Jupyter 从 0 开始
Cell 1: imports and pathsCell 1:导入和路径
from pathlib import Path
import gymnasium as gym
import numpy as np
import sciverse_gym
from sciverse_gym.benchmarks.bo_baselines.simple_bo import (
candidate_actions,
choose_action,
featurize,
)
DATA_PATH = Path("data/alex-mp-20")
print("parquet files:", [p.name for p in DATA_PATH.glob("*.parquet")])
Cell 2: create an MLFF-backed environmentCell 2:创建 MLFF 环境
env = gym.make(
"CrystalDiscovery-v0",
data_path=str(DATA_PATH),
mlff_model="sevennet",
mlff_relax=False,
max_steps=5,
max_dataset_rows=20,
)
obs, info = env.reset(seed=0, options={"index": 0})
print(env.render())
print(info)
Cell 3: submit one action and read the new stateCell 3:提交 action 并读取新 state
action = {"action_type": 0, "site": 0, "element": 28} # 28 = Ni
old_formula = obs["structure"].get_chemical_formula()
obs, reward, terminated, truncated, info = env.step(action)
print("old formula:", old_formula)
print("submitted action:", action)
print("new formula:", info["formula"])
print("new energy:", float(obs["energy"]))
print("reward:", reward)
print("backend:", info["backend"])
print("step:", obs["step"], "budget_left:", obs["budget_left"])
4. Environment API4. 环境接口
env = gym.make("CrystalDiscovery-v0", ...)
| Parameter参数 | Default默认值 | Description说明 |
|---|---|---|
data_path | "data/alex-mp-20" | ALEX-MP-20 parquet directory.ALEX-MP-20 parquet 数据目录。 |
split | "all" | Dataset split. The default reads the merged table.数据 split。默认读取合并表。 |
max_steps | 100 | Episode edit budget. When reached, truncated=True.每个 episode 的编辑预算;达到后 truncated=True。 |
calculator | None | Custom evaluator. Mutually exclusive with mlff_model.自定义 evaluator,不能和 mlff_model 同时传。 |
mlff_model | explicitly recommended推荐显式传入 | One of sevennet, mattersim, or orb.可选 sevennet、mattersim、orb。 |
mlff_relax | False | Relax atomic positions before evaluation.评估前是否优化原子位置。 |
mlff_relax_cell | False | Allow lattice-cell relaxation when relaxation is enabled.开启 relaxation 时是否允许晶胞变化。 |
mlff_compute_phonons | False | Compute finite-displacement phonon stability.是否计算有限位移声子稳定性。 |
mlff_kwargs | None | Extra options such as relax_fmax, relax_steps, phonon_supercell, phonon_displacement, phonon_mesh, and phonon_stability_tolerance.额外参数,例如 relax_fmax、relax_steps、phonon_supercell、phonon_displacement、phonon_mesh、phonon_stability_tolerance。 |
max_dataset_rows | None | Optional row cap for tutorials and small tests.限制数据行数,适合教程和小测试。 |
dataset | None | Mounted dataset implementing __len__, get(index), and sample(rng).自定义数据集,需要实现 __len__、get(index)、sample(rng)。 |
Phonon-related mlff_kwargs example声子相关 mlff_kwargs 示例
env = gym.make(
"CrystalDiscovery-v0",
data_path="data/alex-mp-20",
mlff_model="sevennet",
mlff_compute_phonons=True,
mlff_kwargs={
"phonon_supercell": (2, 2, 2),
"phonon_displacement": 0.01,
"phonon_mesh": (8, 8, 8),
"phonon_stability_tolerance": -0.1,
},
max_steps=1,
)
5. Actions5. Action 结构
Actions are dictionaries. Missing fields use conservative defaults, but explicit fields are recommended.
action 是 dictionary。缺失字段有保守默认值,但推荐显式写清字段。
| action_type | Edit动作 | Fields字段 | Example示例 |
|---|---|---|---|
0 | Element replacement元素替换 | site, element | {"action_type": 0, "site": 3, "element": 28} |
1 | Lattice perturbation晶格扰动 | lattice_delta | {"action_type": 1, "lattice_delta": [0.05, -0.02, 0.0]} |
2 | Atom displacement原子位移 | site, atom_delta | {"action_type": 2, "site": 5, "atom_delta": [0.02, 0.0, -0.01]} |
3 | Vacancy空位 | site | {"action_type": 3, "site": 2} |
4 | Insertion插入原子 | element, insert_position | {"action_type": 4, "element": 3, "insert_position": [0.25, 0.25, 0.25]} |
elementis an atomic number clipped to1..94.element是原子序数,内部裁剪到1..94。lattice_deltais clipped to[-0.15, 0.15]per component.lattice_delta每个分量裁剪到[-0.15, 0.15]。atom_deltais clipped to[-0.25, 0.25]per component.atom_delta每个分量裁剪到[-0.25, 0.25]。
6. Atomic Number Table6. 原子序数表
The table is generated from one shared data source, so both languages show the same atomic numbers and symbols.
下表由同一份数据生成,因此中英文显示相同的原子序数和元素符号。
7. State and Info7. State 与 Info
| Field字段 | Meaning含义 |
|---|---|
obs["structure"] | Current ASE Atoms.当前 ASE Atoms。 |
obs["graph"] | PyG graph when available, otherwise fallback graph data.PyG 可用时为图对象,否则为 fallback 图数据。 |
obs["energy"] | Current total energy from the selected backend.当前后端给出的总能量。 |
obs["step"] | Current environment step.当前环境步数。 |
obs["budget_left"] | Remaining edit budget.剩余编辑预算。 |
info["formation_energy_per_atom"] | Formation energy if same-force-field element references exist; otherwise None.如果存在同力场元素 reference,则为形成能;否则为 None。 |
info["energy_above_hull"] | Energy above convex hull if hull references exist; otherwise None.如果存在 hull reference,则为 hull 上方能量;否则为 None。 |
info["phonon_stable"] | Phonon stability when phonons are enabled; otherwise None.开启声子时返回声子稳定性;否则为 None。 |
8. MLFF8. MLFF 配置
Supported built-in backends are sevennet, mattersim, and orb. Examples use sevennet.
内置后端包括 sevennet、mattersim 和 orb。示例使用 sevennet。
from ase.build import bulk
from sciverse_gym.calculators import mlff_energy
atoms = bulk("Si", "diamond", a=5.43)
energy_per_atom = mlff_energy(atoms, model="sevennet", per_atom=True)
print(energy_per_atom)
9. Reward9. Reward 机制
The default reward combines stability, element abundance, and composition novelty.
默认 reward 由稳定性、元素丰度和组成新颖性三部分构成。
reward = 0.80 * stability + 0.10 * abundance_proxy + 0.10 * novelty
| Term项 | Definition定义 | Meaning含义 |
|---|---|---|
stability | 0 if energy_above_hull is None; otherwise 1 / (1 + max(Ehull, 0) / 0.1) | Lower hull energy scores higher.hull 能量越低,得分越高。 |
abundance_proxy | 1 / (1 + mean(atomic_numbers) / 60) | Lower average atomic number scores higher.平均原子序数越低,得分越高。 |
novelty | 0.25 if the formula has not appeared in the episode, else 0 | Encourages new compositions.鼓励探索新组成。 |
Example:
energy_above_hull = 0.05 eV/atom
mean_Z = 30
new formula in this episode
stability = 1 / (1 + 0.05 / 0.1) = 0.6667
abundance_proxy = 1 / (1 + 30 / 60) = 0.6667
novelty = 0.25
reward = 0.80*0.6667 + 0.10*0.6667 + 0.10*0.25 = 0.6250
10. BO and RL10. BO 和 RL
Run the built-in BO baseline运行内置 BO baseline
python -m sciverse_gym.benchmarks.bo_baselines.simple_bo --steps 5 --mlff-model sevennet
Minimal BO training loop最小 BO 训练循环
bo_env = gym.make(
"CrystalDiscovery-v0",
data_path=str(DATA_PATH),
mlff_model="sevennet",
mlff_relax=False,
max_steps=5,
max_dataset_rows=20,
)
obs, info = bo_env.reset(seed=1, options={"index": 0})
rng = np.random.default_rng(1)
x_train, y_train = [], []
for _ in range(5):
actions = candidate_actions(obs)
action = choose_action(obs, actions, x_train, y_train, rng, exploration=1.5)
old_obs = obs
obs, reward, terminated, truncated, info = bo_env.step(action)
x_train.append(featurize(old_obs, action))
y_train.append(float(reward))
if terminated or truncated:
break
Minimal RL/action-value loop最小 RL/action-value 循环
def action_key(action):
return tuple(sorted((k, tuple(v) if isinstance(v, list) else v) for k, v in action.items()))
q_values = {}
alpha = 0.3
rng = np.random.default_rng(2)
obs, info = env.reset(seed=2, options={"index": 0})
while True:
actions = candidate_actions(obs)
action = dict(actions[int(rng.integers(len(actions)))])
obs, reward, terminated, truncated, info = env.step(action)
key = action_key(action)
q_values[key] = q_values.get(key, 0.0) + alpha * (float(reward) - q_values.get(key, 0.0))
if terminated or truncated:
break
11. Formation Energy, Convex Hull, and Phonons11. 形成能、Convex Hull 和声子
E_form_per_atom = (E_total - sum_i n_i * mu_i) / N
Convex hull requires same-force-field hull reference entries. Without them, energy_above_hull=None.
Convex hull 需要同力场 hull reference entries。没有这些 reference 时,energy_above_hull=None。
from sciverse_gym.calculators import build_alex_mp20_physical_calculator
calculator = build_alex_mp20_physical_calculator(
data_path="data/alex-mp-20",
model="sevennet",
reference_cache_path="data/alex-mp-20/sevennet_reference_hull.json",
max_reference_entries=None,
relax=True,
relax_cell=False,
relax_references=False,
compute_phonons=False,
)
env = gym.make(
"CrystalDiscovery-v0",
data_path="data/alex-mp-20",
calculator=calculator,
)
Phonons can be enabled directly through the MLFF path or through the reference-backed calculator. They are expensive because displaced supercells require force evaluations.
声子可以直接通过 MLFF 路径开启,也可以在带 reference 的 calculator 中开启。声子很慢,因为多个有限位移超胞都要计算 forces。
env = gym.make(
"CrystalDiscovery-v0",
data_path="data/alex-mp-20",
mlff_model="sevennet",
mlff_compute_phonons=True,
mlff_kwargs={
"phonon_supercell": (2, 2, 2),
"phonon_mesh": (8, 8, 8),
"phonon_displacement": 0.01,
"phonon_stability_tolerance": -0.1,
},
max_steps=1,
)
12. Dataset12. 数据集
The default data directory is data/alex-mp-20. The dataset should return StructureRecord objects with atoms, material_id, and metadata.
默认数据目录是 data/alex-mp-20。数据集应返回包含 atoms、material_id、metadata 的 StructureRecord。
env = gym.make(
"CrystalDiscovery-v0",
dataset=my_dataset,
mlff_model="sevennet",
mlff_relax=False,
)
13. API Reference13. API 速查
| API | Purpose用途 |
|---|---|
CrystalDiscoveryEnv | Main Gymnasium environment.主 Gymnasium 环境。 |
apply_action | Apply one structured edit to ASE Atoms.把结构化 action 应用到 ASE Atoms。 |
mlff_energy | Compute total or per-atom MLFF energy.计算总 MLFF 能量或每原子能量。 |
build_alex_mp20_physical_calculator | Build same-force-field FE/hull references.构建同力场 FE/hull reference。 |
candidate_actions | Controlled candidate action set used by BO/RL examples.BO/RL 示例使用的受控候选 action 集。 |
14. Crystal Playground14. 晶体可视化界面
The file docs/crystal-playground.html is a standalone browser interface for exploring SVGym-style
crystal generation and edit actions without installing Python packages or starting a server. It is intended as
a visual entry point before running the Gymnasium environment in code.
docs/crystal-playground.html 是一个可以直接在浏览器打开的本地晶体可视化界面,用来体验
SVGym 风格的晶体生成和编辑动作。它不需要安装 Python 包,也不需要启动服务器,适合在正式写
Gymnasium 代码前先理解结构、action 和 observation 的关系。
Open it from zero从零打开
- Open the repository folder on your computer.在电脑上打开本项目文件夹。
- Go to
docs/and double-clickcrystal-playground.html.进入docs/目录,双击crystal-playground.html。 - Use the language button in the top-right area of the page to switch between English and Chinese.使用页面右上角的语言按钮在英文和中文之间切换。
- No network, backend service, or build step is required.不需要网络、后端服务或构建步骤。
Generate a preset crystal生成预设晶体
In Structure preset, choose a template such as rocksalt, BCC, FCC, diamond, perovskite, fluorite, rutile, or spinel. The three chemistry-channel selectors define which elements are placed on the A, B, and C/anion sites for these presets.
在 结构预设 中选择 rocksalt、BCC、FCC、diamond、perovskite、fluorite、rutile、 spinel 等模板。三个化学通道选择器用于决定预设结构中 A、B、C/阴离子位点放入哪些元素。
| Control控件 | Meaning含义 |
|---|---|
Channel A | Element for A-site atoms in presets and one possible replacement target.预设结构中 A 位点元素,也可作为替换动作的目标。 |
Channel B | Element for B-site atoms in presets and one possible replacement target.预设结构中 B 位点元素,也可作为替换动作的目标。 |
Channel C / anion | Element for anion or third-site atoms in presets and one possible replacement target.预设结构中的阴离子或第三类位点元素,也可作为替换动作的目标。 |
Supercell size | Replicates the unit cell as 1x1x1 through 4x4x4.把晶胞复制成 1x1x1 到 4x4x4 的超胞。 |
Lattice constant | Changes the visual lattice scale and the toy energy score.改变可视化晶格尺度,并影响界面中的玩具能量分数。 |
Upload a CIF file上传 CIF 文件
Click Upload CIF and choose a local .cif file. The playground reads fractional
atom coordinates, detects element symbols from _atom_site_type_symbol or labels, expands common
symmetry-operation loops into the full unit cell, and then applies the current supercell size.
点击 上传 CIF 并选择本地 .cif 文件。界面会读取原子分数坐标,从
_atom_site_type_symbol 或 label 中识别元素,读取常见对称操作并展开为完整晶胞,
然后再按照当前超胞尺寸复制。
If a CIF does not contain symmetry operations, the interface shows the atom sites provided by the file.
The exported observation includes cif_asu_atoms and cif_symmetry_operations so you can
confirm whether expansion happened.
如果 CIF 文件没有提供对称操作,界面会显示文件中给出的原子位点。导出的 observation 中包含
cif_asu_atoms 和 cif_symmetry_operations,可用于确认是否完成对称展开。
Use the action buttons使用 action 按钮
| Action动作 | What it does作用 |
|---|---|
SVGym step | Runs one random SVGym-style edit and updates observation, reward, and structure.执行一步 SVGym 风格随机编辑,并更新 observation、reward 和结构。 |
Generate | Rebuilds the current preset or uploaded CIF view using the current sliders.根据当前滑块重新生成预设结构或已上传 CIF 结构。 |
Random mutate | Applies one random edit: lattice perturbation, atom displacement, vacancy, insertion, or replacement.随机执行晶格扰动、原子位移、空位、插入或元素替换。 |
Replace element | Replaces one chemistry channel or detected element group using the A/B/C selectors.使用 A/B/C 选择器替换一个化学通道或检测到的元素组。 |
Relax | Moves atoms toward ideal fractional sites and lowers the toy energy score.让原子向理想分数坐标回退,并降低界面中的玩具能量分数。 |
Insert atom | Adds a new atom at an open random fractional position.在随机开放分数坐标位置插入一个新原子。 |
Read the display阅读界面信息
- Drag the main crystal view to rotate the structure manually.拖动主晶体视图可以手动旋转结构。
- Click an atom to focus the local zoom view on its neighborhood.点击某个原子,右侧局部放大图会聚焦它的邻域。
- The top chips show formula, toy energy, and reward for quick feedback.顶部标签显示化学式、玩具能量和 reward,用于快速反馈。
- The element legend confirms whether CIF elements were detected as separate species.元素图例可以确认 CIF 中的元素是否被识别成不同种类。
- The observation panel shows a JSON-like state snapshot similar to what an environment returns.Observation 面板展示类似环境返回值的 JSON 状态快照。
Export and limitations导出与限制
Use Export JSON to save the current visual observation. The playground is a teaching and exploration interface: its energy and reward values are lightweight toy scores, not MLFF calculations. For real optimization, use the Python environment and MLFF backends described in earlier sections.
使用 导出 JSON 可以保存当前可视化 observation。该界面是教学和探索工具,其中能量与 reward 是轻量玩具分数,不是 MLFF 真实计算。真正的优化任务请使用前面章节介绍的 Python 环境和 MLFF 后端。
15. Troubleshooting15. 常见问题
- If
energy_above_hullisNone, build a same-force-field reference calculator.如果energy_above_hull是None,需要构建同力场 reference calculator。 - If
formation_energy_per_atomisNone, an elemental reference is missing.如果formation_energy_per_atom是None,说明缺少元素 reference。 - If raw random actions select unsupported elements, use controlled candidate actions instead of
env.action_space.sample().如果裸随机 action 抽到 MLFF 不支持的元素,请使用受控候选 action,不要直接用env.action_space.sample()。 - If PyG optional extensions warn about ABI mismatch, the fallback graph path may still allow environment loops to run.如果 PyG 可选扩展出现 ABI warning,fallback graph 路径通常仍可让环境循环运行。
16. Citation16. 引用方式
If you use SVGym (SciVerseGym), please cite:
如果你使用 SVGym (SciVerseGym),请引用:
@misc{cao2026svgymsciversegymenvironmentreinforcement,
title={SVGym (SciVerseGym): An Environment for Reinforcement Learning and Bayesian Optimization in Crystal Discovery},
author={Bin Cao},
year={2026},
eprint={2606.22425},
archivePrefix={arXiv},
primaryClass={cs.AI},
url={https://arxiv.org/abs/2606.22425},
}