欢迎来到DeepModeling教程!

大家好,这里是DeepModeling项目的教程。

使用DeePMD-Kit

本教程告诉你如何使用DeePMD-kit,详细的信息,你可以查看DeePMD-kit文档(https://docs.deepmodeling.org/projects/deepmd/en/latest/)。

简介

在过去的几十年时间里,分子动力学(MD)模拟方法因为在凝聚态物理、材料科学、高分子化学和分子生物学等领域的广泛应用而受到了越来越多的关注。这种模拟手段为研究人员提供了观测原子或分子的运动行为的途径,对于拓宽我们的认知边界意义重大,尤其是在一些实验研究开展难度大、成本高甚至无法进行的情况下。

众所周知,MD模拟的质量取决于势能面的准确性,如何精确表示势能面是分子动力学模拟中极其重要的问题。经验原子间势函数模型与量子力学模型是长期以来最为常用的两种方法,经验原子间势函数模型由低维数项组成,通常计算效率高但精度受限。量子力学模型通过近似求解电子结构的薛定谔方程来计算原子的受力和能量,具有非常高的精度。然而,量子力学模型的计算要求非常高,很难应用于大规模或长时间的计算。总而言之,如何在高计算效率的经验原子间势函数模型和高计算精度的量子力学模型中做出取舍是研究人员面临的困境。

最近,机器学习(ML)模型的出现为解决这个难题提供了有力工具。描述符和ML算法是ML模型的两个主要组成部分。描述符用于保证结构的原有对称性,ML算法基于量子力学产生的数据进行训练,从而建立原子结构与体系能量之间的函数关系。训练完成后,ML模型能给出与训练数据相同等级的量子力学精度,即,如果训练数据是由密度泛函理论(DFT)计算得出,那么ML模型也会是DFT的精度。同时,DFT的计算量随着研究体系增大呈三次方增长,而ML模型的计算量只与体系大小呈线性关系。

到目前为止,文献已经报道了多种ML模型,例如Behler-Parrinello neural network potentials(BPNNP)[1], Gaussian approximation potentials(GAP)[2], spectral neighbor analysis potentials(SNAP)[3], ANI-1[4], SchNet[5] and Deep Potential[6,7,8]。值得一提的是,尽管已取得了较大成功,但ML模型仍面临很多极具挑战性的问题亟待解决[9],例如忽略截断半径外的相互作用导致的系统性预测误差[10]等。

本教程将重点介绍DP模型,除了媲美于量子力学的精度外,目前的DP模型还具有以下特点:(1)易于保持体系的对称性,尤其是当体系存在多种元素时;(2)计算效率高,比DFT至少快五个数量级;(3)端到端模型,减少人为干预的可能;(4)支持MPI和GPU,能够在现代异构高性能超级计算机上高效运行。基于以上优势,DP模型已经成功地应用于水和含水体系[11,12,13,14],金属和合金[15,16,17,18],相图[19,20,21],高熵陶瓷[22,23],化学反应[24,25,26],固态电解质[27],离子液体[28]等研究领域。关于DP在材料领域方面的近期研究,可以参考最近的综述[29]

翻译:区展鹏 校对:方满娣

简易安装

DeePMD-kit有很多简单的安装方式,你可以按需选择。

完成安装流程后,文件中会出现两个已经编译好的程序:DeePMD-kit(dp)和LAMMPS(lmp),你可以输入dp -hlmp -h来获取帮助信息。考虑到并行训练模型和运行LAMMPS的需求,mpirun也将同时被编译。

  • 安装离线软件包

  • 使用conda安装

  • 使用docker安装

利用离线软件包安装

CPU和GPU版本的离线软件包都在可以the Releases page中找到。

由于Github对文件大小的限制,部分安装包被拆分成两个文件,你可以在下载之后进行合并操作。

cat deepmd-kit-2.0.0-cuda11.3_gpu-Linux-x86_64.sh.0 deepmd-kit-2.0.0-cuda11.3_gpu-Linux-x86_64.sh.1 > 
deepmd-kit-2.0.0-cuda11.3_gpu-Linux-x86_64.sh

利用conda安装

DeePMD-kit可以利用Conda安装,首先需要安装AnacondaMiniconda

安装Anaconda或Miniconda之后,你可以创建一个包含CPU版本的DeePMD-kit和LAMMPS的虚拟环境:

conda create -n deepmd deepmd-kit=*=*cpu libdeepmd=*=*cpu lammps-dp -c https://conda.deepmodeling.org

或者创建一个同时包含CUDA Toolkit的GPU虚拟环境:

conda create -n deepmd deepmd-kit=*=*gpu libdeepmd=*=*gpu lammps-dp cudatoolkit=11.3 horovod -c https://conda.deepmodeling.org

CUDA Toolkit版本可以按需从10.1或11.3中选择。

安装指定版本的DeePMD-kit,例如2.0.0:

conda create -n deepmd deepmd-kit=2.0.0=*cpu libdeepmd=2.0.0=*cpu lammps-dp=2.0.0 horovod -c https://conda.deepmodeling.org

创建虚拟环境后,每次使用前需要激活环境:

conda activate deepmd

利用docker安装

DeePMD-kit同样可以通过docker安装。

获取CPU版本:

docker pull ghcr.io/deepmodeling/deepmd-kit:2.0.0_cpu

获取GPU版本:

docker pull ghcr.io/deepmodeling/deepmd-kit:2.0.0_cuda10.1_gpu

获取ROCm版本:

docker pull deepmodeling/dpmdkit-rocm:dp2.0.3-rocm4.5.2-tf2.6-lmp29Sep2021

如果你想从源码开始安装DeePMD-kit,请点此处

翻译:区展鹏 校对:方满娣

理论

在介绍DP具体方法之前, 我们首先定义一个 原子系统的坐标矩阵

表示原子 的三维笛卡尔坐标。此外,我们将坐标矩阵 转换成局域坐标矩阵 ,

其中 是原子 在截断半径内近邻原子的编号, 表示原子 的近邻原子编号, 表示的是原子 和原子 之间的相对距离。

在DP方法中, 一个系统的总能量 等于各个原子的局域能量的总和

其中 是原子 的局域能量. 此外, 取决于原子 的局域环境:

可以通过以下两个步骤得到 的映射:第一步,如图figure 所示,通过将 要映射到特征矩阵,或者说描述子 ,这里的 保留了体系的平移、旋转和置换不变性。具体来说, 首先被映射到一个扩展矩阵

其中 , , . 是一个权重函数,用来减少离原子 比较远的原子的权重, 定义如下:

其中 是原子 和原子 之间的欧式距离, 是“平滑截断半径”。引入 之后, 里的各个参数会从 平滑地趋于零。 接着 , 也就是 的第一列通过一个嵌入神经网络得到一个嵌入矩阵 . 选取 的前 列,我们就得到了另外一个嵌入矩阵 . 最后,我们就可以得到原子 的描述子

在描述子中, 平移和旋转不变性是由矩阵乘积 来保证的, 置换不变性是由矩阵乘积 来保证的。

第二步, 每一个描述子 都将通过一个拟合神经网络被映射到一个局域能量 上面。

嵌入神经网络 和拟合神经网络 都是包含很多隐藏层的前馈神经网络。 前一层的输入数据 通过一个线性运算和一个非线性的激活函数得到下一层的输入数据 .

在公式(8)中, 是权重参数, 是偏置参数, 是一个非线性的激活函数。需要注意的是,在最后一层的输出节点是没有非线性激活函数的。在嵌入网络和拟合网络中的参数由最小化代价函数 得到:

其中 , , 和 分别表示能量、力和维里的方均根误差 (RMSE) . 在训练的过程中, 前置因子 , , 和 由公式

决定,其中 分别表示在训练步数为 和训练步数为0 时的学习率。 的定义为

其中 分别表示学习衰减率以及衰减步数。学习衰减率 要严格小于1。 如果读者想要了解更多细节,可以查看文章DeepPot-SE.

翻译:范家豪 校对:杜云珍

如何在五分钟之内Setup一次DeepMD-kit训练

DeepMD-kit 是一款实现深度势能(Deep Potential)的软件。虽然网上已经有很多关于DeepMD-kit的资料和信息以及官方指导文档,但是对于小白用户仍不是很友好。今天,这篇教程将在五分钟内带你入门DeepMD-kit。

首先让我们先关注一下DeepMD-kit的训练流程:

数据准备->训练->冻结/压缩模型

是不是觉得很简单?让我们对这几个步骤作更深的阐述:

  1. 数据准备 : 将DFT的计算结果转化成DeepMD-kit能够识别的数据格式。

  2. 训练 : 使用前一步准备好的数据通过DeepMD-kit来训练一个深度势能模型(Deep Potential Model)

  3. 冻结/压缩模型 :最后我们需要做的就是冻结/压缩一个训练过程中输出的重启动文件来生成模型。相信你已经迫不及待想要上手试试啦!让我们开始吧!

下载数据

第一步,让我们下载和解压教程中提供给我们的数据:

$ wget https://dp-public.oss-cn-beijing.aliyuncs.com/community/DeePMD-kit-FastLearn.tar
$ tar xvf DeePMD-kit-FastLearn.tar

然后我们可以进入到下载好的数据目录检查一下 : 为不同的目的设置了三个目录:

  • 00.data:包含 VASP 结果 OUTCAR 的示例

  • 01.train:包含DeePMD-kit配置示例input.json

  • data:包含 DeePMD-kit 训练/验证数据的示例

$ cd DeePMD-kit-FastLearn
$ ls
00.data 01.train data

数据准备

现在让我们进入到00.data目录 :

$ cd 00.data
$ ls
OUTCAR

目录当中有一个VASP计算结果输出OUTCAR文件,我们需要将他转换成DeepMD-kit数据格式。DeepMD-kit数据格式在官方文档中有相应的介绍,但是看起来很复杂。别怕,这里将介绍一款数据转换神器dpdata,只用一行python命令就能处理好数据,是不是超级方便!

import dpdata
dpdata.LabeledSystem('OUTCAR').to('deepmd/npy', 'data', set_size=200)

在上面的命令中,我们将VASP计算结果输出文件OUTCAR转换成DeepMD-kit数据格式并保存在data目录当中,其中npy是指numpy压缩格式,也就是DeepMD-kit训练所用的数据格式。

假设你已经有了分子动力学输出“OUTCAR”文件,其中包含了1000帧。set_size=200将会将1000帧分成五个子集,每份200帧,分别命名为data/set.000~data/set.004。这五个子集中,data/set.000~data/set.003将会被DeepMD-kit用作训练集,data/set.004将会被用作测试集。如果设置set_size=1000,那么只有一个集合,这个集合既是训练集又是测试集(当然这个测试的参考意义就不大了)。

教程当中提供的OUTCAR只包含了一帧数据,所以在data目录(与OUTCAR在同一目录)当中将只会出现一个集合data/set.000。如果你想用对数据做一些其他的处理,更详细的信息请参考下一章。

我们将跳过更详细的处理步骤,接下来我们进入到根目录当中使用教程已经为你提供好的数据。

$ cd ..
$ ls
00.data 01.train data

训练

开始DeepMD-kit训练需要准备一个输入脚本,大家是不是还有没从被INCAR脚本支配的恐惧中走出来?别怕,配置DeepMD-kit比配置VASP简单多了。我们已经为你准备好了input.json,你可以在”01.train”目录当中找到它

$ cd 01.train
$ ls
input.json

DeepMD-kit的强大之处在于一样的训练参数可以适配不同的系统,所以我们只需要微调input.json来开始训练。首先需要修改的参数是 :

"type_map":     ["O", "H"],

DeepMD-kit中对每个原子类型是按从0开始的整数编号的。这个参数给了这样的编号系统中每个原子类型一个元素名。这里我们照写data/type_map.raw的内容就好。比如我们改成 :

"type_map":    ["A", "B","C"],

其次,我们修改一下近邻搜索参数 :

"sel":       [46, 92],

这个list中每个数给出了某原子的近邻原子中,各个类型的原子的最大数目。比如46就是类型为0,元素为O的近邻数最多有46个。这里我们换成了ABC,这个参数我们要相应的修改。不知道最大近邻数怎么办?可以用体系的密度粗略估计一个。或者可以盲试一个数,如果不够大DeepMD-kit会在WARNINGS中告诉你的。下面我们改成了 :

"sel":       [64, 64, 64]

此外我们需要修改的参数是"training_data"中的"systems"

"training_data":{
     "systems":     ["../data/data_0/", "../data/data_1/", "../data/data_2/"],

以及"validation_data"

"validation_data":{
     "systems":     ["../data/data_3"],

这里我将稍微介绍一下data system的定义。DeepMD-kit认为,具有同样原子数,且原子类型相同的数据能够形成一个system。我们的数据是从一个分子动力学模拟生成的,当然满足这个条件,因此可以放到一个system中。dpdata也是这么帮我们做的。当数据无法放到一个system中时,就需要设multiple systems,写成一个list。

"systems": ["system1", "system2"]

最后我们还需要改另外一个参数 :

"numb_steps":   1000,

numb_steps表示的是深度学习的SGD方法训练多少步(这只是一个例子,你可以在实际使用当中设置更大的步数)。

配置脚本大功告成!训练开始。我们在当前目录下运行 :

dp train input.json

在训练的过程当中,我们可以通过观察输出文件lcurve.out来观察训练阶段误差的情况。其中第四列和第五列是能量的训练和测试误差,第六列和第七列是力的训练和测试误差。 ##1.4.4. 冻结/压缩模型 训练完成之后,我们可以通过如下指令来冻结模型 :

dp freeze -o graph.pb

其中-o可以给模型命名,默认的模型输出文件名是graph.pb。同样,我们可以通过以下指令来压缩模型。

dp compress -i graph.pb -o graph-compress.pb

以上,我们就获得了一个或好或坏的DP模型。对于模型的可靠性以及如何使用它,我将在下一章中详细介绍。

翻译:欧阳冠宇 校对:史国勇

上机教程(v2.0.3)

本教程将向您介绍 DeePMD-kit 的基本用法,以气相甲烷分子为例。 通常,DeePMD-kit 工作流程包含三个部分:数据准备、训练/冻结/压缩/测试和分子动力学。

DP 模型是使用 DeePMD-kit (v2.0.3) 生成的。 使用 dpdata (v0.2.5) 工具将训练数据转换为 DeePMD-kit 的格式。 需要注意,dpdata 仅适用于 Python 3.5 及更高版本。 MD 模拟使用与 DeePMD-kit 自带的 LAMMPS(29 Sep 2021)进行。 dpdata 和 DeePMD-kit 安装和执行的详细信息可以在DeepModeling 官方 GitHub 站点 中找到。 OVITO 用于 MD 轨迹的可视化。

下载并解压本教程所需的文件。

$ wget https://dp-public.oss-cn-beijing.aliyuncs.com/community/CH4.tar
$ tar xvf CH4.tar

本教程的文件夹结构是这样的:

$ ls
00.data 01.train 02.lmp

有3个文件夹

  1. 00.data 文件夹包含训练数据,

  2. 01.train 包含使用 DeePMD-kit 训练模型的示例脚本,

  3. 02.lmp 包含用于分子动力学模拟的 LAMMPS 示例脚本。

准备数据

DeePMD-kit的训练数据包含原子类型、模拟盒子、原子坐标、原子受力、系统能量和维里。 具有这些信息的分子系统的快照称为一帧。 一个System包含有许多具有相同原子数量和原子类型的帧。 例如,分子动力学轨迹可以转换为一个System,每个时间步长对应于系统中的一帧。

DeepPMD-kit 采用压缩数据格式。 所有的训练数据都应该首先转换成这种格式,然后才能被 DeePMD-kit 使用。 数据格式在 DeePMD-kit 手册中有详细说明,可查看DeePMD-kit 官方网站

我们提供了一个名为 dpdata 的便捷工具,用于将 VASP、Gaussian、Quantum-Espresso、ABACUS 和 LAMMPS 生成的数据转换DeePMD-kit 的压缩格式。

例如,进入数据文件夹:

 $ cd 00.data
 $ ls 
OUTCAR

这里的OUTCAR 是通过使用 VASP 对气相甲烷分子进行从头算分子动力学 (AIMD) 模拟产生的。 现在进入python环境,例如

$ python

然后执行如下命令:

import dpdata 
import numpy as np
data = dpdata.LabeledSystem('OUTCAR', fmt = 'vasp/outcar') 
print('# the data contains %d frames' % len(data))

在屏幕上,我们可以看到 OUTCAR 文件包含 200 帧数据。 我们随机选取 40 帧作为验证数据,其余的作为训练数据。

index_validation = np.random.choice(200,size=40,replace=False)
index_training = list(set(range(200))-set(index_validation))
data_training = data.sub_system(index_training)
data_validation = data.sub_system(index_validation)
data_training.to_deepmd_npy('training_data')
data_validation.to_deepmd_npy('validation_data')
print('# the training data contains %d frames' % len(data_training)) 
print('# the validation data contains %d frames' % len(data_validation)) 

上述命令将OUTCAR(格式为VASP/OUTCAR)导入数据系统,然后将其转换为压缩格式(numpy数组)。DeePMD-kit 格式的数据存放在00.data文件夹里

$ ls training_data
set.000 type.raw type_map.raw
  1. set.000:是一个目录,包含压缩格式的数据(numpy压缩数组)。

  2. type.raw:是一个文件,包含原子的类型(以整数表示)。

  3. type_map.raw:是一个文件,包含原子的类型名称。

$ cat training_data/type.raw 
0 0 0 0 1

由于系统中的所有帧都具有相同的原子类型和原子序号,因此我们只需为整个系统指定一次类型信息。

$ cat training_data/type_map.raw 
H C

其中原子 H 被赋予类型 0,原子 C 被赋予类型 1。

训练

准备输入脚本

一旦数据准备完成,接下来就可以进行训练。进入训练目录:

$ cd ../01.train
$ ls 
input.json

其中 input.json 提供了一个示例训练脚本。 这些选项在DeePMD-kit手册中有详细的解释,所以这里不做详细介绍。

在model模块, 指定嵌入和你和网络的参数。

    "model":{
    "type_map":    ["H", "C"],                           # the name of each type of atom
    "descriptor":{
        "type":            "se_e2_a",                    # full relative coordinates are used
        "rcut":            6.00,                         # cut-off radius
        "rcut_smth":       0.50,                         # where the smoothing starts
        "sel":             [4, 1],                       # the maximum number of type i atoms in the cut-off radius
        "neuron":          [10, 20, 40],                 # size of the embedding neural network
        "resnet_dt":       false,
        "axis_neuron":     4,                            # the size of the submatrix of G (embedding matrix)
        "seed":            1,
        "_comment":        "that's all"
    },
    "fitting_net":{
        "neuron":          [100, 100, 100],              # size of the fitting neural network
        "resnet_dt":       true,
        "seed":            1,
        "_comment":        "that's all"
    },
    "_comment":    "that's all"'
},

描述符se_e2_a用于DP模型的训练。将嵌入和拟合神经网络的大小分别设置为 [10, 20, 40] 和 [100, 100, 100]。 里的成分会从0.5到6Å平滑地趋于0。

下面的参数指定学习效率和损失函数:

    "learning_rate" :{
        "type":                "exp",
        "decay_steps":         5000,
        "start_lr":            0.001,    
        "stop_lr":             3.51e-8,
        "_comment":            "that's all"
    },
    "loss" :{
        "type":                "ener",
        "start_pref_e":        0.02,
        "limit_pref_e":        1,
        "start_pref_f":        1000,
        "limit_pref_f":        1,
        "start_pref_v":        0,
        "limit_pref_v":        0,
        "_comment":            "that's all"
    },

在损失函数中, pref_e从0.02 逐渐增加到1 , and pref_f从1000逐渐减小到1 ,这意味着力项在开始时占主导地位,而能量项和维里项在结束时变得重要。 这种策略非常有效,并且减少了总训练时间。 pref_v 设为0 , 这表明训练过程中不包含任何维里数据。将起始学习率、停止学习率和衰减步长分别设置为0.001,3.51e-8,和5000。模型训练步数为

训练参数如下:

    "training" : {
        "training_data": {
            "systems":            ["../00.data/training_data"],		
            "batch_size":         "auto",                       
            "_comment":           "that's all"
        },
        "validation_data":{
            "systems":            ["../00.data/validation_data/"],
            "batch_size":         "auto",				
            "numb_btch":          1,
            "_comment":           "that's all"
        },
        "numb_steps":             100000,				            
        "seed":                   10,
        "disp_file":              "lcurve.out",
        "disp_freq":              1000,
        "save_freq":              10000,
    },
模型训练

准备好训练脚本后,我们可以用DeePMD-kit开始训练,只需运行

$ dp train input.json

在屏幕上,可以看到数据系统的信息

DEEPMD INFO      ----------------------------------------------------------------------------------------------------
DEEPMD INFO      ---Summary of DataSystem: training     -------------------------------------------------------------
DEEPMD INFO      found 1 system(s):
DEEPMD INFO                              system        natoms        bch_sz        n_bch          prob        pbc
DEEPMD INFO           ../00.data/training_data/             5             7           22         1.000          T
DEEPMD INFO      -----------------------------------------------------------------------------------------------------
DEEPMD INFO      ---Summary of DataSystem: validation   --------------------------------------------------------------
DEEPMD INFO      found 1 system(s):
DEEPMD INFO                               system       natoms        bch_sz        n_bch          prob        pbc
DEEPMD INFO          ../00.data/validation_data/            5             7            5         1.000          T

以及本次训练的开始和最终学习率

DEEPMD INFO      start training at lr 1.00e-03 (== 1.00e-03), decay_step 5000, decay_rate 0.950006, final lr will be 3.51e-08

如果一切正常,将在屏幕上看到每 1000 步打印一次的信息,例如

DEEPMD INFO    batch    1000 training time 7.61 s, testing time 0.01 s
DEEPMD INFO    batch    2000 training time 6.46 s, testing time 0.01 s
DEEPMD INFO    batch    3000 training time 6.50 s, testing time 0.01 s
DEEPMD INFO    batch    4000 training time 6.44 s, testing time 0.01 s
DEEPMD INFO    batch    5000 training time 6.49 s, testing time 0.01 s
DEEPMD INFO    batch    6000 training time 6.46 s, testing time 0.01 s
DEEPMD INFO    batch    7000 training time 6.24 s, testing time 0.01 s
DEEPMD INFO    batch    8000 training time 6.39 s, testing time 0.01 s
DEEPMD INFO    batch    9000 training time 6.72 s, testing time 0.01 s
DEEPMD INFO    batch   10000 training time 6.41 s, testing time 0.01 s
DEEPMD INFO    saved checkpoint model.ckpt

在第 10000 步结束时,模型保存在 TensorFlow 的检查点文件 model.ckpt 中。 同时,训练和测试错误显示在文件 lcurve.out 中。

$ head -n 2 lcurve.out
#step       rmse_val       rmse_trn       rmse_e_val       rmse_e_trn       rmse_f_val       rmse_f_trn           lr
0           1.34e+01       1.47e+01         7.05e-01         7.05e-01         4.22e-01         4.65e-01     1.00e-03

$ tail -n 2 lcurve.out
999000      1.24e-01       1.12e-01         5.93e-04         8.15e-04         1.22e-01         1.10e-01      3.7e-08
1000000     1.31e-01       1.04e-01         3.52e-04         7.74e-04         1.29e-01         1.02e-01      3.5e-08

第 4、5 和 6、7 卷分别介绍了能量和力量训练和测试错误。 证明经过 1000,000 步训练,能量测试误差小于 1 meV,力测试误差在 120 meV/Å左右。还观察到,力测试误差系统地(稍微)大于训练误差,这意味着对相当小的数据集有轻微的过度拟合。

可以通过简单的Python脚本对该文件进行可视化

import numpy as np
import matplotlib.pyplot as plt

data = np.genfromtxt("lcurve.out", names=True)
for name in data.dtype.names[1:-1]:
    plt.plot(data['step'], data[name], label=name)
plt.legend()
plt.xlabel('Step')
plt.ylabel('Loss')
plt.xscale('symlog')
plt.yscale('log')
plt.grid()
plt.show()

当训练过程异常停止时,我们可以从提供的检查点重新开始训练,只需运行

$ dp train  --restart model.ckpt  input.json

在 lcurve.out 中,可以看到训练和测试错误,例如

538000      3.12e-01       2.16e-01         6.84e-04         7.52e-04         1.38e-01         9.52e-02      4.1e-06
538000      3.12e-01       2.16e-01         6.84e-04         7.52e-04         1.38e-01         9.52e-02      4.1e-06
539000      3.37e-01       2.61e-01         7.08e-04         3.38e-04         1.49e-01         1.15e-01      4.1e-06
 #step      rmse_val       rmse_trn       rmse_e_val       rmse_e_trn       rmse_f_val       rmse_f_trn           lr
530000      2.89e-01       2.15e-01         6.36e-04         5.18e-04         1.25e-01         9.31e-02      4.4e-06
531000      3.46e-01       3.26e-01         4.62e-04         6.73e-04         1.49e-01         1.41e-01      4.4e-06

需要注意的是 input.json 需要和上一个保持一致。

冻结和压缩模型

在训练结束时,保存在 TensorFlow 的 checkpoint 文件中的模型参数通常需要冻结为一个以扩展名 .pb 结尾的模型文件。 只需执行

$ dp freeze -o graph.pb
DEEPMD INFO    Restoring parameters from ./model.ckpt-1000000
DEEPMD INFO    1264 ops in the final graph

它将在当前目录中输出一个名为 graph.pb 的模型文件。 压缩 DP 模型通常会将基于 DP 的计算速度提高一个数量级,并且消耗更少的内存。 graph.pb 可以通过以下方式压缩:

$ dp compress -i graph.pb -o graph-compress.pb
DEEPMD INFO    stage 1: compress the model
DEEPMD INFO    built lr
DEEPMD INFO    built network
DEEPMD INFO    built training
DEEPMD INFO    initialize model from scratch
DEEPMD INFO    finished compressing
DEEPMD INFO    
DEEPMD INFO    stage 2: freeze the model
DEEPMD INFO    Restoring parameters from model-compression/model.ckpt
DEEPMD INFO    840 ops in the final graph

将输出一个名为graph-compress.pb 的模型文件。

模型测试

我们可以通过运行如下命令检查训练模型的质量

$ dp test -m graph-compress.pb -s ../00.data/validation_data -n 40 -d results

在屏幕上,可以看到验证数据的预测误差信息

DEEPMD INFO    # number of test data    : 40 
DEEPMD INFO    Energy RMSE              : 3.168050e-03 eV
DEEPMD INFO    Energy RMSE/Natoms       : 6.336099e-04 eV
DEEPMD INFO    Force  RMSE              : 1.267645e-01 eV/A
DEEPMD INFO    Virial RMSE              : 2.494163e-01 eV
DEEPMD INFO    Virial RMSE/Natoms       : 4.988326e-02 eV
DEEPMD INFO    # ----------------------------------------------- 

它将在当前目录中输出名为 results.e.out 和 results.f.out 的文件。

使用LAMMPS运行MD

现在让我们切换到02.lmp目录。

$ cd ../02.lmp

首先,我们将训练目录中的输出模型软链接到当前目录

$ ln -s ../01.train/graph-compress.pb

这里有三个文件

$ ls
conf.lmp  graph-compress.pb  in.lammps

其中 conf.lmp 给出了气相甲烷 MD 模拟的初始配置,文件 in.lammps 是LAMMPS输入脚本。 可以查看in.lammps,它与标准的用于MD模拟的LAMMPS输入脚本只有以下不同:

pair_style  graph-compress.pb
pair_coeff  * *

其中pair_style为deepmd graph-compress.pb,这意味着原子间相互作用将由名为graph-compress.pb的DP模型计算。

可以以标准方式执行

$ lmp  -i  in.lammps

稍等片刻,MD模拟结束,生成log.lammps和ch4.dump文件。 它们分别存储热力学信息和分子的轨迹,我们可以通过OVITO可视化轨迹检查分子构型的演变。

$ ovito ch4.dump

翻译:史国勇 校对:欧阳冠宇

Using DP-GEN

本教程告诉你如何使用DP-GEN,详细的信息,你可以查看 DP-GEN文档 <https://docs.deepmodeling.org/projects/dpgen/en/latest/>

DP-GEN上机教程(v0.10.3)

DP-GEN简介

Deep Potential GENerator (DP-GEN)是一个通过实施“同步学习”方案生成可靠的DP模型的软件包。DP-GEN的工作流程通常包括三个过程:run,init和auto-test。

  • init:通过第一性原理计算产生初始训练数据集。

  • run:DP-GEN的主要流程,在这个阶段可以实现训练数据集的自动扩充和DP模型的质量提高。

  • auto-test:计算一组简单的性质和/或执行测试以与 DFT 和/或经验原子间势函数进行比较。

本上机教程旨在帮助您快速掌握DP-GEN的run过程。

输入文件

在本教程中,我们以气相的甲烷分子作为例子。我们准备的DP-GEN run过程的输入文件位于dpgen_example/run。首先下载并解压dpgen_example:

wget https://dp-public.oss-cn-beijing.aliyuncs.com/community/dpgen_example.tar.xz
tar xvf dpgen_example.tar.xz

进入并查看dpgen_example/run。

$ cd dpgen_example/run
$ ls
INCAR_methane  machine.json  param.json  POTCAR_C  POTCAR_H
  • param.json是当前DP-GEN run过程的设置。

  • machine.json是设置机器环境和资源要求的任务调度器。machine.json会在别处单独介绍。

  • INCAR和POTCAR是VASP软件的INCAR和POTCAR输入文件。

Run过程

DP-GEN的run过程包含一系列连续的迭代。每一次迭代均包含三步:探索,标记和训练。相对应地,每次迭代会产生三个子文件夹:00.train, 01.model_devi 和 02.fp。 param.json 我们提供了一个param.json的示例。

{
     "type_map": ["H","C"],
     "mass_map": [1,12],
     "init_data_prefix": "../",
     "init_data_sys": ["init/CH4.POSCAR.01x01x01/02.md/sys-0004-0001/deepmd"],
     "sys_configs_prefix": "../",
     "sys_configs": [
         ["init/CH4.POSCAR.01x01x01/01.scale_pert/sys-0004-0001/scale-1.000/00000*/POSCAR"],
         ["init/CH4.POSCAR.01x01x01/01.scale_pert/sys-0004-0001/scale-1.000/00001*/POSCAR"]
     ],
     "_comment": " that's all ",
     "numb_models": 4,
     "default_training_param": {
         "model": {
             "type_map": ["H","C"],
             "descriptor": {
                 "type": "se_a",
                 "sel": [16,4],
                 "rcut_smth": 0.5,
                 "rcut": 5.0,
                 "neuron": [120,120,120],
                 "resnet_dt": true,
                 "axis_neuron": 12,
                 "seed": 1
             },
             "fitting_net": {
                 "neuron": [25,50,100],
                 "resnet_dt": false,
                 "seed": 1
             }
         },
         "learning_rate": {
             "type": "exp",
             "start_lr": 0.001,
             "decay_steps": 5000
         },
         "loss": {
             "start_pref_e": 0.02,
             "limit_pref_e": 2,
             "start_pref_f": 1000,
             "limit_pref_f": 1,
             "start_pref_v": 0.0,
             "limit_pref_v": 0.0
         },
         "training": {
             "stop_batch": 400000,
             "disp_file": "lcurve.out",
             "disp_freq": 1000,
             "numb_test": 4,
             "save_freq": 1000,
             "save_ckpt": "model.ckpt",
             "disp_training": true,
             "time_training": true,
             "profiling": false,
             "profiling_file": "timeline.json",
             "_comment": "that's all"
         }
     },
     "model_devi_dt": 0.002,
     "model_devi_skip": 0,
     "model_devi_f_trust_lo": 0.05,
     "model_devi_f_trust_hi": 0.15,
     "model_devi_e_trust_lo": 10000000000.0,
     "model_devi_e_trust_hi": 10000000000.0,
     "model_devi_clean_traj": true,
     "model_devi_jobs": [
         {"sys_idx": [0],"temps": [100],"press": [1.0],"trj_freq": 10,"nsteps": 300,"ensemble": "nvt","_idx": "00"},
         {"sys_idx": [1],"temps": [100],"press": [1.0],"trj_freq": 10,"nsteps": 3000,"ensemble": "nvt","_idx": "01"}
     ],
     "fp_style": "vasp",
     "shuffle_poscar": false,
     "fp_task_max": 20,
     "fp_task_min": 5,
     "fp_pp_path": "./",
     "fp_pp_files": ["POTCAR_H","POTCAR_C"],
     "fp_incar": "./INCAR_methane"
}

以下是关键词的详细说明。 基础关键词 (第 2-3 行): | 关键词 | 类型 | 说明 | |————-|—————–|————————-| | “type_map” | 字符串列表 | 原子类型 | | “mass_map” | 浮点数列表 | 相对原子质量 |

数据相关的关键词 (第 4-10 行): | 关键词 | 类型 | 说明 | |———————–|—————–|————————————————————————————————————-| | “init_data_prefix” | 字符串 | 初始数据目录的前缀 | | “init_data_sys” | 字符串列表 | 初始数据的目录。您可以在此处使用绝对路径或相对路径。 | | “sys_configs_prefix” | 字符串 | sys_configs的前缀 | | “sys_configs” | 字符串列表 | 包含应在迭代中探索的结构的目录。此处支持通配符。 |

训练相关的关键词 (第 12-58 行): | 关键词 | 类型 | 说明 | |—————————|———-|———————————————-| | “numb_models” | 整数 | 在 00.train 阶段训练的目标模型个数。 | | “default_training_param” | 字典 | deepmd-kit的训练参数。 |

探索相关的关键词 (第 59-69 行): | 关键词 | 类型 | 说明 | |————————–|————————-|———————————————————————————————————————————————————————————————————————————————–| | “model_devi_dt” | 浮点数 | MD的时间步长 | | “model_devi_skip” | 整数 | 从每次 MD 中跳过指定数量的结构后进行 fp 计算 | | “model_devi_f_trust_lo” | 浮点数 | 力筛选标准的下限。如果是列表,应该为sys_configs中的每个索引分别设置。 | | “model_devi_f_trust_hi” | 整数 | 力筛选标准的上限。如果是列表,应该为sys_configs中的每个索引分别设置。 | | “model_devi_e_trust_lo” | 浮点数或浮点数列表 | 维里力筛选标准的下限。如果是列表,应该为sys_configs中的每个索引分别设置。应与 DeePMD-kit v2.x 一起使用。 | | “model_devi_e_trust_hi” | 浮点数或浮点数列表 | 维里力筛选标准的上限。如果是列表,应该为sys_configs中的每个索引分别设置。应与 DeePMD-kit v2.x 一起使用。 | | “model_devi_clean_traj” | 布尔数或整数 | 如果是布尔数,代表是否清除MD轨迹文件。如果是整数,将保留最近 n 次迭代的轨迹文件并删除其他文件。 | | “model_devi_jobs” | 字典列表 | 为 01.model_devi 的探索阶段设置。列表中每个字典对应一次迭代。model_devi_jobs的索引与迭代的索引一致。 |

标记相关的关键词 (第 70-76 行): | 关键词 | 类型 | 说明 | |——————-|—————–|————————————————————————————————————————–| | “fp_style” | 字符串 | 第一性原例计算的软件。目前可选择的软件包括 “vasp”, “pwscf”, “siesta” 和 “gaussian”。 | | “shuffle_poscar” | 布尔数 | 是否对poscar进行混洗 | | “fp_task_max” | 整数 | 02.fp 中每次迭代计算的最大结构数量。 | | “fp_task_min” | 整数 | 02.fp 中每次迭代计算的最小结构数量。 | | “fp_pp_path” | 字符串 | 用于 02.fp 的赝势文件的目录路径。 | | “fp_pp_files” | 字符串列表 | 02.fp 中使用的赝势文件。注意元素顺序应与 type.map 一致。 | | “fp_incar” | 字符串 | VASP 的输入文件。INCAR中必须指定 KSPACING 和 KGAMMA。 |

输出文件

在配置好machine.json之后,我们可以通过以下指令简单运行DP-GEN的run过程:

$ dpgen run param.json machine.json

在dpgen_example/run中,可以发现自动生成了一个文件夹和两个文件。

$ ls 
dpgen.log  INCAR_methane  iter.000000  machine.json  param.json  record.dpgen 
  • iter.000000包含DP-GEN run过程中第一次迭代的主要结果。

  • record.dpgen记录run过程的当前阶段。

  • dpgen.log包括时间和迭代信息。

第一次迭代完成后,iter.000000 的文件夹结构如下:

$ tree iter.000000/ -L 1
./iter.000000/
├── 00.train
├── 01.model_devi
└── 02.fp
00.train

首先,我们查看iter.000000/00.train目录。

$ tree iter.000000/00.train -L 1
./iter.000000/00.train/
├── 000
├── 001
├── 002
├── 003
├── data.init -> /root/dpgen_example
├── data.iters
├── graph.000.pb -> 000/frozen_model.pb
├── graph.001.pb -> 001/frozen_model.pb
├── graph.002.pb -> 002/frozen_model.pb
└── graph.003.pb -> 003/frozen_model.pb
  • 文件夹00x包含DeePMD-kit的输入输出文件,在这个文件夹中训练了一个完整的模型。

  • graph.00x.pb是00x/frozen.pb的链接,是DeePMD-kit生成的模型。这些模型之间的唯一区别是神经网络初始化的随机种子。 我们可以随机选择其中之一,如000。

$ tree iter.000000/00.train/000 -L 1
./iter.000000/00.train/000
├── checkpoint
├── frozen_model.pb
├── input.json
├── lcurve.out
├── model.ckpt-400000.data-00000-of-00001
├── model.ckpt-400000.index
├── model.ckpt-400000.meta
├── model.ckpt.data-00000-of-00001
├── model.ckpt.index
├── model.ckpt.meta
└── train.log
  • input.json 是当前DeePMD-kit训练任务的设置。

  • checkpoint用于重启训练。

  • model.ckpt*是模型相关的文件。

  • frozen_model.pb是冻结的模型。

  • lcurve.out记录能量和力的训练精度。

  • train.log包含包括版本、数据、硬件信息、时间等。

01.model_devi

接下来,我们查看 iter.000000/01.model_devi目录。

$ tree iter.000000/01.model_devi -L 1
./iter.000000/01.model_devi/
├── confs
├── graph.000.pb -> /root/dpgen_example/run/iter.000000/00.train/graph.000.pb
├── graph.001.pb -> /root/dpgen_example/run/iter.000000/00.train/graph.001.pb
├── graph.002.pb -> /root/dpgen_example/run/iter.000000/00.train/graph.002.pb
├── graph.003.pb -> /root/dpgen_example/run/iter.000000/00.train/graph.003.pb
├── task.000.000000
├── task.000.000001
├── task.000.000002
├── task.000.000003
├── task.000.000004
├── task.000.000005
├── task.000.000006
├── task.000.000007
├── task.000.000008
└── task.000.000009
  • 文件夹confs包含LAMMPS MD的初始构型,该构型由param.json中“sys_configs”指定的POSCAR转换而来。

  • 文件夹 task.000.00000x 包含LAMMPS的输入输出文件。我们可以随机查看其中之一,如 task.000.000001。

$ tree iter.000000/01.model_devi/task.000.000001
./iter.000000/01.model_devi/task.000.000001
├── conf.lmp -> ../confs/000.0001.lmp
├── input.lammps
├── log.lammps
├── model_devi.log
└── model_devi.out
  • conf.lmp是confs文件夹中000.0001.lmp的链接,作为 MD 的初始构型。

  • input.lammps是LAMMPS的输入文件。

  • model_devi.out记录了MD中相关标签、能量和力的模型偏差。它可以作为挑选结构和进行第一性原理计算的标准。

通过 head model_devi.out,您会看到:

$ head -n 5 ./iter.000000/01.model_devi/task.000.000001/model_devi.out
 #  step max_devi_v     min_devi_v     avg_devi_v     max_devi_f     min_devi_f     avg_devi_f 
 0     1.438427e-04   5.689551e-05   1.083383e-04   8.835352e-04   5.806717e-04   7.098761e-04
10     3.887636e-03   9.377374e-04   2.577191e-03   2.880724e-02   1.329747e-02   1.895448e-02
20     7.723417e-04   2.276932e-04   4.340100e-04   3.151907e-03   2.430687e-03   2.727186e-03
30     4.962806e-03   4.943687e-04   2.925484e-03   5.866077e-02   1.719157e-02   3.011857e-02

现在我们关注max_devi_f。回想一下,我们已经设置了”trj_freq”为 10,所以每10步结构将会被保存一次。是否挑选出该结构取决于它的 “max_devi_f”。如果它位于”model_devi_f_trust_lo”(0.05) 和”model_devi_f_trust_hi”(0.15)之间,DP-GEN 会将该结构视为候选结构。这里只挑选20个结构,其 “max_devi_f”为 5.866077 e-02。

02.fp

最后,让我们查看iter.000000/ 02.fp目录。

$ tree iter.000000/02.fp -L 1
./iter.000000/02.fp
├── data.000
├── task.000.000000
├── task.000.000001
├── task.000.000002
├── task.000.000003
├── task.000.000004
├── task.000.000005
├── task.000.000006
├── task.000.000007
├── task.000.000008
├── task.000.000009
├── task.000.000010
├── task.000.000011
├── candidate.shuffled.000.out
├── POTCAR.000
├── rest_accurate.shuffled.000.out
└── rest_failed.shuffled.000.out
  • POTCAR.000 是根据param.json中”fp_pp_files”生成的VASP POTCAR文件。

  • candidate.shuffle.000.out记录了从上一步01.model_devi中挑选出的候选结构。候选者的数量往往远多于预期单次计算的最大值。在这种情况下DP-GEN将随机选择至多”fp_task_max”个结构并生成 task.*文件夹。

  • rest_accurate.shuffle.000.out记录准确预测的结构(”max_devi_f” 小于”model_devi_f_trust_lo”,这些结构无需进行进一步计算)。

  • rest_failed.shuffled.000.out 记录了预测失败的结构 (”max_devi_f” 大于”model_devi_f_trust_hi”,这些结构可能是非物理的)。

  • data.000: 在第一性原理计算之后,DP-GEN将收集这些数据并转化为DeePMD-kitPMD-kit支持的格式。在下一次迭代的 00.train 中,这些数据将与初始数据一起被训练。

通过 cat candidate.shuffled.000.out | grep task.000.000001,可以看到:

$ cat ./iter.000000/02.fp/candidate.shuffled.000.out | grep task.000.000001
iter.000000/01.model_devi/task.000.000001 190
iter.000000/01.model_devi/task.000.000001 130
iter.000000/01.model_devi/task.000.000001 120
iter.000000/01.model_devi/task.000.000001 150
iter.000000/01.model_devi/task.000.000001 280
iter.000000/01.model_devi/task.000.000001 110
iter.000000/01.model_devi/task.000.000001 30
iter.000000/01.model_devi/task.000.000001 230

task.000.000001 30 是我们在01.model_devi中发现的满足再次计算条件的结构。

第一次迭代之后,我们可以查看 dpgen.log和record.log 的内容。

$ cat dpgen.log
2022-03-07 22:12:45,447 - INFO : start running
2022-03-07 22:12:45,447 - INFO : =============================iter.000000==============================
2022-03-07 22:12:45,447 - INFO : -------------------------iter.000000 task 00--------------------------
2022-03-07 22:12:45,451 - INFO : -------------------------iter.000000 task 01--------------------------
2022-03-08 00:53:00,179 - INFO : -------------------------iter.000000 task 02--------------------------
2022-03-08 00:53:00,179 - INFO : -------------------------iter.000000 task 03--------------------------
2022-03-08 00:53:00,187 - INFO : -------------------------iter.000000 task 04--------------------------
2022-03-08 00:57:04,113 - INFO : -------------------------iter.000000 task 05--------------------------
2022-03-08 00:57:04,113 - INFO : -------------------------iter.000000 task 06--------------------------
2022-03-08 00:57:04,123 - INFO : system 000 candidate :     12 in    310   3.87 %
2022-03-08 00:57:04,125 - INFO : system 000 failed    :      0 in    310   0.00 %
2022-03-08 00:57:04,125 - INFO : system 000 accurate  :    298 in    310  96.13 %
2022-03-08 00:57:04,126 - INFO : system 000 accurate_ratio:   0.9613    thresholds: 1.0000 and 1.0000   eff. task min and max   -1   20   number of fp tasks:     12
2022-03-08 00:57:04,154 - INFO : -------------------------iter.000000 task 07--------------------------
2022-03-08 01:02:07,925 - INFO : -------------------------iter.000000 task 08--------------------------
2022-03-08 01:02:07,926 - INFO : failed tasks:      0 in     12    0.00 % 
2022-03-08 01:02:07,949 - INFO : failed frame:      0 in     12    0.00 % 

可以看出在 iter.000000 中有 310 个结构生成,其中12个结构被收集并用于第一性原理计算。

$ cat record.dpgen
0 0
0 1
0 2
0 3
0 4
0 5
0 6
0 7
0 8

每行包含两个数字:第一个是迭代的索引,第二个的范围从0到9,记录了当前正在运行的是每次迭代的哪个阶段。

| 迭代索引 | “单次迭代的阶段 “ | 过程 | |———————-|—————————–|——————| | 0 | 0 | make_train | | 0 | 1 | run_train | | 0 | 2 | post_train | | 0 | 3 | make_model_devi | | 0 | 4 | run_model_devi | | 0 | 5 | post_model_devi | | 0 | 6 | make_fp | | 0 | 7 | run_fp | | 0 | 8 | post_fp |

如果DP-GEN的run过程由于某种原因停止,DP-GEN可以根据record.dpgen恢复主进程。用户也可以根据自己的目的手动更改它,例如删除最后一次迭代并从某个checkpoint续算。

结果观察

在所有的迭代完成后,我们可以查看 dpgen_example/run 的架构

$ tree ./ -L 2
./
├── dpgen.log
├── INCAR_methane
├── iter.000000
│   ├── 00.train
│   ├── 01.model_devi
│   └── 02.fp
├── iter.000001
│   ├── 00.train
│   ├── 01.model_devi
│   └── 02.fp
├── iter.000002
│   └── 00.train
├── machine.json
├── param.json
└── record.dpgen

和 dpgen.log 的内容。

$ cat cat dpgen.log | grep system
2022-03-08 00:57:04,123 - INFO : system 000 candidate :     12 in    310   3.87 %
2022-03-08 00:57:04,125 - INFO : system 000 failed    :      0 in    310   0.00 %
2022-03-08 00:57:04,125 - INFO : system 000 accurate  :    298 in    310  96.13 %
2022-03-08 00:57:04,126 - INFO : system 000 accurate_ratio:   0.9613    thresholds: 1.0000 and 1.0000   eff. task min and max   -1   20   number of fp tasks:     12
2022-03-08 03:47:00,718 - INFO : system 001 candidate :      0 in   3010   0.00 %
2022-03-08 03:47:00,718 - INFO : system 001 failed    :      0 in   3010   0.00 %
2022-03-08 03:47:00,719 - INFO : system 001 accurate  :   3010 in   3010 100.00 %
2022-03-08 03:47:00,722 - INFO : system 001 accurate_ratio:   1.0000    thresholds: 1.0000 and 1.0000   eff. task min and max   -1    0   number of fp tasks:      0

可以发现在 iter.000001 生成了3010个结构,但没有新的结构被收集并用于第一性原理计算。因此,iter.000002/00.train 的最终模型不再更新。

翻译:方满娣 校对:梁文硕

Practical-Guidelines-for-DP

DP 实用指南

在开始一个新的 Deep Potential (DP) 项目之前,建议大家(尤其是新手)先阅读以下内容,以了解我们可以使用哪些工具、我们可能会遇到哪些问题和困难,以及我们如何顺利推进一个新的DP项目。本文的撰写重点是“局域构型空间”,这对于在处理DP项目时思考、分析和解决问题非常有用。本文分为三个主要部分:

  1. “了解你的工具箱” :从局域构型空间的视角,简要介绍了DP方法以及DP-GEN(Deep Potential GENerator)和DP Library(Deep Potential Library)。

  2. “了解系统的物理性质” :简单讨论了如何根据研究对象的属性设置参数,这可能对新手有所帮助。

  3. “了解问题的边界”:探讨如何以最有效的方式生成满足我们要求的DP模型,或者我们如何将项目切割成碎片并使项目更易于实施。


了解你的工具箱

了解你的工具箱意味着你不仅需要知道工具箱里有什么,这些工具可以用来做什么,还知道这种工具的局限性以及使用这些工具时可能会发生什么样的风险。

DP

深度势能 (DP) 是一种通过深度神经网络拟合原子间相互作用势(也叫势能面,potential energy surface, PES)的方法。训练数据集通常是由基于密度泛函理论(density functional theory, DFT)的方法计算获得。 相关软件是DeePMD-kit。DP方法通用性高、准确性高、计算效率高且并行效率高,是最受欢迎的机器学习势之一。 https://dp-public.oss-cn-beijing.aliyuncs.com/community-tutorial/DP.pngDP   与其他机器学习势类似,DP的核心思想是系统的总能量可以划分为单个原子的势能之和,$E=∑_{i=0}^{n}E_i$, 其中每个原子的势能 $E_i$ 取决于它的局域原子构型。每个原子都由一个DP深度神经网络模型来描述 $E_i$。DP 模型由两组神经网络组成。第一组是嵌入网络,被设计为满足基本的不变性(置换、平移、旋转)要求,并将原子的局域环境编码为描述符。第二个是拟合网络,它将嵌入网络的输出映射到 $E_i$. https://dp-public.oss-cn-beijing.aliyuncs.com/community-tutorial/DP_Illustration.pngDP_Illustration

构型空间

局域构型空间包括空间构型和化学构型。对于空间构型,以碳为例,可以结晶成石墨或金刚石。在石墨中,每个碳原子通过$\rm{sp}^2$键与其他三个碳原子相连 ,形成平面结构。在金刚石中, 每个碳原子通过 $\rm{sp}^3$ 键与其他四个碳相连。此外,碳还可以形成许多其他结构, 例如无定形结构,富勒烯等。除了局部原子结构的这些明显差异外,原子相对平衡位置的偏离也属于空间构型。对于化学构型,我们以理想的BCC晶格为例。在最简单的情况下,所有晶格位置都被同一个原子占据,例如Ti。另一种情况是四角被Ti占据,内中心被Al占据,是B2结构的有序TiAl化合物。因此,Ti周围的局域化学环境发生了变化。在更复杂的情况下,所有位点可能被不同的原子随机占据,例如高熵合金,可能导致巨大的化学构型空间。需要强调的是,这种划分为了便于理解做的概念性划分。实际上,空间构型和化学构型是耦合在一起的,不能明确分离开。

https://dp-public.oss-cn-beijing.aliyuncs.com/community-tutorial/Configuration.pngConfiguration

采样方法

综上所述,在开发新的DP模型时”我们所需要做的就是尽可能覆盖足够的局域构型空间”。这里介绍实践中常用的局域构型空间采样方法。粗略地,这些方法可以分为四类:手动设计、MD+MC模拟、结构搜索和增强采样。

  • 手动设计 尽管可以使用多种多样的方法来辅助采样,但手动设计仍然是最重要的采样方法之一,尤其是对于缺陷结构的采样。例如,间隙、空位、层错、位错、表面、晶界的初始结构几乎总是需要人为构建。在其他一些情况下,初始结构也需要由专家构建,例如不同材料之间的相界面、吸附结构等。

  • MD+MC模拟 MD和MC模拟是对局域构型空间进行采样的有效方法,也是最易实现的方法。例如,原子在固体中围绕平衡位置附近的振动(MD),液体中的局域环境的变化(MD),在固溶体中交换相似原子(MD+MC)等。MD/MC 模拟可以覆盖的构型空间取决于模拟的温度和时间。在实践中,也可以采用其他加速MD方法来更有效地辅助采样。

  • 结构搜索 结构搜索方法,例如CALYPSOUSPEX,有助于探索具有强方向键的材料的合理结构,(例如大多数陶瓷,以及一些其他无机非金属材料碳、硼、磷等) 或高压下的未知结构。在这种情况下,手动构建和MD+MC遍历能力不足。由于我们需要覆盖足够的构型空间,因此在结构搜索过程中,不仅需要收集稳态结构来丰富我们的数据集,还需要那些能量不是很高的亚稳态结构。 -增强采样 增强采样是一种对稀有事件进行采样的有效方法,通常用于对PES周围的鞍点进行采样。在一个系统中,构型被采样的概率是 $p \propto exp(-U/k_BT)$。因此,高能态,例如相变中间态、反应的过渡态,很难通过MD模拟进行采样。在增强采样方法中,通常会添加偏置势以使PES变平,从而增强高能态被访问的概率。

https://dp-public.oss-cn-beijing.aliyuncs.com/community-tutorial/Sampling_methods.pngSampling_methods

局限性和风险

由于机器学习模型有较好的表示和拟合能力,机器学习势比传统经验势更精确。但是,硬币总有正反面。几乎所有机器学习都有一个典型的缺点,即样本分布外的外推能力低。如下图所示,该模型在数据集覆盖的区域拟合得非常好,而在数据集未覆盖的区域预测了完全错误的结果。在这个例子中,由于靠近原子核区域缺乏排斥力,两个原子可能会非物理地结合在一起。通常,在采样期间,彼此靠得非常近的原子对是不在数据集中的。为了避免这种非物理结合,可以在这个区域人为地设计一些排斥势,或者在数据集中添加双原子构型,让模型自己学习近核排斥。 https://dp-public.oss-cn-beijing.aliyuncs.com/community-tutorial/Risks.pngRisks  这只是一个简单的例子来说明如果训练数据集在局域构型空间上的覆盖率很差,模拟中可能发生的非物理现象的风险。这里说明机器学习势的这种风险,并不是鼓励人们在训练DP模型时覆盖所有构型空间。相反,在“了解问题的边界”一节中,我们鼓励大家对研究问题所在的构型空间区域进行采样。这意味着训练一个对所研究问题足够准确的DP模型即可。理论上讲,在某些情况下,构型空间可能会太大而无法完全采样。所以, “训练一个全局可用的稳定DP模型并不是一件容易的事”。

DP-GEN

DP-GEN是“Deep Potential GENerator”的缩写,是在同步学习框架下设计的DP模型自动生成器。在DP-GEN中,数据集的增加和DP模型的改进是同时进行的。DP-GEN软件可以自动管理整个流程,包括准备作业脚本 (例如训练模型,探索构型空间、检查现有模型在构型空间的准确性并筛选出准确性不足的候选构型,以及通过DFT计算给候选构型打标签), 将作业提交到云计算或其他高性能计算集群上, 并监控工作状态。下图显示了一个典型的DP-GEN自动迭代流程,包括三个典型的过程:

  1. 训练一组DP模型(通常是四个),这些模型将被用来探索构型空间并检查探索的构型是否能够被准确预测。

  2. 采用其中一个DP模型探索构型空间,并通过比较不同DP模型之间的预测偏差来检查每个构型的预测精度。

  3. 选择一些预测精度较低的构型作为候选构型,并通过DFT计算给候选构型打标签。

最初,需要提供一个包含数百至数千个DFT计算获得的数据集(初始数据集),之后便可以启动并连续运行DP-GEN的自动迭代流程。初始数据集可以由DP-GEN软件生成 (例如通过使用”init_bulk”, “init_surf”模块,或者”autotest” 模块), 也可以自己生成。在DP-GEN迭代过程中,数据集对构型空间的覆盖范围是有限的,尤其是在前几轮迭代中。正如在“局限性和风险”一节中所讲,在此时数据集上训练的DP模型能力也是受限的。当构型在已探索区域内时,模型能够准确预测该构型;当构型稍微超出已探索区域的边界时,预测结果准确性不足;当构型远离已探索区域时,预测则是错误的。此外,当使用DP模型探索构型空间时(例如通过MD),当构型远离已探索区域时,可能会出现非物理构型。为了避免选择非物理构型,只选择已探索区域边界附近的那些构型作为候选。因此,选择候选构型时需要设置预测偏差的上下限。在实践过程中,如果存在可用的经验势,则可以使用经验势来进行采样,这将更加稳健,并且可以避免出现非物理构型。在这种情况下,可以将预测偏差的上限设置为一个较大的值。通过改变采样方法或采样参数,探索区域的边界随着迭代而扩展,例如增加MD温度和模拟时间。 https://dp-public.oss-cn-beijing.aliyuncs.com/community-tutorial/DP_GEN.pngDP-GEN

DP Library

DFT方法计算量大且非常耗时。因此,我们建立了DP library共享DFT计算源数据,以避免由于重复计算造成的浪费,并鼓励大家贡献自己的DFT源数据,丰富数据集,并不断改进DP模型。有了这个基础设施,对构型空间不同区域的采样可以由不同的研究人员贡献,如下图所示。当数据集更加丰富时,可以自动重新训练和改进DP模型。最后,在DP library上会得到许多DP模型。这些模型适用于大多数问题,以便研究人员可以将精力集中于应用DP模型解决实际问题,而不是耗费在构建DP模型中。当我们需要一个DP模型时,可以按照以下步骤检查应该做什么:

  1. 检查是否存在训练好的模型,直接从DP library下载模型

  2. 如果不存在,检查是否DP library上是否存在可用的DFT数据集,自己添加一些数据并训练一个模型

  3. 如果既没有训练好的模型也没有任何有价值的数据,则从头开始生成数据并从头开始训练模型

  4. 如果你愿意,将DFT源数据和模型贡献给DP library,以方便更多人使用你的数据或者模型。

https://dp-public.oss-cn-beijing.aliyuncs.com/community-tutorial/DP_LIB.pngDP_LIB

了解系统的物理性质

当实施一个DP项目时,有许多参数需要确定。例如:生成初始数据集时,形变量和位移量;利用分子动力学采集构型空间时,温度、压强和模拟步数等。虽然可以从其他地方复制一些脚本并且在不怎么修改参数的情况下运行DP-GEN,但在实践中这并不是一个好办法。我们需要了解研究体系的物理性质以便帮助设计各种参数,获得更优的实践经验。   局域构型空间的势能面形状取决于与之相关的键合强度。下图显示了化学键强度图谱。与弱化学键的相关的构型空间对应的局部势能面形状是相对平缓的,而与强化学键相关的构型空间对应的局部势能面形状是尖锐的。 https://dp-public.oss-cn-beijing.aliyuncs.com/community-tutorial/bond_nature.pngbond_nature 1.尖锐区域:势能面中的深谷 -单个分子的振动 -固体中原子的振动 2.平缓区域:势能面中的浅坑 -液体中原子或分子的运动 -固溶体 3.势垒区域: -相变路径中间态 -反应的过渡态 以液体分子为例。分子内的化学键对应一个尖锐的势能面,对应于构型空间中原子在平衡位置附近的振动。振动的特征时间非常短(~fs),因此在短时间MD模拟中,对构型空间的采样可能就比较充分了。相比之下,分子间化学键对应一个平缓的势能面,在构型空间中体积较大。分子间相互移动的特征时间较大(-ps),因此构型空间中的充分采样需要长时间MD模拟,或从不同构型开始的许多短时间MD模拟。类似的考虑也适用于化学构型空间。以$\rm{Zr}_{1−x}{Hf}_xC$为例,众所周知,改变Zr-Hf并不会显著改变能量,这与平缓的势能面相对应,因此就需要较多的MC步数来对构型空间进行采样。然而,反位缺陷Zr-C或Hf-C的能量非常高。因此,可能不需要对反位缺陷进行采样。 https://dp-public.oss-cn-beijing.aliyuncs.com/community-tutorial/PES.pngPES  为了简单起见,以Al为例来阐述材料的物理性质与DP-GEN参数之间的关系。 1.首先需要生成初始数据集。例如,使用DP-GEN中提供的“init_bulk”方法。在该方法中,我们需要设置整体的单轴压缩/膨胀、晶格变形以及原子移动的范围。通常,对于固体材料而言,从室温到熔点的体积膨胀约为5%,沿每个方向约为2%。因此,除了在高压区域外,将线性压缩/膨胀范围设置为±2%通常可以很好地覆盖固体边界。随机的晶格变化也可以设置为类似的值,例如,对于每个应变模式可以取为[-3%,3%]间的随机数。原子位置移动的值可参考最近邻的键长(例如<1%d,其中d为键长)。一般情况下可以设为0.01Å。 2.当使用DP-GEN自动迭代时,我们一般通过不断增加温度和压强进行MD模拟对构型空间进行采样。温度的设置可以参考Al的熔点Tm (~1000 K)与此同时,关于压强的设置可以参考 铝的体模量B (~80 GPa)。例如,可以将温度设置为四组:[0.0Tm,0.5Tm],[0.5Tm,1.0Tm],[1.0Tm,1.5Tm]和[1.5Tm,2.0Tm]。在每组中可以选择几个温度值,例如,可以将[0.0Tm,0.5Tm]分成[0.0Tm,0.1Tm,0.2Tm,0.3Tm,0.4Tm](实际上,0.0Tm是无用的)。在MD模拟的过程中,压力会发生波动,在小体系中,其幅度可能约为体模量的1%。因此,将压强设定为[0.00B、0.03B、0.06B、0.09B]通常就足够了。添加-0.01B可能有助于固体结构的采样,一般不会为液体结构设置负压,以避免模拟盒子持续膨胀的风险。 3.选择候选构型的上下限(“trust_level_low”和“trust_level_high”)可能取决于体系中最强的化学键。例如,分子体系中的值可能高于金属体系中的值。在固体中,上限和下限约为力的RMSE(约化均方误差)$\sqrt{\sum f_i^2} $的0.2和0.5。此外,上下限取值也可参考熔点或体模量,因为力与这些性质成正比。例如,对于Al来说DP-GEN的“trust_level_low”为0.05 eV/Å,而W的“trust_level_low”为0.15 eV/Å,其值是Al的三倍。W的熔点(~3600 K)也是Al熔点(~1000 K)的约三倍。当对照上述键合强度图谱时,这些物性可以作为好的参考指标,用来辅助设定DP-GEN的参数。然而,这些标准可能不适用于液体分子。这是由于液体分子内键合很强,即使它们的熔点很低,但仍然需要相对较高的上下限值。

了解问题的边界

请记住,“训练一个全局可用的稳定DP模型并不是一件容易的事”。通常,我们只需要一个符合我们要求的DP模型。对于不同的任务,数据集需要覆盖的构型空间范围是不同的。下面举一个例子来说明: 1.我们对Al的室温弹性性能感兴趣 -我们对Al弹性性质的温度依赖性更感兴趣 2.我们对Al的熔点感兴趣 -我们对Al的凝固过程更感兴趣 3.我们对铝的缺陷(例如,空位、间隙、位错、表面、晶界)感兴趣 https://dp-public.oss-cn-beijing.aliyuncs.com/community-tutorial/Example_Al.pngExample_Al

 在第一种情况下,计算弹性性质只需要平衡态附近小形变构型。因此,只需要铝固态的平衡态附近的数据。运行DP-GEN从000到006对应的迭代可能就足够了。此外,如果我们想知道弹性性质的温度依赖关系,应该添加从007到024的迭代,进一步采样铝固态的高能状态(例如,热膨胀导致的晶格膨胀)。  在第二种情况下,图中的所有迭代都应该进行,对铝的固态和液态构型都进行采样。然而,如果我们关心液态铝的形核细节。数据集可能足以(或不足以)准确描述固液界面。通常情况下,如果材料中的键合方向性不强,例如,对于大多数金属而言数据集就足够了。有时,当材料中的键合具有强方向性时,情况并非如此。例如,Ga、Si等。然后,应在DP-GEN过程中结合增强采样的方法对一些特殊构型进行取样,例如,形核。如图所示可以沿图中的虚线进行多次模拟,以收集鞍点周围的构型。  在第三种情况下,需要基于缺陷构型(例如,空位、间隙、位错、表面、晶界)进行额外的DP-GEN过程。幸运的是,缺陷周围的一些局部原子结构可能类似于一些扭曲的晶格结构或非晶结构。因此,在采样期间,没有必要完全包括所有缺陷构型。  从这个简单的例子可以看出,如果能很好地定义一个问题的边界,大部分工作都可以节省下来。例如,如果我们只关心铝的弹性性质,就没有必要对熔体或缺陷构型进行采样,即便一般而言在开发金属的DP模型时都会对熔体和缺陷构型进行采样。相比之下,在开发化合物的DP模型时,尤其是对于那些具有复杂结构的化合物,只有在必要时才对熔体和缺陷构型进行采样。因此,在开始一个新问题之前,需要花一些时间思考问题的边界在哪里,以及应该覆盖多大的构型空间。  当我们得到一个新项目时,与其过于兴奋迫不及待地付诸实践,倒不如先将项目分割成一些更容易实现的小目标,这可能有助于整个项目的实施。例如,如果我们的最终目标是研究Al的缺陷,我们可以将整个问题分成几个部分并分阶段进行,如上文所述的阶段1、2和3。在每个阶段之后,我们可以获得一些里程碑成果,之后再顺利进入下一阶段。

翻译:史国勇、杜云珍,校对:戴付志

Gas-Phase

Simulation of the oxidation of methane

Jinzhe Zeng, Liqun Cao, and Tong Zhu

This tutorial was adapted from: Jinzhe Zeng, Liqun Cao, Tong Zhu (2022), Neural network potentials, Pavlo O. Dral (Eds.), Quantum Chemistry in the Age of Machine Learning, Elsevier. Please cite the above chapter if you follow the tutorial.


In this tutorial, we will take the simulation of methane combustion as an example and introduce the procedure of DP-based MD simulation. All files needed in this section can be downloaded from tongzhugroup/Chapter13-tutorial. Besides DeePMD-kit (with LAMMPS), ReacNetGenerator should also be installed.

Step 1: Preparing the reference dataset

In the reference dataset preparation process, one also has to consider the expect accuracy of the final model, or at what QM level one should label the data. In this paper, the Gaussian software was used to calculate the potential energy and atomic forces of the reference data at the MN15/6-31G** level. The MN15 functional was employed because it has good accuracy for both multi-reference and single-reference systems, which is essential for our system as we have to deal with a lot of radicals and their reactions. Here we assume that the dataset is prepared in advance, which can be downloaded from tongzhugroup/Chapter13-tutorial.

Step 2. Training the Deep Potential (DP)

Before the training process, we need to prepare an input file called methane_param.json which contains the control parameters. The training can be done by the following command:

$ $deepmd_root/bin/dp train methane_param.json

There are several parameters we need to define in the methane_param.json file. The type_map refers to the type of elements included in the training, and the option of rcut is the cut-off radius which controls the description of the environment around the center atom. The type of descriptor is se_a in this example, which represents the DeepPot-SE model. The descriptor will decay smoothly from rcut_smth (R_on) to the cut-off radius rcut (R_off). Here rcut_smth and rcut are set to 1.0 Å and 6.0 Å respectively. The sel defines the maximum possible number of neighbors for the corresponding element within the cut-off radius. The options neuron in descriptor and fitting_net is used to determine the shape of the embedding neural network and the fitting network, which are set to (25, 50, 100) and (240, 240, 240) respectively. The value of axis_neuron represents the size of the embedding matrix, which was set to 12.

Step 3: Freeze the model

This step is to extract the trained neural network model. To freeze the model, the following command will be executed:

$ $deepmd_root/bin/dp freeze -o graph.pb

A file called graph.pb can be found in the training folder. Then the frozen model can be compressed:

$ $deepmd_root/bin/dp compress -i graph.pb -o graph_compressed.pb -t methane_param.json

Step 4: Running MD simulation based on the DP

The frozen model can be used to run reactive MD simulations to explore the detailed reaction mechanism of methane combustion. The MD engine is provided by the LAMMPS software. Here we use the same system from our previous work, which contains 100 methane and 200 oxygen molecules. The MD will be performed under the NVT ensemble at 3000 K for 1 ns. The LAMMPS program can be invoked by the following command:

$ $deepmd_root/bin/lmp -i input.lammps 

The input.lammps is the input file that controls the MD simulation in detail, technique details can be found in the manual of LAMMPS. To use the DP, the pair_style option in this input should be specified as follows:

pair_style deepmd graph_compressed.pb 
pair_coeff * * 

Step 5: Analysis of the trajectory

After the simulation is done, we can use the ReacNetGenerator software which was developed in our previous study to extract the reaction network from the trajectory. All species and reactions in the trajectory will be put on an interactive web page where we can analyze them by mouse clicks. Eventually we should be able to obtain reaction networks that consistent with the following figure.

$ reacnetgenerator -i methane.lammpstrj -a C H O --dump

https://media.springernature.com/full/springer-static/image/art%3A10.1038%2Fs41467-020-19497-z/MediaObjects/41467_2020_19497_Fig2_HTML.png?as=webpThe initial stage of combustion

Fig: The initial stage of combustion. The figure is taken from this paper and more results can be found there.


Acknowledge

This work was supported by the National Natural Science Foundation of China (Grants No. 22173032, 21933010). J.Z. was supported in part by the National Institutes of Health (GM107485) under the direction of Darrin M. York. We also thank the ECNU Multifunctional Platform for Innovation (No. 001) and the Extreme Science and Engineering Discovery Environment (XSEDE), which is supported by National Science Foundation Grant ACI-1548562.56 (specifically, the resources EXPANSE at SDSC through allocation TG-CHE190067), for providing supercomputer time.

References

  1. Jinzhe Zeng, Liqun Cao, Tong Zhu (2022), Neural network potentials, Pavlo O. Dral (Eds.), Quantum Chemistry in the Age of Machine Learning, Elsevier.

  2. Jinzhe Zeng, Liqun Cao, Mingyuan Xu, Tong Zhu, John Z. H. Zhang, Complex reaction processes in combustion unraveled by neural network-based molecular dynamics simulation, Nature Communications, 2020, 11, 5713.

  3. Frisch, M.; Trucks, G.; Schlegel, H.; Scuseria, G.; Robb, M.; Cheeseman, J.; Scalmani, G.; Barone, V.; Petersson, G.; Nakatsuji, H., Gaussian 16, revision A. 03. Gaussian Inc., Wallingford CT 2016.

  4. Han Wang, Linfeng Zhang, Jiequn Han, Weinan E, DeePMD-kit: A deep learning package for many-body potential energy representation and molecular dynamics, Computer Physics Communications, 2018, 228, 178-184.

  5. Aidan P. Thompson, H. Metin Aktulga, Richard Berger, Dan S. Bolintineanu, W. Michael Brown, Paul S. Crozier, Pieter J. in ‘t Veld, Axel Kohlmeyer, Stan G. Moore, Trung Dac Nguyen, Ray Shan, Mark J. Stevens, Julien Tranchida, Christian Trott, Steven J. Plimpton, LAMMPS - a flexible simulation tool for particle-based materials modeling at the atomic, meso, and continuum scales, Computer Physics Communications, 2022, 271, 108171.

  6. Denghui Lu, Wanrun Jiang, Yixiao Chen, Linfeng Zhang, Weile Jia, Han Wang, Mohan Chen, DP Train, then DP Compress: Model Compression in Deep Potential Molecular Dynamics, 2021.

  7. Jinzhe Zeng, Liqun Cao, Chih-Hao Chin, Haisheng Ren, John Z. H. Zhang, Tong Zhu, ReacNetGenerator: an automatic reaction network generator for reactive molecular dynamics simulations, Phys. Chem. Chem. Phys., 2020, 22 (2), 683–691.

Learning Resources

Here is the learning Resources:

Some Video Resources:

Basic theoretical courses:

DeePMD-kit and DP-GEN

DeePKS-kit

Writing Tips

Hello volunteers, this docs tells you how to write articles for DeepModeling tutorials.

You can just follow 2 steps:

  1. Write in markdown format and put it into proper directories.

  2. Change index.rst to show your doc.

Write in Markdown and Put into proper directories.

  1. You should learn how to write a markdown document. It is quite easy!

Here we recommend you 2 website:

  1. You should know the proper directories.

Our Github Address is: https://github.com/deepmodeling/tutorials

All doc is in: “source” directories. According to your doc’s purpose, your doc can be put into 4 directories in “source”:

  • Tutorials: Telling beginners how to run Deepmodeling projects.

  • Casestudies: Some case telling people how to use Deepmodeling projects.

  • Resources: Other resources for learning.

  • QA: Some questions and answers.

After that, you should find the proper directories and put your docs.

For example, if you write a “methane.md” for case study, you can put it into “/source/CaseStudies/Gas-phase”.

Change indexs.rst to show your doc.

Then you should change the index.rst to show your doc.

You can learn rst format here: reStructuredText

In short, you can simply change index.rst in your parent directories.

For example, if you put “methane.md” into “/source/CaseStudies/Gas-phase”, you can find and change “index.rst” in “source/CaseStudies/Gas-phase”. All you should do is imitating such file. I believe you can do it!


If you want to learn more detailed information about how to build this website, you can check this:

Q & A

here is Q & A

讨论和反馈:

这些教程需要你的反馈。如果你认为有些教程是混乱的,请在我们的`讨论板<https://github.com/deepmodeling/tutorials/discussions>`上写下你的反馈意见。

目前的工作:

目前,我们正在为以下项目编写教程:

  • DeePMD-Kit

  • DP-GEN

另一个团队正专注于为初学者编写一些AI + Science的简要材料,如。

  • 什么是机器学习

  • 什么是分子动力学模拟

  • 关于AI + Science的核心概念

索引和表格