Skip to content

Commit 6ca5ab7

Browse files
authored
Merge branch 'main' into batching-enhancements
2 parents 12bf806 + fcdeca1 commit 6ca5ab7

49 files changed

Lines changed: 1834 additions & 356 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/integration-test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
strategy:
1313
max-parallel: 10
1414
matrix:
15-
python_version: ['3.10', '3.12']
15+
python_version: ['3.11', '3.14']
1616

1717
steps:
1818
- uses: actions/checkout@v7

.github/workflows/stale.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
issues: write
1111
pull-requests: write
1212
steps:
13-
- uses: actions/stale@v10.4.0
13+
- uses: actions/stale@v11.0.0
1414
with:
1515
days-before-stale: 30
1616
days-before-close: 14

.github/workflows/sync-fork.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
name: sync fork
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
workflow_dispatch:
8+
9+
permissions:
10+
contents: read
11+
12+
concurrency:
13+
group: sync-fork-main
14+
cancel-in-progress: true
15+
16+
jobs:
17+
push-to-private:
18+
if: github.repository == facebookresearch/fairchem
19+
runs-on: ubuntu-latest
20+
environment: sync-private
21+
steps:
22+
- name: Checkout public repository
23+
uses: actions/checkout@v7
24+
with:
25+
fetch-depth: 0
26+
token: ${{ secrets.SYNC_PAT}}
27+
28+
- name: Push to private repository
29+
run: |
30+
git push \
31+
https://github.com/fairinternal/fairchem.git \
32+
HEAD:refs/heads/main \
33+
--force

.github/workflows/test.yml

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
# Without it, GitHub auto-expands EVERY field of the object-typed
3333
# `shard` matrix entry — including `shard.paths` — into a
3434
# >100-character truncated string like
35-
# `test (3.13, core, tests/core/models tests/core/graph ...`.
35+
# `test (3.14, core, tests/core/models tests/core/graph ...`.
3636
# That diverges from the short custom status emitted by
3737
# multi-trigger-setup, forcing branch protection to pick one event
3838
# type's names and break the others.
@@ -54,7 +54,7 @@ jobs:
5454
max-parallel: 10
5555
fail-fast: false
5656
matrix:
57-
python_version: ['3.11', '3.13']
57+
python_version: ['3.11', '3.14']
5858
# tests/perf is run by perf-test.yml on a separate cadence.
5959
# tests/applications and tests/lammps are run by integration-test.yml
6060
# and test_lammps_gpu respectively. Both shards below intentionally
@@ -112,7 +112,7 @@ jobs:
112112
-r tests/requirements.txt # pin test packages
113113
114114
- name: Install torchsim (Python 3.12+)
115-
if: ${{ matrix.python_version == '3.12' || matrix.python_version == '3.13' }}
115+
if: ${{ matrix.python_version == '3.12' || matrix.python_version == '3.13' || matrix.python_version == '3.14' }}
116116
run: |
117117
pip install packages/fairchem-core[torchsim]
118118
@@ -145,7 +145,7 @@ jobs:
145145
run: |
146146
pytest -m "serial and not gpu" ${{ matrix.shard.paths }} -vv --ignore=tests/demo/ocpapi/tests/integration/ --exclude-models=uma-s-1p1,uma-s-1p2 --cov-report=xml --cov=fairchem --cov-append --junitxml=junit-serial-${{ matrix.shard.name }}.xml -o junit_family=legacy -c ./packages/fairchem-core/pyproject.toml --suppress-no-test-exit-code
147147
148-
- if: ${{ matrix.python_version == '3.13' }}
148+
- if: ${{ matrix.python_version == '3.14' }}
149149
name: codecov-coverage
150150
uses: codecov/codecov-action@v7
151151
with:
@@ -154,7 +154,7 @@ jobs:
154154
token: ${{ secrets.CODECOV_TOKEN }}
155155
verbose: true
156156

157-
- if: ${{ matrix.python_version == '3.13' }}
157+
- if: ${{ matrix.python_version == '3.14' }}
158158
name: codecov-test-results
159159
uses: codecov/test-results-action@v1
160160
with:
@@ -180,7 +180,7 @@ jobs:
180180
strategy:
181181
fail-fast: false
182182
matrix:
183-
python_version: ['3.13']
183+
python_version: ['3.14']
184184
sweep_model: [uma-s-1p1, uma-s-1p2]
185185
shard: *cpu_shards
186186

@@ -225,7 +225,7 @@ jobs:
225225
-r tests/requirements.txt # pin test packages
226226
227227
- name: Install torchsim (Python 3.12+)
228-
if: ${{ matrix.python_version == '3.12' || matrix.python_version == '3.13' }}
228+
if: ${{ matrix.python_version == '3.12' || matrix.python_version == '3.13' || matrix.python_version == '3.14' }}
229229
run: |
230230
pip install packages/fairchem-core[torchsim]
231231
@@ -285,7 +285,7 @@ jobs:
285285
strategy:
286286
fail-fast: false
287287
matrix:
288-
python_version: ['3.13']
288+
python_version: ['3.14']
289289
# YAML anchor: shard list is reused by test_gpu_sweep below.
290290
# Do not reorder jobs (the alias must follow the anchor textually).
291291
shard: &gpu_shards
@@ -327,7 +327,7 @@ jobs:
327327
-r tests/requirements.txt # pin test packages
328328
329329
- name: Install torchsim (Python 3.12+)
330-
if: ${{ matrix.python_version == '3.12' || matrix.python_version == '3.13' }}
330+
if: ${{ matrix.python_version == '3.12' || matrix.python_version == '3.13' || matrix.python_version == '3.14' }}
331331
run: |
332332
pip install packages/fairchem-core[torchsim]
333333
@@ -375,7 +375,7 @@ jobs:
375375
strategy:
376376
fail-fast: false
377377
matrix:
378-
python_version: ['3.13']
378+
python_version: ['3.14']
379379
sweep_model: [uma-s-1p1, uma-s-1p2]
380380
shard: *gpu_shards
381381

@@ -408,7 +408,7 @@ jobs:
408408
-r tests/requirements.txt # pin test packages
409409
410410
- name: Install torchsim (Python 3.12+)
411-
if: ${{ matrix.python_version == '3.12' || matrix.python_version == '3.13' }}
411+
if: ${{ matrix.python_version == '3.12' || matrix.python_version == '3.13' || matrix.python_version == '3.14' }}
412412
run: |
413413
pip install packages/fairchem-core[torchsim]
414414
@@ -450,15 +450,15 @@ jobs:
450450
strategy:
451451
max-parallel: 1
452452
matrix:
453-
python_version: ['3.13']
453+
python_version: ['3.14']
454454

455455
steps:
456456
- uses: actions/checkout@v7
457457
- uses: mamba-org/setup-micromamba@v3
458458
with:
459459
generate-run-shell: true # This is the default behavior
460460
environment-name: test_env # Specifies a new environment to be created
461-
create-args: python=3.13 # Specifies packages to install into the new environment
461+
create-args: python=3.14 # Specifies packages to install into the new environment
462462

463463
- name: Checkout code
464464
uses: actions/checkout@v7

CLAUDE.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,32 @@ configs/ # Hydra YAML configs (datasets, tasks, backbone, optimi
242242
- `lmdb` - Dataset storage format
243243
- `ray[serve]>=2.53.0` - Distributed computing
244244
245+
## Testing Gotchas
246+
247+
- Tests that download registered checkpoints must declare their models with a
248+
`pretrained` marker. This lets base CI deselect them with `--exclude-models`
249+
and routes them to the matching model-sweep job.
250+
- Freeze inference parameters after inference-specific module replacement.
251+
Main's folded-batch linear path removes the former general-backend regression:
252+
on one H100, freezing improved compiled general inference by 15-17% and cut
253+
peak allocated memory by 27-29% at 100-2,000 atoms. PyTorch 2.13 CPU checks
254+
improved by 4% at 32 atoms and were neutral at 1,000 atoms. Custom backward
255+
paths must preserve input derivatives independently of parameter gradients.
256+
- `umas_fast_gpu` custom backward operators do not implement `vmap` batching.
257+
Compute Hessians through the per-component loop (`hessian_vmap=False`) when
258+
exercising that backend, and ensure inference settings forward that option
259+
into the backbone configuration.
260+
- Set `CI=true` when reproducing CPU CI shards locally. Some multi-GPU graph
261+
parallel tests rely on that environment variable for skipping instead of the
262+
`gpu` marker, so the CI marker expression alone will still collect them.
263+
- `graph_parallel_group_size=None` disables graph-parallel setup. A value of
264+
`1` intentionally initializes singleton graph- and data-parallel groups and
265+
is used to exercise those paths in tests; do not treat it as disabled.
266+
- Keep the full `AtomicData.clone()` boundary in prediction unless benchmarks
267+
justify changing it and every model-side mutation has been audited. Graph
268+
parallelism, MOLE preparation, and conservative gradients can replace or
269+
mutate input fields, so a selective shallow copy is brittle.
270+
245271
## Numerical Precision
246272
247273
- Model constructors must not mutate process-wide PyTorch precision settings

docs/core/common_tasks/ase_calculator.md

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,21 @@ os.environ['HF_TOKEN'] = 'MY_TOKEN'
6060

6161
## Default mode
6262

63-
UMA is designed for both general-purpose usage (single or batched systems) and single-system long rollout (MD simulations, relaxations, etc.). For general-purpose use, we suggest using the [default settings](https://github.com/facebookresearch/fairchem/blob/main/src/fairchem/core/units/mlip_unit/api/inference.py#L92). This is a good trade-off between accuracy, speed, and memory consumption and should suffice for most applications. In this setting, on a single 80GB H100 GPU, we expect a user should be able to compute on systems as large as 50k-100k neighbors (depending on their atomic density). Batching is also supported in this mode.
63+
UMA defaults to the `merge_mole + compile` fast mode with TF32 disabled. This fast path requires fixed composition, task, charge, and spin across repeated evaluations. If a later evaluation changes any of these, the calculator prints a warning and permanently falls back to the unmerged, uncompiled model. Batching is supported; a mixed batch across any of the same parameters triggers the same fallback.
64+
65+
## Batch mode
66+
67+
Use batch mode for heterogeneous batches whose systems differ in composition, task, charge, or spin. It currently keeps MOLE unmerged and leaves compilation disabled. The named mode provides a stable entry point for future batch-specific optimizations, such as compilation without MOLE merging.
68+
69+
```{code-cell} python3
70+
predictor = pretrained_mlip.get_predict_unit(
71+
"uma-s-1p2", device="cuda", inference_settings="batch"
72+
)
73+
```
6474

6575
## Turbo mode
6676

67-
For long rollout trajectory use-cases, such as molecular dynamics (MD) or relaxations, we provide a special mode called **turbo**, which optimizes for speed but restricts the user to using a single system where the atomic composition is held constant. Turbo mode is approximately 1.5-2x faster than default mode, depending on the situation. However, batching is not supported in this mode. It can be easily activated as shown below.
77+
Turbo mode uses the same `merge_mole + compile` fast path as default mode and additionally enables TF32. TF32 can improve performance on compatible hardware at a small precision trade-off. Similar to default mode, any changes in composition, task, charge, and spin across different evaluations trigger a fallback to the unoptimized execution path.
6878

6979
```{code-cell} python3
7080
predictor = pretrained_mlip.get_predict_unit(
@@ -74,7 +84,7 @@ predictor = pretrained_mlip.get_predict_unit(
7484

7585
## Custom modes for advanced users
7686

77-
The advanced user might quickly see that **default** mode and **turbo** mode are special cases of our [inference settings api](https://github.com/facebookresearch/fairchem/blob/main/src/fairchem/core/units/mlip_unit/api/inference.py#L47). You can customize it for your application if you understand what you are doing. The following table provides more information.
87+
The advanced user might quickly see that **default**, **batch**, and **turbo** modes are special cases of our [inference settings api](https://github.com/facebookresearch/fairchem/blob/main/src/fairchem/core/units/mlip_unit/api/inference.py#L47). You can customize it for your application if you understand what you are doing. The following table provides more information.
7888

7989
| Setting Flag | Description |
8090
| ----- | ----- |

docs/core/common_tasks/workflows.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Below is an example that uses the default `elastic_tensor_flow` flow:
2525
from __future__ import annotations
2626
2727
from ase.build import bulk
28-
from quacc.recipes.mlp.elastic import elastic_tensor_flow
28+
from quacc.recipes.mlip.elastic import elastic_tensor_flow
2929
3030
# Make an Atoms object of a bulk Cu structure
3131
atoms = bulk("Cu")
@@ -35,7 +35,7 @@ result = elastic_tensor_flow(
3535
atoms,
3636
job_params={
3737
"all": dict(
38-
method="fairchem",
38+
library="fairchem",
3939
name_or_path="uma-s-1p2",
4040
task_name="omat",
4141
),

packages/fairchem-core/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ name = "fairchem-core"
77
description = "Machine learning models for chemistry and materials science by the FAIR Chemistry team"
88
license = {text = "MIT License"}
99
dynamic = ["version", "readme"]
10-
requires-python = ">=3.11, <3.14"
10+
requires-python = ">=3.11, <3.15"
1111
dependencies = [
1212
"torch~=2.13.0",
1313
"ray[serve]>=2.53.0",

packages/fairchem-lammps/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ name = "fairchem-lammps"
77
description = "Fairchem extension package to use LAMMPs with fairchem models"
88
license = {text = "GnuV2 License"}
99
dynamic = ["version", "readme"]
10-
requires-python = ">=3.10,<3.14"
10+
requires-python = ">=3.10,<3.15"
1111
dependencies = [
1212
"fairchem.core>=2.4.0",
1313
]

src/fairchem/core/calculate/ase_calculator.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,11 @@ def from_model_checkpoint(
134134
name_or_path: A model name from fairchem.core.pretrained.available_models or a path to the checkpoint
135135
file
136136
task_name: Task name
137-
inference_settings: Settings for inference. Can be "default" (general purpose) or "turbo"
138-
(optimized for speed but requires fixed atomic composition). Advanced use cases can
139-
use a custom InferenceSettings object.
137+
inference_settings: Settings for inference. Both "default" and "turbo" use the
138+
merge_mole + compile fast path, with automatic fallback if its fixed-input
139+
contract is broken. "turbo" additionally enables TF32. "batch" keeps MOLE
140+
unmerged for heterogeneous inputs. More advanced use cases can use a custom
141+
InferenceSettings object.
140142
overrides: Optional dictionary of settings to override default inference settings.
141143
device: Optional torch device to load the model onto.
142144
seed: Random seed for reproducibility.

0 commit comments

Comments
 (0)