ASC22 - deePMD-kit

第一次参加ASC比赛,只完成了 deePMD-kit 初步的优化,记录一个月来的心得与总结

Introduction

DeePMD-kit是用Python/ c++编写的DeePMD实现,旨在最小化构建基于深度学习的原子间势能和力场模型以及进行分子动力学模拟所需的工作量。这为解决分子模拟中准确性与效率的两难问题带来了新的希望。DeePMD-kit的应用范围从有限分子到扩展系统,从金属系统到化学键合系统。

The DeepMD 挑战要求大学生团队利用超级计算机运行deepmd-kit框架去进行三个最具代表性的物质( Water, Copper and Al-Cu-Mg ternary alloy)的深度势能(Deep Potential)训练,来模拟不同物质的分子动力学。Simultaneously, teams 在保证准确率的前提下,要尽可能地减少训练模型所花费的时间和计算资源

DeepMD-kit的构造过程,要满足模型在空间中的平移,旋转和交换不变性。
保证模型的连续性,只考虑以中心原子为圆心附近一定半径内其他原子对其的作用,构造平滑模型
ASC22 - deePMD-kit_第1张图片

整体构图过程:
ASC22 - deePMD-kit_第2张图片
Deepmd-kit的执行过程:

ASC22 - deePMD-kit_第3张图片

核心为两个主要的神经网络模型:”descriptor”和”fitting_net”用于模型的训练。
DeePMD的并行训练是在Horovod的帮助下以同步方式实现的通过,能利用 MPI实现应用环状规约,显著提升模型的实用性与性能表现。支持同步更新式的数据并行,根据训练进程的数量和可用的GPU卡数量,DeePMD-kit将决定是以并行(分布式)模式还是串行模式启动训练。

题目要求

ASC22 - deePMD-kit_第4张图片ASC22 - deePMD-kit_第5张图片

Information Preparation & Run

In deePMD-kit challenge, 以mgalcu模型为例

数据集内含有:data_sets 和 input.json
data_sets表示训练数据集和输入,input.json为训练脚本,控制DeePMD-kit的训练过程。
通过Anaconda指令:conda activate XX来激活python36的环境;再通过dp的指令:dp train input.json来训练相关的模型

写了相关的shell脚本run.sh来启动训练:

#!/bin/bash
source [fileName]
export [-fnp][variableName]= [Variable settings]

#export Other environment variable parameters

dp train input.json  

We use following loads to start deePMD-kit:

cd (deePMD)/src
conda activate lzj_py
nohup ./run.sh 1>result.log &

实时观察或者分析终端结果:

tail -f result.log 
vim result.log

也通过在集群上利用slurm作业调度系统提交作业,我们在run.sh脚本上加上相关的BASH命令:

#!/bin/sh
#SBATCH –nodelist=[nodename],[nodename],...
#SBATCH -J [jobname]
#SBATCH -e [errorname]
source [fileName]
export [-fnp][variableName]= [Variable settings]

Use ”sbatch Use ”sinfo” 查看可用计算节点信息的命令
Use “squeue” 查看一下当前用户的作业状态

Baseline

运行脚本

#!/bin/bash
source [fileName]

dp train input.json  

ASC22 - deePMD-kit_第6张图片
为了与优化后的程序进行比较以及求得相应的相对提升,并考虑程序的功耗限制,我们将得到的基准测试基时记录下来
在CPU和GPU两个环境下运行:
CPU: 在CPU集群(2节点,每个节点12核)。初始程序没有mpi和openmp等优化代码。程序被正确地执行。
GPU:在GPU集群(GPU型号,4个)。初始程序没有cuda和openmp等优化代码。程序被正确地执行。

DeePMD-kit作为一款科学计算软件,对算法精度要求较高,为了满足题目对于模型精度的要求,我们将baseline跑出的模型作为标准模型,利用DeePMD-kit的dp测试方法验证算法的正确性,用来衡量之后优化模型的准确性,具体操作如下:

dp freeze -o frozen_model.pb
dp test -m frozen_model.pb -s data

get a result similar to:
ASC22 - deePMD-kit_第7张图片
以上测试结果将在优化过程中起到衡量标准的作用。

Hotspot

本次比赛经验不足,采用的是cprofile来分析热点,但经过分析发现,用cprofile输出的部分有关C函数会被tensorflow包进会话中,不能得到有限结果。应该要采用手打计时的方法。
cProfile用法:
cProfile
下次比赛要注重这一方面的学习

优化

本次比赛由于没有经验,优化方面只完成了环境参数的寻找、测试方面
在代码层面由于水平、能力有限,未能完成

part 1

在训练脚本文件input.json中, 更改题目所要求的参数

“model/descriptor/precision”
“model/fitting_net/precision”
“model/descriptor/type_one_side”

其中type_one_side是bool型变量,其值为true表示尝试构建N_types嵌入网络,否则,则构建N_types^2的嵌入网。precision表示内嵌网络参数的精度选项,支持选项"default", “float16”, “float32”, “float64”.

初始设想为在合适的嵌入网络下,精度越低,模型模拟的速度应该越快,但相应的模型准确率将会降低。所以,在优化之前,我们设计并进行了以下几组对比实验。
ASC22 - deePMD-kit_第8张图片
在N_types嵌入网络下(type_one_side = true)进行下一步分析

ASC22 - deePMD-kit_第9张图片
result:
训练mgalcu模型耗时最少的input.json的参数

model/descriptor/precision=float32,
model/fitting_net/precision=float 32,
model/descriptor/type_one_side=true;

通过dp test检验,其模型精度满足题意

part 2

ASC22 - deePMD-kit_第10张图片
DeepMD-kit在训练模型时节点上使用的线程数,由”num_intra_threads”和”num_inter_threads”所决定,这两个参数控制一个节点上CPU的个数和核数。TensorFlow在创建session时会根据这些参数的设置,将待实现的任务分配给每个线程,达到控制session操作的线程并行程度。

在脚本文件中,我们通过设置环境变量来实现改变”num_intra_threads”和”num_inter_threads”参数的值。

export TF_INTRA_OP_PARALLELISM_THREADS = XX
export TF_INTER_OP_PARALLELISM_THREADS = XX

intra_op_parallelism_threads 控制运算符op内部的并行,单一运算符op,在内部实现并行
inter_op_parallelism_threads 控制多个运算符op之间的并行计算,当有多个运算符op,并且他们之间比较独立,运算符和运算符之间没有直接的路径Path相连。
测试:
ASC22 - deePMD-kit_第11张图片ASC22 - deePMD-kit_第12张图片
ASC22 - deePMD-kit_第13张图片
result:
ASC22 - deePMD-kit_第14张图片
在经过之后的学习,发现:
若要求得num_inter_threads 和 num_intra_threads的数值,直接运行此脚本可获得大致的值:
get the number of physical core per socket and number of sockets on your platform

#!/bin/bash
total_cpu_cores=$(nproc)
number_sockets=$(($(grep "^physical id" /proc/cpuinfo | awk '{print $4}' | sort -un | tail -1)+1))
number_cpu_cores=$(( (total_cpu_cores/2) / number_sockets))

echo "number of CPU cores per socket: $number_cpu_cores";
echo "number of socket: $number_sockets";

由于时间和资源的限制,更多参数没来得及测试:
more:
最大化TensorFlow* CPU性能 (shell)

https://www.intel.com/content/www/us/en/developer/articles/technical/maximize-tensorflow-performance-on-cpu-considerations-and-recommendations-for-inference.htm

part 3

基于tf的代码优化层面未能完成
自己的知识不足

Problems and solutions encountered in the competition & Attempt

1.pip install .error pip是Python 的软件包安装程序,可以使用pip从Python软件包索引和其他索引安装软件包。搭建环境的python接口时,存在 Install the DeePMD-kit’s python interface 一步中pip install .实现不了的问题,且由于直接下载包是连接国外的网站下载速度慢,所以使用清华镜像地址来解决(即在使用pip的时候加参数“-i 清华镜像地址)
利用清华源的镜像:

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple deepmd-kit==2.0.3

2.Output the problem of running function time. 我们在获取deepmd调用C函数时(比如env.py文件下的op_module模块,它是在linuxC的动态链接库libop_abi.so加载,C的文件存在source,加载完调用的函数就是C的文件名)一开始我们采用cprofile来输出函数耗时,之后经过分析发现,用cprofile输出的部分有关C函数会被tensorflow包进会话中,不能得到有限结果。解决方法:在python层面输出函数耗时:

#!/usr/bin/python
import time

print "time.time(): %f " %  time.time()

利用 time.time()函数

ASC22 - deePMD-kit_第15张图片
summary(1)

我们团队所使用的GPU集群
ASC22 - deePMD-kit_第16张图片
集群上有4个GPU可以利用,所以我们用horovodrun启动训练进程,在同一主机上启动4个进程:

CUDA_VISIBLE_DEVICES=0,1,2,3 horovodrun -np 4 \
    dp train --mpi-log=workers input.json

但是训练模型的过程中发现只是同步更新式的数据并行,每个GPU都把所有的数据跑了一遍,没有实现异步更新式的数据并行。查阅资料发现,Horovod 的分布式只支持同步更新式的数据并行,至于模型并行和异步更新式的数据并行,根据 ring-allreduce 算法可知,是不支持的。训练模型的速度并没有提升。
进一步优化方向:代码加强数据并行,再用上horovod。

还有利用 dp compress 等等

资料

知乎

DeePMD-kit的模型训练

【DP视频教程-01】DeePMD-kit视频教程

简单操作,训练加速3倍|DP压缩训练功能上线

机器学习助推分子动力学模拟

DeePMD-kit的并行效率

训练提速60%!只需5行代码,PyTorch 1.6即将原生支持自动混合精度训练。

深度势能学习(2)—DeepMD-kit学习

浅谈混合精度训练

CSDN

ASC22 - deePMD-kit_第17张图片博客园的忘记点收藏了 @@

GitHub

install-from-source

train-input-auto

others

ubuntu 修改或创建交换分区的大小

A tutorial introduction to DeePMD-kit

GPU并行运算与CUDA编程–优化篇

自我总结

mine

模型优化之XLA

数据 并行

Xshell 7学生版

GPU优化

备忘录 - ASC22

VTune

tensorflow

ASC22讲座

ASC - DAY2 - 分享

InfiniBand& RDMA

GPU并行与CUDA编程

CUDA.

2002/3/5 共勉!!!

你可能感兴趣的