Spaces:
Running
Running
add version tag
Browse files- .github/README.md +1 -1
- mlip_arena/models/chgnet.py +0 -54
- mlip_arena/models/externals.py +0 -283
- mlip_arena/models/registry.yaml +5 -2
- pyproject.toml +1 -0
- serve/leaderboard.py +5 -3
- serve/tasks/stability.py +2 -6
.github/README.md
CHANGED
@@ -10,7 +10,7 @@
|
|
10 |
> [!NOTE]
|
11 |
> If you're interested in joining the effort, please reach out to Yuan at [cyrusyc@berkeley.edu](mailto:cyrusyc@berkeley.edu).
|
12 |
|
13 |
-
MLIP Arena is
|
14 |
|
15 |
## Contribute
|
16 |
|
|
|
10 |
> [!NOTE]
|
11 |
> If you're interested in joining the effort, please reach out to Yuan at [cyrusyc@berkeley.edu](mailto:cyrusyc@berkeley.edu).
|
12 |
|
13 |
+
MLIP Arena is a platform for evaluating foundation machine learning interatomic potentials (MLIPs) beyond conventional energy and force error metrics. It focuses on revealing the underlying physics and chemistry learned by these models and assessing their performance in molecular dynamics (MD) simulations. The platform's benchmarks are specifically designed to evaluate the readiness and reliability of open-source, open-weight models in accurately reproducing both qualitative and quantitative behaviors of atomic systems.
|
14 |
|
15 |
## Contribute
|
16 |
|
mlip_arena/models/chgnet.py
DELETED
@@ -1,54 +0,0 @@
|
|
1 |
-
from typing import Optional, Tuple
|
2 |
-
|
3 |
-
import numpy as np
|
4 |
-
import torch
|
5 |
-
from ase import Atoms
|
6 |
-
from ase.calculators.calculator import all_changes
|
7 |
-
from huggingface_hub import hf_hub_download
|
8 |
-
from torch_geometric.data import Data
|
9 |
-
|
10 |
-
from mlip_arena.models import MLIP, MLIPCalculator
|
11 |
-
|
12 |
-
# TODO: WIP
|
13 |
-
|
14 |
-
|
15 |
-
class CHGNet(MLIPCalculator):
|
16 |
-
def __init__(
|
17 |
-
self,
|
18 |
-
device: torch.device | None = None,
|
19 |
-
restart=None,
|
20 |
-
atoms=None,
|
21 |
-
directory=".",
|
22 |
-
**kwargs,
|
23 |
-
):
|
24 |
-
self.device = device or torch.device(
|
25 |
-
"cuda" if torch.cuda.is_available() else "cpu"
|
26 |
-
)
|
27 |
-
|
28 |
-
super().__init__(
|
29 |
-
model=model, restart=restart, atoms=atoms, directory=directory, **kwargs
|
30 |
-
)
|
31 |
-
|
32 |
-
self.name: str = self.__class__.__name__
|
33 |
-
self.implemented_properties = ["energy", "forces", "stress"]
|
34 |
-
|
35 |
-
def calculate(
|
36 |
-
self, atoms: Atoms, properties: list[str], system_changes: list = all_changes
|
37 |
-
):
|
38 |
-
"""Calculate energies and forces for the given Atoms object"""
|
39 |
-
super().calculate(atoms, properties, system_changes)
|
40 |
-
|
41 |
-
output = self.forward(atoms)
|
42 |
-
|
43 |
-
self.results = {}
|
44 |
-
if "energy" in properties:
|
45 |
-
self.results["energy"] = output["energy"].item()
|
46 |
-
if "forces" in properties:
|
47 |
-
self.results["forces"] = output["forces"].cpu().detach().numpy()
|
48 |
-
if "stress" in properties:
|
49 |
-
self.results["stress"] = output["stress"].cpu().detach().numpy()
|
50 |
-
|
51 |
-
def forward(self, x: Data | Atoms) -> dict[str, torch.Tensor]:
|
52 |
-
"""Implement data conversion, graph creation, and model forward pass"""
|
53 |
-
# TODO
|
54 |
-
raise NotImplementedError
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mlip_arena/models/externals.py
DELETED
@@ -1,283 +0,0 @@
|
|
1 |
-
from __future__ import annotations
|
2 |
-
|
3 |
-
import os
|
4 |
-
from pathlib import Path
|
5 |
-
from typing import Literal
|
6 |
-
|
7 |
-
import matgl
|
8 |
-
import requests
|
9 |
-
import torch
|
10 |
-
from alignn.ff.ff import AlignnAtomwiseCalculator, get_figshare_model_ff, default_path
|
11 |
-
from ase import Atoms
|
12 |
-
from chgnet.model.dynamics import CHGNetCalculator
|
13 |
-
from chgnet.model.model import CHGNet as CHGNetModel
|
14 |
-
from fairchem.core import OCPCalculator
|
15 |
-
from mace.calculators import MACECalculator
|
16 |
-
from matgl.ext.ase import PESCalculator
|
17 |
-
from orb_models.forcefield import pretrained
|
18 |
-
from orb_models.forcefield.calculator import ORBCalculator
|
19 |
-
from sevenn.sevennet_calculator import SevenNetCalculator
|
20 |
-
|
21 |
-
|
22 |
-
# Avoid circular import
|
23 |
-
def get_freer_device() -> torch.device:
|
24 |
-
"""Get the GPU with the most free memory, or use MPS if available.
|
25 |
-
s
|
26 |
-
Returns:
|
27 |
-
torch.device: The selected GPU device or MPS.
|
28 |
-
|
29 |
-
Raises:
|
30 |
-
ValueError: If no GPU or MPS is available.
|
31 |
-
"""
|
32 |
-
device_count = torch.cuda.device_count()
|
33 |
-
if device_count > 0:
|
34 |
-
# If CUDA GPUs are available, select the one with the most free memory
|
35 |
-
mem_free = [
|
36 |
-
torch.cuda.get_device_properties(i).total_memory
|
37 |
-
- torch.cuda.memory_allocated(i)
|
38 |
-
for i in range(device_count)
|
39 |
-
]
|
40 |
-
free_gpu_index = mem_free.index(max(mem_free))
|
41 |
-
device = torch.device(f"cuda:{free_gpu_index}")
|
42 |
-
print(
|
43 |
-
f"Selected GPU {device} with {mem_free[free_gpu_index] / 1024**2:.2f} MB free memory from {device_count} GPUs"
|
44 |
-
)
|
45 |
-
elif torch.backends.mps.is_available():
|
46 |
-
# If no CUDA GPUs are available but MPS is, use MPS
|
47 |
-
print("No GPU available. Using MPS.")
|
48 |
-
device = torch.device("mps")
|
49 |
-
else:
|
50 |
-
# Fallback to CPU if neither CUDA GPUs nor MPS are available
|
51 |
-
print("No GPU or MPS available. Using CPU.")
|
52 |
-
device = torch.device("cpu")
|
53 |
-
|
54 |
-
return device
|
55 |
-
|
56 |
-
|
57 |
-
class MACE_MP_Medium(MACECalculator):
|
58 |
-
def __init__(
|
59 |
-
self,
|
60 |
-
checkpoint="http://tinyurl.com/5yyxdm76",
|
61 |
-
device: str | None = None,
|
62 |
-
default_dtype="float32",
|
63 |
-
**kwargs,
|
64 |
-
):
|
65 |
-
cache_dir = Path.home() / ".cache" / "mace"
|
66 |
-
checkpoint_url_name = "".join(
|
67 |
-
c for c in os.path.basename(checkpoint) if c.isalnum() or c in "_"
|
68 |
-
)
|
69 |
-
cached_model_path = f"{cache_dir}/{checkpoint_url_name}"
|
70 |
-
if not os.path.isfile(cached_model_path):
|
71 |
-
import urllib
|
72 |
-
|
73 |
-
os.makedirs(cache_dir, exist_ok=True)
|
74 |
-
_, http_msg = urllib.request.urlretrieve(checkpoint, cached_model_path)
|
75 |
-
if "Content-Type: text/html" in http_msg:
|
76 |
-
raise RuntimeError(
|
77 |
-
f"Model download failed, please check the URL {checkpoint}"
|
78 |
-
)
|
79 |
-
model = cached_model_path
|
80 |
-
|
81 |
-
device = device or str(get_freer_device())
|
82 |
-
|
83 |
-
super().__init__(
|
84 |
-
model_paths=model, device=device, default_dtype=default_dtype, **kwargs
|
85 |
-
)
|
86 |
-
|
87 |
-
|
88 |
-
# TODO: could share the same class with MACE_MP_Medium
|
89 |
-
class MACE_OFF_Medium(MACECalculator):
|
90 |
-
def __init__(
|
91 |
-
self,
|
92 |
-
checkpoint="https://github.com/ACEsuit/mace-off/raw/main/mace_off23/MACE-OFF23_medium.model?raw=true",
|
93 |
-
device: str | None = None,
|
94 |
-
default_dtype="float32",
|
95 |
-
**kwargs,
|
96 |
-
):
|
97 |
-
cache_dir = Path.home() / ".cache" / "mace"
|
98 |
-
checkpoint_url_name = "".join(
|
99 |
-
c for c in os.path.basename(checkpoint) if c.isalnum() or c in "_"
|
100 |
-
)
|
101 |
-
cached_model_path = f"{cache_dir}/{checkpoint_url_name}"
|
102 |
-
if not os.path.isfile(cached_model_path):
|
103 |
-
import urllib
|
104 |
-
|
105 |
-
os.makedirs(cache_dir, exist_ok=True)
|
106 |
-
_, http_msg = urllib.request.urlretrieve(checkpoint, cached_model_path)
|
107 |
-
if "Content-Type: text/html" in http_msg:
|
108 |
-
raise RuntimeError(
|
109 |
-
f"Model download failed, please check the URL {checkpoint}"
|
110 |
-
)
|
111 |
-
model = cached_model_path
|
112 |
-
|
113 |
-
device = device or str(get_freer_device())
|
114 |
-
|
115 |
-
super().__init__(
|
116 |
-
model_paths=model, device=device, default_dtype=default_dtype, **kwargs
|
117 |
-
)
|
118 |
-
|
119 |
-
|
120 |
-
class CHGNet(CHGNetCalculator):
|
121 |
-
def __init__(
|
122 |
-
self,
|
123 |
-
checkpoint: CHGNetModel | None = None, # TODO: specifiy version
|
124 |
-
device: str | None = None,
|
125 |
-
stress_weight: float | None = 1 / 160.21766208,
|
126 |
-
on_isolated_atoms: Literal["ignore", "warn", "error"] = "warn",
|
127 |
-
**kwargs,
|
128 |
-
) -> None:
|
129 |
-
use_device = device or str(get_freer_device())
|
130 |
-
super().__init__(
|
131 |
-
model=checkpoint,
|
132 |
-
use_device=use_device,
|
133 |
-
stress_weight=stress_weight,
|
134 |
-
on_isolated_atoms=on_isolated_atoms,
|
135 |
-
**kwargs,
|
136 |
-
)
|
137 |
-
|
138 |
-
def calculate(
|
139 |
-
self,
|
140 |
-
atoms: Atoms | None = None,
|
141 |
-
properties: list | None = None,
|
142 |
-
system_changes: list | None = None,
|
143 |
-
) -> None:
|
144 |
-
super().calculate(atoms, properties, system_changes)
|
145 |
-
|
146 |
-
# for ase.io.write compatibility
|
147 |
-
self.results.pop("crystal_fea", None)
|
148 |
-
|
149 |
-
|
150 |
-
class M3GNet(PESCalculator):
|
151 |
-
def __init__(
|
152 |
-
self,
|
153 |
-
checkpoint="M3GNet-MP-2021.2.8-PES",
|
154 |
-
# TODO: cannot assign device
|
155 |
-
state_attr: torch.Tensor | None = None,
|
156 |
-
stress_weight: float = 1.0,
|
157 |
-
**kwargs,
|
158 |
-
) -> None:
|
159 |
-
potential = matgl.load_model(checkpoint)
|
160 |
-
super().__init__(potential, state_attr, stress_weight, **kwargs)
|
161 |
-
|
162 |
-
|
163 |
-
class EquiformerV2(OCPCalculator):
|
164 |
-
def __init__(
|
165 |
-
self,
|
166 |
-
checkpoint="EquiformerV2-lE4-lF100-S2EFS-OC22", # TODO: import from registry
|
167 |
-
# TODO: cannot assign device
|
168 |
-
local_cache="/tmp/ocp/",
|
169 |
-
cpu=False,
|
170 |
-
seed=0,
|
171 |
-
**kwargs,
|
172 |
-
) -> None:
|
173 |
-
super().__init__(
|
174 |
-
model_name=checkpoint,
|
175 |
-
local_cache=local_cache,
|
176 |
-
cpu=cpu,
|
177 |
-
seed=seed,
|
178 |
-
**kwargs,
|
179 |
-
)
|
180 |
-
|
181 |
-
def calculate(self, atoms: Atoms, properties, system_changes) -> None:
|
182 |
-
super().calculate(atoms, properties, system_changes)
|
183 |
-
|
184 |
-
self.results.update(
|
185 |
-
force=atoms.get_forces(),
|
186 |
-
)
|
187 |
-
|
188 |
-
|
189 |
-
class EquiformerV2OC20(OCPCalculator):
|
190 |
-
def __init__(
|
191 |
-
self,
|
192 |
-
checkpoint="EquiformerV2-31M-S2EF-OC20-All+MD", # TODO: import from registry
|
193 |
-
# TODO: cannot assign device
|
194 |
-
local_cache="/tmp/ocp/",
|
195 |
-
cpu=False,
|
196 |
-
seed=0,
|
197 |
-
**kwargs,
|
198 |
-
) -> None:
|
199 |
-
super().__init__(
|
200 |
-
model_name=checkpoint,
|
201 |
-
local_cache=local_cache,
|
202 |
-
cpu=cpu,
|
203 |
-
seed=seed,
|
204 |
-
**kwargs,
|
205 |
-
)
|
206 |
-
|
207 |
-
|
208 |
-
class eSCN(OCPCalculator):
|
209 |
-
def __init__(
|
210 |
-
self,
|
211 |
-
checkpoint="eSCN-L6-M3-Lay20-S2EF-OC20-All+MD", # TODO: import from registry
|
212 |
-
# TODO: cannot assign device
|
213 |
-
local_cache="/tmp/ocp/",
|
214 |
-
cpu=False,
|
215 |
-
seed=0,
|
216 |
-
**kwargs,
|
217 |
-
) -> None:
|
218 |
-
super().__init__(
|
219 |
-
model_name=checkpoint,
|
220 |
-
local_cache=local_cache,
|
221 |
-
cpu=cpu,
|
222 |
-
seed=seed,
|
223 |
-
**kwargs,
|
224 |
-
)
|
225 |
-
|
226 |
-
def calculate(self, atoms: Atoms, properties, system_changes) -> None:
|
227 |
-
super().calculate(atoms, properties, system_changes)
|
228 |
-
|
229 |
-
self.results.update(
|
230 |
-
force=atoms.get_forces(),
|
231 |
-
)
|
232 |
-
|
233 |
-
|
234 |
-
class ALIGNN(AlignnAtomwiseCalculator):
|
235 |
-
def __init__(self, device=None, **kwargs) -> None:
|
236 |
-
# TODO: cannot control version
|
237 |
-
# _ = get_figshare_model_ff(dir_path=dir_path)
|
238 |
-
model_path = default_path()
|
239 |
-
|
240 |
-
device = device or get_freer_device()
|
241 |
-
super().__init__(path=model_path, device=device, **kwargs)
|
242 |
-
|
243 |
-
|
244 |
-
class SevenNet(SevenNetCalculator):
|
245 |
-
def __init__(
|
246 |
-
self,
|
247 |
-
checkpoint="7net-0", # TODO: import from registry
|
248 |
-
device=None,
|
249 |
-
**kwargs,
|
250 |
-
):
|
251 |
-
device = device or get_freer_device()
|
252 |
-
super().__init__(checkpoint, device=device, **kwargs)
|
253 |
-
|
254 |
-
|
255 |
-
class ORB(ORBCalculator):
|
256 |
-
def __init__(
|
257 |
-
self,
|
258 |
-
checkpoint="orbff-v1-20240827.ckpt",
|
259 |
-
device=None,
|
260 |
-
**kwargs,
|
261 |
-
):
|
262 |
-
device = device or get_freer_device()
|
263 |
-
|
264 |
-
cache_dir = Path.home() / ".cache" / "orb"
|
265 |
-
cache_dir.mkdir(parents=True, exist_ok=True)
|
266 |
-
ckpt_path = cache_dir / "orbff-v1-20240827.ckpt"
|
267 |
-
|
268 |
-
url = f"https://storage.googleapis.com/orbitalmaterials-public-models/forcefields/{checkpoint}"
|
269 |
-
|
270 |
-
if not ckpt_path.exists():
|
271 |
-
print(f"Downloading ORB model from {url} to {ckpt_path}...")
|
272 |
-
try:
|
273 |
-
response = requests.get(url, stream=True, timeout=120)
|
274 |
-
response.raise_for_status()
|
275 |
-
with open(ckpt_path, "wb") as f:
|
276 |
-
for chunk in response.iter_content(chunk_size=8192):
|
277 |
-
f.write(chunk)
|
278 |
-
print("Download completed.")
|
279 |
-
except requests.exceptions.RequestException as e:
|
280 |
-
raise RuntimeError("Failed to download ORB model.") from e
|
281 |
-
|
282 |
-
orbff = pretrained.orb_v1(weights_path=ckpt_path, device=device)
|
283 |
-
super().__init__(orbff, device=device, **kwargs)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mlip_arena/models/registry.yaml
CHANGED
@@ -50,7 +50,7 @@ M3GNet:
|
|
50 |
class: M3GNet
|
51 |
family: matgl
|
52 |
package: matgl==1.1.2
|
53 |
-
checkpoint:
|
54 |
username: cyrusyc
|
55 |
last-update: 2024-07-08T00:00:00
|
56 |
datetime: 2024-07-08T00:00:00
|
@@ -135,6 +135,7 @@ eqV2(OMat):
|
|
135 |
prediction: EFS
|
136 |
nvt: true
|
137 |
npt: true
|
|
|
138 |
github: https://github.com/FAIR-Chem/fairchem
|
139 |
doi: https://arxiv.org/abs/2410.12771
|
140 |
|
@@ -206,6 +207,8 @@ MACE-OFF(M):
|
|
206 |
module: externals
|
207 |
class: MACE_OFF_Medium
|
208 |
family: mace-off
|
|
|
|
|
209 |
username: cyrusyc
|
210 |
last-update: 2024-03-25T14:30:00
|
211 |
datetime: 2024-03-25T14:30:00 # TODO: Fake datetime
|
@@ -228,7 +231,7 @@ ALIGNN:
|
|
228 |
class: ALIGNN
|
229 |
family: alignn
|
230 |
package: alignn==2024.5.27
|
231 |
-
checkpoint:
|
232 |
username: cyrusyc
|
233 |
last-update: 2024-07-08T00:00:00
|
234 |
datetime: 2024-07-08T00:00:00
|
|
|
50 |
class: M3GNet
|
51 |
family: matgl
|
52 |
package: matgl==1.1.2
|
53 |
+
checkpoint: M3GNet-MP-2021.2.8-PES
|
54 |
username: cyrusyc
|
55 |
last-update: 2024-07-08T00:00:00
|
56 |
datetime: 2024-07-08T00:00:00
|
|
|
135 |
prediction: EFS
|
136 |
nvt: true
|
137 |
npt: true
|
138 |
+
date: 2024-10-18
|
139 |
github: https://github.com/FAIR-Chem/fairchem
|
140 |
doi: https://arxiv.org/abs/2410.12771
|
141 |
|
|
|
207 |
module: externals
|
208 |
class: MACE_OFF_Medium
|
209 |
family: mace-off
|
210 |
+
package: mace-torch==0.3.4
|
211 |
+
checkpoint: MACE-OFF23_medium.model
|
212 |
username: cyrusyc
|
213 |
last-update: 2024-03-25T14:30:00
|
214 |
datetime: 2024-03-25T14:30:00 # TODO: Fake datetime
|
|
|
231 |
class: ALIGNN
|
232 |
family: alignn
|
233 |
package: alignn==2024.5.27
|
234 |
+
checkpoint: 2024.5.27
|
235 |
username: cyrusyc
|
236 |
last-update: 2024-07-08T00:00:00
|
237 |
datetime: 2024-07-08T00:00:00
|
pyproject.toml
CHANGED
@@ -163,6 +163,7 @@ ignore = [
|
|
163 |
"FBT003", # boolean positional variable in function call
|
164 |
"PERF203", # `try`-`except` within a loop incurs performance overhead (no overhead in Py 3.11+)
|
165 |
"F405", # 'module' may be undefined, or defined from star imports
|
|
|
166 |
]
|
167 |
fixable = ["ALL"]
|
168 |
pydocstyle.convention = "google"
|
|
|
163 |
"FBT003", # boolean positional variable in function call
|
164 |
"PERF203", # `try`-`except` within a loop incurs performance overhead (no overhead in Py 3.11+)
|
165 |
"F405", # 'module' may be undefined, or defined from star imports
|
166 |
+
"C0301", # Line too long
|
167 |
]
|
168 |
fixable = ["ALL"]
|
169 |
pydocstyle.convention = "google"
|
serve/leaderboard.py
CHANGED
@@ -28,6 +28,7 @@ table = pd.DataFrame(
|
|
28 |
"Training Set",
|
29 |
"Code",
|
30 |
"Paper",
|
|
|
31 |
"First Release",
|
32 |
]
|
33 |
)
|
@@ -46,6 +47,7 @@ for model in MODELS:
|
|
46 |
"Training Set": metadata.get("datasets", []),
|
47 |
"Code": metadata.get("github", None) if metadata else None,
|
48 |
"Paper": metadata.get("doi", None) if metadata else None,
|
|
|
49 |
"First Release": metadata.get("date", None),
|
50 |
}
|
51 |
table = pd.concat([table, pd.DataFrame([new_row])], ignore_index=True)
|
@@ -73,11 +75,11 @@ st.markdown(
|
|
73 |
|
74 |
### :red[Introduction]
|
75 |
|
76 |
-
Foundation machine learning interatomic potentials (fMLIPs) trained on extensive databases containing millions of density functional theory (DFT) calculations have
|
77 |
|
78 |
-
However, MLIPs trained on atomic energy and force labels do not
|
79 |
|
80 |
-
MLIP Arena aims to provide
|
81 |
|
82 |
""",
|
83 |
unsafe_allow_html=True,
|
|
|
28 |
"Training Set",
|
29 |
"Code",
|
30 |
"Paper",
|
31 |
+
"Checkpoint",
|
32 |
"First Release",
|
33 |
]
|
34 |
)
|
|
|
47 |
"Training Set": metadata.get("datasets", []),
|
48 |
"Code": metadata.get("github", None) if metadata else None,
|
49 |
"Paper": metadata.get("doi", None) if metadata else None,
|
50 |
+
"Checkpoint": metadata.get("checkpoint", None),
|
51 |
"First Release": metadata.get("date", None),
|
52 |
}
|
53 |
table = pd.concat([table, pd.DataFrame([new_row])], ignore_index=True)
|
|
|
75 |
|
76 |
### :red[Introduction]
|
77 |
|
78 |
+
Foundation machine learning interatomic potentials (fMLIPs), trained on extensive databases containing millions of density functional theory (DFT) calculations, have demonstrated remarkable zero-shot predictive capabilities for complex atomic interactions. These potentials derive quantum mechanical insights with high accuracy, expressivity, and generalizability, significantly outperforming classical empirical force fields while maintaining comparable computational efficiency.
|
79 |
|
80 |
+
However, MLIPs trained on atomic energy and force labels do not necessarily capture the correct atomic interactions, even though they often excel in error-based metrics for bulk systems. To drive further advancements in this field, it is crucial to establish mechanisms that ensure fair and transparent benchmarking practices beyond basic regression metrics.
|
81 |
|
82 |
+
MLIP Arena aims to provide a fair and transparent platform for benchmarking MLIPs in a crowdsourced setting. Its primary goal is to uncover the learned physics and chemistry of open-source, open-weight MLIPs. The benchmarks are designed to be agnostic to both the underlying architecture and specific training targets, such as density functionals, ensuring a cross-comparable and unbiased evaluation.
|
83 |
|
84 |
""",
|
85 |
unsafe_allow_html=True,
|
serve/tasks/stability.py
CHANGED
@@ -19,7 +19,7 @@ st.markdown("""
|
|
19 |
Stable and accurate molecular dynamics (MD) simulations are important for understanding the properties of matters.
|
20 |
However, many MLIPs have unphysical potential energy surface (PES) at the short-range interatomic distances or under many-body effect. These are often manifested as softened repulsion and hole in the PES and can lead to incorrect and sampling of the phase space.
|
21 |
|
22 |
-
Here, we analyze the stability of the MD simulations under high pressure conditions by gradually increasing the pressure from 0 to 1000 GPa at 300K until the system crashes or completes 100 ps trajectory. This benchmark also explores faster the far-from-equilibrium dynamics of the system and the
|
23 |
""")
|
24 |
|
25 |
st.markdown("### Methods")
|
@@ -80,7 +80,6 @@ method_color_mapping = {
|
|
80 |
###
|
81 |
|
82 |
# Determine the bin edges for the entire dataset to keep them consistent across groups
|
83 |
-
# bins = np.histogram_bin_edges(df['total_steps'], bins=10)
|
84 |
|
85 |
max_steps = df["total_steps"].max()
|
86 |
max_target_steps = df["target_steps"].max()
|
@@ -89,14 +88,11 @@ bins = np.append(np.arange(0, max_steps + 1, max_steps // 10), max_target_steps)
|
|
89 |
bin_labels = [f"{bins[i]}-{bins[i+1]}" for i in range(len(bins) - 1)]
|
90 |
|
91 |
num_bins = len(bin_labels)
|
92 |
-
# colormap = px.colors.sequential.Darkmint_r
|
93 |
colormap = px.colors.sequential.YlOrRd_r
|
94 |
indices = np.linspace(0, len(colormap) - 1, num_bins, dtype=int)
|
95 |
bin_colors = [colormap[i] for i in indices]
|
96 |
-
# bin_colors[-1] = px.colors.sequential.Greens[-1]
|
97 |
|
98 |
# Initialize a dictionary to hold the counts for each method and bin range
|
99 |
-
# counts_per_method = {method: [0] * len(bin_labels) for method in df["method"].unique()}
|
100 |
counts_per_method = {method: [0] * len(bin_labels) for method in df["method"].unique()}
|
101 |
|
102 |
|
@@ -160,7 +156,7 @@ plot_md_steps(counts_per_method, count_or_percetange)
|
|
160 |
|
161 |
st.markdown(
|
162 |
"""
|
163 |
-
> The histogram shows the distribution of the total number of MD steps before the system crashes or completes the trajectory. :red[The color of the bins indicates the number of steps in the bin]. :blue[The height of the bars indicates the percentage of each bin among all the runs].
|
164 |
"""
|
165 |
)
|
166 |
|
|
|
19 |
Stable and accurate molecular dynamics (MD) simulations are important for understanding the properties of matters.
|
20 |
However, many MLIPs have unphysical potential energy surface (PES) at the short-range interatomic distances or under many-body effect. These are often manifested as softened repulsion and hole in the PES and can lead to incorrect and sampling of the phase space.
|
21 |
|
22 |
+
Here, we analyze the stability of the MD simulations under high pressure conditions by gradually increasing the pressure from 0 to 1000 GPa at 300K until the system crashes or completes 100 ps trajectory. This benchmark also explores faster the far-from-equilibrium dynamics of the system and the durability of the MLIPs under extreme conditions.
|
23 |
""")
|
24 |
|
25 |
st.markdown("### Methods")
|
|
|
80 |
###
|
81 |
|
82 |
# Determine the bin edges for the entire dataset to keep them consistent across groups
|
|
|
83 |
|
84 |
max_steps = df["total_steps"].max()
|
85 |
max_target_steps = df["target_steps"].max()
|
|
|
88 |
bin_labels = [f"{bins[i]}-{bins[i+1]}" for i in range(len(bins) - 1)]
|
89 |
|
90 |
num_bins = len(bin_labels)
|
|
|
91 |
colormap = px.colors.sequential.YlOrRd_r
|
92 |
indices = np.linspace(0, len(colormap) - 1, num_bins, dtype=int)
|
93 |
bin_colors = [colormap[i] for i in indices]
|
|
|
94 |
|
95 |
# Initialize a dictionary to hold the counts for each method and bin range
|
|
|
96 |
counts_per_method = {method: [0] * len(bin_labels) for method in df["method"].unique()}
|
97 |
|
98 |
|
|
|
156 |
|
157 |
st.markdown(
|
158 |
"""
|
159 |
+
> The histogram shows the distribution of the total number of MD steps before the system crashes or completes the trajectory. :red[The color of the bins indicates the number of steps in the bin]. :blue[The height of the bars indicates the number or percentage of each bin among all the runs].
|
160 |
"""
|
161 |
)
|
162 |
|