Jinzhe Zeng's Blog

苟利国家生死以,岂因祸福避趋之

0%

paper

今天,笔者的第二篇第一作者论文“Complex reaction processes in combustion unraveled by neural network-based molecular dynamics simulation”在Nature Communications正式发表。华东师范大学为论文的第一单位。

在这篇论文中,笔者生成了甲烷燃烧的数据集,并使用DeePMD-kit软件构建了基于深度学习方法的反应势能面,进行了长达1 ns的甲烷燃烧反应的分子动力学模拟。借助笔者开发的ReacNetGenerator软件,笔者探明了甲烷燃烧的微观反应机理,对每个基元反应提供了原子尺度的理解。

在此,本文以个人视角,回顾这篇论文产生和发表的历程。

Read more »

时至2021年8月,从大三算起,我从事科研工作也快满四年了。四年来,我也用过不少计算软件,它们无一例外都有一些通病,一是文档写得极差,遇到不属于bug的错误总要手动搜索答案,形成了“软件使用经验”的壁垒,有些软件甚至催生了不少第三方论坛、博客、培训机构提供教程,形成了完整的产业链;二是对于开源项目来说,注释和开发文档几乎没有,看代码只能靠猜,给二次开发带来了极大障碍。

原先,DeePMD-kit也存在着这样的问题。当年我还是DeePMD-kit的用户时,就常常为了理解代码背后的逻辑而被折磨得痛不欲生。虽然解决这个问题需要付出的努力很多,但不积跬步,无以至千里;不积小流,无以成江海。这一问题仍需要去推动、去解决。v2.0.0对这个问题进行了针对性优化,虽然仍有很多欠缺之处,但是用林峰的一句话来说,算是“小学毕业”了。

新版的文档分为了三个板块,一是Getting started,通过一个简单的案例,供初学者入门;二是Advanced,为使用者带来了详细的文档和具体的参数;三是Developer Guide,包含了具体的Python和C++的API,供开发者参考。

image

API部分旨在为各个函数和类的功能和参数提供完整的注释,以DescrptSeA为例,DescrptSeA的公式和参数都放到了docstring内,相信能给二次开发带来极大的方便。有所欠缺的是,这个坑极大,目前有很多仍未完成。

image

C++的注释以InputNlist为例,没有注释的话没有人知道如何理解各个member。

image

另一方面,我在解答问题的时候能够发现,很多人都会遇到同样的不是bug的报错,而这些具体指南是可以写在error message里面的。v2.0.0增加了很多指南型的error message,用户遇到error后可以不去任何地方问,直接跟着指南走就行了。

总之,文档和注释目前仍然是一个很大的坑,但如果想让DeePMD-kit成为一个成熟的、经久不衰的开源软件,这就是一道必须面对的槛!

两周前,经过一周的努力,我终于成功编译了TensorFlow 2.5。在TF 2.5中,我亲自参与的#43951得到了修复。但众所周知,TensorFlow每个新版本都会更新一些bug,TF2.5更新了6个新bug!

Read more »

今年,组里申到了Longhorn约二十万V100机时。Longhorn是Texas Advanced Computing Center(TACC)前年建成的超算,建成那年在TOP500排名120,不过目前已经下滑到228了,可见现在的硬件迭代速度飞快。这么多机时,它的队列又是空空荡荡的,那当然要尝试一下。尝试了两周,解决了两个很坑的问题,终于跑通了。


第一个问题是,Longhorn开了强制两步认证,登录时即使设置了密钥,仍会受到以下提示:

To access the system:

  1. If not using ssh-keys, please enter your TACC password at the password prompt
  2. At the TACC Token prompt, enter your 6-digit code followed by.

(*****@longhorn.tacc.utexas.edu) TACC Token Code:

根据用户手册,我们需要下载一个名为TACC Token的App,扫码获取这个Token Code。

image

乍看起来,这确实是WorkFlow的噩梦。当我们同时运行十几个甚至几十个WorkFlow时,可能随时都会发生登录事件,让程序去等待人类(可能在睡觉,可能在躺平,甚至可能不可描述)去输token,实在是不可接受的。

但是仔细一看,这个token,其实就是已经成为通用标准的“基于时间的一次性密码算法”(Time-based One-time Password,TOTP)。所谓TOTP,就是基于预设密钥和当前时间戳生成token的算法,维基百科的介绍如下:

image

扫描二维码,会得到形如这样的地址:

otpauth://totp/njzjz%3Anjzjz?secret=这里有一串密钥&issuer=TACC

secret后面的就是base32以后的密钥,可以用base64.b32decode(secret)进行解码;时间戳可以从time.time()得到;而TOTP算法所需的HMAC算法,则是Python内置的。因此我们生成TOTP的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
def generate_totp(secret: str, period: int=30, token_length: int=6) -> int:
"""Generate time-based one time password (TOTP) from the secret.
Some HPCs use TOTP for two-factor authentication for safety.
Parameters
----------
secret: str
The encoded secret provided by the HPC. It's usually extracted
from a 2D code and base32 encoded.
period: int, default=30
Time period where the code is valid in seconds.
token_length: int, default=6
The token length.

Returns
-------
token: int
The generated token.
"""
timestamp = time.time()
counter = int(timestamp) // period
msg = struct.pack('>Q', counter)
digest = hmac.new(base64.b32decode(secret), msg, hashlib.sha1).digest()
ob = digest[19]
pos = ob & 15
base = struct.unpack('>I', digest[pos:pos + 4])[0] & 0x7fffffff
token = base % (10**token_length)
return str(token).zfill(token_length)

得到了TOTP的密钥后,我们把它喂给paramiko的password参数,这个问题就算解决了!

去年,DeePMD-kit的开发者意识到了文档的重要性,给输入的JSON文件input.json的所有参数添加了相应的文档。为了实现这一重要目标,Yixiao将配置参数抽象成了dargs.Arugenmentdargs.Variant类,每个Arugenment类代表一个参数,类的属性里还有允许类型、文档、允许的子Argument等信息;Variant则表示不同的配置变种,例如local_frame描述符和se_e2_a描述符。就在此时,我们看到Sion Wang吐槽过DeePMD-kit缺少文档,用起来是最痛苦的。

除了文档以外,我们也意识到,一个优秀的用户界面(user interface,UI)也可以大幅度提升用户体验。JSON文件是一种对程序友好却反人类的语言,常常看到有用户这里多一个逗号、那里少一个逗号。我们也发现,有时用户也会把参数写错位置,却不知错在哪里。例如,在下面节选的参数中,type_mapmodel的子参数,但有用户把type_map放在model之前,使其无法被正确读取。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  
{
"model": {
"type_map": ["O", "H"],
"descriptor" :{
"type": "se_e2_a",
"sel": [46, 92],
"rcut_smth": 0.50,
"rcut": 6.00,
"neuron": [25, 50, 100],
"resnet_dt": false,
"axis_neuron": 16,
"seed": 1
},
"fitting_net" : {
"neuron": [240, 240, 240],
"resnet_dt": true,
"seed": 1
}
}
}

因此,我常常想着能否为用户提供一个图形界面(graphical user interface,GUI),生成这些JSON文件。很多科学计算软件都只有命令行界面(command line interface,CLI),GUI位于鄙视链的最末端,但我认为应该给新手提供更加友好的环境。

上周,我想到了一个绝妙的idea,立即在开发群里提出,获得了其它开发者的赞同:

Read more »

今天dev通道推送了Windows 11 Insider Preview 22000,赶紧体验一把。

image
界面

image
底下的任务栏,图标跑到了中间。二屏的任务栏被砍了(好像只是个bug)。

PS:右下角并未出现水印。

image
完全变样的开始菜单。

image
搜索框跑到了最上面。

image
似曾相似的“小组件”。

image
通知和日历。

image
操作栏。

image
文件资源管理器。

image
Microsoft Store。并没有发现什么新app。

image
设置。

image
系统→关于。

新增功能
根据更新日志,好像没有增加什么有用的功能。。。

组里拨科研经费新入了16块3090,正好用3090测试一下深度学习势能+分子动力学模拟(MD)的性能。

程序版本:DeePMD-kit 2.0.0.b0 双精度[1][2],TensorFlow 2.4.1,CUDA Toolkit 11.1,LAMMPS 29Oct2020

测试结果

测试样本为examples中的水,模型为se_e2_a。

项目30902080TiV100P100
训练10000步时间(s)341670214228
10000步MD时间(s)1291544954

可以看出,在上述测试案例中,3090的双精度性能较2080Ti有较大提升,但仍落后于V100和P100等专业计算显卡。当然,考虑到计算卡的价格也是3090的数倍,3090仍是不错的选择。


  1. 1.Computer Physics Communications, 2018, 228, 178-184.
  2. 2.SC20, 2020, 1-14.

惊闻微软终——于——放出了WSL GUI(WSLg),赶紧体验一把!

Read more »

2018年,我第一次接触DeePMD-kit时,花了整整一周的时间才测试成功。那时,对于一位驾轻就熟的老司机来说,在超算上安装DeePMD-kit可能仅需要2个小时;然而,对于刚刚接触这一切的新手来说,安装过程可能是数天的折磨,甚至是一辈子也无法解决的噩梦。2019年春,在开源社区的倡议下,优化安装过程被明确列入DeePMD-kit的开发计划。

Pip安装

在DeePMD-kit v0版本中,Python和C++的接口均调用了用TensorFlow的C++库编译的操作。然而,与Python版本的TensorFlow库相比,TensorFlow的C++库需要漫长的编译过程,对新手极不友好,也不利于开发。

于是,在v1版本中,开发者将Python接口与C++接口解除耦合,Python接口调用TensorFlow的Python包中的C++库进行编译。同时,开发者在主目录中添加了setup.py,调用scikit-build实现编译的自动化,并实现了自动搜索TensorFlow,从而使得用户能够用pip命令一键安装DeePMD-kit。

之后,开发者发现,一键安装DeePMD-kit的前提是提前装好scikit-build和cmake,这使得安装流程“不够一键”。这时,开发者发现了PEP-518,这一特性使得pip可以提前装好构建所需的工具。然而,PEP-518带来了包隔离特性,使得发现TensorFlow变得异常困难。在反复尝试下,开发者用了一些trick解决了一些问题。

在此基础上,开发者编译了wheel文件,上传到pypi上,使得安装DeePMD-kit变得异常简单:

pip install tensorflow deepmd-kit
安装成功后,运行dp -h可以调用DeePMD-kit的Python接口。

Conda安装

在解决了Python接口的安装难题后,我们仍然面临C++接口的安装困难。这时,开发者把目光转向了conda。conda是包的分发和管理工具,和其它二进制分发工具相比,其最大优点在于安装时无需root权限。很多人认为,conda是Python包的管理工具,但其实,它也能分发C++的包。一般来说,分发编译后的二进制包,总有各种各样的静态库的依赖问题,但conda将所有的静态库都打包成了conda包,使得程序运行时无需调用系统自带的静态库。

Conda-build是conda包的打包工具,打包文件主要包括这两个文件:meta.yaml(配方文件,用于定义包的基本信息和依赖)、build.sh(构建包需要执行的命令),以及其它必须的文件。开发者将TensorFlow、DeePMD-kit和LAMMPS依次打包,并传到了anaconda.org上。于是,用户安装Anaconda或Miniconda后,可以使用下述命令安装:

conda install deepmd-kit=*=gpu lammps-dp==*gpu -c deepmodeling
之后运行dp -hlmp -h即可调用DeePMD-kit或LAMMPS。

为了节约人力,DP开源社区将conda包的编译过程搬到了GitHub上,使用Azure Pipeline自动编译。同时,DP开源社区也将DeePMD-kit提交到了conda-forge开源社区中,并积极推动着conda-forge社区TensorFlow的编译。另外值得注意的是,DP开源社区请求清华大学开源软件镜像站镜像了deepmodeling的conda仓库,同时镜像站此前已经镜像了conda-forge的仓库,为国内的用户带来了很大的便利。截至今日,deepmodeling仓库DeePMD-kit的下载量已达6815次,conda-forge仓库DeePMD-kit的下载量已达21182次。

离线包安装

对于不能连通互联网的机器来说,离线包是必不可少的利器。开发者发现conda提供了constructor程序,只需一个配方文件,就可以打包已经编译好的conda程序,生成离线包。这些离线包同样由CI自动生成,可以在GitHub的Releases页面下载。

Docker安装

在离线包的基础上,开发者开发了Docker镜像,使用CI上传到了DockerHub及GitHub Package上,方便Docker精通者使用。

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

子曰:“工欲善其事,必先利其器。”在2021年的今天,无论是新手还是老手,均可在5分钟内完成DeePMD-kit的安装。这一变化,为广大科研工作者带来了巨大的便利,也推动着DP走向世界,迈向更有前景的明天。

三年前的一个平常的清晨,天尚未亮,笔者前往秋实阁校车站,乘坐6:30的校车。

2018年1月8日晨
2018年1月8日晨

一校两区,理科大楼到宿舍的距离长达25公里。交通不便,除了100元一次的出租车外,5元一次的校车则是唯一的选择。40分钟的车程后,校车准时抵达河东食堂门口,笔者愉快地开始用餐,同时在知乎上浏览最新的劝退信息。30分钟后,笔者掏出钥匙,打开办公室的大门。此时的办公室空无一人。打开显示器,一天的科研生活正式开始。

9:30,每周的组会开始,大家聚集在一起,交流领域内的文章和工作进展。两校区之间路途遥远,因此每周笔者只去办公室1-2次,剩下的日子则在宿舍工作,每周的例会时间便由此固定下来。

中餐和晚餐,笔者往往在河西食堂用餐,早已对每个窗口卖什么菜烂熟于胸。20:15,笔者结束手头的科研工作,前往停车场乘坐20:50的返程校车。又是40分钟的车程后,笔者抵达闵行校区校医院,一天的科研时光到此结束。

今天,上海轨道交通15号线正式开通,笔者却回想起了当年的“科研路”。正是坚持在往返两校区的路途中,笔者才产出了人生中最初的科研成果,开启了人生的科研路。

后记:这个系列目前的更新速度是每年一篇,那么我们明年再见吧。