dpdata读取ABACUS输出与训练标签
从真实PW、LCAO、结构优化和MD输出提取能量、力与维里,检查缺失标签和结构精度,再导出DeepMD数据集。
阅读本篇目录
ABACUS算完之后,不能只把坐标复制成一个XYZ就当作训练集。还需要核对每一帧对应的能量、原子力、晶胞、元素顺序,以及应力到维里的单位转换。本篇使用鸢算科技已经完成的四组真实计算输出,按实际文件演示这些操作。
1 下载、运行与输出位置#
下载ABACUS数据读取操作包,保存为dpdata-abacus-labels.zip。附件提供ABACUS输入和日志、逐步结构、MD_dump,以及完整读取/绘图脚本;不附带赝势和轨道文件,也不重新运行ABACUS。
普通批作业可以解压后执行sbatch job.slurm。在已经分配的CPU资源内,也可以依次运行:
python3 -m zipfile -e dpdata-abacus-labels.zip .
cd dpdata-abacus-labels
bash setup.sh
bash run.sh
bash verify.sh
bash plot.sh
使用dpdata1.1.0及集群已有gpumdkit-1.5.8的Python环境,env.sh会加载所需路径并限制为1线程;这一步只调用Python数据工具,不运行GPUMD。results/保存提取结果和导出的数据集,plots/保存两张真实数据图。
2 先检查目录和计算类型#
SCF需要原计算目录中的INPUT、STRU和对应OUT.<suffix>/running_scf.log;优化还应保留running_relax.log与逐步STRU_IONj_D;MD需要running_md.log和MD_dump。
例如,suffix tutorial对应OUT.tutorial/,不能把不同任务的日志、结构和MD_dump拼在一起。格式别名里的pw或lcao不替你验证基组类型,应以真实INPUT中的basis_type为准。
import dpdata
pw = dpdata.LabeledSystem('input-data/pw-scf', fmt='abacus/pw/scf')
lcao = dpdata.LabeledSystem('input-data/lcao-scf', fmt='abacus/lcao/scf')
relax = dpdata.LabeledSystem('input-data/mos2-relax', fmt='abacus/pw/relax')
md = dpdata.LabeledSystem('input-data/al-npt-md', fmt='abacus/pw/md')
print(len(pw), len(lcao), len(relax), len(md))
本次得到1、1、2、81帧。优化与MD的帧不是独立平衡样本;这个例子用于格式与标签提取,不把短轨迹解释成收敛热力学数据。
3 查看有哪些标签,不给缺失数据补零#
| 真实计算 | 原子数 | 读取帧数 | 能量 | 力 | 维里 |
|---|---|---|---|---|---|
| PW Si SCF | 8 | 1 | 有 | 有 | 有 |
| LCAO Si SCF | 2 | 1 | 有 | 未输出 | 未输出 |
| MoS₂结构优化 | 3 | 2 | 有 | 有 | 有 |
| Al NPT MD | 32 | 81 | 有 | 有 | 有 |
LCAO这个源任务设置了cal_force 0和cal_stress 0。读取后力是空数组,维里字段不可用;它们不是“所有力和应力等于零”。本例不把这一组导出成带力标签的训练集。
print(lcao.data['energies'])
print(lcao.data.get('forces'))
print('virials' in lcao.data)
需要力或应力训练数据时,在原ABACUS输入里设置相应输出并进行真实计算;不要通过改数组形状来伪造标签。
4 能量与应力单位#
本例PW Si8的总能量为−857.07071222 eV;LCAO Si2为−256.82319796 eV。两组模型、基组和设置不同,不直接用绝对总能量比较哪种方法更好。
Al32 MD含0–80步,每步0.5 fs,共40 fs;首末电子能量分别为−1806.7178969与−1806.0380885 eV。图中除以32后展示每原子电子能量,它不是包括离子动能的MD总能量。

ABACUS此处输出的应力单位为kbar,dpdata的virials单位为eV。本例采用原生约定:
维里 = 应力 × 当前帧体积 × 0.000624150907446
这里体积单位ų,常数用于kbar→eV/ų。符号沿用ABACUS/dpdata的这条读取路径;与其他程序交换数据时,应核对各自的应力符号约定。不能漏乘体积,也不能把kbar数值直接存入eV字段。
5 优化结构精度:保留每步STRU#
本例优化日志将晶格常数打印为1.88973 Bohr,原STRU保存更多有效数字。当前dpdata优化读取路径使用日志中打印的晶格参数,因此与高精度STRU相比,晶胞最大差约4.74×10⁻⁵ Å,坐标最大差约2.69×10⁻⁵ Å。
这些差别很小,但说明数据精度受源文件输出位数限制。增加输出数组的小数位数不会恢复已经丢掉的信息。

附件对这条优化轨迹明确增加了一个示例数据步骤:第一帧取原始STRU,后续帧取对应的STRU_IONj_D,先按周期等价的分数坐标确认帧序,再替换晶胞和坐标;原能量、原子力保持不变,维里按新旧体积比换算,以保留同一应力。
这个步骤位于run.py中的restore_relax_geometry(),是附件中的显式数据整理,不是dpdata默认行为,也不修改软件安装。保存的fields.npz同时保留native_cells、native_coords和处理后的cells_A、coords_A。没有逐步STRU时,应承认日志精度边界,不能凭空补出高精度几何。
6 导出DeepMD数据集并回读#
数据完整后可以用:
md.to('deepmd/npy', 'my-training-data', prec='float64', set_size=1000)
back = dpdata.LabeledSystem('my-training-data', fmt='deepmd/npy')
print(back.data['coords'].shape, back.data['forces'].shape)
完整脚本用NumPy的float64类型指定精度,写出后逐项回读核对。示例已经为PW SCF、整理后的MoS₂优化和Al MD生成独立数据集,分别在各自结果目录的deepmd/下。
python3 -c "import json; v=json.load(open('results/VALIDATION.json')); print(v['results'])"
不要把同一条短轨迹相邻帧随意拆成训练/测试集后,就把误差当作跨结构泛化精度。本篇只完成数据读取、标签检查与存储往返;模型训练还应独立设计结构覆盖和数据划分。
source env.sh
python3 -c "import dpdata; s=dpdata.LabeledSystem('results/al-npt-md/deepmd', fmt='deepmd/npy'); print(len(s), s.data['coords'].shape, s.data['forces'].shape, s.data['virials'].shape)"
ls -lh plots/abacus-label-energy-stress.png plots/abacus-label-structures-precision.png
参考:dpdata格式、别名和读写方向。本文演示ABACUS的常见能量/力/维里输出;自旋约束、磁力或其他可选属性需再按对应版本与源文件检查,不从这四组例子推断全部可选标签都已具备。