Skip to content

fix(pt): calibrate DPA4 bias and support PyTorch 2.13 compile - #5910

Merged
OutisLi merged 9 commits into
deepmodeling:masterfrom
OutisLi:pr/dpa4
Jul 30, 2026
Merged

fix(pt): calibrate DPA4 bias and support PyTorch 2.13 compile#5910
OutisLi merged 9 commits into
deepmodeling:masterfrom
OutisLi:pr/dpa4

Conversation

@OutisLi

@OutisLi OutisLi commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Calibrate DPA4/SeZM output bias statistics through the complete atomic-model forward path, including model-level preprocessing and analytical contributions.
  • Apply the same frame masks and intensive reductions used by the public model outputs when computing statistics, including min_pair_dist filtering and multitask data handling.
  • Extend the PyTorch torch.compile compatibility range to PyTorch 2.13 and apply the Inductor symbolic-divisibility workaround to the affected releases.
  • Add and update coverage for SeZM bias calibration, spin-model behavior, training statistics, and compile compatibility.

Root cause

Bias calibration previously used an incomplete output path, so model-level contributions and output reduction semantics could be omitted from the fitted bias. Separately, PyTorch 2.13 was rejected before compilation, even though it requires the same Inductor compatibility handling as PyTorch 2.12.

Validation

  • git diff --check passed.
  • Tests were not run locally, per request; the cherry-picked commits include the relevant test updates.

Summary by CodeRabbit

  • New Features

    • Added minimum pair-distance frame filtering for training and statistics, with synchronized distributed step skipping when no frames are valid.
    • Added model support for statistics-driven atomic output prediction to power “change-by-statistic” bias adjustment.
    • Introduced an atomic-output-only execution mode for SeZM models, including a safe temporary preservation of training/eval state.
  • Bug Fixes

    • Fixed edge cases where empty samples/frames could break statistics and reduction logic, including safer intensive/masked reductions.
    • Improved SeZM spin/bridging output handling and migrated analytical bridging potential naming from InterPotential to InnerPotential.

OutisLi added 2 commits July 28, 2026 11:35
Use the production SeZM forward topology for residual statistics so inner potentials, exclusions, and spin expansion are represented consistently. Align minimum-distance filtering across statistics and distributed training.
PyTorch 2.13 still routes symbolic-denominator divisibility through
Inductor's non-factoring Mod, the regression introduced in 2.12, so the
existing repair applies unchanged and 2.13 needs no workaround of its
own. Collapse the version gates into SUPPORTED_COMPILE_TORCH and
_DIVISIBILITY_REGRESSION_TORCH so the runtime check, the patch selector
and the compile-parity test skip all read one declaration.
Copilot AI review requested due to automatic review settings July 28, 2026 03:37
@dosubot dosubot Bot added the bug label Jul 28, 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.

@coderabbitai

coderabbitai Bot commented Jul 28, 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 atomic-only SeZM prediction for statistic-based bias adjustment, minimum pair-distance filtering across statistics and distributed training, renames the analytical bridging potential to InnerPotential, and makes PyTorch compile compatibility version-driven.

Changes

Atomic statistics and SeZM prediction

Layer / File(s) Summary
Statistics prediction contracts
deepmd/pt/model/atomic_model/base_atomic_model.py, deepmd/pt/model/model/model.py, deepmd/pt/model/model/make_model.py, deepmd/pt/utils/stat.py
Adds the atomic prediction contract and routes statistic-based bias adjustment through complete, mask-aware atomic predictions.
SeZM atomic-only execution
deepmd/pt/model/model/sezm_model.py, deepmd/pt/model/model/sezm_property_model.py
Adds atomic-output-only execution that bypasses compilation and derivative setup while retaining masked atomic outputs and bridging contributions.
SeZM support and validation
deepmd/pt/model/model/sezm_spin_model.py, source/tests/pt/model/*
Preserves training state, updates spin statistic packing, and tests bias invariance, empty statistics, pair exclusion, and statistic energy consistency.

Minimum-distance frame filtering

Layer / File(s) Summary
Statistics and training filtering
deepmd/pt/utils/stat.py, deepmd/pt/train/training.py, deepmd/utils/argcheck.py
Adds frame masks, filtered batch selection, threshold propagation, and synchronized distributed retries.
Filtering tests
source/tests/pt/test_training.py
Tests accepted-frame selection, empty filtered systems, collective skip behavior, and retry scheduling.

InnerPotential migration

Layer / File(s) Summary
Implementation and model wiring
deepmd/dpmodel/atomic_model/inner_potential.py, deepmd/dpmodel/model/*, deepmd/pt_expt/*, deepmd/pt/model/model/*
Renames the analytical potential, updates registration and serialization identifiers, and changes model construction and exports.
Regression coverage
source/tests/common/*, source/tests/infer/*, source/tests/pt_expt/*, source/api_cc/tests/*, source/lmp/tests/*
Updates analytical-potential and composition tests to use InnerPotential names and identifiers.

PyTorch compile compatibility

Layer / File(s) Summary
Version-driven compile policy
deepmd/pt/utils/compile_compat.py, source/tests/pt/model/test_sezm_model.py, source/tests/pt/model/test_sezm_spin_model.py
Uses explicit supported and regression-affected PyTorch release sets for validation, patching, and test skip logic.

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

Possibly related PRs

Suggested labels: bug, enhancement, Python

Suggested reviewers: njzjz, wanghan-iapcm, iprozd

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 61.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 accurately captures the two main changes: DPA4 bias calibration and extended PyTorch compile support.
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: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
deepmd/pt/utils/stat.py (1)

267-291: 🚀 Performance & Scalability | 🟡 Minor | ⚡ Quick win

Use the forwarded atype shape for the auto-batch size hint.

_compute_model_predict() forwards model_coord and model_atype, but model_forward_auto_batch_size() still passes system["atype"].shape[-1] to AutoBatchSize. For models that populate model_atype differently from system["atype"], the hint can under/overestimate the actual atom count and waste batching iterations. Use atype.shape[-1] for this hint.

🤖 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/pt/utils/stat.py` around lines 267 - 291, Update
model_forward_auto_batch_size() to pass the forwarded atype.shape[-1] value to
AutoBatchSize.execute_all instead of system["atype"].shape[-1]. Keep the
existing model_forward arguments and batching flow unchanged.
🧹 Nitpick comments (1)
deepmd/pt/train/training.py (1)

774-792: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate min_pair_dist parsing.

This re-derives the exact same value(s) already computed earlier in __init__ for the DataRequirementItem/single_model_stat wiring (single-task: line ~502-504; multi-task: line ~578-582, per model_key). Two independent copies of the same parsing logic risk silently diverging if one is edited without the other.

♻️ Suggested consolidation

Compute self.min_pair_dist/self.has_min_pair_filter once, earlier in __init__ (before the single/multi-task data-loading blocks), and reuse self.min_pair_dist at the two existing call sites instead of the local min_pair_dist variables.

🤖 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/pt/train/training.py` around lines 774 - 792, Consolidate
min_pair_dist parsing in __init__ by computing self.min_pair_dist and
self.has_min_pair_filter once before the single-task and multi-task data-loading
blocks. Remove the duplicate parsing shown here, and update the existing
DataRequirementItem/single_model_stat wiring to reuse self.min_pair_dist instead
of local min_pair_dist values for both task modes.
🤖 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/pt/train/training.py`:
- Around line 2456-2481: Update all_ranks_have_valid_frames to select the
collective tensor device based on the active device and supported backend
capabilities, not an exact dist.get_backend() == "nccl" comparison. Preserve
CUDA/NCCL synchronization when available while retaining CPU/Gloo fallback for
CPU-only environments and ensure dist.all_reduce uses the selected device.

In `@deepmd/pt/utils/compile_compat.py`:
- Around line 61-64: Update _DIVISIBILITY_REGRESSION_TORCH to remove the (2, 13)
entry, leaving only releases that still require
patch_inductor_symbolic_divisibility. Adjust the adjacent comments to state that
PyTorch 2.13 and later are fixed and must not receive the workaround.

In `@deepmd/pt/utils/stat.py`:
- Around line 319-332: Update _reduce_model_prediction to handle frames with
zero unmasked atoms before dividing in the intensive path. Ensure zero-count
frames produce a finite, defined result without inf or nan, while preserving the
existing averaging behavior for frames with at least one unmasked atom.

In `@source/tests/pt/model/test_sezm_spin_model.py`:
- Line 497: Update the skip gate for test_compile_matches_eager to use the
shared SUPPORTED_COMPILE_TORCH versions, importing that symbol and deriving the
skip condition and reason from it. Ensure Torch 2.11, 2.12, and 2.13 are
eligible unless the spin compile path is explicitly intended to support only
2.11.

---

Outside diff comments:
In `@deepmd/pt/utils/stat.py`:
- Around line 267-291: Update model_forward_auto_batch_size() to pass the
forwarded atype.shape[-1] value to AutoBatchSize.execute_all instead of
system["atype"].shape[-1]. Keep the existing model_forward arguments and
batching flow unchanged.

---

Nitpick comments:
In `@deepmd/pt/train/training.py`:
- Around line 774-792: Consolidate min_pair_dist parsing in __init__ by
computing self.min_pair_dist and self.has_min_pair_filter once before the
single-task and multi-task data-loading blocks. Remove the duplicate parsing
shown here, and update the existing DataRequirementItem/single_model_stat wiring
to reuse self.min_pair_dist instead of local min_pair_dist values for both task
modes.
🪄 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 Plus

Run ID: 099ead31-de6c-43d0-8d12-b21758bb8912

📥 Commits

Reviewing files that changed from the base of the PR and between 2f419f4 and c9cad8c.

📒 Files selected for processing (13)
  • deepmd/pt/model/atomic_model/base_atomic_model.py
  • deepmd/pt/model/model/make_model.py
  • deepmd/pt/model/model/model.py
  • deepmd/pt/model/model/sezm_model.py
  • deepmd/pt/model/model/sezm_property_model.py
  • deepmd/pt/model/model/sezm_spin_model.py
  • deepmd/pt/train/training.py
  • deepmd/pt/utils/compile_compat.py
  • deepmd/pt/utils/stat.py
  • deepmd/utils/argcheck.py
  • source/tests/pt/model/test_sezm_model.py
  • source/tests/pt/model/test_sezm_spin_model.py
  • source/tests/pt/test_training.py

Comment thread deepmd/pt/train/training.py
Comment thread deepmd/pt/utils/compile_compat.py
Comment thread deepmd/pt/utils/stat.py
Comment thread source/tests/pt/model/test_sezm_spin_model.py Outdated
Copilot AI review requested due to automatic review settings July 28, 2026 04:34

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.

Comment thread deepmd/pt/utils/compile_compat.py
@codecov

codecov Bot commented Jul 28, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 91.11111% with 20 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.00%. Comparing base (4f827cc) to head (29c04f0).

Files with missing lines Patch % Lines
deepmd/pt/utils/stat.py 89.04% 8 Missing ⚠️
deepmd/pt/train/training.py 92.00% 4 Missing ⚠️
deepmd/pt/utils/compile_compat.py 63.63% 4 Missing ⚠️
deepmd/pt/model/model/sezm_model.py 96.00% 2 Missing ⚠️
deepmd/pt/model/model/model.py 50.00% 1 Missing ⚠️
deepmd/pt/model/model/sezm_spin_model.py 91.66% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #5910      +/-   ##
==========================================
- Coverage   79.21%   79.00%   -0.21%     
==========================================
  Files        1069     1069              
  Lines      124070   124232     +162     
  Branches     4522     4527       +5     
==========================================
- Hits        98278    98146     -132     
- Misses      24171    24468     +297     
+ Partials     1621     1618       -3     

☔ 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.

@OutisLi
OutisLi requested review from njzjz and wanghan-iapcm July 28, 2026 06:38

@njzjz-bot njzjz-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.

Requesting changes for the inline compatibility regression.

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

Comment thread deepmd/pt/model/model/sezm_model.py
Copilot AI review requested due to automatic review settings July 28, 2026 11:43

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.

@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: 1

🤖 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/dpmodel/atomic_model/inner_potential.py`:
- Around line 269-270: Update InnerPotentialAtomicModel deserialization and its
registry compatibility so serialized models with type "inter_potential" resolve
to the current "inner_potential" implementation. Preserve normal
"inner_potential" lookup while accepting the legacy type during composition
deserialization, using an alias or schema upgrade alongside the existing
BaseAtomicModel registration.
🪄 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 Plus

Run ID: 8640731c-57ad-4f23-aecf-7441bfece09a

📥 Commits

Reviewing files that changed from the base of the PR and between c9cad8c and 17a57b4.

📒 Files selected for processing (19)
  • deepmd/dpmodel/atomic_model/inner_potential.py
  • deepmd/dpmodel/model/dp_linear_model.py
  • deepmd/dpmodel/model/model.py
  • deepmd/pt/train/training.py
  • deepmd/pt/utils/stat.py
  • deepmd/pt_expt/model/get_model.py
  • deepmd/pt_expt/utils/__init__.py
  • deepmd/pt_expt/utils/inner_potential.py
  • deepmd/pt_expt/utils/serialization.py
  • source/api_cc/tests/test_deeppot_dpa4_zbl_ptexpt.cc
  • source/api_cc/tests/test_deepspin_dpa4_zbl_ptexpt.cc
  • source/lmp/tests/test_lammps_dpa4_zbl_pt2.py
  • source/tests/common/dpmodel/test_inner_potential.py
  • source/tests/common/dpmodel/test_zbl_bridging.py
  • source/tests/infer/gen_dpa4_spin_zbl.py
  • source/tests/infer/gen_dpa4_zbl.py
  • source/tests/pt/model/test_sezm_spin_model.py
  • source/tests/pt/test_training.py
  • source/tests/pt_expt/model/test_zbl_bridging.py
🚧 Files skipped from review as they are similar to previous changes (4)
  • source/tests/pt/test_training.py
  • source/tests/pt/model/test_sezm_spin_model.py
  • deepmd/pt/utils/stat.py
  • deepmd/pt/train/training.py

Comment thread deepmd/dpmodel/atomic_model/inner_potential.py

@njzjz-bot njzjz-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.

The coordinated InnerPotential rename is internally consistent across PT, dpmodel, pt_expt, serialization identifiers, and tests. Given the stated development-stage API policy for DPA4/SeZM, I have no remaining blocking concern.

Focused validation: 37 inner-potential and ZBL-bridging tests passed.

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

@wanghan-iapcm wanghan-iapcm 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.

The direction of the bias fix is right, and I checked that rather than assuming it: routing the analytical term through the prediction removes a genuine prior double count, where ZBL was absorbed into the fitted bias and then added again at inference. Reasoning through test_zbl_change_out_bias_is_invariant_for_self_labels, self-generated labels include ZBL while the old stats path excluded it, so the bias would shift and the invariance assertion should fail pre-fix - that makes it a real regression test. I did not execute it against the parent, so treat that as reasoning rather than a measurement.

What I did measure: the pre-existing shared-path suites still pass against this branch - test_atomic_model_atomic_stat.py, test_atomic_model_global_stat.py and test_polar_atomic_model_stat.py all green, and the three failures in test_change_bias.py reproduce identically on the parent commit from an unrelated libcupti problem. So "Tests were not run locally, per request" is a process gap here, not a hidden regression. Worth running them before merge all the same, since make_model.py, base_atomic_model.py and stat.py are on the path of every pt model, not just SeZM.

Eight comments inline. The one on base_atomic_model.py is about the API shape; the others are individual defects.

One finding cannot be anchored because the file is not in this diff. deepmd/pt/entrypoints/main.py calls make_stat_input(...) with no min_pair_dist:

model = training.get_model_for_wrapper(model_params)
type_map = (
model_params["type_map"]
if not multi_task
else model_params["model_dict"][model_branch]["type_map"]
)
model_to_change = model if not multi_task else model[model_branch]

So dp train now calibrates on filtered data while dp change-bias calibrates on unfiltered data, and the same dataset plus config yields two different biases. It is structural rather than a one-line oversight: change_bias() only receives the frozen model's model_params, never the training input config, so there is no min_pair_dist value available to thread through. Worth deciding explicitly whether change-bias should grow the option or whether the filter belongs somewhere both entry points can see.

On atomic_output_only: it exists because predict_atomic_outputs_for_stat calls forward_common under torch.no_grad(), and forward_common computes force and virial through autograd, so the derivative work has to be suppressed. That is the same design choice as the model_forward argument, one layer down - both follow from reusing the whole model forward for a job that only needs atomic outputs. If the model instead exposed just its analytical atomic contribution, the atomic model's existing predictor plus that term would give the complete output with neither the flag nor the new argument. The flag also has a side effect worth a second look: it gates the dens branch as well (get_active_mode() == "dens" and not atomic_output_only), so a dens-mode model computes its statistics through the ener edge schema - the same "incomplete output path" divergence this PR set out to remove. If dens models are not meant to reach bias calibration, raising would be clearer than silently switching schema.

Smaller notes, not worth their own threads:

  1. SUPPORTED_COMPILE_TORCH and _DIVISIBILITY_REGRESSION_TORCH are now independent tuples. Previously the == (2, 12) test was bound to the same literal as the gate, so they could not drift; a future (2, 14) added to the first alone would compile without the divisibility patch and hit CantSplit. Deriving the second as "everything supported except (2, 11)" would be failure-proof.

  2. The model_forward is None fallback branch in change_out_bias - the one every non-SeZM model takes - is covered only by the pre-existing suites noted above, none of which are in this diff.

  3. The PR bundles bias calibration with PyTorch 2.13 compile support. The commits are mostly separable (ba3705b8a bias, c9cad8c99 compile), so splitting would make each independently revertable.

  4. test_change_out_bias_is_invariant_for_self_labels and its ZBL sibling assert at atol=1e-12. Worth confirming that tolerance was chosen from observed residuals rather than inherited.

Comment thread deepmd/pt/model/atomic_model/base_atomic_model.py Outdated
Comment thread deepmd/pt/model/model/sezm_model.py
Comment thread deepmd/pt/train/training.py Outdated
Comment thread deepmd/pt/utils/stat.py
Comment thread deepmd/pt/utils/stat.py Outdated
Comment thread deepmd/pt/utils/compile_compat.py
Comment thread deepmd/pt/utils/stat.py
Copilot AI review requested due to automatic review settings July 28, 2026 15:39

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.

@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: 2

🤖 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/pt/model/model/make_model.py`:
- Around line 374-379: Update the model-level compute_or_load_stat flow and its
underlying output-stat computation so statistics are generated through
predict_atomic_outputs_for_stat rather than directly through the atomic model’s
compute_or_load_out_stat. Ensure model overrides such as SEZM’s predictor
participate in initial calibration and retain the model-level residual-bias
update path, while preserving existing atomic-model behavior otherwise.

In `@deepmd/pt/train/training.py`:
- Around line 793-811: In deepmd/pt/train/training.py:793-811 and 2340-2382,
change the multi-task retry-budget flow so each step uses one attempt limit
shared across ranks for the selected task, rather than independently keyed
per-task limits. Update the initialization around _training_batch_attempts and
its use in _next_training_batch() so the limit is derived and broadcast
consistently for the current task before all_ranks_have_valid_frames() retries,
preventing any rank from exhausting its budget before peers complete the
collective.
🪄 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 Plus

Run ID: 866658be-6d04-471a-803b-99d3549daeff

📥 Commits

Reviewing files that changed from the base of the PR and between 17a57b4 and fb3f3ac.

📒 Files selected for processing (9)
  • deepmd/pt/model/atomic_model/base_atomic_model.py
  • deepmd/pt/model/model/make_model.py
  • deepmd/pt/model/model/sezm_model.py
  • deepmd/pt/train/training.py
  • deepmd/pt/utils/compile_compat.py
  • deepmd/pt/utils/stat.py
  • source/tests/pt/model/test_sezm_model.py
  • source/tests/pt/model/test_sezm_spin_model.py
  • source/tests/pt/test_training.py
🚧 Files skipped from review as they are similar to previous changes (3)
  • source/tests/pt/model/test_sezm_spin_model.py
  • deepmd/pt/utils/compile_compat.py
  • deepmd/pt/model/model/sezm_model.py

Comment thread deepmd/pt/model/model/make_model.py
Comment thread deepmd/pt/train/training.py
Copilot AI review requested due to automatic review settings July 28, 2026 16:23

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.

@OutisLi
OutisLi requested a review from wanghan-iapcm July 28, 2026 16:49
Copilot AI review requested due to automatic review settings July 29, 2026 07:27

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.

@wanghan-iapcm wanghan-iapcm 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.

Went back through all seven threads against HEAD rather than the replies, and they hold up. The atomic change_out_bias signature is back to the three-argument contract that is byte-identical across the other backends, with the residual calibration moved to the model layer -- and routing it through predict_atomic_outputs_for_stat with return rather than falling through to the atomic call is right, since _store_out_stat(..., add=True) accumulates and running both would double-count. The StopIteration restart is restored with an empty-loader guard, the empty-sample case raises, and the compile allowlist no longer claims CI coverage it does not have.

On the intensive-reduction thread, I accept your reasoning and am not pressing it. A silent NaN bias is worse than an abort, and the frame it rejects -- one with no unmasked atoms -- is pathological rather than routine.

The bug-fix reflection also comes out clean. The reason existing tests missed this is specific: pt/test_finetune.py::test_finetune_change_out_bias does cover a ZBL model, but it calls model.atomic_model.change_out_bias(...), entering at the atomic layer and bypassing the model layer where the analytical term is added -- so the incomplete path was invisible to it by construction, and every other bias test uses non-bridged models where the atomic output already is the complete output. test_change_out_bias_is_invariant_for_self_labels closes exactly that gap and genuinely fails pre-fix: it labels the sample with the model's own energy, so any term missing from the statistics path shows up directly as a non-zero delta bias. Pinning the side conditions too (no compile, no derivatives, training mode and caches restored, no leaked grads) is a nice touch.

Two follow-ups below, both non-blocking and both about coverage rather than correctness.

Comment thread deepmd/pt/model/model/sezm_model.py
Comment thread deepmd/pt/train/training.py
Copilot AI review requested due to automatic review settings July 29, 2026 09:16

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.

Copilot AI review requested due to automatic review settings July 30, 2026 04:50

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.

@OutisLi
OutisLi enabled auto-merge July 30, 2026 04:52
@OutisLi
OutisLi added this pull request to the merge queue Jul 30, 2026
Merged via the queue into deepmodeling:master with commit 62aa235 Jul 30, 2026
59 of 63 checks passed
@OutisLi
OutisLi deleted the pr/dpa4 branch July 30, 2026 17:37
wanghan-iapcm pushed a commit to wanghan-iapcm/deepmd-kit that referenced this pull request Jul 31, 2026
Resolutions: keep the capability-based _needs_with_comm_artifact and the
_compose_bridging owner (renamed to upstream's InnerPotentialAtomicModel,
deepmodeling#5910); drop this branch's pt extended-atype ZBL fix in favor of
upstream's equivalent descriptor_atype at the relocated injection site.
njzjz-bot pushed a commit to njzjz-bot/deepmd-kit that referenced this pull request Aug 12, 2026
…odels (deepmodeling#5966)

Close deepmodeling#5927 — resolved **as designed**, with documentation and semantic
pin tests instead of a behavior change.

## The definitions (verified against the code)

The model energy decomposes as `E = E_model + E_bias`, where `E_model`
is everything the model computes (learned network, analytical ZBL term,
or a `linear_ener` combination) and `E_bias` is the per-type output
bias.

- **`set-by-statistic`** assigns `E_bias` directly: user values, or the
per-type least-squares statistic of the **raw labels**. It never calls a
model forward (`compute_output_stats` with `model_forward=None`, stored
with `add=False`) — it is independent of `E_model` **by definition**,
ignoring a trained network and the analytical ZBL term alike.
- **`change-by-statistic`** fits the residual of the labels against the
**complete model prediction** (the bridged predictor since deepmodeling#5910) and
adds the delta to the existing bias.

Under these definitions the "double count" described in the issue is not
a bridging bug: `set` uniformly ignores all of `E_model` for every model
kind. A bridged model after `set` carries no compensation for the mean
ZBL contribution — exactly as a trained plain model after `set` carries
no compensation for its network output. The two modes "disagree" because
they are defined to answer different questions; a self-consistent
calibration is `change`'s job.

Verified conformance of the `linear_ener` composition path in both
backends: children compute no output statistics
(`compute_or_load_out_stat=False`); the composition level performs one
`set` fit on the raw labels. Also verified: the ZBL term contributes
exactly zero for isolated atoms, so its own statistics are trivially
`bias = 0`.

## Changes

- `doc/model/change-bias.md`: precise definitions of the two modes, and
the guidance that calibrating a bridged (or any nonzero-`E_model`) model
self-consistently requires `change-by-statistic`.
- `doc/model/dpa4.md`: note in the ZBL section.
- Semantic pin tests (pt `SeZMModel` + dpmodel `LinearEnergyAtomicModel`
composition): `set-by-statistic` equals the raw-label least-squares fit
exactly — guarding against a future "fix" that would subtract the
analytical term and silently create a third, model-dependent mode.

## Known limitations

- No behavior change anywhere; the pin tests cover
`model.change_out_bias` (the `dp change-bias --mode set` and finetune
routes) and the dpmodel composition out-stat; the pt training-init chain
was verified in-session and funnels into the same pinned branch.
- The spin variants share the machinery but have no dedicated pin.
- Fact worth knowing when reading the docs: `InnerPotential` adds the
full ZBL over the whole cutoff (not only below `bridging_r_outer`), so
the label-side ZBL at equilibrium geometries is small but not strictly
zero; the docs state the offset plainly.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Documentation**
* Clarified how `set` and `change` statistic modes handle model energy,
analytical contributions, labels, residuals, and existing bias.
* Documented the interaction between output-bias calibration and ZBL
bridging, including guidance for self-consistent calibration.

* **Tests**
* Added regression coverage confirming that `set-by-statistic`
calibration uses raw energy labels independently of learned and ZBL
model contributions.
* Verified calibration correctly replaces seeded bias and remains
consistent when repeated.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Han Wang <wang_han@iapcm.ac.cn>
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.

5 participants