From 772c2dcadba9e8b0d128e84418a8f9657fbe213e Mon Sep 17 00:00:00 2001 From: Han Wang Date: Fri, 14 May 2021 15:29:43 +0800 Subject: [PATCH 1/2] support converting models to 2.0 compatibility --- source/train/CMakeLists.txt | 2 +- source/train/convert_to.py | 61 +++++++++++++++++++++++++++++++++++++ source/train/main.py | 15 +++++++++ 3 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 source/train/convert_to.py diff --git a/source/train/CMakeLists.txt b/source/train/CMakeLists.txt index 34363a6826..3e678993a8 100644 --- a/source/train/CMakeLists.txt +++ b/source/train/CMakeLists.txt @@ -2,7 +2,7 @@ configure_file("RunOptions.py.in" "${CMAKE_CURRENT_BINARY_DIR}/RunOptions.py" @ONLY) -file(GLOB LIB_PY main.py common.py env.py compat.py calculator.py Network.py Deep*.py Data.py DataSystem.py Model*.py Descrpt*.py Fitting.py Loss.py LearningRate.py Trainer.py TabInter.py EwaldRecp.py DataModifier.py ${CMAKE_CURRENT_BINARY_DIR}/RunOptions.py transform.py argcheck.py doc.py) +file(GLOB LIB_PY main.py common.py env.py compat.py calculator.py Network.py Deep*.py Data.py DataSystem.py Model*.py Descrpt*.py Fitting.py Loss.py LearningRate.py Trainer.py TabInter.py EwaldRecp.py DataModifier.py ${CMAKE_CURRENT_BINARY_DIR}/RunOptions.py transform.py argcheck.py doc.py convert_to.py) file(GLOB CLS_PY Local.py Slurm.py) diff --git a/source/train/convert_to.py b/source/train/convert_to.py new file mode 100644 index 0000000000..a08e487f9e --- /dev/null +++ b/source/train/convert_to.py @@ -0,0 +1,61 @@ +import os +from deepmd.env import tf +from google.protobuf import text_format +from tensorflow.python.platform import gfile +from tensorflow.python import pywrap_tensorflow +from tensorflow.python.framework import graph_util + +def convert_13_to_20(args): + convert_pb_to_pbtxt(args.input_model, 'frozen_model.pbtxt') + convert_dp13_to_dp20('frozen_model.pbtxt') + convert_pbtxt_to_pb('frozen_model.pbtxt', args.output_model) + if os.path.isfile('frozen_model.pbtxt'): + os.remove('frozen_model.pbtxt') + print("the converted output model(2.0 support) is saved in %s" % args.output_model) + +def convert_pb_to_pbtxt(pbfile, pbtxtfile): + with gfile.FastGFile(pbfile, 'rb') as f: + graph_def = tf.GraphDef() + graph_def.ParseFromString(f.read()) + tf.import_graph_def(graph_def, name='') + tf.train.write_graph(graph_def, './', pbtxtfile, as_text=True) + +def convert_pbtxt_to_pb(pbtxtfile, pbfile): + with tf.gfile.FastGFile(pbtxtfile, 'r') as f: + graph_def = tf.GraphDef() + file_content = f.read() + # Merges the human-readable string in `file_content` into `graph_def`. + text_format.Merge(file_content, graph_def) + tf.train.write_graph(graph_def, './', pbfile, as_text=False) + +def convert_dp13_to_dp20(fname): + with open(fname) as fp: + file_content = fp.read() + file_content += """ +node { + name: "model_attr/model_version" + op: "Const" + attr { + key: "dtype" + value { + type: DT_STRING + } + } + attr { + key: "value" + value { + tensor { + dtype: DT_STRING + tensor_shape { + } + string_val: "1.0" + } + } + } +} +""" + file_content = file_content\ + .replace('DescrptSeA', 'ProdEnvMatA')\ + .replace('DescrptSeR', 'ProdEnvMatR') + with open(fname, 'w') as fp: + fp.write(file_content) diff --git a/source/train/main.py b/source/train/main.py index 8cb039bc0e..c9675b63f7 100644 --- a/source/train/main.py +++ b/source/train/main.py @@ -6,6 +6,7 @@ from .test import test from .transform import transform from .doc import doc_train_input +from .convert_to import convert_13_to_20 def main () : parser = argparse.ArgumentParser( @@ -61,6 +62,15 @@ def main () : parser_tst.add_argument("-d", "--detail-file", type=str, help="The file containing details of energy force and virial accuracy") + parser_transform = subparsers.add_parser('convert-to', help='convert dp-1.3 model to higher model compatibility') + parser_transform.add_argument('TO', type = str, + choices = ['2.0'], + help="The target model compatibility") + parser_transform.add_argument('-i', "--input-model", default = "frozen_model.pb", type=str, + help = "the input dp-1.3 model") + parser_transform.add_argument("-o","--output-model", default = "convert_out.pb", type=str, + help='the output model') + parser_train = subparsers.add_parser('doc-train-input', help='print the documentation (in rst format) of input training parameters.') @@ -79,6 +89,11 @@ def main () : test(args) elif args.command == 'transform' : transform(args) + elif args.command == 'convert-to' : + if args.TO == '2.0': + convert_13_to_20(args) + else: + raise RuntimeError('unsupported model compatibility ' + args.TO) elif args.command == 'doc-train-input' : doc_train_input(args) else : From 01e5f5747bbaf29cd5ffad4d6714271018421b84 Mon Sep 17 00:00:00 2001 From: Han Wang Date: Fri, 27 Aug 2021 11:07:28 +0800 Subject: [PATCH 2/2] add doc for model conversion --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 2ce48317fd..960dff3143 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,11 @@ When the version of DeePMD-kit used to training model is different from the that DeePMD-kit guarantees that the codes with the same major and minor revisions are compatible. That is to say v0.12.5 is compatible to v0.12.0, but is not compatible to v0.11.0 nor v1.0.0. +One can convert the model trained with DeePMD-kit v1.3 to v2 compatible by using the command +```shell +dp convert-to 2.0 -i frozen_model.pb -o frozen_model_2.0.pb +``` + ## Installation: inadequate versions of gcc/g++ Sometimes you may use a gcc/g++ of version <4.9. If you have a gcc/g++ of version > 4.9, say, 7.2.0, you may choose to use it by doing ```bash