DP-GEN 构建训练数据并生成深度势模型
为了构建高质量的LiCl熔体深度势能模型的训练数据集,我们可以使用DP-GEN(Deep Potential GENerator)软件。DP-GEN是一个自动化的训练数据集生成工具,可以根据预设的参数和条件搜索材料的结构和相态空间。
目的
学习完本课程后你应该:
掌握 DP-GEN 输入文件(param.json 和 machine.json) 中主要关键词的设置;
利用 DP-GEN 为 LiCl 熔体构建训练数据并生成深度势模型;
分析和解读 DP-GEN 迭代过程中的结果和输出文件,以便更好地理解模型训练的过程和效果。
资源
在本教程中,我们以LiCl熔体分子为例,构建训练数据并生成深度势模型。我们已经在work/ex4中准备了需要的文件。
wget --content-disposition https://github.com/LiangWenshuo1118/LiCl/raw/main/work.tar.gz
tar zxvf work.tar.gz
首先,使用 tree 命令查看 work/ex4 文件夹。
$ tree ex4 -L 2
你应该可以在屏幕上看到输出:
ex4
|-- abacus
| |-- Cl_ONCV_PBE-1.2.upf
| |-- Cl_gga_8au_100Ry_2s2p1d.orb
| |-- Li_ONCV_PBE-1.2.upf
| `-- Li_gga_8au_100Ry_4s1p.orb
|-- machine.json
`-- param_abacus.json
*.upf和*.orb是 ABACUS 的输入文件param.json是运行当前任务的 DP-GEN 设置。machine.json是一个任务调度程序,其中设置了计算机环境和资源要求。
本教程采用DeePMD-kit(2.1.5),AVACUS(3.1.0)和DP-GEN(0.11.0)程序完成。使用Bohrium registry.dp.tech/dptech/dpgen:0.10.6 管理节点,镜像在machine.json文件中指定。
作业
运行过程包含一系列连续迭代,按顺序进行,例如将系统加热到特定温度。每次迭代由三个步骤组成:探索 (Exploration),标记 (Labeling)和训练 (Training)。
输入文件
首先,介绍 DP-GEN 运行过程所需的输入文件。
param.json
param.json 中的关键字可以分为 4 个部分:
系统和数据 (System and Data):用于指定原子类型、初始数据等。
训练 (Training):主要用于指定训练步骤中的任务;
探索 (Exploration):主要用于在探索步骤中指定任务;
标记 (Labeling):主要用于指定标记步骤中的任务。
这里我们以LiCl熔体为例,介绍param.json中的主要关键词。
系统和数据 (System and Data)
系统和数据相关内容:
{
"type_map": ["Li","Cl"],
"mass_map": [6.941,35.453],
"init_data_prefix": "../ex3",
"init_data_sys": ["00.data/training_data"],
"sys_format": "abacus/stru",
"sys_configs_prefix": "../ex2",
"sys_configs": [["01.md/STRU"]],
"_comment": " that's all ",
关键词描述:
关键词 |
类型 |
描述 |
|---|---|---|
“type_map” |
list |
元素列表,这里是Li和Cl |
“mass_map” |
list |
原子质量列表 |
“init_data_prefix” |
str |
initial data 的前置路径 |
“init_data_sys” |
list |
初始训练数据文件的路径列表。可以使用绝对路径或相对路径 |
“sys_format” |
str |
指定构型的格式 |
“sys_configs_prefix” |
str |
sys_configs 的前置路径 |
“sys_configs” |
list |
构型文件的路径列表,此处支持通配符 |
案例说明:
“type_map”和“mass_map”给出了元素类型和原子质量。在这里,系统包含锂(Li)和氯(Cl)两种,质量分别为6.941和35.453。 “init_data_prefix”和“init_data_sys”关键词共同指定了初始训练数据的位置。“sys_configs_prefix”和“sys_configs”共同指定了探索的构型的位置。“sys_format”指定了构型的格式。在这里,训练数据位于../ex3/00.data/training_data目录下。构型文件位于../ex2/01.md/STRU目录下,采用ABACUS软件的abacus/stru格式
训练(Training)
与训练相关的内容如下:
"numb_models": FILL,
"default_training_param": {
"model": {
"type_map": ["Li","Cl"],
"descriptor": {
"type": "se_e2_a",
"sel": "auto",
"rcut_smth": 0.5,
"rcut": 7.0,
"neuron": [25,50,100],
"resnet_dt": false,
"axis_neuron": 12,
"seed": 1
},
"fitting_net": {
"neuron": [240,240,240],
"resnet_dt": true,
"seed": 1
}
},
"learning_rate": {
"type": "exp",
"start_lr": 0.001,
"decay_steps": 5000
},
"loss": {
"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
},
"training": {
"numb_steps": 400000,
"disp_file": "lcurve.out",
"disp_freq": 1000,
"numb_test": 1,
"save_freq": 10000,
"save_ckpt": "model.ckpt",
"disp_training": true,
"time_training": true,
"profiling": false,
"profiling_file": "timeline.json",
"_comment": "that's all"
}
},
关键词描述:
键词 |
字段类型 |
描述 |
|---|---|---|
“numb_models” |
int |
在 00.train 中训练的模型数量。 |
“default_training_param” |
dict |
DeePMD-kit 的训练参数 |
填写提示:
训练相关键指定训练任务的详细信息。numb_models指定要训练的模型数量。default_training_param指定了 DeePMD-kit 的训练参数。在这里,将训练 4 个 DP 模型。
DP-GEN 的训练部分由 DeePMD-kit 执行,因此此处的关键字与 DeePMD-kit 的关键字相同,此处不再赘述。有关这些关键字的详细说明,请访问DeePMD-kit 文档。
**探索 (Exploration) **
与探索相关的内容如下:
"model_devi_dt": 0.001,
"model_devi_skip": 0,
"model_devi_f_trust_lo": FILL,
"model_devi_f_trust_hi": FILL,
"model_devi_clean_traj": false,
"model_devi_jobs": [
{"sys_idx": [0],"temps": [FILL,FILL,FILL,FILL],"press": [FILL,FILL,FILL,FILL,FILL], "trj_freq": FILL, "nsteps": FILL,"ensemble": "npt", "_idx": "00"},
{"sys_idx": [0],"temps": [FILL,FILL,FILL,FILL],"press": [FILL,FILL,FILL,FILL,FILL], "trj_freq": FILL, "nsteps": FILL,"ensemble": "npt", "_idx": "01"},
{"sys_idx": [0],"temps": [FILL,FILL,FILL,FILL],"press": [FILL,FILL,FILL,FILL,FILL], "trj_freq": FILL, "nsteps": FILL,"ensemble": "npt", "_idx": "02"}
],
关键词描述:
键词 |
字段类型 |
描述 |
|---|---|---|
“model_devi_dt” |
float |
MD 的时间步长 |
“model_devi_skip” |
int |
每个 MD 中为 fp 跳过的结构数 |
“model_devi_f_trust_lo” |
float |
选择的力下限。如果为 List,则应分别为每个索引设置sys_configs。 |
“model_devi_f_trust_hi” |
int |
选择的力上限。如果为 List,则应分别为每个索引设置sys_configs。 |
“model_devi_clean_traj” |
bool or int |
如果model_devi_clean_traj的类型是布尔类型,则表示是否清理MD中的traj文件。如果是 Int 类型,则将保留 traj 文件夹的最新 n 次迭代,其他迭代将被删除。 |
“model_devi_clean_traj” |
bool |
控制在模型偏差(model_devi)阶段是否合并生成的轨迹文件 |
“model_devi_jobs” |
list |
01.model_devi 中的探索设置。列表中的每个字典对应于一次迭代。model_devi_jobs 的索引与迭代的索引完全一致 |
“sys_idx” |
List of integer |
选择系统作为MD的初始结构并进行探索。序列与“sys_configs”完全对应。 |
“temps” |
list |
分子动力学模拟的温度 (K) |
“press” |
list |
分子动力学模拟的压力 (Bar) |
“trj_freq” |
int |
MD中轨迹的保存频率。 |
“nsteps” |
int |
分子动力学运行步数 |
“ensembles” |
str |
决定在 MD 中选择的集成算法,选项包括 “npt” , “nvt”等. |
填写提示:
在在“model_devi_jobs”中设置了三次迭代。对于每次迭代,在不同的温度(900, 1000, 1100和1200 K)和压力条件(0, 10, 100, 1000和10000 Bar)下,使用”npt”系综和“sys_configs_prefix”和“sys_configs”指定的构型进行100000步模拟,时间步长为0.001 ps。我们选择保存 MD 轨迹文件,并将保存频率“trj_freq”设置为 10。如果轨迹中构型的“max_devi_f”介于 0.08 和 0.18 之间,DP-GEN 会将该结构视为候选结构。如果要保存 traj 文件夹的最近n次迭代,可以将“model_devi_clean_traj”设置为整数。
** 标记 (Labeling)**
与标记相关的内容如下:
"fp_style": "abacus",
"shuffle_poscar": false,
"fp_task_max": FILL,
"fp_task_min": FILL,
"fp_pp_path": "./abacus",
"fp_pp_files": ["Li_ONCV_PBE-1.2.upf","Cl_ONCV_PBE-1.2.upf"],
"fp_orb_files": ["Li_gga_8au_100Ry_4s1p.orb","Cl_gga_8au_100Ry_2s2p1d.orb"],
"k_points":[1, 1, 1, 0, 0, 0],
"user_fp_params":{
"ntype": 2,
"symmetry": 0,
"vdw_method":"d3_bj",
"ecutwfc": 100,
"scf_thr":1e-7,
"scf_nmax":120,
"basis_type":"lcao",
"smearing_method": "gauss",
"smearing_sigma": 0.002,
"mixing_type": "pulay",
"mixing_beta": 0.4,
"cal_force":1,
"cal_stress":1
关键词描述:
键词 |
字段类型 |
描述 |
|---|---|---|
“fp_style” |
String |
第一性原理软件软件。到目前为止,选项包括ABACUS, VASP等。 |
“shuffle_poscar” |
Boolean |
|
“fp_task_max” |
Integer |
每次迭代 在 02.fp 中要计算的最大结构。 |
“fp_task_min” |
Integer |
每次迭代 在 02.fp 中要计算的最小结构。 |
“fp_pp_path” |
String |
用于 02.fp 的赝势文件路径。 |
“fp_pp_files” |
List of string |
用于 02.fp 的赝势文件。请注意,元素的顺序应与 type_map 中的顺序相对应。 |
“fp_orb_files” |
List of string |
用于 02.fp 的轨道文件。请注意,元素的顺序应与 type_map 中的顺序相对应。 |
“k_points” |
List of Integer |
用于生成ABACUS KPT文件。 |
“user_fp_params” |
dict |
用于生成ABACUS INPUT文件。如果”user_fp_params”中指定了 kspacing,可以不设置”k_points”。 |
填写提示:
标记相关键词指定标记任务的详细信息。 在这里,最少 50 个和最多 200 个结构将使用 ABACUS 代码进行标记,在每次迭代中,INPUT 文件依据“user_fp_params”生成,KPT文件依据 “k_points”生成。请注意,”fp_pp_files” 和 “fp_orb_files” 中元素的顺序应与 type_map 中的顺序相对应。
machine.json
DP-GEN 运行过程中的每次迭代都由三个步骤组成:探索、标注和训练。因此,machine.json 由三个步骤组成:train、model_devi 和 fp。每个步骤都是字典列表。每个字典都可以被视为一个独立的计算环境。
在本节中,我们将向您展示如何在Bohrium上执行train, model_devi和fp 步骤。 对于每个步骤,需要三种类型的关键词:
命令 (Command):提供用于执行每个步骤的命令。
机器 (Machine):指定机器环境(本地工作站、本地或远程集群或云服务器)。
资源 (Resources):指定组、节点、CPU 和 GPU 的数量;启用虚拟环境。
在此示例中,我们在Bohrium上执行train步骤。
{
"api_version": "1.0",
"deepmd_version": "2.1.5",
"train" :[
{
"command": "dp",
"machine": {
"batch_type": "Lebesgue",
"context_type": "LebesgueContext",
"local_root" : "./",
"remote_profile":{
"email": "xxx",
"password": "xxx",
"program_id": xxx,
"keep_backup":true,
"input_data":{
"job_type": "container",
"log_file": "00*/train.log",
"grouped":true,
"job_name": "dpgen_train_job",
"disk_size": 100,
"scass_type":"c12_m92_1 * NVIDIA V100",
"checkpoint_files":["00*/checkpoint","00*/model.ckpt*"],
"checkpoint_time":5,
"platform": "ali",
"image_name":"registry.dp.tech/dptech/deepmd-kit:2.1.5-cuda11.6",
"on_demand":0
}
}
},
"resources": {
"local_root":"./",
"group_size": 1
}
}],
"model_devi":
[{
"command": "export LAMMPS_PLUGIN_PATH=/opt/deepmd-kit-2.1.5/lib/deepmd_lmp && lmp -i input.lammps -v restart 0",
"machine": {
"batch_type": "Lebesgue",
"context_type": "LebesgueContext",
"local_root" : "./",
"remote_profile":{
"email": "xxx",
"password": "xxx",
"program_id": xxx,
"keep_backup":true,
"input_data":{
"job_type": "container",
"log_file": "task*/model_devi.out",
"grouped":true,
"job_name": "dpgen_model_devi_job",
"disk_size": 200,
"scass_type":"c12_m92_1 * NVIDIA V100",
"platform": "ali",
"image_name":"registry.dp.tech/dptech/deepmd-kit:2.1.5-cuda11.6",
"checkpoint_files": "sync_files",
"checkpoint_time":5,
"on_demand":0
}
}
},
"resources": {
"local_root":"./",
"group_size": 1
}
}],
"fp":
[{
"command": "OMP_NUM_THREADS=1 mpirun -np 4 abacus",
"machine": {
"batch_type": "Lebesgue",
"context_type": "LebesgueContext",
"local_root" : "./",
"remote_profile":{
"email": "xxx",
"password": "xxx",
"program_id": xxx,
"keep_backup":true,
"input_data":{
"log_file": "task*/output",
"grouped":true,
"job_name": "dpgen_fp_job",
"checkpoint_files": "sync_files",
"checkpoint_time":5,
"scass_type":"c8_m64_cpu",
"platform": "ali",
"image_name":"registry.dp.tech/dptech/abacus:3.1.0",
"job_type": "container",
"on_demand":0
}
}
},
"resources": {
"group_size": 2,
"local_root":"./",
"source_list": []
}
}
]
}
案例说明:
在 command 参数中,train,model_devi和fp步骤使用的程序分别为 DeePMD-kit,LAMMPS 和 ABACUS,其相应的调用命令分别为“dp”,”export LAMMPS_PLUGIN_PATH=/opt/deepmd-kit-2.1.5/lib/deepmd_lmp && lmp -i input.lammps -v restart 0” 和 “OMP_NUM_THREADS=1 mpirun -np 4 abacus”。
在 machine 参数中,”scass_type”指定训练使用的机型。对于train和model_devi步骤,建议使用GPU机型,这里使用的机型为“c12_m92_1 * NVIDIA V100”。对于fp步骤,建议使用CPU机型,这里使用的机型为“c8_m64_cpu”。
在 resources 参数中,“group_size”指定了一个 group 中任务的数量。对于train和model_devi步骤,由于任务数量较少(分别为4和20),我们可以将“group_size”设置为 1, 使所有任务同时执行。对于fp步骤,由于任务数量较多(200),我们可以将“group_size”设置为 2, 使100个任务同时执行。
注意:用户需要填入自己的 Bohrium 账户邮箱,密码和项目ID(共三处)。其他参数通常不需修改。
运行DP-GEN
准备好了 param.json 和 machine.json,我们就可以通过以下方式轻松运行 DP-GEN:
dpgen run param.json machine.json
成功运行 DP-GEN 之后,在 work/ex4 下,可以发现生成了一个文件夹和两个文件:
iter.000000 文件夹:包含 DP-GEN 迭代过程中第一次迭代的主要结果;
dpgen.log 文件:主要记录时间和迭代信息;
record.dpgen 文件:记录迭代过程的当前阶段。
如果 DP-GEN 的进程由于某种原因停止,DP-GEN 将通过 record.dpgen文件自动恢复主进程。我们也可以根据自己的目的手动更改它,例如删除上次迭代并从一个检查点恢复。record.dpgen文件每行包含两个数字:第一个是迭代的索引,第二个是 0 到 9 之间的数字,记录每个迭代中的哪个阶段当前正在运行。
Index of iterations |
Stage in each iteration |
Process |
|---|---|---|
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 |
结果分析
第一次迭代完成后,iter.000000 的文件夹结构如下,主要是 3 个文件夹:
$ tree iter.000000/ -L 1
./iter.000000/
├── 00.train
├── 01.model_devi
└── 02.fp
00.train 文件夹:主要是基于现有数据训练的多个 DP 模型(默认是 4 个);
01.model_devi 文件夹:使用 00.train 中得到的 DP 模型进行 MD 模拟,产生新的构型;
02.fp 文件夹:对选定的构型进行第一原理计算,并将计算结果转换成训练数据
首先,我们来查看 iter.000000/ 00.train。
$ tree iter.000000/00.train -L 1
./iter.000000/00.train/
|-- 000
|-- 001
|-- 002
|-- 003
|-- data.init -> /data/work/ex3
|-- 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包括版本、数据、硬件信息、时间等。
然后,我们来查看iter.000000/ 01.model_devi。
$ tree iter.000000/01.model_devi -L 1
./iter.000000/01.model_devi/
|-- confs
|-- graph.000.pb -> /data/work/ex4/iter.000000/00.train/graph.000.pb
|-- graph.001.pb -> /data/work/ex4/iter.000000/00.train/graph.001.pb
|-- graph.002.pb -> /data/work/ex4/iter.000000/00.train/graph.002.pb
|-- graph.003.pb -> /data/work/ex4/iter.000000/00.train/graph.003.pb
|-- task.000.000000
|-- task.000.000001
|-- ...
|-- task.000.000018
`-- task.000.000019
文件夹 confs 包含从您在 param.json 的“sys_configs”中设置的 STRU 转换而来的 LAMMPS MD 的初始配置。
文件夹 task.000.00000x 包含 LAMMPS 的输入和输出文件。我们可以随机选择其中之一,例如 task.000.000000。
$ 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
`-- traj
conf.lmp,链接到文件夹 confs 中的“000.0001.lmp”,作为 MD 的初始配置。input.lammps是 LAMMPS 的输入文件。model_devi.out记录在 MD 训练中相关的标签,能量和力的模型偏差。它是选择结构和进行第一性原理计算的标准。traj存储LAMMPS MD轨迹。
通过查看 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.325778e-02 1.273135e-03 7.165758e-03 1.805290e-02 5.604093e-03 1.014306e-02
10 1.384183e-02 4.033422e-04 7.237393e-03 1.629300e-02 5.911181e-03 1.090707e-02
20 1.366198e-02 3.721965e-04 7.527250e-03 2.594799e-02 7.528770e-03 1.298601e-02
30 1.250935e-02 8.420508e-04 7.166151e-03 2.916632e-02 6.933435e-03 1.464892e-02
回想一下,我们将“trj_freq”设置为10,因此每10个步骤保存结构。是否选择结构取决于其“max_devi_f”。如果它介于“model_devi_f_trust_lo”(0.08)和“model_devi_f_trust_hi”(0.18)之间,DP-GEN 会将该结构视为候选结构。对于0,10,20 和 30 步保存结构,其“max_devi_f”均小于 0.08,所以不会被视为候选结构。
最后,我们来查看 iter.000000/ 02.fp 。
$ tree iter.000000/02.fp -L 1
./iter.000000/02.fp
|-- data.000
|-- candidate.shuffled.000.out
|-- rest_accurate.shuffled.000.out
|-- rest_failed.shuffled.000.out
|-- task.000.000000
|-- task.000.000001
|-- ...
|-- task.000.000198
`-- task.000.000199
candidate.shuffle.000.out记录将从最后一步 01.model_devi 中选择哪些结构。 候选的数量总是远远超过您一次期望计算的最大值。在这种情况下,DP-GEN将随机选择最多fp_task_max结构并形成文件夹任务。rest_accurate.shuffle.000.out记录了我们的模型准确的其他结构(max_devi_f小于model_devi_f_trust_lo),rest_failed.shuffled.000.out记录了我们的模型太不准确的其他结构,这些结构通常是非物理的(大于model_devi_f_trust_hi)。data.000:经过ABACUS SCF计算后,DP-GEN 将收集这些数据并将其更改为 DeePMD-kit 所需的格式。在下一次迭代的“00.train”中,这些数据将与初始数据一起训练。
通过 cat candidate.shuffled.000.out | grep task.000.000000, 你将会看到从task.000.000000中收集的候选构型:
$ cat ./iter.000000/02.fp/candidate.shuffled.000.out | grep task.000.000001
iter.000000/01.model_devi/task.000.000000 52910
iter.000000/01.model_devi/task.000.000000 24370
iter.000000/01.model_devi/task.000.000000 59930
iter.000000/01.model_devi/task.000.000000 9370
iter.000000/01.model_devi/task.000.000000 96490
...
在第一次迭代之后,我们检查 dpgen.log 的内容。
$ cat dpgen.log
2023-03-20 10:13:30,696 - INFO : start running
2023-03-20 10:13:30,707 - INFO : =============================iter.000000==============================
2023-03-20 10:13:30,707 - INFO : -------------------------iter.000000 task 00--------------------------
2023-03-20 10:13:30,802 - INFO : -------------------------iter.000000 task 01--------------------------
2023-03-20 11:51:16,496 - INFO : -------------------------iter.000000 task 02--------------------------
2023-03-20 11:51:16,514 - INFO : -------------------------iter.000000 task 03--------------------------
2023-03-20 11:51:16,973 - INFO : -------------------------iter.000000 task 04--------------------------
2023-03-20 12:40:25,181 - INFO : -------------------------iter.000000 task 05--------------------------
2023-03-20 12:40:25,185 - INFO : -------------------------iter.000000 task 06--------------------------
2023-03-20 12:40:26,985 - INFO : system 000 candidate : 21098 in 200020 10.55 %
2023-03-20 12:40:26,986 - INFO : system 000 failed : 19178 in 200020 9.59 %
2023-03-20 12:40:26,986 - INFO : system 000 accurate : 159744 in 200020 79.86 %
2023-03-20 12:40:27,294 - INFO : system 000 accurate_ratio: 0.7986 thresholds: 1.0000 and 1.0000 eff. task min and max -1 200 number of fp tasks: 200
2023-03-20 12:41:57,507 - INFO : -------------------------iter.000000 task 07--------------------------
2023-03-20 12:55:55,728 - INFO : -------------------------iter.000000 task 08--------------------------
2023-03-20 12:55:58,276 - INFO : failed tasks: 0 in 200 0.00 %
可以发现,在 iter.000000 中生成了 200020 个结构,其中候选构型21098个,挑选了 200 个结构进行ABACUS SCF计算,且全部成功收敛。
在所有迭代结束之后,我们来检查 work/ex4 的文件结构:
$ tree -L 2
.
|-- abacus
| |-- Cl_ONCV_PBE-1.2.upf
| |-- Cl_gga_8au_100Ry_2s2p1d.orb
| |-- Li_ONCV_PBE-1.2.upf
| `-- Li_gga_8au_100Ry_4s1p.orb
|-- dpdispatcher.log
|-- dpgen.log
|-- iter.000000
| |-- 00.train
| |-- 01.model_devi
| `-- 02.fp
|-- iter.000001
| |-- 00.train
| |-- 01.model_devi
| `-- 02.fp
|-- iter.000002
| |-- 00.train
| |-- 01.model_devi
| `-- 02.fp
|-- iter.000003
| `-- 00.train
|-- machine.json
|-- param_abacus.json
`-- record.dpgen
以及 dpgen.log 的内容:
$ cat cat dpgen.log | grep system
2023-03-20 12:40:26,985 - INFO : system 000 candidate : 21098 in 200020 10.55 %
2023-03-20 12:40:26,986 - INFO : system 000 failed : 19178 in 200020 9.59 %
2023-03-20 12:40:26,986 - INFO : system 000 accurate : 159744 in 200020 79.86 %
2023-03-20 12:40:27,294 - INFO : system 000 accurate_ratio: 0.7986 thresholds: 1.0000 and 1.0000 eff. task min and max -1 200 number of fp tasks: 200
2023-03-20 15:24:24,243 - INFO : system 000 candidate : 299 in 200020 0.15 %
2023-03-20 15:24:24,243 - INFO : system 000 failed : 64 in 200020 0.03 %
2023-03-20 15:24:24,243 - INFO : system 000 accurate : 199657 in 200020 99.82 %
2023-03-20 15:24:24,536 - INFO : system 000 accurate_ratio: 0.9982 thresholds: 1.0000 and 1.0000 eff. task min and max -1 200 number of fp tasks: 200
2023-03-20 20:22:25,403 - INFO : system 000 candidate : 9 in 200020 0.00 %
2023-03-20 20:22:25,403 - INFO : system 000 failed : 1 in 200020 0.00 %
2023-03-20 20:22:25,404 - INFO : system 000 accurate : 200010 in 200020 100.00 %
2023-03-20 20:22:25,699 - INFO : system 000 accurate_ratio: 1.0000 thresholds: 1.0000 and 1.0000 eff. task min and max -1 200 number of fp tasks: 9
可以发现,仅在三个iteration后accurate_ratio接近100.00 %。在 ‘iter.000002’ 中收集了 9 个候选结构,小于param.json中fp_task_min关键词指定的50。因此,模型不会在 iter.000003/00.train 中更新。
为了更直观监测迭代过程,我们提供了提供了一个名为max_devi_f.py的python脚本,用于统计每个iteration中所有构型max_devi_f的分布
import os
import numpy as np
import matplotlib.pyplot as plt
for i in range(0,3): # 指定迭代的轮数
max_devi_f_values = []
for j in range(20): # 在iter*/01.model_devi中有20个LAMMPS任务
directory = "./iter.{:06d}/01.model_devi/task.000.{:06d}".format(i, j)
file_path = os.path.join(directory, "model_devi.out")
data = np.genfromtxt(file_path, skip_header=1, usecols=4)
max_devi_f_values.append(data)
# 把列表转换成numpy数组
max_devi_f_values = np.concatenate(max_devi_f_values)
# 使用numpy.histogram()计算max_devi_f在每个统计区间的频率
hist, bin_edges = np.histogram(max_devi_f_values, range=(0, 0.2), bins=100)
# 把频率转换成百分数
hist = hist / len(max_devi_f_values) * 100
# Use matplotlib.pyplot.plot() to plot the frequency of each value
plt.plot(bin_edges[:-1], hist,label = 'iter{:02d}'.format(i))
plt.legend()
plt.xlabel("max_devi_f eV/Å")
plt.ylabel("Distribution %")
with open(f'./iter{i:02d}_dist-max-devi-f.txt'.format(i), 'w') as f:
f.write("{:>12} {:>12}\n".format("bin_edges", "hist"))
for x, y in zip(bin_edges[:-1], hist):
f.write('{:>12.3f} {:>12.3f}\n'.format(x, y))
plt.savefig('max-devi-f.png',dpi=300)

至此,我们应该已经了解了如何使用 DP-GEN 生成和训练深度势模型,以及如何分析输出结果。