AllScAIP and UMA integration#496
Open
allaffa wants to merge 16 commits into
ORNL:mainORNL/HydraGNN:mainfrom
allaffa:allscaip_uma_integrationallaffa/HydraGNN:allscaip_uma_integrationCopy head branch name to clipboard
Open
AllScAIP and UMA integration#496allaffa wants to merge 16 commits intoORNL:mainORNL/HydraGNN:mainfrom allaffa:allscaip_uma_integrationallaffa/HydraGNN:allscaip_uma_integrationCopy head branch name to clipboard
allaffa wants to merge 16 commits into
ORNL:mainORNL/HydraGNN:mainfrom
allaffa:allscaip_uma_integrationallaffa/HydraGNN:allscaip_uma_integrationCopy head branch name to clipboard
Conversation
- Vendor minimal AllScAIP code under hydragnn/utils/model/allscaip/
(plus shared EScAIP utilities under hydragnn/utils/model/escaip/utils/).
- Add hydragnn/models/AllScAIPStack.py wrapper:
* runs the full transformer backbone in _embedding(), exposes the
result as the invariant node feature for HydraGNN's standard
multi-head decoders;
* uses standard num_conv_layers as the AllScAIP depth and replaces
Base's per-layer loop with a single Identity no-op iteration;
* inherits HydraGNN's activation_function (no separate
allscaip_activation knob);
* documents that AllScAIP is NOT e3nn-equivariant (scalar
transformer; SH used as input features only).
- Wire allscaip_* hyperparameters as first-class Architecture keys via
create_model / create_model_config / update_config (matches PNA,
MACE, EGNN, ... patterns).
- setup.py: switch to find_namespace_packages so the vendored
subpackages are installed.
- CI: add 'AllScAIP' to the basic mpnn parametrization in
tests/test_graphs.py::pytest_train_model and
tests/test_graphs_graphattr.py::pytest_train_model_graphattr
(8 new cases pass). Excluded from equivariant / lengths /
vectoroutput / global-attention families since AllScAIP is
is_edge_model=False and not equivariant.
- Add UMAStack thin wrapper around fairchem.core eSCNMDBackbone, with lazy import + clear error if fairchem-core is missing. - Wire uma_* config keys through create_model and update_config (sphere_channels<-hidden_dim, lmax<-max_ell, etc.); uma_hidden_channels defaults to hidden_dim. Clamp uma_mmax<=max_ell to avoid zero-channel SO(2) convs. Robust cell/pbc handling for batched PyG graphs. - Add fairchem-core to requirements-optional.txt. - Add UMA to CI parametrization in tests/test_graphs.py and tests/test_graphs_graphattr.py (basic + equivariant suites). - Add UMA to LennardJones training CI in tests/test_forces_equivariant_training.py and to the energy-only equivariance benchmark in tests/test_forces_equivariant.py. - Apply black==21.5b1 formatting.
Adds the standard 10-line BSD-3-clause header to every Python file that lacked one. The year reflects the file's last git-commit year (falls back to mtime). Vendored FairChem trees under examples/*/fairchem/core/** are intentionally skipped; they retain Meta's MIT header.
allaffa
force-pushed
the
allscaip_uma_integration
branch
from
July 20, 2026 19:36
e0b059e to
9e8169f
Compare
Vendor the transitive fairchem.core import closure required by the UMA (eSCNMDBackbone) backbone verbatim into hydragnn/utils/model/uma/_vendored/fairchem/core/** (78 .py files plus the Jd.pt / wigner_d_coefficients.pt coefficient tensors and pretrained model metadata). All 'fairchem.core' imports are rewritten to point at the vendored tree, and every package __init__.py is neutralized to avoid the upstream eager side-effect imports (registry / pretrained_mlip) that would otherwise pull in modules outside the closure. - tools/vendor_uma.py: reproducible vendoring tool that enumerates the import closure via AST (resolving relative imports), mirrors the sources, rewrites imports, and copies sibling resource files. - UMAStack.py: import eSCNMDBackbone from the vendored tree; remove the lazy fairchem-core import and install hint. - requirements-optional.txt: drop the fairchem-core dependency. - setup.py / MANIFEST.in: package the vendored .pt/.json resources. The vendored tree is fully self-contained: eSCNMDBackbone imports and constructs with the externally installed fairchem package blocked, and all 11 UMA CI tests pass.
Introduce a 'uma_variant' config key selecting the UMA capacity tier: - 'S' (default): single dense eSCNMDBackbone. - 'M' / 'L': Mixture-of-Linear-Experts (MoLE) routing via eSCNMDMoeBackbone, with progressively larger routed-expert counts (defaults M=8, L=32, overridable via 'uma_num_experts'). MoLE routing coefficients are derived from the per-system charge/spin (and optionally atomic-composition) embeddings, so no HydraGNN-side dataset labelling is required. New config keys: uma_variant, uma_num_experts, uma_moe_dropout, uma_use_composition_embedding, wired through create_model and defaulted in config_utils. Verified: all three variants run a forward pass; the default 'S' path still passes the UMA CI (tests/test_graphs.py -k UMA, 3 passed).
Full rewrite of the AllScAIP HydraGNN wrapper with a redesigned config surface and completed conditioning/force-training support: - Charge/spin conditioning: per-graph charge/spin read from data.charge / data.spin when present (defaulting to neutral / singlet), fed into the backbone's ChgSpinEmbedding. - Dataset conditioning: new DatasetEmbedding in the AllScAIP InputBlock, threaded through GraphAttentionData (custom_types) and populated in data_preprocess. Enabled when a non-empty dataset list is configured; routes per-graph dataset ids into the node embeddings. - Force training: autograd-based forces stay invariant; the soft-kNN radius graph keeps energy differentiable w.r.t. positions (verified gradient flow to data.pos). - Config surface redesign: allscaip_* keys wired through create_model and defaulted in config_utils. Verified: backbone forward with/without dataset routing and force-grad flow to positions; AllScAIP CI passes (tests/test_graphs.py -k AllScAIP, 2 passed).
- examples/LennardJones/LJ_UMA.json: runnable UMA (S variant) config for the LennardJones energy+forces example driver (--inputfile LJ_UMA.json). - examples/LennardJones/LJ_AllScAIP.json: runnable AllScAIP config for the same driver. - tests/test_example_configs_uma_allscaip.py: lightweight smoke tests that build a model from each shipped example config via update_config + create_model_config on a tiny in-memory dataset, plus coverage that the UMA config constructs for every S / M / L capacity tier. All 5 smoke tests pass.
- setup.py: reformat the package_data literal to satisfy black==21.5b1 (the version pinned in requirements-dev.txt and .pre-commit-config). - pyproject.toml: add [tool.black] force-exclude for the verbatim vendored UMA mirror (hydragnn/utils/model/uma/_vendored). force-exclude is honoured by both CI's 'black .' and the pre-commit hook (which passes explicit paths), keeping the upstream-faithful mirror out of reformatting. Verified: 'black --check .' reports all files unchanged.
The vendored FairChem UMA tree transitively imports fairchem-core's own third-party deps (omegaconf, hydra, torchtnt, monty, ray) which are not part of HydraGNN's core requirements. Importing eSCNMDBackbone at UMAStack module level made 'import hydragnn' -- and therefore all CI test collection -- fail with ModuleNotFoundError. - UMAStack: defer the vendored import to _load_uma_backbones(), invoked only when a UMA model is constructed; raise a clear ImportError pointing at requirements-optional when the deps are absent. - tests/uma_optional.py: uma_available() helper; UMA parametrizations now skip (not error) when the optional deps are missing. - requirements-optional.txt: document the UMA backbone deps. AllScAIP is unaffected (only needs torch/e3nn).
Investigation showed the vendored UMA backbone only reaches two lightweight deps at import/construct/forward time -- omegaconf and monty. The heavy fairchem-core deps (torchtnt/ray/wandb via mlip_unit; hydra via models/base) are used solely in checkpoint/inference code paths that HydraGNN never runs; they were merely dragged in by module-level imports. - Vendored escn_md.py / base.py: defer the OutputSpec/Task (mlip_unit) and hydra imports to their single use sites. tools/vendor_uma.py now applies these as reproducible post-vendor PATCHES so re-vendoring keeps them. - requirements-base.txt: add omegaconf + monty (UMA now works with core deps). - requirements-optional.txt: drop the UMA dep block. - UMAStack: keep the lazy backbone import (fast 'import hydragnn') with an updated error message pointing at requirements-base. - tests: UMA is now a plain parametrization like MACE; removed the skipif scaffolding and tests/uma_optional.py. Verified with ray/wandb/torchtnt/hydra fully blocked: import, construct, forward, and a full forward+backward+optimizer step all succeed. 427 tests collect clean; UMA train + smoke tests pass; black 21.5b1 clean.
Adding omegaconf==2.3.0 to requirements-base broke CI: it pulls the sdist-only antlr4-python3-runtime, which fails to build under CI's --no-build-isolation. Instead of shipping extra deps, guard the two lightweight import-time deps in the vendored FairChem UMA backbone: * escn_md.py: omegaconf DictConfig/ListConfig -> fall back to () (they are only used in isinstance() checks, which handle empty tuples). * radius_graph_pbc_nvidia.py, atomic_data.py: monty.dev.requires -> faithful fallback decorator (the guarded functions are never called by HydraGNN). UMA now needs zero dependencies beyond HydraGNN's core requirements. Reverts the requirements-base additions and records the three guards as reproducible PATCHES in tools/vendor_uma.py. Verified: UMA unit tests pass and 427 tests collect with ray, wandb, torchtnt, hydra, omegaconf and monty all blocked at interpreter startup.
Replaces the try/except import fallbacks in the vendored FairChem UMA backbone with plain imports, and instead declares omegaconf and monty in requirements-optional.txt. CI now installs them in a dedicated step that keeps build isolation enabled, so omegaconf's sdist-only antlr4-python3-runtime dependency can build its own backend (this is what previously broke the --no-build-isolation base install). Changes: * escn_md.py / radius_graph_pbc_nvidia.py / atomic_data.py: restore the verbatim upstream imports of omegaconf / monty.dev.requires. * tools/vendor_uma.py: drop the three guard PATCHES (keep only the mlip_unit / hydra deferrals); update header comment. * requirements-optional.txt: add omegaconf and monty. * .github/workflows/CI.yml: install omegaconf + monty with build isolation before the torch/pyg/deepspeed steps. * UMAStack.py: point the lazy-import error message and NOTE at requirements-optional.txt. Verified: black clean, 427 tests collect, vendored UMA imports resolve.
omegaconf/monty differ from the rest of requirements-optional: they are required whenever UMA runs (and UMA is tested in CI), so they get a dedicated build-isolated CI install step. Add a section header explaining this so the separation is not lost in the flat list.
Instead of hardcoding omegaconf/monty in the CI workflow, put them in a dedicated, informatively-named requirements file for model-specific backbone dependencies. The file header documents that it must be installed WITH pip build isolation (omegaconf pulls the sdist-only antlr4-python3-runtime). * requirements-specific-models.txt: new file (omegaconf, monty). * CI.yml: install '-r requirements-specific-models.txt' (build isolated) and add it to the pip cache key. * install_dependencies.sh: install it too (build isolated). * requirements-optional.txt: drop the UMA block (now lives in the new file). * UMAStack.py / tools/vendor_uma.py: point references at the new file.
All ORNL BSD headers already matched the hydragnn/models/Base.py format exactly; only the year varied inconsistently (2021/2024/2025/2026). Set each file's copyright year to that file's git last-commit year so the header format stays identical to Base.py and only the year differs per file. 124 files updated, each changed by exactly one line.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.