Every training run in ALIGNN is controlled by a single JSON file. The schema is
enforced by two pydantic classes: TrainingConfig (top-level) in
alignn/config.py
and a per-model config (e.g. ALIGNNAtomWiseConfig) in
alignn/models/alignn_atomwise.py.
At runtime the config is validated and any unknown field is rejected, so this
file is the authoritative list of what's available.
Cache built graphs in LMDB (fast reload, memory-bounded).
read_existing
False
If True, reuse an existing LMDB cache on disk. Must match the current model backend (DGL vs pure-torch). Default False rebuilds from scratch every run to avoid footguns.
Multiplier applied to ∂E/∂r when converting to forces. Physics convention F = −∂E/∂x ⇒ -1.
add_reverse_forces
True
Sum ∂E/∂r over both (i→j)and(j→i) edges (proper Newton's third law on directed graphs).
lg_on_fly
True
Recompute bond-angle cosines inside the autograd graph every forward (needed for exact force/stress derivatives). Leave True unless profiling.
batch_stress
True
Compute stress per graph in the batch (vs. one stress per whole batch).
force_mult_natoms
False
Scale forces by number of atoms (rare; use for unit conventions).
energy_mult_natoms
True
Treat the graph-head output as energy per atom and multiply by natoms before taking the gradient. Standard for ALIGNN-FF.
stress_multiplier
1.0
Final scalar on the stress output (for unit fixes).
include_pos_deriv
False
Alternative force path: differentiate through Cartesian positions directly (rather than through edge displacements). Currently experimental; the _pure variant accepts the field but ignores it.
Add a repulsive penalty when any bondlength falls below penalty_threshold. Prevents the model from hallucinating attractive wells at unphysical distances — important for MD stability.
model.name = "alignn_atomwise_pure" swaps the DGL message-passing core for
scatter_add / scatter_mean primitives. The forward outputs are numerically
equivalent to alignn_atomwise — parity sweep across all doc examples shows
|Δ| ≤ 0.04 on all losses after 3 epochs (force-field scenario is bit-identical,
see alignn/scripts/parity_dgl_vs_pure.py). Residual drift is scatter_add
nondeterminism on CUDA, not a modelling difference.
Not carried over from alignn_atomwise (config fields accepted but ignored):
include_pos_deriv
Some extra_features code paths — experimental in the DGL model too.
When the pure model is selected, the training pipeline automatically:
Uses alignn/pure_lmdb_dataset.py (pickles TorchGraph objects, no DGL).
Uses PureTorchLMDBDataset.collate_line_graph for batching.
Leaves dataloader / loss / metrics / checkpoints untouched.
For LAMMPS integration, call
alignn/scripts/torch/export_torchscript.py (installed as the export_torchscript.py console script) — it scripts the
forward_tensors_z(positions, lattice, atomic_numbers, src, dst, shift,
compute_stress) entry point and bakes the atomic-number → feature lookup into
the .pt so the C++ host only needs atomic numbers.
atom_input_features vs atom_features. These must match (cgcnn → 92,
atomic_number → 1, basic → 11, cfid → 438). A mismatch raises a shape error
at the first forward pass, not at config parse.
read_existing. Keep false unless you're sure the cache matches the
current model backend + graph settings. Backend-mismatch (DGL vs pure) is
caught and raises a clear error; parameter drift (different cutoff etc.) is
not caught.
gradwise_weight=0 silently disables calculate_gradient in the model
code. If you think forces should be training but see Grad=0.0000, check
both flags.
use_penalty=true with a loose cutoff can inflate training loss when
your data legitimately has short bonds (e.g. H-containing systems). Lower
penalty_threshold or set use_penalty=false in that case.
batch_stress=false + large batch gives one stress for the whole
batch, not per-graph — almost never what you want.
lg_on_fly=false caches triplet angle cosines; saves time but forces
computed by autograd will be missing the angle-contribution unless you
recompute them. Leave true for force-field training.