MLIP
MLIP runs machine-learned interatomic potentials through Atomli’s retained
native inference session. It is intended for systems and workflows where a
trained model covers the required elements and configurations.
Load a model
Section titled “Load a model”A catalog id downloads once, verifies its checksum, and then reuses the local cache:
from atomli.calculators.mlip import MLIP
atoms.calc = MLIP("nequix-mp-1")energy = atoms.get_potential_energy()forces = atoms.get_forces()Silicon: accuracy and cost
Section titled “Silicon: accuracy and cost”Diamond silicon with nequix-mp-1:
Cost first, because that is the reason to reach for a potential at all:
| Atoms | One energy | Per atom |
|---|---|---|
| 8 | 3.8 ms | 474 µs |
| 64 | 8.1 ms | 127 µs |
| 216 | 18.8 ms | 87 µs |
| 512 | 42.9 ms | 84 µs |
512 atoms in 43 ms, and the per-atom cost falls by 6× across that range as the fixed per-call overhead amortizes. Compare GFN2-xTB on the same lattice, where 64 atoms already costs 0.8 s. That gap is the whole argument for a potential, and it is why long trajectories and large cells are where these models belong.
The energy per atom is flat to 20 µeV across all four cell sizes, which is the correctness check that matters for a short-range model: a supercell of a periodic crystal must give the same energy per atom as the primitive cell, and a broken neighbour list or a cutoff larger than half the box would break exactly that.
Accuracy is the other half, and it is more nuanced. Fitting the energy against the lattice constant over 23 points puts the minimum at 5.504 Å with a minimum energy of -5.428 eV/atom:
| Quantity | nequix-mp-1 | Reference | Difference |
|---|---|---|---|
| lattice constant | 5.504 Å | 5.431 Å (experiment) | +1.34% |
| energy per atom | -5.417 eV | ≈-5.42 eV (GGA-PBE, Materials Project) | 0.003 eV |
The energy sits on its training label. The lattice constant does not sit on experiment, and it should not be expected to: this model was trained on GGA-PBE energies, PBE itself overestimates the silicon lattice constant, and the model then adds its own error on top. A potential cannot be more right than the labels it learned from. Judge one against its reference method first, and only then ask how far that method is from the measurement.
That whole scan took 15 ms. Construction, which is where the weights are resolved from cache or downloaded, took 1 ms here because the cache was already warm; the first run on a fresh machine pays a network fetch instead.
You can also supply a local model:
atoms.calc = MLIP("/models/custom.nqx")For local paths, Atomli infers NequIP packages from .zip and Equiformer
checkpoints from .pt. Set runtime="nequix", "nequip", or
"equiformer" explicitly when suffix inference is not enough.
Runtime families
Section titled “Runtime families”| Runtime | Typical file | Catalog examples |
|---|---|---|
| Nequix | .nqx |
nequix-mp-1, nequix-oam-1, nequix-omat-1 |
| NequIP | .nequip.zip |
nequip-s, nequip-l |
| Equiformer | .pt |
equiformer, equiformer-gradient |
Catalog ids pin their own runtime, so the file and runtime cannot drift apart. See MLIP models for the complete catalog and cache controls.
Energy, forces, and stress
Section titled “Energy, forces, and stress”The Python calculator exposes energy, forces, and stress. Periodic models
can drive fixed-cell dynamics and cell optimization:
atoms.calc = MLIP("nequix-mp-1")stress = atoms.get_stress()A stress request returns the full 3 × 3 tensor and requires periodic boundary conditions and a cell. The loaded model also validates the structure’s elements against its own species table before inference.
Device modes
Section titled “Device modes”CPU is the default:
atoms.calc = MLIP("nequip-s", device="cpu")GPU-capable wheels accept device="wgpu" (alias "gpu"), which runs on
Metal, Vulkan, or DX12 through one portable path:
atoms.calc = MLIP("nequip-s", device="wgpu")device="auto" measures both paths on the first inference in each system-size
bucket and keeps the winner, falling back to CPU when no adapter exists.
On a multi-GPU host, pin the adapter in the device string, by enumeration index or by a case-insensitive name substring:
atoms.calc = MLIP("nequix-mp-1", device="wgpu:1")atoms.calc = MLIP("nequix-mp-1", device="wgpu:a100")The pin is resolved at the first GPU initialization in the process and the context is kept, so choose one adapter per process. A selector that matches no adapter fails with the list of available adapters.
An explicit WGPU request fails when the wheel lacks GPU support or no adapter is available. Atomli never reports CPU timings after silently downgrading a GPU request.
CPU and GPU use the same model but are not bitwise identical because inference
crosses an f32 model boundary and reductions occur in a different order.
Select one device for a trajectory or relaxation and keep it fixed.
Model delivery and reproducibility
Section titled “Model delivery and reproducibility”Model weights are not stored in the wheel. Resolution follows this order:
- an existing local path or verified cache entry;
- the Tako-hosted default when the catalog provides one;
- the
mlip-modelsGitHub Release as the backup.
Every catalog file has a pinned byte size and SHA-256 digest. A bad cache entry
or mismatched download is rejected. Use ATOMLI_MODELS_DIR to pin the cache
location for managed environments.
State reuse
Section titled “State reuse”The native calculator retains its loaded runtime, exact-geometry calculation cache, device buffers, and neighbor-list state. A narrower property request at the same geometry can reuse an earlier inference, which matters in optimizers that ask for closely related values in succession.
Python features
Section titled “Python features”- Nequix, NequIP, and Equiformer runtimes
- Catalog ids and direct local paths
- CPU and optional WGPU devices
- Energy, forces, and periodic stress
- Periodic structures and cell optimization
- Download, checksum verification, and platform cache management
Native-only features
Section titled “Native-only features”The mlip.rs adapter additionally exposes inference counts, explicit cache reset, neighbor-list skin configuration, and neighbor-list rebuild/reuse statistics. Its GPU path installs a default neighbor skin to keep topology and device buffers stable during repeated evaluations.
Those tuning and diagnostic methods are native engine capabilities. They are
not yet public methods on the Python MLIP object.
Use cases
Section titled “Use cases”Choose MLIP for long trajectories, large periodic cells, screening, or repeated relaxations when a validated model covers the relevant chemistry. A model is not a universal replacement for electronic structure: check its training domain, supported elements, energy convention, and validation error for the target workflow.