DPA1 Inference β Correctness Bugs in pt_expt Backend#
Two distinct bugs affect DPA1 inference in the PT-experimental (pt_expt) backend. Both involve graph-eligible DPA1 models (i.e., attn_layer: 0, se_atten_v2/dpa1 descriptor type) but manifest in different scenarios.
Bug 1 β Wrong Outputs from .pt Checkpoint Inference (Issue #5862)#
Root cause: DeepPot(model.ckpt.pt) routes inference through the dense lower (forward_common_lower) instead of the graph-native path used by the model's public forward() .
The raw .pt loader in deepmd/pt_expt/infer/deep_eval.py::_load_pt reconstructs the model but installs an eager runner that calls model.forward_common_lower(...). For graph-eligible DPA1, model.forward(...) instead reaches call_common β graph-native route. These paths are not numerically equivalent when descriptor statistics are nonzero .
Why the discrepancy is large: The dense DPA1 body retains a phantom padding-neighbor residual of -davg/dstd for all vacant neighbor slots (documented in deepmd/dpmodel/descriptor/dpa1.py). Models with large sel values β e.g., sel=416 on OMat24 β have most dense slots occupied by padding, massively amplifying the residual. The graph path omits padding neighbors entirely .
Observed magnitude on a real OMat24 checkpoint:
| Path | Energy MAE | Force MAE |
|---|---|---|
Direct model.forward (graph) | 0.04 eV | 0.03 eV/Γ |
DeepPot(.pt) / dp test (dense) | 2600 eV | 13 eV/Γ |
Trigger conditions:
- PT-experimental backend
type: dpa1orse_atten_v2descriptor withattn_layer: 0set_davg_zero: false(default) β nonzero descriptor mean statistics- Loaded via
DeepPot(*.pt)ordp --pt-expt test -m model.ckpt.pt
Key files:
deepmd/pt_expt/infer/deep_eval.pyβ_load_pt/_eager_runner: installs dense lower pathdeepmd/pt_expt/model/ener_model.pyβEnergyModel.forwardβcall_common: graph-native routedeepmd/dpmodel/descriptor/dpa1.pyβ documents the dense padding-neighbor residual
Status: PR #5785 (merged 2026-07-16) fixed a related routing issue (DescrptDPA1.call no longer routes through _call_graph_adapter). Issue #5862 specifically targets the checkpoint-loading failure; the structural fix must make DeepPot(.pt) select the graph-native path for graph-eligible DPA1 checkpoints. The recommended regression guard is extending source/tests/pt_expt/infer/test_deep_eval_pt_checkpoint.py with a graph-eligible DPA1 fixture whose davg is nonzero .
Bug 2 β f_use_norm Training Failure on NPY Data (Issue #5813)#
Root cause: Shape mismatch between force predictions and force labels when f_use_norm: true is used with an NPY training system and a graph-eligible DPA1 model .
The graph lower returns force as shape (nf, nloc, 3). Legacy NPY (DeepmdDataSystem) supplies force labels as shape (nf, nloc * 3) (flat). Most force-loss paths in deepmd/dpmodel/loss/ener.py::EnergyLoss.call first flatten both tensors into diff_f, making the shape difference invisible. The f_use_norm branches instead subtract the original (unflattened) tensors before reshaping, triggering a shape broadcast error :
RuntimeError: The size of tensor a (576) must match the size of tensor b (3)
at non-singleton dimension 2
File "deepmd/dpmodel/loss/ener.py", line 445
diff_3 = xp.reshape(force_hat - force, (_nf, _nloc, 3))
Trigger conditions (all must be true):
- PT-experimental backend
type: dpa1withattn_layer: 0(graph-eligible)- NPY training data β does not reproduce with LMDB (LMDB normalizes force shape to
(nloc, 3)on read) loss.f_use_norm: truecombined withloss_func: "mae"oruse_huber: true
Key files:
deepmd/dpmodel/loss/ener.pyβEnergyLoss.call,f_use_normbranches subtract original tensors before reshapedeepmd/pt_expt/train/training.pyβ_CompiledModel._forward_graphexposes force as(nf, nloc, 3)deepmd/dpmodel/utils/batch.pyβnormalize_batchpreserves the legacy flat NPY label shape
Fix direction: Derive every f_use_norm force difference from the already-flattened diff_f (reshaped to (_nf, _nloc, 3) where needed) rather than re-computing force_hat - force on the original layouts .
Relationship Between the Two Bugs#
Both bugs involve graph-eligible DPA1 (attn_layer: 0) in pt_expt and are rooted in the dense β graph-native path transition:
| Bug 1 (#5862) | Bug 2 (#5813) | |
|---|---|---|
| Symptom | Silent wrong results | Hard training crash |
| Trigger | .pt checkpoint inference | f_use_norm + NPY training data |
| Divergence | Dense lower β graph-native forward | NPY flat (nf, nloc*3) β graph (nf, nloc, 3) |
| LMDB affected? | Yes | No |
Key References#
- Issue #5862 β
.ptcheckpoint wrong-output report with standalone reproducer - Issue #5813 β
f_use_norm+ NPY crash report - PR #5785 β Related merged fix: DPA1 dense-call routing via
_call_graph_adapter - PR #5294 β Introduced
f_use_normtoEnergyLoss - Force Loss Computation (KB) β Explains
f_use_norm,relative_f, andEnergyStdLossshape flows