Deprecate descriptor-scoped exclude_types in favour of the model-level build-seam owner

Open
#5,947 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 3 days

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
48/100
Issue type
Refactor
Clarity
Clearly specified
Activity status
Quiet
Tech stack
python

Research direction

Read deepmd/pt_expt/model/get_model.py:148-162 and deepmd/pt/model/model/init.py:388-403, then inspect the descriptor application sites in dpa4.py, dpa1.py, and repformers.py. Run the cross-backend consistency harness with descriptor-only and model-level exclusions; done means the warning is emitted, promotion is removed in both backends, and the model-level seam gives consistent results.

Written by the indexing model from the issue text.

Description

enhancement

Since #5733 pair exclusion is a graph-native transform, but there are still two owners with two different scopes, and one builder silently promotes between them. That promotion makes two otherwise-equivalent model builders disagree by ~80 eV on the same input.

The two owners
key applied where scope
model-level pair_exclude_types graph build seam, folded into the graph before the atomic model sees it every child of the composition, including analytical bridging (ZBL)
descriptor-level exclude_types inside the descriptor forward, apply_pair_exclusion(graph, atype, self.emask) the learned descriptor features only

Application sites for the descriptor-scoped key: deepmd/dpmodel/descriptor/dpa4.py:1514, deepmd/dpmodel/descriptor/dpa1.py:1866, deepmd/dpmodel/descriptor/repformers.py:622.

The split is already documented in deepmd/dpmodel/descriptor/dpa4_nn/edge_cache.py:279:

Model-level pair_exclude_types is a separate, graph-BUILD transform, already folded into the incoming graph.

The promotion

get_sezm_model copies the descriptor-scoped key into the model-scoped one, writes it back down onto the descriptor, and raises if both are set to different values:

  • deepmd/pt_expt/model/get_model.py:148-162
  • deepmd/pt/model/model/__init__.py:388-403 (identical)

get_standard_model does not do this, in either pt_expt or dpmodel.

Observable consequence

Same config in both builders — descriptor.exclude_types=[[0,1]], bridging_method: ZBL, bridging_r_inner: 0.8, bridging_r_outer: 1.2, type_map: [Ni, O] — evaluated on a 0.9 A Ni-O dimer:

route energy
type: "dpa4" (promotes) -0.909 eV
type: "standard" (does not) +79.056 eV

dE = 79.97 eV, max|dF| = 318.48 eV/A. The difference is entirely whether the analytical ZBL child still sees the excluded pair. Surfaced during review of #5939.

Why the promotion is the wrong side to keep

A descriptor-scoped setting should stay descriptor-scoped. The promotion also forecloses a physically meaningful configuration: hiding a pair from the network while keeping its real short-range nuclear repulsion. And because only one of the two builders promotes, "which builder did you use" silently changes the physics.

Proposal
  1. Emit a DeprecationWarning when descriptor.exclude_types is set, directing users to model-level pair_exclude_types.
  2. Remove the promotion from get_sezm_model in pt and pt_expt together, so the backends cannot diverge mid-flight.
  3. Leave pair_exclude_types as the single build-seam owner; at that point there is nothing left to reconcile and every builder agrees by construction.
  4. Cover it in the cross-backend consistency harness (a data row exercising descriptor-only vs model-level exclusion), not a bespoke test, so a backend that skips the seam is visible.
Backwards compatibility

Step 2 is a behaviour change for existing dpa4/sezm configs that set only descriptor.exclude_types and rely on it reaching the bridging term — their energies will change. Hence the staged warning first. Configs that set pair_exclude_types explicitly are unaffected.

Dominant language
Python
Stars
2.1k
Forks
663
Avg merge
3d 11h
Merged PRs (30d)
25

Getting set up

Open in Codespaces

Starts the project's dev container in your browser, under your own GitHub account.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from deepmodeling/deepmd-kit

All issues in deepmodeling/deepmd-kit

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.