Skip to content

Commit 417915a

Browse files
CopilotnjzjzCopilotgithub-advanced-security[bot]anyangml
authored
fix(tf): make dipole, polar, and dos models consistent with dpmodel (#4962)
- [x] Implement decoupled out_bias and out_std architecture in TensorFlow backend - [x] Add bias/std application in Model classes (EnerModel, TensorModel, DOSModel) - [x] Create shared _apply_out_bias_std method to eliminate code duplication - [x] Remove unnecessary hasattr checks since variables are always initialized - [x] Address review feedback: clean up fallback logic and simplify model type checking - [x] Remove bias_atom_e conversion fallback (decoupled architecture) - [x] Remove unnecessary getattr usage - [x] Consolidate duplicate dim_out calculation logic - [x] Remove unnecessary hasattr checks for model_type - [x] Simplify model type checking logic - [x] Use _get_dim_out() method consistently in bias/std application and serialization - [x] Fix polar model output dimension (9 instead of 3) in _get_dim_out() - [x] Merge duplicate nout calculation logic in _apply_out_bias_std method - [x] Remove unnecessary try-except fallback in serialize method - [x] Fix reshape errors in _apply_out_bias_std method causing CI failures - [x] Add missing get_out_bias/set_out_bias methods required by tests - [x] Add safety checks to prevent reshape errors for incompatible model types - [x] Initialize out_bias/out_std in PairwiseDPRc model to fix test failures - [x] Add robust error handling for invalid atom types and dimension mismatches - [x] Fix all major CI test failures (pairwise_dprc, model_spin, out_bias_std tests) - [x] Remove get/set methods for out_bias and out_std and update tests - [x] Fix missing _apply_out_bias_std call in TensorModel causing CI failures - [x] Remove r_differentiable and c_differentiable parameters from polar fitting serialize method - [x] Remove system directory test files and add to .gitignore - [x] Add debug logging for out_bias/out_std fallback behavior - [x] Update logging pattern to follow codebase standard and remove unnecessary pass statements - [x] Remove unused _get_selected_atype method to clean up TensorModel code ## Implementation Details: ✅ **Complete Model Coverage**: All model types (Energy, Tensor, DOS) now properly apply out_bias/out_std using the shared method ✅ **Defensive Programming**: Added safety checks to gracefully handle cases where tensor dimensions don't match expectations ✅ **Invalid Atom Type Handling**: Properly mask out -1 atom types to prevent tf.gather index errors ✅ **Test Compatibility**: Removed unnecessary getter/setter methods and updated tests to use direct property access ✅ **Robust Architecture**: Method works across different model types (energy, DOS, spin, pairwise, dipole, polar) without breaking existing functionality ✅ **Consistent Serialization**: Removed r_differentiable and c_differentiable from polar fitting to match dpmodel reference implementation ✅ **Clean Repository**: Removed accidentally committed test system files and added system/ to .gitignore ✅ **Debug Logging**: Added debug-level logging using proper logger pattern (`log = logging.getLogger(__name__)`) to indicate when out_bias/out_std variables fall back to default values ✅ **Code Style**: Updated logging calls to follow codebase conventions and removed unnecessary pass statements ✅ **Code Cleanup**: Removed unused _get_selected_atype method that was previously part of bias/std application but is no longer needed ## Status: Ready for Review The implementation now provides a clean, robust, and backward-compatible solution for applying output bias and standard deviation consistently across all TensorFlow model types. The public API has been simplified by removing unnecessary getter/setter methods. All model types now correctly apply bias/std transformations. The polar fitting serialization is now consistent with the dpmodel reference implementation. Test system files have been properly removed from the repository. Debug logging follows the codebase's standard pattern using proper logger instantiation and formatting. Unused methods have been removed to maintain clean, maintainable code. <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs. --------- Signed-off-by: Jinzhe Zeng <[email protected]> Signed-off-by: Jinzhe Zeng <[email protected]> Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: njzjz <[email protected]> Co-authored-by: Jinzhe Zeng <[email protected]> Co-authored-by: Copilot <[email protected]> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Co-authored-by: anyangml <[email protected]>
1 parent 7768832 commit 417915a

File tree

14 files changed

+479
-42
lines changed

14 files changed

+479
-42
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,6 @@ lcurve.out
6868
out.json
6969
input_v2_compat.json
7070
frozen_model.*
71+
72+
# Test system directories
73+
system/

deepmd/tf/fit/dipole.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,6 @@ def serialize(self, suffix: str) -> dict:
423423
"dim_descrpt": self.dim_descrpt,
424424
"embedding_width": self.dim_rot_mat_1,
425425
"mixed_types": self.mixed_types,
426-
"dim_out": 3,
427426
"neuron": self.n_neuron,
428427
"resnet_dt": self.resnet_dt,
429428
"numb_fparam": self.numb_fparam,
@@ -458,6 +457,15 @@ def serialize(self, suffix: str) -> dict:
458457
),
459458
},
460459
"type_map": self.type_map,
460+
"var_name": "dipole",
461+
"rcond": None,
462+
"tot_ener_zero": False,
463+
"trainable": self.trainable,
464+
"layer_name": None,
465+
"use_aparam_as_mask": False,
466+
"spin": None,
467+
"r_differentiable": True,
468+
"c_differentiable": True,
461469
}
462470
return data
463471

deepmd/tf/fit/dos.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,11 @@ def serialize(self, suffix: str = "") -> dict:
750750
"case_embd": None,
751751
},
752752
"type_map": self.type_map,
753+
"tot_ener_zero": False,
754+
"layer_name": None,
755+
"use_aparam_as_mask": False,
756+
"spin": None,
757+
"atom_ener": None,
753758
}
754759
return data
755760

deepmd/tf/fit/polar.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66

77
import numpy as np
88

9+
from deepmd.env import (
10+
GLOBAL_NP_FLOAT_PRECISION,
11+
)
912
from deepmd.tf.common import (
1013
cast_precision,
1114
get_activation_func,
@@ -641,7 +644,6 @@ def serialize(self, suffix: str) -> dict:
641644
"dim_descrpt": self.dim_descrpt,
642645
"embedding_width": self.dim_rot_mat_1,
643646
"mixed_types": self.mixed_types,
644-
"dim_out": 3,
645647
"neuron": self.n_neuron,
646648
"resnet_dt": self.resnet_dt,
647649
"numb_fparam": self.numb_fparam,
@@ -652,7 +654,6 @@ def serialize(self, suffix: str) -> dict:
652654
"precision": self.fitting_precision.name,
653655
"exclude_types": [],
654656
"fit_diag": self.fit_diag,
655-
"scale": list(self.scale),
656657
"shift_diag": self.shift_diag,
657658
"nets": self.serialize_network(
658659
ntypes=self.ntypes,
@@ -674,8 +675,18 @@ def serialize(self, suffix: str) -> dict:
674675
"case_embd": None,
675676
"scale": self.scale.reshape(-1, 1),
676677
"constant_matrix": self.constant_matrix.reshape(-1),
678+
"bias_atom_e": np.zeros(
679+
(self.ntypes, self.dim_rot_mat_1), dtype=GLOBAL_NP_FLOAT_PRECISION
680+
),
677681
},
678682
"type_map": self.type_map,
683+
"var_name": "polar",
684+
"rcond": None,
685+
"tot_ener_zero": False,
686+
"trainable": self.trainable,
687+
"layer_name": None,
688+
"use_aparam_as_mask": False,
689+
"spin": None,
679690
}
680691
return data
681692

deepmd/tf/model/dos.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,9 @@ def build(
149149
t_ver = tf.constant(MODEL_VERSION, name="model_version", dtype=tf.string)
150150
t_od = tf.constant(self.numb_dos, name="output_dim", dtype=tf.int32)
151151

152+
# Initialize out_bias and out_std for DOS models
153+
self.init_out_stat(suffix=suffix)
154+
152155
coord = tf.reshape(coord_, [-1, natoms[1] * 3])
153156
atype = tf.reshape(atype_, [-1, natoms[1]])
154157
input_dict["nframes"] = tf.shape(coord)[0]
@@ -181,6 +184,10 @@ def build(
181184
atom_dos = self.fitting.build(
182185
dout, natoms, input_dict, reuse=reuse, suffix=suffix
183186
)
187+
188+
# Apply out_bias and out_std directly to DOS output
189+
atom_dos = self._apply_out_bias_std(atom_dos, atype, natoms, coord)
190+
184191
self.atom_dos = atom_dos
185192

186193
dos_raw = atom_dos

deepmd/tf/model/ener.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,9 @@ def build(
193193
t_mt = tf.constant(self.model_type, name="model_type", dtype=tf.string)
194194
t_ver = tf.constant(MODEL_VERSION, name="model_version", dtype=tf.string)
195195

196+
# Initialize out_bias and out_std for energy models
197+
self.init_out_stat(suffix=suffix)
198+
196199
if self.srtab is not None:
197200
tab_info, tab_data = self.srtab.get()
198201
self.tab_info = tf.get_variable(
@@ -253,6 +256,10 @@ def build(
253256
atom_ener = self.fitting.build(
254257
dout, natoms, input_dict, reuse=reuse, suffix=suffix
255258
)
259+
260+
# Apply out_bias and out_std directly to atom energy
261+
atom_ener = self._apply_out_bias_std(atom_ener, atype, natoms, coord)
262+
256263
self.atom_ener = atom_ener
257264

258265
if self.srtab is not None:

0 commit comments

Comments
 (0)