Skip to content

feat(jax): support DPA4 training#5748

Open
njzjz wants to merge 8 commits into
deepmodeling:masterfrom
njzjz:feat/dpa4-jax-train
Open

feat(jax): support DPA4 training#5748
njzjz wants to merge 8 commits into
deepmodeling:masterfrom
njzjz:feat/dpa4-jax-train

Conversation

@njzjz

@njzjz njzjz commented Jul 7, 2026

Copy link
Copy Markdown
Member

Summary

  • Add JAX wrappers/registrations for DPA4/SeZM descriptor and dpa4_ener fitting.
  • Route model.type: dpa4/sezm through the JAX model factory.
  • Handle DPA4 force shape normalization and zero-size checkpoint leaves in the JAX trainer.
  • Enable DPA4 JAX coverage in the existing source/tests/consistent/descriptor/test_dpa4.py and source/tests/consistent/fitting/test_dpa4_ener.py files.

Benchmark

1000-step DPA4 water benchmark, batch size 1, srun --gres=gpu:1 dp, GPU: NVIDIA GeForce RTX 5090.

Backend Command Total wall time Batch 1000 avg Notes
JAX dp --jax train input_jax.json --skip-neighbor-stat 95.860 s 0.0362 s/step Includes initial JAX compile; batch 1 avg 37.0563 s/step.
TF2 dp --tf2 train input_tf2.json --skip-neighbor-stat 164.388 s 0.0148 s/step Includes TF/XLA/PTX compile; batch 1 avg 149.4788 s/step.

PT/pt-expt are not included in the final comparison per follow-up scope.

Validation

  • ruff format .
  • ruff check .
  • python -m py_compile deepmd/jax/descriptor/dpa4.py deepmd/jax/fitting/dpa4_ener.py deepmd/jax/model/model.py deepmd/jax/train/trainer.py source/tests/consistent/descriptor/test_dpa4.py source/tests/consistent/fitting/test_dpa4_ener.py
  • dp --jax train /tmp/deepmd_dpa4_tiny_1vnghlkx/input_jax.json --skip-neighbor-stat -o /tmp/deepmd_dpa4_tiny_1vnghlkx/out_jax.json
  • srun --gres=gpu:1 dp --jax train /tmp/deepmd_dpa4_bench_1000/input_jax.json --skip-neighbor-stat -o /tmp/deepmd_dpa4_bench_1000/out_jax.json

Note: collecting the existing DPA4 consistent test module in this local environment segfaults while importing the existing PT DPA4/Triton path before -k jax selection is applied, so I validated the new JAX path with the smoke train and benchmark above.

Summary by CodeRabbit

  • New Features
    • Added public JAX exports for the DPA4 descriptor and DPA4/SeZM energy fitting support.
    • Expanded JAX model routing and BaseModel deserialization to accept SeZM/DPA4 aliases with automatic descriptor/fitting defaults.
  • Bug Fixes
    • Improved JAX training to reconcile mismatched force tensor shapes between predictions and labels.
    • Improved JAX checkpoint save/restore to correctly handle zero-size tensor leaves and restoration.
  • Tests
    • Added/updated JAX tests covering trainable vs frozen state conversion, PT→JAX DPA4 checkpoint conversion, and JAX descriptor/fitting consistency/evaluation.

@dosubot dosubot Bot added the new feature label Jul 7, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions github-actions Bot added the Python label Jul 7, 2026
Comment thread deepmd/jax/descriptor/dpa4.py Fixed
Comment thread deepmd/jax/descriptor/dpa4.py Fixed
Comment thread deepmd/jax/descriptor/dpa4.py Fixed
Comment thread deepmd/jax/fitting/dpa4_ener.py Fixed
@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds JAX/Flax wrappers and registrations for DPA4/SeZM descriptor and fitting components, routes model construction through SeZM handling, updates force-shape and checkpoint processing, and adds conversion and backend tests.

Changes

DPA4/SeZM JAX support

Layer / File(s) Summary
DPA4 descriptor wrappers and parameter promotion
deepmd/jax/descriptor/...
Adds Flax wrappers, deserialization mappings, trainable-parameter promotion, and public exports.
DPA4 fitting and model construction
deepmd/dpmodel/fitting/dpa4_ener.py, deepmd/jax/fitting/..., deepmd/jax/model/...
Adds fitting wrappers, per-layer trainability persistence, SeZM/DPA4 model aliases, checkpoint normalization, and factory validation.
Trainer and checkpoint persistence
deepmd/jax/train/trainer.py, deepmd/jax/utils/serialization.py
Normalizes force shapes and removes/restores zero-size checkpoint leaves.
Conversion and backend validation
source/tests/jax/..., source/tests/consistent/...
Adds JAX consistency execution, model conversion coverage, parameter-freezing tests, factory tests, and trainer serialization tests.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

Suggested reviewers: wanghan-iapcm, iProzd

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 39.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the PR’s main change: adding JAX support for DPA4 training.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
deepmd/jax/descriptor/dpa4.py (1)

216-249: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

New promotion logic appears untested by the accompanying consistency test.

_promote_trainable/_promote_trainable_lists (and therefore the whole _promote_trainable_tree path wired into DescrptDPA4.__init__/deserialize) are gated by getattr(module, "trainable", True) and return immediately when trainable is falsy. The DPA4 descriptor consistency test fixture (source/tests/consistent/descriptor/test_dpa4.py) constructs the descriptor with "trainable": False, which means this newly added promotion path is never actually exercised by the new JAX consistency coverage introduced in this PR stack.

Also applies to: 270-283

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@deepmd/jax/descriptor/dpa4.py` around lines 216 - 249, The new
trainable-promotion path in _promote_trainable, _promote_trainable_lists, and
_promote_trainable_tree is skipped whenever module.trainable is false, so the
current DPA4 consistency coverage does not exercise it. Update the descriptor
consistency test in test_dpa4.py to include a trainable-true case (or otherwise
invoke DescrptDPA4.__init__ and deserialize with trainable enabled) so the
promotion logic is actually covered and validated.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@deepmd/jax/fitting/dpa4_ener.py`:
- Around line 52-54: The SeZMEnergyFittingNet.__setattr__ override is currently
a no-op because it only forwards to super without adding any behavior. Either
remove this dead override entirely, or implement the intended
trainable-parameter promotion logic for SeZMEnergyFittingNet and any related
GLUFittingNet internals so this wrapper matches the descriptor-side pattern used
by _promote_trainable_tree.

In `@deepmd/jax/model/model.py`:
- Around line 127-130: The defaults in model/model.py do not handle explicit
null values for descriptor and fitting_net, so the subsequent setdefault calls
can fail on None. Update the initialization in the model config parsing logic
around the data.setdefault usage to normalize both fields with
data.get("descriptor") or {} and data.get("fitting_net") or {} before calling
setdefault on their type keys, keeping the existing dpa4 and dpa4_ener defaults
intact.

In `@deepmd/jax/train/trainer.py`:
- Line 836: The checkpoint save path in trainer.py is dropping zero-size leaves
via _drop_zero_size_array_leaves(state), but the restart flow that rebuilds the
model and calls replace_by_pure_dict() expects those paths to exist. Update the
save/restore logic around the trainer state so zero-size entries are either
preserved in the saved state or explicitly reinserted during restore before
replace_by_pure_dict() runs, using the existing checkpoint/state handling code
paths in trainer.py.

---

Nitpick comments:
In `@deepmd/jax/descriptor/dpa4.py`:
- Around line 216-249: The new trainable-promotion path in _promote_trainable,
_promote_trainable_lists, and _promote_trainable_tree is skipped whenever
module.trainable is false, so the current DPA4 consistency coverage does not
exercise it. Update the descriptor consistency test in test_dpa4.py to include a
trainable-true case (or otherwise invoke DescrptDPA4.__init__ and deserialize
with trainable enabled) so the promotion logic is actually covered and
validated.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 5aa70f59-efa8-4ae4-ac9f-cf147f7b123b

📥 Commits

Reviewing files that changed from the base of the PR and between 1cd6556 and 51ee5de.

📒 Files selected for processing (9)
  • deepmd/jax/descriptor/__init__.py
  • deepmd/jax/descriptor/dpa4.py
  • deepmd/jax/fitting/__init__.py
  • deepmd/jax/fitting/dpa4_ener.py
  • deepmd/jax/model/ener_model.py
  • deepmd/jax/model/model.py
  • deepmd/jax/train/trainer.py
  • source/tests/consistent/descriptor/test_dpa4.py
  • source/tests/consistent/fitting/test_dpa4_ener.py

Comment thread deepmd/jax/fitting/dpa4_ener.py Outdated
Comment thread deepmd/jax/model/model.py Outdated
Comment thread deepmd/jax/train/trainer.py
@njzjz

njzjz commented Jul 8, 2026

Copy link
Copy Markdown
Member Author

Pushed follow-up commit 590823bb2 for the JAX CI/review feedback.\n\nChanges:\n- Avoid direct nnx.List usage when the installed Flax NNX does not provide it.\n- Remove the no-op SeZMEnergyFittingNet.__setattr__ override.\n- Normalize explicit null descriptor / fitting_net blocks before setting DPA4 defaults.\n- Reinsert missing zero-size state leaves during JAX checkpoint restore, matching the save-side filtering.\n- Reverted the extra source/tests/consistent churn from this follow-up, per request.\n\nLocal validation:\n- JAX smoke for DPA4 descriptor construction, fitting construction, DPA4 model construction with fitting_net: null, and zero-size state reinsertion passed.\n- ruff format . && ruff check . && git diff --check passed.\n\nCI is rerunning.

@codecov

codecov Bot commented Jul 8, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.81250% with 23 lines in your changes missing coverage. Please review.
✅ Project coverage is 71.52%. Comparing base (0c5a914) to head (72aa9ef).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
deepmd/jax/utils/serialization.py 81.57% 7 Missing ⚠️
deepmd/jax/descriptor/dpa4.py 96.27% 6 Missing ⚠️
deepmd/jax/model/base_model.py 87.17% 5 Missing ⚠️
deepmd/jax/train/trainer.py 78.57% 3 Missing ⚠️
deepmd/dpmodel/fitting/dpa4_ener.py 80.00% 1 Missing ⚠️
deepmd/pt/model/task/sezm_ener.py 80.00% 1 Missing ⚠️

❗ There is a different number of reports uploaded between BASE (0c5a914) and HEAD (72aa9ef). Click for more details.

HEAD has 42 uploads less than BASE
Flag BASE (0c5a914) HEAD (72aa9ef)
56 14
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #5748      +/-   ##
==========================================
- Coverage   79.69%   71.52%   -8.18%     
==========================================
  Files        1020      996      -24     
  Lines      116359   110632    -5727     
  Branches     4303     3532     -771     
==========================================
- Hits        92736    79129   -13607     
- Misses      22076    30707    +8631     
+ Partials     1547      796     -751     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment thread deepmd/jax/descriptor/dpa4.py Fixed
Comment thread deepmd/jax/descriptor/dpa4.py
Comment thread deepmd/jax/utils/serialization.py
Coding-Agent: Codex
Codex-Version: codex-cli 0.144.1
Model: gpt-5.6-sol
Reasoning-Effort: xhigh
@njzjz

njzjz commented Jul 11, 2026

Copy link
Copy Markdown
Member Author

Pushed follow-up commit 68cb12e for the remaining review feedback.

Changes:

  • Promote optional cross-grid FrameContract/FrameExpand weights and FFN LayerScale leaves to JAX parameters.
  • Remove the redundant imports reported by CodeQL.
  • Add focused coverage for parameter promotion, zero-size checkpoint restore, DPA4 factory validation, and force-shape normalization.

Validation:

  • Focused JAX tests: 9 passed, 5 subtests passed.
  • DPA4 fitting consistency: 28 passed, 36 skipped.
  • ruff format . and ruff check . passed.

Coding agent: Codex
Codex version: codex-cli 0.144.1
Model: gpt-5.6-sol
Reasoning effort: xhigh

@OutisLi OutisLi left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes for the blocking DPA4 fitting-trainability correctness issue described inline.

Comment thread deepmd/jax/fitting/dpa4_ener.py

@OutisLi OutisLi left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding a second blocking DPA4 correctness finding; the existing changes-requested state remains applicable.

Comment thread deepmd/jax/train/trainer.py

@OutisLi OutisLi left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding the approved DPA4 exclusion-routing correctness finding.

Comment thread deepmd/jax/model/model.py Outdated

@OutisLi OutisLi left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding the approved DPA4 descriptor-freeze correctness finding.

Comment thread deepmd/jax/descriptor/dpa4.py Outdated

@OutisLi OutisLi left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional interoperability finding.

Comment thread deepmd/jax/model/ener_model.py

@OutisLi OutisLi left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding the approved charge/spin-conditioning training finding.

Comment thread deepmd/jax/model/model.py
Preserve DPA4 freeze policies, support PT SeZM conversion, and apply zero-size filtering to every JAX checkpoint writer.

Coding-Agent: Codex
Codex-Version: codex-cli 0.144.1
Model: gpt-5.6-sol
Reasoning-Effort: xhigh

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
source/tests/jax/test_dpa4.py (1)

88-102: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover mixed per-layer trainability.

The scalar frozen case would also pass the prior all-or-nothing policy. Add a [False, True] round trip and assert the policy persists with optimizer-visible parameters.

Proposed coverage
+def test_mixed_fitting_trainability_survives_round_trip() -> None:
+    fitting = SeZMEnergyFittingNet(
+        ntypes=2,
+        dim_descrpt=4,
+        neuron=[4],
+        trainable=[False, True],
+        precision="float64",
+        mixed_types=True,
+        seed=20260712,
+    )
+    restored = SeZMEnergyFittingNet.deserialize(fitting.serialize())
+
+    assert restored.nets[0].trainable == [False, True]
+    assert len(nnx.to_flat_state(nnx.state(restored, nnx.Param))) > 0

As per coding guidelines, use pytest for the single new test case.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@source/tests/jax/test_dpa4.py` around lines 88 - 102, Extend
test_frozen_fitting_stays_frozen_after_conversion_round_trip with a mixed
per-layer trainability case using [False, True], then serialize and deserialize
the fitting network. Assert restored.nets[0].trainable preserves [False, True]
and verify nnx.to_flat_state(nnx.state(restored, nnx.Param)) contains the
expected optimizer-visible parameters; run this as a single pytest test case.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@source/tests/jax/test_dpa4.py`:
- Around line 88-102: Extend
test_frozen_fitting_stays_frozen_after_conversion_round_trip with a mixed
per-layer trainability case using [False, True], then serialize and deserialize
the fitting network. Assert restored.nets[0].trainable preserves [False, True]
and verify nnx.to_flat_state(nnx.state(restored, nnx.Param)) contains the
expected optimizer-visible parameters; run this as a single pytest test case.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 8151ce1f-2748-4c4c-9dd2-fcb561d862d7

📥 Commits

Reviewing files that changed from the base of the PR and between 1c8c03b and 7304a67.

📒 Files selected for processing (11)
  • deepmd/dpmodel/fitting/dpa4_ener.py
  • deepmd/jax/descriptor/dpa4.py
  • deepmd/jax/fitting/dpa4_ener.py
  • deepmd/jax/model/base_model.py
  • deepmd/jax/model/model.py
  • deepmd/jax/train/trainer.py
  • deepmd/jax/utils/serialization.py
  • source/tests/jax/test_dpa4.py
  • source/tests/jax/test_dpa4_conversion.py
  • source/tests/jax/test_model_factory.py
  • source/tests/jax/test_training.py
💤 Files with no reviewable changes (1)
  • deepmd/jax/fitting/dpa4_ener.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • deepmd/jax/model/model.py
  • deepmd/jax/descriptor/dpa4.py

Resolve DPA4 JAX training conflicts while retaining the latest shared multi-task and Array API Strict coverage from master.

Coding-Agent: Codex
Codex-Version: codex-cli 0.144.1
Model: gpt-5.6-sol
Reasoning-Effort: xhigh
@njzjz-bot

njzjz-bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Resolved the merge conflicts with the latest master and pushed merge commit 3727480. pre-commit.ci subsequently applied its automatic formatting fix in 180fff0.

The resolution retains the JAX DPA4 shape-handling tests from this PR and the latest multi-task/stat-merging and Array API Strict coverage from master.

Validation:

  • Focused JAX/DPA4 suite: 73 passed, 224 deselected, 6 subtests passed.
  • ruff check . passed.
  • ruff format . reported no local changes before the merge commit.
  • No unresolved review threads remain.

Coding agent: Codex
Codex version: codex-cli 0.144.1
Model: gpt-5.6-sol
Reasoning effort: xhigh

Coding-Agent: Codex
Codex-Version: codex-cli 0.144.1
Model: gpt-5.6-sol
Reasoning-Effort: xhigh
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants