Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(tf): fix compress suffix in DescrptDPA1Compat #4243

Merged
merged 10 commits into from
Oct 26, 2024
70 changes: 63 additions & 7 deletions deepmd/tf/descriptor/se_atten.py
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,7 @@
table_stride_2: float = 0.1,
check_frequency: int = -1,
suffix: str = "",
tebd_suffix: str = "",
) -> None:
"""Reveive the statisitcs (distance, max_nbor_size and env_mat_range) of the training data.

Expand All @@ -444,6 +445,8 @@
The overflow check frequency
suffix : str, optional
The suffix of the scope
tebd_suffix : str, optional
The suffix of the type embedding scope, only for DescrptDPA1Compat
"""
# do some checks before the mocel compression process
assert (
Expand Down Expand Up @@ -496,7 +499,9 @@
min_nbor_dist, table_extrapolate, table_stride_1, table_stride_2
)

self.final_type_embedding = get_two_side_type_embedding(self, graph)
self.final_type_embedding = get_two_side_type_embedding(
self, graph, suffix=tebd_suffix
)
type_side_suffix = get_extra_embedding_net_suffix(type_one_side=False)
self.matrix = get_extra_side_embedding_net_variable(
self, graph_def, type_side_suffix, "matrix", suffix
Expand Down Expand Up @@ -558,17 +563,18 @@
if nvnmd_cfg.restore_descriptor:
davg, dstd = build_davg_dstd()
check_switch_range(davg, dstd)
with tf.variable_scope("descrpt_attr" + suffix, reuse=reuse):
if davg is None:
davg = np.zeros([self.ntypes, self.ndescrpt]) # pylint: disable=no-explicit-dtype
if dstd is None:
dstd = np.ones([self.ntypes, self.ndescrpt]) # pylint: disable=no-explicit-dtype
with tf.variable_scope("descrpt_attr", reuse=reuse):
t_ntypes = tf.constant(self.ntypes, name="ntypes", dtype=tf.int32)
Fixed Show fixed Hide fixed
Fixed Show fixed Hide fixed
t_rcut = tf.constant(
np.max([self.rcut_r, self.rcut_a]),
name="rcut",
dtype=GLOBAL_TF_FLOAT_PRECISION,
)
t_ntypes = tf.constant(self.ntypes, name="ntypes", dtype=tf.int32)
with tf.variable_scope("descrpt_attr" + suffix, reuse=reuse):
njzjz marked this conversation as resolved.
Show resolved Hide resolved
if davg is None:
davg = np.zeros([self.ntypes, self.ndescrpt]) # pylint: disable=no-explicit-dtype
if dstd is None:
dstd = np.ones([self.ntypes, self.ndescrpt]) # pylint: disable=no-explicit-dtype
t_ndescrpt = tf.constant(self.ndescrpt, name="ndescrpt", dtype=tf.int32)
t_sel = tf.constant(self.sel_a, name="sel", dtype=tf.int32)
t_original_sel = tf.constant(
Expand Down Expand Up @@ -2248,6 +2254,56 @@
self.dout = tf.concat([self.dout, atom_embed], axis=-1)
return self.dout

def enable_compression(
self,
min_nbor_dist: float,
graph: tf.Graph,
graph_def: tf.GraphDef,
table_extrapolate: float = 5,
table_stride_1: float = 0.01,
table_stride_2: float = 0.1,
check_frequency: int = -1,
suffix: str = "",
tebd_suffix: str = "",
) -> None:
"""Reveive the statisitcs (distance, max_nbor_size and env_mat_range) of the training data.

Parameters
----------
min_nbor_dist
The nearest distance between atoms
graph : tf.Graph
The graph of the model
graph_def : tf.GraphDef
The graph_def of the model
table_extrapolate
The scale of model extrapolation
table_stride_1
The uniform stride of the first table
table_stride_2
The uniform stride of the second table
check_frequency
The overflow check frequency
suffix : str, optional
The suffix of the scope
tebd_suffix : str, optional
Same as suffix.
"""
assert (
tebd_suffix == ""
), "DescrptDPA1Compat must use the same tebd_suffix as suffix!"
super().enable_compression(
min_nbor_dist,
graph,
graph_def,
table_extrapolate=table_extrapolate,
table_stride_1=table_stride_1,
table_stride_2=table_stride_2,
check_frequency=check_frequency,
suffix=suffix,
tebd_suffix=suffix,
)

def init_variables(
self,
graph: tf.Graph,
Expand Down
4 changes: 2 additions & 2 deletions deepmd/tf/utils/compress.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ def get_type_embedding(self, graph):
return type_embedding


def get_two_side_type_embedding(self, graph):
type_embedding = get_tensor_by_name_from_graph(graph, "t_typeebd")
def get_two_side_type_embedding(self, graph, suffix=""):
type_embedding = get_tensor_by_name_from_graph(graph, f"t_typeebd{suffix}")
type_embedding = type_embedding.astype(self.filter_np_precision)
type_embedding_shape = type_embedding.shape

Expand Down
154 changes: 154 additions & 0 deletions source/tests/tf/test_model_compression_dpa1_compat_suffix_only.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
# SPDX-License-Identifier: LGPL-3.0-or-later
import unittest

import numpy as np

from deepmd.common import (
make_default_mesh,
)
from deepmd.env import (
GLOBAL_NP_FLOAT_PRECISION,
)
from deepmd.tf.descriptor.se_atten import DescrptDPA1Compat as tf_SeAtten
from deepmd.tf.env import (
GLOBAL_TF_FLOAT_PRECISION,
default_tf_session_config,
tf,
)
from deepmd.tf.utils.sess import (
run_sess,
)


def build_tf_descriptor(obj, natoms, coords, atype, box, suffix):
t_coord = tf.placeholder(GLOBAL_TF_FLOAT_PRECISION, [None], name="i_coord")
t_type = tf.placeholder(tf.int32, [None], name="i_type")
t_natoms = tf.placeholder(tf.int32, natoms.shape, name="i_natoms")
t_box = tf.placeholder(GLOBAL_TF_FLOAT_PRECISION, [9], name="i_box")
t_mesh = tf.placeholder(tf.int32, [None], name="i_mesh")
t_des = obj.build(
t_coord,
t_type,
t_natoms,
t_box,
t_mesh,
{},
suffix=suffix,
)
return [t_des], {
t_coord: coords,
t_type: atype,
t_natoms: natoms,
t_box: box,
t_mesh: make_default_mesh(True, False),
}


def build_eval_tf(sess, obj, natoms, coords, atype, box, suffix):
t_out, feed_dict = build_tf_descriptor(obj, natoms, coords, atype, box, suffix)

t_out_indentity = [
tf.identity(tt, name=f"o_{ii}_{suffix}") for ii, tt in enumerate(t_out)
]
run_sess(sess, tf.global_variables_initializer())
return run_sess(
sess,
t_out_indentity,
feed_dict=feed_dict,
)


class TestDescriptorSeA(unittest.TestCase):
def setUp(self):
self.device = "cpu"
self.seed = 21
self.sel = [9, 10]
self.rcut_smth = 5.80
self.rcut = 6.00
self.neuron = [6, 12, 24]
self.axis_neuron = 3
self.ntypes = 2
self.coords = np.array(
[
12.83,
2.56,
2.18,
12.09,
2.87,
2.74,
00.25,
3.32,
1.68,
3.36,
3.00,
1.81,
3.51,
2.51,
2.60,
4.27,
3.22,
1.56,
],
dtype=GLOBAL_NP_FLOAT_PRECISION,
)
self.atype = np.array([0, 1, 1, 0, 1, 1], dtype=np.int32)
# self.atype = np.array([0, 0, 1, 1, 1, 1], dtype=np.int32)
self.box = np.array(
[13.0, 0.0, 0.0, 0.0, 13.0, 0.0, 0.0, 0.0, 13.0],
dtype=GLOBAL_NP_FLOAT_PRECISION,
)
self.natoms = np.array([6, 6, 2, 4], dtype=np.int32)
self.suffix = "test"
self.type_one_side = False
self.se_a_tf = tf_SeAtten(
self.rcut,
self.rcut_smth,
self.sel,
self.ntypes,
self.neuron,
self.axis_neuron,
type_one_side=self.type_one_side,
seed=21,
precision="float32",
tebd_input_mode="strip",
temperature=1.0,
attn_layer=0,
)

def test_tf_pt_consistent(
self,
):
with tf.Session(config=default_tf_session_config) as sess:
graph = tf.get_default_graph()
ret = build_eval_tf(
sess,
self.se_a_tf,
self.natoms,
self.coords,
self.atype,
self.box,
self.suffix,
)
output_graph_def = tf.graph_util.convert_variables_to_constants(
sess,
graph.as_graph_def(),
[f"o_{ii}_{self.suffix}" for ii, _ in enumerate(ret)]
+ ["descrpt_attr/ntypes"],
)
with tf.Graph().as_default() as new_graph:
tf.import_graph_def(output_graph_def, name="")
self.se_a_tf.init_variables(
new_graph,
output_graph_def,
suffix=self.suffix,
)
self.se_a_tf.enable_compression(
1.0,
new_graph,
output_graph_def,
suffix=self.suffix,
)


if __name__ == "__main__":
unittest.main()