Skip to content

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

Description

@wanghan-iapcm

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions