alignn 2026.8.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- alignn/__init__.py +3 -0
- alignn/cli.py +73 -0
- alignn/config.py +253 -0
- alignn/data.py +578 -0
- alignn/dataset.py +180 -0
- alignn/ff/__init__.py +1 -0
- alignn/ff/all_models_alignn.json +59 -0
- alignn/ff/all_models_alignn_atomwise.json +58 -0
- alignn/ff/calculators.py +572 -0
- alignn/ff/ff.py +1574 -0
- alignn/ff/lammps_bridge.py +175 -0
- alignn/ff/unified_calculator.py +274 -0
- alignn/graphs.py +1353 -0
- alignn/lmdb_dataset.py +316 -0
- alignn/md/__init__.py +13 -0
- alignn/md/forces.py +79 -0
- alignn/md/integrators.py +382 -0
- alignn/md/relax.py +104 -0
- alignn/models/__init__.py +7 -0
- alignn/models/alignn.py +357 -0
- alignn/models/alignn_atomwise.py +701 -0
- alignn/models/alignn_atomwise_pure.py +909 -0
- alignn/models/alignn_atomwise_pure_smooth.py +717 -0
- alignn/models/ealignn_atomwise.py +452 -0
- alignn/models/model_zoo.py +246 -0
- alignn/models/utils.py +407 -0
- alignn/pretrained.py +672 -0
- alignn/pretrained2.py +1464 -0
- alignn/profiler.py +83 -0
- alignn/pure_lmdb_dataset.py +366 -0
- alignn/run_alignn_ff.py +257 -0
- alignn/scripts/__init__.py +1 -0
- alignn/scripts/alignn_evac.py +137 -0
- alignn/scripts/all_train_cgcnn.py +73 -0
- alignn/scripts/bench_dgl_vs_pure.py +345 -0
- alignn/scripts/compare_cfid.py +134 -0
- alignn/scripts/cubic_mat_relax.py +55 -0
- alignn/scripts/defect.py +74 -0
- alignn/scripts/early_stopping_checker.py +50 -0
- alignn/scripts/ev_curve.py +212 -0
- alignn/scripts/ev_curve_comp.py +64 -0
- alignn/scripts/export_torchscript.py +214 -0
- alignn/scripts/final_model.py +58 -0
- alignn/scripts/graph_viz.py +13 -0
- alignn/scripts/make_test_split_cross_pred.py +75 -0
- alignn/scripts/parity_dgl_vs_pure.py +229 -0
- alignn/scripts/plot_ff_results.py +163 -0
- alignn/scripts/plot_phonons_ff.py +61 -0
- alignn/scripts/predict.py +52 -0
- alignn/scripts/predict_db.py +83 -0
- alignn/scripts/predict_db_all.py +111 -0
- alignn/scripts/train_all_hmof.py +49 -0
- alignn/scripts/train_all_hpov.py +49 -0
- alignn/scripts/train_all_jv.py +71 -0
- alignn/scripts/train_all_jv_class.py +70 -0
- alignn/scripts/train_all_jv_dal.py +72 -0
- alignn/scripts/train_all_mp.py +50 -0
- alignn/scripts/train_all_oqmd.py +51 -0
- alignn/scripts/train_all_pdbbind.py +44 -0
- alignn/scripts/train_all_qetb.py +52 -0
- alignn/scripts/train_all_qm9_jctc.py +56 -0
- alignn/scripts/train_all_qmof.py +51 -0
- alignn/scripts/train_cgcnn_repo.py +66 -0
- alignn/scripts/train_edos_pdos.py +44 -0
- alignn/scripts/train_megnet.py +150 -0
- alignn/torch_graph_builder.py +689 -0
- alignn/train.py +934 -0
- alignn/train_alignn.py +573 -0
- alignn/train_props.py +181 -0
- alignn/utils.py +196 -0
- alignn-2026.8.6.data/scripts/export_torchscript.py +98 -0
- alignn-2026.8.6.data/scripts/pretrained.py +672 -0
- alignn-2026.8.6.data/scripts/run_alignn_ff.py +257 -0
- alignn-2026.8.6.data/scripts/train_alignn.py +573 -0
- alignn-2026.8.6.dist-info/METADATA +482 -0
- alignn-2026.8.6.dist-info/RECORD +79 -0
- alignn-2026.8.6.dist-info/WHEEL +6 -0
- alignn-2026.8.6.dist-info/licenses/LICENSE.rst +32 -0
- alignn-2026.8.6.dist-info/top_level.txt +1 -0
alignn/__init__.py
ADDED
alignn/cli.py
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"""Ignite training cli."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
import shutil
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
# from typing import Any, Dict, Optional, Union
|
|
9
|
+
from typing import Optional
|
|
10
|
+
|
|
11
|
+
import torch
|
|
12
|
+
import typer
|
|
13
|
+
|
|
14
|
+
from alignn.config import TrainingConfig
|
|
15
|
+
from alignn.profiler import profile_dgl
|
|
16
|
+
from alignn.train import train_dgl
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def cli(
|
|
20
|
+
config: Optional[Path] = typer.Argument(None),
|
|
21
|
+
progress: bool = False,
|
|
22
|
+
checkpoint_dir: Path = Path("/tmp/models"),
|
|
23
|
+
store_outputs: bool = False,
|
|
24
|
+
tensorboard: bool = False,
|
|
25
|
+
profile: bool = False,
|
|
26
|
+
):
|
|
27
|
+
"""ALIGNN training cli.
|
|
28
|
+
|
|
29
|
+
config: path to json config file (conform to TrainingConfig)
|
|
30
|
+
progress: enable tqdm console logging
|
|
31
|
+
tensorboard: enable tensorboard logging
|
|
32
|
+
profile: run profiling script for one epoch instead of training
|
|
33
|
+
"""
|
|
34
|
+
model_dir = config.parent
|
|
35
|
+
|
|
36
|
+
if config is None:
|
|
37
|
+
model_dir = os.getcwd()
|
|
38
|
+
config = TrainingConfig(epochs=10, n_train=32, n_val=32, batch_size=16)
|
|
39
|
+
|
|
40
|
+
elif config.is_file():
|
|
41
|
+
model_dir = config.parent
|
|
42
|
+
with open(config, "r") as f:
|
|
43
|
+
config = json.load(f)
|
|
44
|
+
config = TrainingConfig(**config)
|
|
45
|
+
|
|
46
|
+
if profile:
|
|
47
|
+
profile_dgl(config)
|
|
48
|
+
return
|
|
49
|
+
|
|
50
|
+
hist = train_dgl(
|
|
51
|
+
config,
|
|
52
|
+
progress=progress,
|
|
53
|
+
checkpoint_dir=checkpoint_dir,
|
|
54
|
+
store_outputs=store_outputs,
|
|
55
|
+
log_tensorboard=tensorboard,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
# print(model_dir)
|
|
59
|
+
# with open(model_dir / "metrics.json", "w") as f:
|
|
60
|
+
# json.dump(hist, f)
|
|
61
|
+
|
|
62
|
+
torch.save(hist, model_dir / "metrics.pt")
|
|
63
|
+
|
|
64
|
+
with open(model_dir / "fullconfig.json", "w") as f:
|
|
65
|
+
json.dump(json.loads(config.json()), f, indent=2)
|
|
66
|
+
|
|
67
|
+
# move temporary checkpoint data into model_dir
|
|
68
|
+
for checkpoint in checkpoint_dir.glob("*.pt"):
|
|
69
|
+
shutil.copy(checkpoint, model_dir / checkpoint.name)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
if __name__ == "__main__":
|
|
73
|
+
typer.run(cli)
|
alignn/config.py
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
"""Pydantic model for default configuration and validation."""
|
|
2
|
+
|
|
3
|
+
import subprocess
|
|
4
|
+
from typing import Optional, Union
|
|
5
|
+
import os
|
|
6
|
+
from typing import Literal
|
|
7
|
+
from alignn.utils import BaseSettings
|
|
8
|
+
from alignn.models.alignn import ALIGNNConfig
|
|
9
|
+
from alignn.models.alignn_atomwise import ALIGNNAtomWiseConfig
|
|
10
|
+
from alignn.models.alignn_atomwise_pure import ALIGNNAtomWisePureConfig
|
|
11
|
+
from alignn.models.alignn_atomwise_pure_smooth import (
|
|
12
|
+
ALIGNNAtomWisePureSmoothConfig,
|
|
13
|
+
)
|
|
14
|
+
from alignn.models.ealignn_atomwise import eALIGNNAtomWiseConfig
|
|
15
|
+
|
|
16
|
+
# import torch
|
|
17
|
+
|
|
18
|
+
try:
|
|
19
|
+
VERSION = (
|
|
20
|
+
subprocess.check_output(["git", "rev-parse", "HEAD"]).decode().strip()
|
|
21
|
+
)
|
|
22
|
+
except Exception:
|
|
23
|
+
VERSION = "NA"
|
|
24
|
+
pass
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
FEATURESET_SIZE = {"basic": 11, "atomic_number": 1, "cfid": 438, "cgcnn": 92}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
TARGET_ENUM = Literal[
|
|
31
|
+
"formation_energy_peratom",
|
|
32
|
+
"optb88vdw_bandgap",
|
|
33
|
+
"bulk_modulus_kv",
|
|
34
|
+
"shear_modulus_gv",
|
|
35
|
+
"mbj_bandgap",
|
|
36
|
+
"slme",
|
|
37
|
+
"magmom_oszicar",
|
|
38
|
+
"spillage",
|
|
39
|
+
"kpoint_length_unit",
|
|
40
|
+
"encut",
|
|
41
|
+
"optb88vdw_total_energy",
|
|
42
|
+
"epsx",
|
|
43
|
+
"epsy",
|
|
44
|
+
"epsz",
|
|
45
|
+
"mepsx",
|
|
46
|
+
"mepsy",
|
|
47
|
+
"mepsz",
|
|
48
|
+
"max_ir_mode",
|
|
49
|
+
"min_ir_mode",
|
|
50
|
+
"n-Seebeck",
|
|
51
|
+
"p-Seebeck",
|
|
52
|
+
"n-powerfact",
|
|
53
|
+
"p-powerfact",
|
|
54
|
+
"ncond",
|
|
55
|
+
"pcond",
|
|
56
|
+
"nkappa",
|
|
57
|
+
"pkappa",
|
|
58
|
+
"ehull",
|
|
59
|
+
"exfoliation_energy",
|
|
60
|
+
"dfpt_piezo_max_dielectric",
|
|
61
|
+
"dfpt_piezo_max_eij",
|
|
62
|
+
"dfpt_piezo_max_dij",
|
|
63
|
+
"gap pbe",
|
|
64
|
+
"e_form",
|
|
65
|
+
"e_hull",
|
|
66
|
+
"energy_per_atom",
|
|
67
|
+
"formation_energy_per_atom",
|
|
68
|
+
"band_gap",
|
|
69
|
+
"e_above_hull",
|
|
70
|
+
"mu_b",
|
|
71
|
+
"bulk modulus",
|
|
72
|
+
"shear modulus",
|
|
73
|
+
"elastic anisotropy",
|
|
74
|
+
"U0",
|
|
75
|
+
"HOMO",
|
|
76
|
+
"LUMO",
|
|
77
|
+
"R2",
|
|
78
|
+
"ZPVE",
|
|
79
|
+
"omega1",
|
|
80
|
+
"mu",
|
|
81
|
+
"alpha",
|
|
82
|
+
"homo",
|
|
83
|
+
"lumo",
|
|
84
|
+
"gap",
|
|
85
|
+
"r2",
|
|
86
|
+
"zpve",
|
|
87
|
+
"U",
|
|
88
|
+
"H",
|
|
89
|
+
"G",
|
|
90
|
+
"Cv",
|
|
91
|
+
"A",
|
|
92
|
+
"B",
|
|
93
|
+
"C",
|
|
94
|
+
"all",
|
|
95
|
+
"target",
|
|
96
|
+
"max_efg",
|
|
97
|
+
"avg_elec_mass",
|
|
98
|
+
"avg_hole_mass",
|
|
99
|
+
"_oqmd_band_gap",
|
|
100
|
+
"_oqmd_delta_e",
|
|
101
|
+
"_oqmd_stability",
|
|
102
|
+
"edos_up",
|
|
103
|
+
"pdos_elast",
|
|
104
|
+
"bandgap",
|
|
105
|
+
"energy_total",
|
|
106
|
+
"net_magmom",
|
|
107
|
+
"b3lyp_homo",
|
|
108
|
+
"b3lyp_lumo",
|
|
109
|
+
"b3lyp_gap",
|
|
110
|
+
"b3lyp_scharber_pce",
|
|
111
|
+
"b3lyp_scharber_voc",
|
|
112
|
+
"b3lyp_scharber_jsc",
|
|
113
|
+
"log_kd_ki",
|
|
114
|
+
"max_co2_adsp",
|
|
115
|
+
"min_co2_adsp",
|
|
116
|
+
"lcd",
|
|
117
|
+
"pld",
|
|
118
|
+
"void_fraction",
|
|
119
|
+
"surface_area_m2g",
|
|
120
|
+
"surface_area_m2cm3",
|
|
121
|
+
"indir_gap",
|
|
122
|
+
"f_enp",
|
|
123
|
+
"final_energy",
|
|
124
|
+
"energy_per_atom",
|
|
125
|
+
"ead",
|
|
126
|
+
]
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class TrainingConfig(BaseSettings):
|
|
130
|
+
"""Training config defaults and validation."""
|
|
131
|
+
|
|
132
|
+
version: str = VERSION
|
|
133
|
+
|
|
134
|
+
# dataset configuration
|
|
135
|
+
dataset: Literal[
|
|
136
|
+
"dft_3d",
|
|
137
|
+
"jdft_3d-8-18-2021",
|
|
138
|
+
"dft_2d",
|
|
139
|
+
"megnet",
|
|
140
|
+
"megnet2",
|
|
141
|
+
"mp_3d_2020",
|
|
142
|
+
"qm9",
|
|
143
|
+
"qm9_dgl",
|
|
144
|
+
"qm9_std_jctc",
|
|
145
|
+
"user_data",
|
|
146
|
+
"oqmd_3d_no_cfid",
|
|
147
|
+
"edos_up",
|
|
148
|
+
"edos_pdos",
|
|
149
|
+
"qmof",
|
|
150
|
+
"qe_tb",
|
|
151
|
+
"hmof",
|
|
152
|
+
"hpov",
|
|
153
|
+
"pdbbind",
|
|
154
|
+
"pdbbind_core",
|
|
155
|
+
"tinnet_OH",
|
|
156
|
+
"tinnet_O",
|
|
157
|
+
"tinnet_N",
|
|
158
|
+
] = "dft_3d"
|
|
159
|
+
target: TARGET_ENUM = "exfoliation_energy"
|
|
160
|
+
atom_features: Literal["basic", "atomic_number", "cfid", "cgcnn"] = "cgcnn"
|
|
161
|
+
neighbor_strategy: Literal[
|
|
162
|
+
"k-nearest",
|
|
163
|
+
"voronoi",
|
|
164
|
+
"radius_graph",
|
|
165
|
+
"radius_graph_jarvis",
|
|
166
|
+
"fast_graph",
|
|
167
|
+
"torch_graph",
|
|
168
|
+
"pure_torch",
|
|
169
|
+
] = "k-nearest"
|
|
170
|
+
id_tag: Literal["jid", "id", "_oqmd_entry_id"] = "jid"
|
|
171
|
+
|
|
172
|
+
# training configuration
|
|
173
|
+
dtype: str = "float32"
|
|
174
|
+
random_seed: Optional[int] = 123
|
|
175
|
+
classification_threshold: Optional[float] = None
|
|
176
|
+
# target_range: Optional[List] = None
|
|
177
|
+
n_val: Optional[int] = None
|
|
178
|
+
n_test: Optional[int] = None
|
|
179
|
+
n_train: Optional[int] = None
|
|
180
|
+
train_ratio: Optional[float] = 0.8
|
|
181
|
+
val_ratio: Optional[float] = 0.1
|
|
182
|
+
test_ratio: Optional[float] = 0.1
|
|
183
|
+
target_multiplication_factor: Optional[float] = None
|
|
184
|
+
epochs: int = 300
|
|
185
|
+
batch_size: int = 64
|
|
186
|
+
gpu_memory_fraction: Optional[float] = None
|
|
187
|
+
use_amp: bool = False # bf16 mixed precision (A100/H100/RTX 30+)
|
|
188
|
+
# DDP tuning. find_unused_parameters=True is slow; enable only if
|
|
189
|
+
# your model has conditional branches whose gradients vary per step.
|
|
190
|
+
ddp_find_unused_parameters: bool = False
|
|
191
|
+
# Resume optimizer/scheduler/epoch from <output_dir>/current_state.pt if
|
|
192
|
+
# present. Lets a run that hit the walltime continue with a single
|
|
193
|
+
# continuous LR schedule instead of restarting it (weights alone are
|
|
194
|
+
# restored via --restart_model_path, which does not restore these).
|
|
195
|
+
resume_checkpoint: bool = False
|
|
196
|
+
# LR-schedule horizon in epochs, independent of how many epochs this job
|
|
197
|
+
# runs (`epochs`). Set it to the FINAL target when a run is split into
|
|
198
|
+
# resumed segments so OneCycle spans the whole run and stays continuous
|
|
199
|
+
# across restarts. None => use `epochs` (the single-job default).
|
|
200
|
+
lr_total_epochs: Optional[int] = None
|
|
201
|
+
# When True, forces cuDNN determinism (slower). Decoupled from seed so
|
|
202
|
+
# you can seed for reproducibility without paying the speed cost.
|
|
203
|
+
deterministic: bool = False
|
|
204
|
+
weight_decay: float = 0
|
|
205
|
+
learning_rate: float = 1e-2
|
|
206
|
+
filename: str = "sample"
|
|
207
|
+
warmup_steps: int = 2000
|
|
208
|
+
criterion: Literal["mse", "l1", "poisson", "zig"] = "mse"
|
|
209
|
+
optimizer: Literal["adamw", "sgd"] = "adamw"
|
|
210
|
+
scheduler: Literal["onecycle", "none"] = "onecycle"
|
|
211
|
+
pin_memory: bool = False
|
|
212
|
+
save_dataloader: bool = False
|
|
213
|
+
write_checkpoint: bool = True
|
|
214
|
+
write_predictions: bool = True
|
|
215
|
+
store_outputs: bool = True
|
|
216
|
+
progress: bool = True
|
|
217
|
+
log_tensorboard: bool = False
|
|
218
|
+
standard_scalar_and_pca: bool = False
|
|
219
|
+
use_canonize: bool = True
|
|
220
|
+
compute_line_graph: bool = True
|
|
221
|
+
num_workers: int = 4
|
|
222
|
+
cutoff: float = 5.0
|
|
223
|
+
cutoff_extra: float = 3.0
|
|
224
|
+
# Separate 3-body cutoff used by neighbor_strategy="pure_torch".
|
|
225
|
+
# When None, defaults to `cutoff`. Must be <= cutoff.
|
|
226
|
+
three_body_cutoff: Optional[float] = 3.5
|
|
227
|
+
max_neighbors: Optional[int] = 12
|
|
228
|
+
keep_data_order: bool = True
|
|
229
|
+
normalize_graph_level_loss: bool = False
|
|
230
|
+
distributed: bool = False
|
|
231
|
+
data_parallel: bool = False
|
|
232
|
+
n_early_stopping: Optional[int] = None # typically 50
|
|
233
|
+
output_dir: str = os.path.abspath(".")
|
|
234
|
+
use_lmdb: bool = True
|
|
235
|
+
# When True, reuse an existing LMDB cache on disk (fast, but the
|
|
236
|
+
# cache must match the current model backend + graph config).
|
|
237
|
+
# Default False: always rebuild from scratch for safety.
|
|
238
|
+
read_existing: bool = False
|
|
239
|
+
# alignn_layers: int = 4
|
|
240
|
+
# gcn_layers: int =4
|
|
241
|
+
# edge_input_features: int= 80
|
|
242
|
+
# hidden_features: int= 256
|
|
243
|
+
# triplet_input_features: int=40
|
|
244
|
+
# embedding_features: int=64
|
|
245
|
+
|
|
246
|
+
# model configuration
|
|
247
|
+
model: Union[
|
|
248
|
+
ALIGNNConfig,
|
|
249
|
+
ALIGNNAtomWiseConfig,
|
|
250
|
+
ALIGNNAtomWisePureConfig,
|
|
251
|
+
ALIGNNAtomWisePureSmoothConfig,
|
|
252
|
+
eALIGNNAtomWiseConfig,
|
|
253
|
+
] = ALIGNNAtomWiseConfig(name="alignn_atomwise")
|