Machine-learning interatomic potentials (MACE)¶
Which MACE?¶
Two separate projects use this name:
Project |
Purpose |
Relation to vibe-qc |
|---|---|---|
ACEsuit MACE, installed as |
Machine-learned energy, forces and stress |
Provides |
DFT workflow automation for CRYSTAL, including structure preparation, job management and analysis |
Separate workflow application |
Mendoza’s v1.1.5 announcement, browser GUI and mace gui connect command
refer to the workflow application. Our MLIP interface uses ACEsuit’s
calculator API. Install the mace-torch distribution for this interface;
a package named mace is not a substitute. Keep applications that occupy
the same Python import namespace in separate environments.
vibe-qc can run ACEsuit MACE, a pre-trained E(3)-equivariant graph-neural-network interatomic potential, as a first-class method:
from vibeqc import Molecule
from vibeqc.runner import run_job
mol = Molecule.from_xyz("h2o.xyz")
run_job(mol, method="mace", output="h2o_mace")
MACE predicts energy, forces, and stress on a DFT-fitted potential-energy surface, it does not solve the Schrödinger equation and builds no wavefunction. vibe-qc drives MACE’s pre-trained forward pass and attributes it as an external pre-trained model in the citation block; the energy is MACE’s, not a vibe-qc ab-initio total. Within its trained domain it provides a fast model surface, but accuracy must be established against an external observable for the system and protocol in question. It gives no electronic structure (no orbitals / charges / gap) and only covers its trained elements.
Status. The vibe-qc interface (registry, licence gate, molecular and periodic drivers, provenance) is production. The model behind it is an external pre-trained potential and not a vibe-qc method: vibe-qc computes none of its numbers and cannot vouch for their accuracy beyond what the model papers report. The label vocabulary is defined in Methods: theory and status.
Background: what MACE is¶
MACE (Batatia, Ilyes, Kovács, Dávid Péter, et al. (2022). *MACE: Higher Order Equivariant Message Passing Neural Networks for Fast and Accurate Force Fields.* Advances in Neural Information Processing Systems, **35**, 11423–11436. doi:[10.52202/068431-0830](https://doi.org/10.52202/068431-0830)) is a message-passing neural network interatomic potential. The total energy is a sum of atomic site energies,
each a learned function of the atom’s neighbourhood within a cutoff. Forces and the stress are the analytic negative derivatives of \(E\) with respect to positions and strain, obtained by automatic differentiation, so they are exactly consistent with the energy. Three ideas make MACE what it is.
Equivariance. Every internal feature is a set of irreducible representations of \(E(3)\) (scalars, vectors, rank-2 tensors, …) built from spherical harmonics of the neighbour directions and a learned radial basis. Rotating or reflecting the input rotates the features accordingly and leaves the energy unchanged, so symmetry is exact by construction rather than learned from augmented data.
Body order from the atomic cluster expansion. The message an atom receives in one layer is not a sum of pair terms but a many-body expansion: MACE forms symmetric tensor products of the neighbour features up to a correlation order \(\nu\) (the published models use \(\nu = 3\), so one message already contains up to four-body information) using the atomic cluster expansion, and two such layers are sufficient in practice. This is why MACE reaches its accuracy with few layers and a modest receptive field.
Training data. The parameters are fitted to DFT energies, forces and stresses of large datasets. MACE-MP-0 (Batatia, Ilyes, Benner, Philipp, et al. (2025). *A foundation model for atomistic materials chemistry.* The Journal of Chemical Physics, **163**(18), 184110. doi:[10.1063/5.0297006](https://doi.org/10.1063/5.0297006)) is trained on MPtrj, the relaxation trajectories of the Materials Project (PBE and PBE+U), and MACE-MPA-0 on MPtrj plus a subsample of the Alexandria database; both cover 89 elements and are released under the MIT licence. MACE-OFF23 (Kovács, Dávid Péter, Moore, J. Harry, et al. (2025). *MACE-OFF: Short-Range Transferable Machine Learning Force Fields for Organic Molecules.* Journal of the American Chemical Society, **147**(21), 17598–17611. doi:[10.1021/jacs.4c07099](https://doi.org/10.1021/jacs.4c07099)) is trained on the SPICE dataset of organic molecules at the \(\omega\)B97M-D3(BJ)/def2-TZVPPD level, covers H, C, N, O, F, P, S, Cl, Br and I, and is released under the Academic Software License (academic, non-commercial), which is why vibe-qc gates it. The absolute energy of each family sits on the reference scale of its training functional minus a per-element offset, hence the energy-scale caveat below.
What follows from this for a user: a MACE energy is a regression estimate
of the training functional on the training distribution. Inside that
distribution it is fast and typically close to the DFT it learned; outside
it (unusual oxidation states, charged or open-shell species, elements or
bonding motifs absent from the data, very short contacts) it fails without
warning, because there is no variational principle, no SCF residual and no
electronic structure to inspect. The registry exported by
mace_model_registry() records the training data and theory level of each
model so that this provenance travels with every result.
Single-point evaluation validates the backend energy, forces, and applicable
3D stress before returning or caching a result. Missing properties, wrong
array shapes, and non-finite values raise ValueError; backend exceptions
propagate. A failed evaluation cannot leave a partially accepted energy in
the cache. These checks validate the result contract, not model accuracy.
Molecular and periodic optimizers require a finite positive fmax and a
non-negative integer step budget (max_opt_steps for molecular run_job,
max_steps for periodic drivers). They reject invalid controls before loading
a model. Molecular run_job also rejects these controls before creating output.
A zero-step budget is allowed to assess the initial structure against the
requested force criterion; it does not imply convergence.
The fixed-cell optimizer’s gradient() is the physical energy derivative
in Ha/bohr, including forces on frozen atoms. Its max_force_eva and
converged fields use the constrained forces, with frozen atoms excluded
from the stopping criterion.
fixed_indices requires integer atom indices; fractional values and strings
are rejected instead of converted. Both periodic optimizers check the final
energy and physical forces for finite values before returning. Cell
relaxation also checks the final stress.
MACE checks that coordinates have finite values and shape (n_atoms, 3)
and that a supplied cell has finite values and shape (3, 3) before
loading the backend. Explicit pbc masks contain three booleans or integer
0/1 flags. The model copies the supplied cell. A rejected structure update
in a reusable evaluator preserves the previous structure and cached result.
These checks validate input representation, not a geometry’s physical
suitability for a trained model.
Installation, the [mace] extra (Python ≤ 3.13)¶
MACE is an optional dependency (a heavy PyTorch + e3nn stack), not part of the default install:
pip install 'vibe-qc[mace]'
The extra selects mace-torch>=0.3.16,<0.4. ACEsuit’s
supported 0.3.x line
provides the calculator and serialized checkpoint APIs used here.
Its planned 1.0 rewrite changes those APIs and requires checkpoint conversion.
When installed mace-torch version metadata is available, other API series
raise an installation error before importing the ML stack or changing its
runtime environment. Source trees without distribution metadata still pass
through the calculator import checks. A missing stack or calculator reports
the ACEsuit package name and installation command, preserving the original
import failure as the exception cause.
Supported installation: Python ≤ 3.13. The
[mace]extra is markedpython_version < "3.14"and installs no MACE stack on Python 3.14. If the backend is missing,method="mace"raises an installation error. A manually installed newer stack may import and run; this does not extend the supported interpreter range or qualify that stack for production.
Apple MPS requires MLIPOptions(device="mps", dtype="float32").
vibe-qc loads and converts the checkpoint on CPU before transferring the
model to MPS; inference stays on the requested device. Invalid precision
choices and unavailable MPS devices fail explicitly.
MACE 0.3.16 has a separate forward-pass float64 cast that prevents MPS
inference even with float32 weights. MPS also requires an upstream build
containing the node-energy fix, commit 22f0809.
Installing the ordinary extra with MACE 0.3.16 does not satisfy that
requirement. The real MPS energy/force/stress regression remains active on
MPS hardware so this dependency limitation is not hidden.
The foundation-model weights are fetched on demand into the XDG cache
(~/.cache/mace/) on first use, vibe-qc bundles none of them.
Run the dependency-only health check before downloading weights:
python examples/mlip/00_runtime_healthcheck.py
For a reproducible runtime, record the VibeQC source SHA and version,
Python version, MACE/Torch/e3nn/ASE versions, device, dtype and model key.
The health-check example reports everything available before a model is
loaded. Loading snapshots the registered checkpoint and computes a SHA256
digest of the same bytes passed to PyTorch. MACEModel.weight_identity and
periodic result objects expose this digest, byte count, registered URL and
checkpoint loader. The loader model metadata names the upstream registry
selector; checkpoint.loader identifies VibeQC’s snapshot loader.
The URL identifies the registry entry, not proof of the cached file’s origin.
The digest identifies the serialized checkpoint, not subsequent in-memory
modifications or the scientific accuracy of its predictions. Upstream cache
names and the bundled MPA-0 preference are preserved; clearing a cache fetches
the registered weights again.
Molecular run_job records the executed model, device and dtype in
.system under [run.mlip] and in QVF provenance.mlip, together with
the loader, license, citation and energy scale. Its QVF job specification
preserves those runtime choices for replay, resolving aliases to the
canonical model name. .out, .system and QVF also record the checkpoint
identity. Replay supplies its digest as MLIPOptions(weight_sha256=...) and
rejects different bytes before deserialization. This option can also pin a
checkpoint for a new job. Older archives without a digest still load the
selected model, but cannot enforce checkpoint identity.
Output records do not copy academic-license acknowledgment;
replaying an OFF23 calculation still requires the caller’s acknowledgment.
QVF provenance marks the forward pass as scf_applicable=false and omits
SCF convergence and iteration claims.
Selecting a model, MLIPOptions¶
The default is the MIT-licensed MACE-MPA-0 (materials). Pass an
MLIPOptions to choose another registered model, the device, or the
dtype. Organic-family work uses MACE-OFF23 and must acknowledge its
license explicitly:
from vibeqc import Molecule, run_job
from vibeqc.mlip import MLIPOptions
ethanol = Molecule.from_xyz("ethanol.xyz")
options = MLIPOptions(
model="off23-medium",
accept_academic_license=True,
device="cpu",
dtype="float64",
)
run_job(
ethanol,
method="mace",
mlip_options=options,
output="ethanol_off23",
)
Model key |
Family |
Domain |
License |
|---|---|---|---|
|
MACE-MP / MPA |
materials (89 elements) |
MIT |
|
MACE-OFF23 |
organic (H, C, N, O, F, P, S, Cl, Br, I) |
ASL |
Aliases (mpa-0, off23, …) resolve to the canonical keys; see
vibeqc.mlip.MACE_MODELS. The supported public scope contains only
registered MACE-MP/MPA-0 and MACE-OFF23 keys. OMAT, MATPES, MH, MDP,
arbitrary URLs, local weight paths, and other unregistered weights are
outside this scope.
Unknown keys are rejected before the MACE backend imports. A license acknowledgement does not make an unregistered model supported or scientifically appropriate.
The registry is available without importing Torch or MACE:
from vibeqc.mlip import mace_model_registry, save_mace_model_registry
registry = mace_model_registry()
save_mace_model_registry("mace-models.toml")
The exported rows contain the exact model key, loader and loader argument, license, domain, element coverage, training data, theory, citation key, and DOI.
The ASL license gate¶
MACE’s code is MIT, but the foundation-model weights are licensed separately. The materials line (MP-0 / MPA-0) is MIT, free for commercial and academic use. The organic MACE-OFF23 model is under the Academic Software License (ASL), academic, non-commercial use only.
Selecting an ASL model raises PermissionError unless you acknowledge
the academic license, MLIPOptions(accept_academic_license=True) or the
environment variable VIBEQC_ACCEPT_ASL=1. MIT models are never gated.
This prevents a commercial workflow from silently pulling academic-only
weights. Full licensing detail: license.md.
Energy-scale caveat¶
A method="mace" energy is on a model-specific reference scale (each
model subtracts its own per-element atomic energies), not a vibe-qc
total electronic energy, and not comparable across models. Two MACE
families can assign very different absolute values to the same H₂O
geometry while both provide internally consistent forces.
Use MACE energies for relative energetics (geometry optimization,
reaction energies at fixed composition + model, MD), not as absolute
totals, and never mix them with vibe-qc SCF or semiempirical totals.
For method comparisons, normalize each fixed-composition curve to its
own reference point, then compare curve shapes or externally referenced
observables. The .out prints a provenance block naming the model, its
license, and this caveat.
Supported public APIs¶
Task |
Public API |
Result and units |
|---|---|---|
Molecular single point |
|
|
Molecular optimization |
|
optimized structure and ASE trajectory |
Molecular or periodic reaction path |
|
fixed-model relative path energies and forces; preserves 1D/2D/3D periodic axes and skew cells |
Bare ASE workflow |
|
upstream ASE calculator in eV and Angstrom units |
Periodic single point |
|
1D/2D/3D |
Sequential periodic scan |
|
same result, with one retained model and calculator |
Fixed-cell periodic/slab relaxation |
|
result containing the relaxed |
3D periodic cell relaxation |
|
converged 3D |
Registry export |
|
dependency-free provenance metadata |
MACEModel is the lower-level molecular wrapper behind these APIs.
Most user workflows should prefer run_job so output manifests,
citations, and provenance are written automatically.
MACEModel and PeriodicMACEEvaluator copy the supplied MLIPOptions when
constructed. Later edits to those options do not change the loaded model or
its reported device and precision. MACEModel.options returns a detached copy;
construct a new model to use different runtime settings.
Molecular run_job(..., method="mace", optimize=True) retains the optimizer’s
loaded model for the final energy and gradient. The reported result and its
checkpoint digest therefore describe the same potential as the trajectory,
even if the cached checkpoint or caller’s options change during optimization.
MACE reaction-path QVF archives mark SCF as inapplicable and omit SCF
convergence and iteration counts. Path convergence is the separate NEB force
criterion exposed by NEBResult.converged.
The results of run_neb, run_dimer, and run_irc with method="mace"
retain model_info, device, dtype, and weight_identity from the loaded
potential. NEBResult.write_qvf includes these in provenance.mlip, including
the checkpoint digest and model license. Changing the caller’s options after
loading does not relabel a path. Reaction-path archives do not currently
provide a replayable NEB job specification.
run_periodic_job(method="mace") is not supported. It is an SCF runner;
use the direct periodic MACE APIs above.
Variable-cell relaxation checks ASE’s combined atomic and cell-force criterion.
Zero atomic forces alone do not qualify a strained cell. If the step budget
is exhausted, optimize_periodic_mace_cell raises
PeriodicMACECellOptimizationError (a RuntimeError), preserving the last
PeriodicSystem in error.system, the completed and allowed step counts in
error.n_steps and error.max_steps, and the terminal cell-filter force norm
and requested threshold in error.final_max_force and error.target_max_force.
Those last two values use ASE’s filter scaling, not raw physical stress units.
An already converged starting structure may return with max_steps=0.
Both the relaxed structure and error.system retain the input charge and
spin multiplicity for subsequent electronic-structure calculations. These
labels do not change the neutral MACE potential or suppress its charge/spin
warning.
Optimizer convergence does not establish dynamical stability or predictive
accuracy of the selected model.
macOS note¶
On macOS, vibe-qc’s native core and PyTorch each link an OpenMP runtime;
to avoid an abort (OMP Error #15) vibe-qc auto-sets
KMP_DUPLICATE_LIB_OK=TRUE for the MACE run, with a one-time warning. It
also caps the MACE process to one OpenMP/BLAS thread by default, because
duplicate OpenMP runtimes can still segfault when both sides create worker
pools. The MACE forward pass is verified to produce identical energies
with the duplicate-runtime workaround set. To opt into a different MACE
thread count, set VIBEQC_MACE_OPENMP_THREADS=N before importing vibe-qc.
Citations¶
Every method="mace" run auto-emits the MACE method paper (Batatia et
al. 2022) and the foundation-model paper for the model used (MACE-MP →
Batatia et al. 2024; MACE-OFF23 → Kovács et al. 2023) to the .bibtex /
.references siblings. Cite them in published work. PyTorch / e3nn
are infrastructure (their versions appear in the banner + .system
manifest), not cited.
Visualization¶
A method="mace" run writes the same structural output as any vibe-qc job,
so the geometry, and, for optimize=True, the relaxation trajectory,
visualize out of the box:
MolTUI (terminal viewer; the
[viewer]extra) renders the.xyzgeometry:moltui output-h2o-mace.xyz.vibe-view (GPU 3D viewer, installed from its separate repository) opens the
.qvfarchive written withoutput_qvf=True, which carries the structure, the optimization-trajectory animation, and the citations:vibe-view open output.qvf.
There is no orbital / density / band visualization. MACE produces no
wavefunction or AO density (it is a learned potential, not an SCF), so the
default capability-aware output plan contains neither .molden nor
.population.{txt,json} for method="mace". Explicitly requesting either
with write_molden_file=True or write_population_file=True raises before
model loading; None (the default) records them as inapplicable by omitting
the corresponding guaranteed plan rows.
Implementation, runtime, dispatch, and evidence¶
Keep these five statements separate:
Implemented in VibeQC. The model registry, license gate, molecular wrapper, periodic direct driver, reusable periodic evaluator, stress, cell relaxation, and citation plumbing exist in the source tree.
Runtime available. Real calculations additionally require Python 3.13 or earlier plus the
[mace]extra and accessible model weights. A normal Python 3.14 VibeQC runtime does not satisfy this condition.Molecular dispatch supported.
run_job(..., method="mace")handles molecular single points and optimization;run_neb(method="mace")handles molecular reaction paths.Direct periodic support.
run_periodic_mace,PeriodicMACEEvaluator,optimize_periodic_mace_positions, andoptimize_periodic_mace_cellare public. Periodic MACE is not routed throughrun_periodic_job.Scientifically validated landed evidence. Import checks, wrapper parity with the upstream calculator, finite energies, symmetric forces, stress parity, and smoke relaxations establish execution and unit conversion. They do not establish reference-EOS accuracy or general model accuracy. Those claims need external comparisons.
Limitations¶
Molecular single-point energies + forces and geometry optimization (
optimize=True) work today.Periodic energy and forces support 1D, genuine 2D slabs, and 3D through direct drivers. Fixed-cell position optimization supports frozen atom indices, including
SlabInfo.bottom_layer_indices(n). Stress and variable-cell relaxation are intentionally 3D-only: a true 2D slab’s third lattice vector is non-physical bookkeeping, so reporting a volume-normalized stress or relaxing that vector would be misleading.from vibeqc.mlip.mace import ( PeriodicMACEEvaluator, optimize_periodic_mace_cell, optimize_periodic_mace_positions, run_periodic_mace, ) res = run_periodic_mace(system) # .energy (Ha), .gradient() (Ha/bohr), # .stress() (Ha/bohr³, 3×3) relaxed = optimize_periodic_mace_cell(system, fmax=0.05) # variable-cell slab_opt = optimize_periodic_mace_positions( slab, fmax=0.05, fixed_indices=slab_info.bottom_layer_indices(2), ) relaxed_slab = slab_opt.system # A fixed-model scan loads the model once and reuses its calculator. evaluator = PeriodicMACEEvaluator() scan_results = [evaluator.run(point) for point in strained_systems]
(
method="mace"is not yet wired intorun_periodic_job; use these drivers directly.) APeriodicMACEEvaluatoris sequential; create one per worker when scan points run in parallel.No electronic structure (orbitals / charges / gap).
Trained-domain only, fails out-of-distribution.
Charge and spin do not select an electronic state. Non-neutral and open-shell inputs warn because the learned neutral potential ignores those quantum numbers.
A zero return, finite energy, or low force at one symmetric geometry is not an EOS or accuracy validation.
Startup, wall time, peak RSS, device, dtype, and model-reload behavior are diagnostics. Record discrepancies rather than turning them into scientific claims.
Examples¶
Runnable scripts (require the [mace] extra, Python ≤ 3.13) live in
examples/mlip/:
00_runtime_healthcheck.py, dependency, source, registry, API, and cache preflight without loading model weights.01_water_mace.py, molecular single-point + geometry optimization on H₂O.02_periodic_mace_silicon.py, periodic energy/forces/stress + variable-cell relaxation on bulk Si, with a reusable two-point strain probe by default.03_neb_mace.py, NH₃ umbrella-inversion reaction path viarun_neb(method="mace")(climbing-image NEB on the MACE potential).04_surface_adsorption.py, H₂O + NH₃ adsorption energies on MgO, CaO, Al₂O₃, TiO₂, Pt, and Cu slabs with MACE-MPA-0 as an exploratory protocol, not reference adsorption data.05_mace_pm6_relative_curve.py, independently normalized MACE and PM6 H₂O stretch curves for a safe cross-family comparison.06_optimize_water_off23_for_dlpno.pyand07_dlpno_ccsdt_on_mace_geometry.py, a two-runtime molecular geometry handoff from explicitly acknowledged MACE-OFF23 to DLPNO-CCSD(T).08_relax_h2o_hbn_then_periodic_dft.py, a genuine 2D H2O/h-BN fixed-cell relaxation with a frozen sheet, followed optionally by a periodic PBE single point on the relaxed structure.
MACE also drives reaction-path searches: run_neb(..., method="mace") runs a Nudged Elastic Band on the MACE potential,
analytic forces, no SCF, and (for periodic bands) no finite-difference
gradient. Each image must return a finite scalar energy and a finite force
vector for every atom. Invalid model output stops the calculation before it
can enter the band or its optimizer state. See neb.md § MACE backend.
run_dimer(..., method="mace") uses the same checked energy and force
evaluations for a saddle search from one starting structure. For periodic
systems, every evaluation retains the input’s 1D, 2D or 3D periodic axes
and cell, including skew cells.
Force tolerances (conv_tol_force, rotation_force_tol), dimer_separation,
max_step, and initial_step must be finite and positive. Invalid values
are rejected before loading a model or evaluating forces; an infinite force
threshold cannot certify a nonstationary structure as a converged saddle.
The positive integer max_iter limits evaluated dimer centres. When that
budget is exhausted, the result keeps the last evaluated geometry, its
energy and force residual, and converged=False; it does not return an
unevaluated final displacement.
run_irc(..., method="mace") follows molecular paths from an explicit
transition_mode, for example a dimer mode. step_size and conv_tol_grad
must be finite and positive; max_points must be a nonnegative integer.
Invalid controls are rejected before loading a model. Each branch evaluates
the initial displacement and allows up to max_points further step attempts,
including rejected trials. The convergence flag reflects the maximum absolute
Cartesian gradient at the last accepted point, including a final accepted
step. Repeated rejected steps cannot certify convergence. A stalled or
exhausted branch retains its accepted path and energies, with its convergence
flag false unless the endpoint satisfies conv_tol_grad in Ha/bohr. Check
that flag before treating forward_minimum or reverse_minimum as a minimum
or interpreting the corresponding barrier as a converged result.
See also: ase_integration.md,
external_codes.md, and the
roadmap § MACE MLIP interface.
Scope relative to upstream MACE¶
vibe-qc is not feature-par with the whole upstream MACE project, and is not intended to be its training frontend. It exposes a license-reviewed, reproducible inference subset:
Capability |
Upstream MACE |
vibe-qc wrapper |
|---|---|---|
Registered foundation-model inference |
yes |
yes: MP/MPA-0 and OFF23 only |
Molecular energy, forces, optimization |
yes through ASE |
yes |
Periodic bulk energy, forces, stress |
yes |
yes; stress is 3D-only |
True slab energy, forces, fixed-cell optimization |
yes through ASE PBC/constraints |
yes; exact 2D PBC and frozen indices |
Training, fine-tuning, custom checkpoints |
yes |
no |
MD, descriptors, Hessians, per-atom outputs, committees |
yes |
use the bare upstream calculator where scientifically appropriate; no first-class vibe-qc result contract |
Charge-aware/polar/dipole models and newer foundation families |
available upstream |
outside the registered scope |
This distinction matters for surface work. The MACE-MP foundation-model
paper includes interfaces and catalysis examples, but also reports systems
with material deviations from the reference DFT and cases where fine-tuning
was needed. A relaxed foundation-model structure is therefore a candidate
geometry to validate with an electronic method, not proof of reference-level
surface accuracy. See Batatia et al.,
MACE method and
MACE-MP foundation model (J. Chem.
Phys. 163, 184110 (2025)), and Kovács et al.,
MACE-OFF (J. Am. Chem. Soc.
147, 17598 (2025)); the emitted .bibtex cites these versions of
record, not the earlier arXiv preprints.