Skip to content

[BUG][pt_expt][DPA1] Automatic graph-lower export changes predictions for dense-trained se_atten_v2 models with nonzero davg #5973

Description

@hcustc

Bug summary

I trained a DPA1-L0 model with the standard PyTorch backend (dp --pt train) and converted the
frozen .pth model to .pt2 using dp convert-backend. The descriptor used the default
set_davg_zero: false and has nonzero davg.

The automatically selected graph-lower model loads and runs, but it is not numerically
equivalent to the source model. On the same six-frame system, the force-component difference
is:

  • MAE: 1.1381067 eV/Angstrom
  • RMSE: 1.7619205 eV/Angstrom
  • Maximum absolute difference: 6.7789032 eV/Angstrom

In contrast, a manually exported nlist/dense-lower .pt2 model reproduces the source model
with a force-component MAE of 5.13e-6 eV/Angstrom and a maximum difference of 1.91e-5 eV/ Angstrom.

The discrepancy is reproduced by an uncompiled CPU eager comparison between
forward_common_lower and forward_common_lower_graph, and is already present in the
descriptor output. As a diagnostic, setting the descriptor mean (davg) to zero in memory
reduces the descriptor discrepancy to numerical noise.

I also independently retrained four models with set_davg_zero: true. After automatic graph-
lower conversion, their force-component MAE differences are 1.76e-51.84e-5 eV/Angstrom,
with a maximum observed difference of 1.33e-4 eV/Angstrom.

These results indicate that automatic conversion accepts a dense-trained se_atten_v2 model
with nonzero davg, even though its graph-lower representation is not functionally equivalent.

DeePMD-kit Version

0.1.dev1+gbc902daf7.d20260809

Backend and its version

PyTorch 2.11.0+cu128

How did you download the software?

Built from source

Input Files, Running Commands, Error Log, etc.

A minimal reproducer archive is attached containing:

reproducer/
├── frozen_model.pth
├── input.json
├── compare_predictions.py
└── test_system/
    ├── type.raw
    ├── type_map.raw
    ├── nopbc
    └── set.000/
        ├── box.npy
        ├── coord.npy
        ├── energy.npy
        └── force.npy

The test system is nonperiodic and contains six frames with seven atoms per frame.

Relevant model settings:

{
  "type_map": ["C", "Cl", "H", "O"],
  "descriptor": {
    "type": "se_atten_v2",
    "sel": 250,
    "rcut": 6.0,
    "attn": 128,
    "attn_layer": 0,
    "tebd_input_mode": "strip",
    "precision": "float32"
  }
}

set_davg_zero was not specified during training, so its effective value is false. The trained
descriptor has nonzero davg; its largest absolute value is approximately 0.01418.

Environment:

DeePMD-kit: 0.1.dev1+gbc902daf7.d20260809
Git commit: bc902daf747d93c5d7314338d287fd2dd0a7e32c
PyTorch: 2.11.0+cu128
Python: 3.12.12
OS: Linux x86_64

The build is based on the official master branch. The only local source change preserves an
explicitly requested `CMAKE_CUDA_ARCHITECTURES=120`; no Python, model, descriptor,
serialization, or inference code was modified.

There is no exception or error traceback. Conversion and inference both exit successfully. This
is a silent numerical correctness failure.

Observed source .pth versus automatic graph-lower .pt2 difference:

Energy MAE:                  1.3291797 eV/frame
Energy maximum difference:  2.0507687 eV/frame
Force-component MAE:        1.1381067 eV/Angstrom
Force-component RMSE:       1.7619205 eV/Angstrom
Force maximum difference:   6.7789032 eV/Angstrom

For comparison, manually exporting the same model through nlist/dense lower gives a force-
component MAE of 5.13e-6 eV/Angstrom and a maximum difference of 1.91e-5 eV/Angstrom.

### Steps to Reproduce

[deepmd-dpa1-graph-lower-reproducer.zip](https://github.com/user-attachments/files/31117915/deepmd-dpa1-graph-lower-reproducer.zip)

1. Extract the attached minimal reproducer and enter its directory:

   ```bash
   unzip deepmd-dpa1-graph-lower-reproducer.zip
   cd deepmd-dpa1-graph-lower-reproducer

2. Convert the supplied source model. dp convert-backend automatically selects graph lower:

   dp convert-backend frozen_model.pth model_graph.pt2

3. Evaluate the source and converted models on the same six-frame system:

  dp --pt test -m frozen_model.pth -s test_system -n 32 -d pth
  dp --pt-expt test -m model_graph.pt2 -s test_system -n 32 -d graph

4. Compare their predictions:

   python compare_predictions.py pth graph

   Expected reproduction output:

   Energy MAE difference:              1.3291797 eV/frame
   Energy maximum absolute difference: 2.0507687 eV/frame
   Force-component MAE:                1.1381067 eV/Angstrom
   Force-component RMSE:               1.7619205 eV/Angstrom
   Force-component maximum difference: 6.7789032 eV/Angstrom

No retraining, LAMMPS, or Kokkos is required. The same underlying dense-versus-graph
discrepancy was also reproduced independently in uncompiled CPU eager execution.

### Further Information, Files, and Links

_No response_

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions