orb-models

repository·main·Indexed 20 days ago

https://github.com/orbital-materials/orb-models

Foundation models for computational chemistry designed for atomic simulations. The library provides pretrained models to predict energy, forces, and stress, featuring integration with the Atomic Simulation Environment (ASE) via ORBCalculator and high-performance batched simulations through TorchSim. It supports D3 dispersion correction, per-atom confidence scores for Orb-v3 models, and the ability to finetune models using custom ASE sqlite databases.

Tokens
5.9K
Snippets
15
Records
28
Agent score
70%

What's inside orb-models

  1. Understand Orb-v3 model naming conventions

    main

    Orb-v3 models follow the naming pattern orb-v3-X-Y-Z. Choose your configuration based on the following components:

    X: Model Type

    • direct: Computes forces and stress directly. Faster and uses less memory.
    • conservative: Computes forces and stress via backpropagation. Physically motivated for simulations like NVE Molecular Dynamics, but significantly slower and more memory-intensive.

    Y: Maximum Neighbors per Atom

    • 20: Finite cutoff. Reduces latency and memory usage but induces discontinuities in the Potential Energy Surface (PES), which can impact sensitive calculations like Hessians.
    • inf: Unlimited neighbors. Ensures a continuous PES.

    Z: Training Dataset

    • omat: Trained on the OMat24 dataset (bulk crystals). Generally generalizes well to organic molecules or slabs.
    • mpa: Trained on the MPA dataset. Generally less performant; only use if required for specific benchmarks like Matbench Discovery.
  2. Prepare data in ASE SQLite database format for finetuning

    main

    The finetune.py script requires training data to be stored in an ASE SQLite database format. Each entry in the database must be an ASE Atoms object with specific properties attached via a SinglePointCalculator.

    Required Properties

    • Positions: Atomic positions (stored in the Atoms object).
    • Atomic numbers: Element types (stored in the Atoms object).
    • Cell: Unit cell vectors (for periodic systems).
    • Energy: Total energy in eV.
    • Forces: Forces on each atom in eV/Å, shape (n_atoms, 3).
    • Stress (optional): Stress tensor in Voigt notation (6 components), in eV/ų.

    Stress Tensor Format

    If providing stress, use Voigt notation [σ_xx, σ_yy, σ_zz, σ_yz, σ_xz, σ_xy]. To convert a 3x3 tensor:

    stress_voigt = [
        stress_3x3[0, 0],  # σ_xx
        stress_3x3[1, 1],  # σ_yy
        stress_3x3[2, 2],  # σ_zz
        stress_3x3[1, 2],  # σ_yz
        stress_3x3[0, 2],  # σ_xz
        stress_3x3[0, 1],  # σ_xy
    ]
    import ase
    import ase.db
    from ase import Atoms
    from ase.calculators.singlepoint import SinglePointCalculator
    
    # Create a database file
    db = ase.db.connect('my_training_data.db')
    
    for structure in my_structures:
        atoms = Atoms(
            symbols=structure['symbols'],
            positions=structure['positions'],
            cell=structure['cell'],
            pbc=True
        )
        
        calc = SinglePointCalculator(
            atoms=atoms,
            energy=structure['energy'],
            forces=structure['forces'],
            stress=structure['stress']
        )
        atoms.calc = calc
        db.write(atoms)
  3. Configure and run Orb-v3 models

    main

    Orb-v3 models are compiled by default using PyTorch 2.6.0+ and support dynamic batching.

    Performance Note: The first call to the model will be slower because the graph is being compiled by torch. Subsequent calls will be faster.

    Recommended Setup for Testing: For the highest accuracy during initial testing, use the conservative model with inf neighbors and specify float32-highest precision:

    • Model: orb-v3-conservative-inf-omat (or 20 if memory is a constraint)
    • Precision: precision='float32-highest'
  4. Apply D3 dispersion correction

    main

    To improve modeling of van der Waals interactions, wrap your existing model with D3SumModel using an AlchemiDFTD3 module. This can be used with both the standard ORBCalculator and OrbTorchSimModel.

    from orb_models.forcefield.inference.calculator import ORBCalculator
    from orb_models.forcefield.inference.d3_model import D3SumModel, AlchemiDFTD3
    
    # Wrap the model
    orbff_d3 = D3SumModel(orbff, AlchemiDFTD3(functional="PBE", damping="BJ", compile=True))
    
    # Use with ASE Calculator
    calc = ORBCalculator(orbff_d3, atoms_adapter=atoms_adapter, device=device)
    atoms.calc = calc
  5. Specify charge and spin for OrbMol models

    main

    OrbMol models (like orbmol_v2) require the total charge and spin multiplicity to be explicitly provided. You must set these in the atoms.info dictionary of your ASE Atoms object before graph construction.

    import ase
    from ase.build import molecule
    from orb_models.forcefield import pretrained
    
    device = "cpu"
    orbff, atoms_adapter = pretrained.orbmol_v2(
      device=device,
      precision="float32-high",
    )
    atoms = molecule("C6H6")
    
    # Required for OrbMol
    atoms.info["charge"] = 0  # total charge
    atoms.info["spin"] = 1    # spin multiplicity
    
    graph = atoms_adapter.from_ase_atoms(atoms, device=device)
    result = orbff.predict(graph, split=False)
  6. Finetune a model with a custom dataset

    main

    You can finetune pretrained models using a custom ASE sqlite database.

    Requirements:

    • Dataset must be an ASE sqlite database containing energy, forces, and stress data.
    • Use the finetune.py script.

    Basic Command:

    python finetune.py --dataset=<dataset_name> --data_path=<your_data_path> --base_model=<base_model>

    Note: <base_model> must be a key from orb_models.forcefield.pretrained.ORB_PRETRAINED_MODELS.

    Loading a finetuned checkpoint:

    from orb_models.forcefield import pretrained
    
    model, atoms_adapter = getattr(pretrained, <base_model>)( 
      weights_path=<path_to_ckpt>, 
      device="cpu",
      precision="float32-high"
    )
  7. Load finetuned models and their reference energies

    main

    When you save a checkpoint after finetuning, the reference energies (whether custom or trained) are saved in the state dict. To use the model for inference, load the architecture first, then load the state dict.

    Example: Loading a checkpoint

    import torch
    from orb_models.forcefield import pretrained
    
    # Load model architecture (set train=False for inference)
    model, atoms_adapter = pretrained.orbmol_v2(train=False)
    
    # Load your finetuned checkpoint
    model.load_state_dict(torch.load('path/to/finetuned_checkpoint.pt'))
    
    # The custom/trained reference energies are now loaded!
  8. Perform batched simulations with TorchSim

    main

    For high-performance batched optimization and MD simulations, use the OrbTorchSimModel with TorchSim. This requires the torch-sim-atomistic package.

    Workflow:

    1. Convert a list of ASE atoms to a TorchSim state using ts.io.atoms_to_state().
    2. Initialize OrbTorchSimModel(orbff, atoms_adapter).
    3. Use ts.optimize() for geometry relaxation or run the model directly on the state for MD.
    import ase
    import torch
    import torch_sim as ts
    from ase.build import bulk
    from orb_models.forcefield import pretrained
    from orb_models.forcefield.inference.orb_torchsim import OrbTorchSimModel
    
    device = "cpu"
    orbff, atoms_adapter = pretrained.orb_v3_conservative_inf_omat(
      device=device,
      precision="float32-high",
    )
    
    atoms1 = bulk('Cu', 'fcc', a=3.58, cubic=True)
    atoms2 = bulk('Si', 'diamond', a=5.43, cubic=True)
    atoms_list = [atoms1, atoms2]
    
    # Convert to TorchSim state
    ts_state = ts.io.atoms_to_state(atoms_list, device, dtype=torch.get_default_dtype())
    
    ts_model = OrbTorchSimModel(orbff, atoms_adapter)
    
    # Optimize
    relaxed_state = ts.optimize(
        system=ts_state,
        convergence_fn=ts.generate_force_convergence_fn(force_tol=0.01, include_cell_forces=False),
        model=ts_model,
        optimizer=ts.Optimizer["fire"],
        max_steps=100,
        steps_between_swaps=10,
    )
    results = ts_model(relaxed_state)
    print(results["energy"])
  9. Use orb-models for direct atomic simulation

    main

    You can use orb-models directly by loading a pretrained model and an atoms adapter. This workflow involves converting ASE atoms to a graph, predicting properties (energy, forces, stress), and optionally converting the results back to ASE atoms.

    Key steps:

    1. Load model and adapter via pretrained.<model_name>().
    2. Convert ASE atoms to a graph using atoms_adapter.from_ase_atoms().
    3. Predict using orbff.predict(graph).
    4. Convert back to ASE using graph.to_ase_atoms().
    import ase
    from ase.build import bulk
    from orb_models.forcefield import pretrained
    
    device = "cpu"  # or device="cuda"
    orbff, atoms_adapter = pretrained.orb_v3_conservative_inf_omat(
      device=device,
      precision="float32-high",   # or "float32-highest" / "float64"
    )
    atoms = bulk('Cu', 'fcc', a=3.58, cubic=True)
    graph = atoms_adapter.from_ase_atoms(atoms, device=device)
    
    result = orbff.predict(graph, split=False)
    
    # Convert to ASE atoms
    atoms = graph.to_ase_atoms(
        energy=result["energy"],
        forces=result["forces"],
        stress=result["stress"]
    )