xnn
Machine-learning interatomic potentials for molecules and materials behind one PyTorch interface.
x in xnn refers to the neural network model architectures: g stands for graph, d for dense, c for convolutional, ff for classical force-fields, sqm for semi-empirical quantum mechanics, hybrid for mixed models, all sharing one data object, one trainer and one deployment path. This categorization is reflected in the package structure.
Documentation: https://molssi-ai.github.io/xnn/
Installation
pip install xnns # core (torch, numpy, pyyaml)
pip install "xnns[gnn,ase]" # + e3nn for NequIP/MACE/Allegro, + ASE calculator
pip install -e ".[all]" # from a clone: everything, for development
The distribution is xnns; the import name and the command line are xnn.
Design principles
- One data object. Every model takes an
AtomicGraphand returns{"node_energy", "energy"}. Periodicity lives only in the edge vectors, so molecules and crystals look the same to a model. - Featurizers are first-class. Descriptors (symmetry functions, AEV) and equivariant edge features (spherical harmonics, Cartesian monomials) are standalone modules that models compose and you can inspect on their own.
- Forces and stress in one place.
ForceStressOutputdifferentiates any model's energy for forces and stress; models never implement them. Wrappers in the same style add long-range electrostatics (LES) and DFT-D3 / DFT-D4 dispersion to any model. - One config, three frontends.
@register_modelexposes a model to the YAML, argparse and Hydra interfaces, all of which fill oneConfigdataclass.
Load data
Structures are plain dictionaries (pos, atomic_numbers, optional cell,
pbc and energy / forces / stress targets), any ASE-readable file, or a
dataset from the hub:
from xnn.common.data import AtomicDataset, load_dataset
# From a list of structures dict
data = AtomicDataset(structures, cutoff=5.0)
# From a file (e.g., .extxyz, .cif, VASP, ...)
data = AtomicDataset.from_file("trajectory.extxyz", cutoff=5.0)
# From the xnn data hub (e.g., RMD17 dataset)
data = load_dataset("rmd17", molecule="aspirin", split="train", cutoff=5.0)
Train
from xnn.common.config import Config
from xnn.common.train import Trainer
# Initialize the configuration
cfg = Config()
# Set the model and data configuration
cfg.model.name = "nequip"
cfg.model.extra = {"species": [1, 6, 8], "l_max": 2}
cfg.data.batch_size = 16
# Train the model
Trainer(cfg, data).fit()
or from the command line: xnn train --config configs/train.yaml --set optim.epochs=50.
Pretrained models
from xnn.common.models import from_pretrained, list_models
# Foundation models, xnn models, local cache
list_models()
# MACE-MP / MACE-OFF, converted once and cached
model = from_pretrained("mace-off23-small")
# Your own checkpoints
model = from_pretrained("runs/exp/best.pt")
Fine-tune
Any pretrained model continues training through the same Trainer: naive
fine-tuning, LoRA, multi-head replay (with original or pseudolabelled replay
data), layer freezing and model-aware reference-energy reestimation, all from
the config:
model:
pretrained: mace-off23-small
cutoff: 5.0
lora: {rank: 16} # or heads: [pt_head, Default] with data.replay_path
atomic_energies: estimated
Benchmark
Score pre-trained checkpoints on one dataset (energy / force / stress MAE, MSE or RMSE, per atom or as atomization energies), tabulated per model and written to CSV, JSON or Markdown:
xnn benchmark --config configs/benchmark.yaml
Deploy
from xnn.common.deploy import XNNCalculator, export_to_lammps
# Export as ASE calculator
atoms.calc = XNNCalculator(model, cutoff=5.0)
# Export to LAMMPS (TorchScript)
export_to_lammps(model, cutoff=5.0, path="deployed.pt")
xnn mdi --ckpt runs/exp/best.pt serves a model to an external MD code through
the MolSSI Driver Interface.
Models
| Family | Models |
|---|---|
Generic add-ons (common) |
LES long-range electrostatics (optionally charge-constrained or charge-equilibrated); DFT-D3 (zero, BJ, mzero, op damping) and DFT-D4 dispersion |
Graph neural networks (gnn) |
SchNet, DimeNet, DimeNet++, PaiNN, NequIP, MACE, Allegro, CACE, AIMNet2 |
Dense neural networks (dnn) |
ANI (ANI-1, ANI-1x, ANI-1ccx, ANI-2x), PhysNet, HDNNP (generations 1 to 4) |
Convolutional neural networks (cnn) |
3D steerable-/ conventional- / spherical-CNN |
Force field neural networks (ffnn) |
ReaxFF / ReaxFF-nn, OPLS-AA / L-OPLS, DREIDING / X6 |
Hybrid neural networks (hybrid) |
BAMBOO, SpookyNet |
Semiempirical quantum mechanics neural networks (sqmnn) |
PM3, PM6, PM6-ORG, PM7 (classics or trainable) |
Each model is checked against its reference code or paper
(examples/fidelity_checks/). SchNet, DimeNet, PaiNN, SpookyNet, NequIP, MACE, Allegro and AIMNet2
also export to TorchScript / LAMMPS; every model deploys through ASE and the MDI
engine.
Examples and tests
Executed notebooks for every model are under examples/
(pip install -e ".[examples]"); examples/quickstart.py is a minimal script.
Run the tests with pytest tests/.
Contributing
Bug reports, fixes and new models are welcome. Read CONTRIBUTING.md first: it explains how to report a bug with a reproducible example and what a pull request needs to be merged.
License
MIT
How to cite
If you use xnn in your work, please cite it as:
@software{Mostafanejad:2026:xnn,
author = {Mostafanejad, Mohammad},
title = {xnn: Machine-learning interatomic potentials for molecules and materials},
year = {2026},
version = {0.11.0},
url = {https://github.com/molssi-ai/xnn}
}
Author: Mohammad Mostafanejad, The Molecular Sciences Software Institute (MolSSI)
Metadata
Release files for xnns 0.11.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| xnns-0.11.1.tar.gz | 1.7 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| xnns-0.11.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 3.3 MB
Release files / xnns-0.11.1.tar.gz
| Download URL | xnns-0.11.1.tar.gz |
|---|---|
| Size | 1.7 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
adec0a0be6a2dbca2047eb41756915e467d632f7af927dbf21bb451c313e672a
|
|
BLAKE2b-256 checksum How to use checksums |
d60490600974780909761c07b0b34f2635d1933e0a4dba8847906b4c7da43e13
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.
Transparency logRelease files / xnns-0.11.1-py3-none-any.whl
| Download URL | xnns-0.11.1-py3-none-any.whl |
|---|---|
| Size | 1.6 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
bd2cbaf46f74a9eed1bb9a0856aeada8d8c8eff1c24802364bff5696a17f543d
|
|
BLAKE2b-256 checksum How to use checksums |
2fc6810e051459d4f589072504c547d17900d76e0643938c122d04daf939242b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.
Transparency log