1. 背景与目标

本文档总结 GAP-20(论文 An accurate and transferable machine learning potential for carbon)随附数据包的结构差异,以及将其中的 extxyz(extended XYZ)训练数据使用 dpdata 转换为 DeepMD(deepmd/npy)格式的可复现实操流程,并解释转换过程中出现的典型错误及其解决方法。


2. Carbon_GAP_20.tgztrain_GAP20_optB88vdW.xyz.gz 的区别

2.1 Carbon_GAP_20.tgz(发行/交付包)

该压缩包通常是“可运行交付包”,内容包括:

  • 势函数模型文件(GAP XML):用于 QUIP/LAMMPS 调用的 GAP 模型参数(如 SOAP/2b 等,存放于 Carbon_GAP_20/ 目录)
  • 训练数据集文件
    • Carbon_Training_Set_Total.xyz:训练数据全集(通常较大,包含多类构型)
    • Carbon_GAP_20_Training_Set.xyz:用于拟合 GAP-20 的训练子集
  • 辅助/示例文件
    • r6_innercut.xml:半解析 2-body 项
    • Example_Job/:LAMMPS 示例输入(如何加载/调用 GAP-20)

结论:Carbon_GAP_20.tgz 是“模型 + 数据 + 示例”的完整交付包。

2.2 train_GAP20_optB88vdW.xyz.gz(单独训练数据文件)

该文件通常是某一来源/某一 DFT 设置(例如 optB88-vdW)导出的训练数据,只包含数据,不包含 GAP XML 模型与示例作业文件。文件体积(11MB)偏小的常见原因是:

  • gzip 压缩对文本数据压缩比很高;
  • 该文件可能只是 Total 数据集的一部分(子集或某一路 functional 数据)。

3. 数据格式确认:extxyz/QUIP 风格特征

GAP-20 附带的训练数据常为 extxyz(extended XYZ)格式,典型特征:

  • 每帧第二行(comment 行)包含键值对,例如 energy=...pbc="T T T"Lattice="..."
  • Properties=... 指明每行原子信息包含 species/pos/force 等字段;
  • 部分帧包含 virial="..."(9 个数)字段,用于描述应力/维里相关信息。

4. dpdata 转换问题与根因分析

4.1 现象 A:CLI 报错 TypeError: 'str' object is not a mapping

典型触发方式:

  • 使用 dpdata CLI 默认逻辑读取 multi-system 文件(一个 xyz 中混有多个原子数/多个体系),但 CLI 默认按单体系(LabeledSystem)处理;
  • 或者参数使用不当(例如把输出目录写成 -o 而非 -O、type_map 写成 6 而非 C)。

结论:当输入文件实际上是多体系(MultiSystems)时,必须使用 dpdata 的 --multi 参数,或改用 Python 的 MultiSystems.from_file()

4.2 现象 B:Python MultiSystems.from_file() 报错 RuntimeError: system has virials, but this does not

根因:

  • 同一个体系/同一 formula(如 C64)下,部分帧在 comment 行包含 virial="...",部分帧没有该字段;
  • dpdata 在合并为一个 System 时要求标签字段一致,因此拒绝合并。

结论:需要让所有帧的标签一致:要么全部保留 virial,要么全部去掉 virial(或拆分成两套数据)。


5. 已验证可用的最终流程(推荐方案:去掉 virial + dpdata CLI multi 转换)

5.1 去掉 virial 字段(生成统一标签的 extxyz)

已验证可用命令:

sed "/^energy/s+virial.* cutoff+cutoff+g" Carbon_GAP_20_Training_Set.xyz > test.xyz

更稳健的推荐写法(只删除 virial="..." 字段本身,不依赖 cutoff 顺序):

sed '/^energy=/ s/ virial="[^"]*"//g' Carbon_GAP_20_Training_Set.xyz > test.xyz

5.2 使用 dpdata CLI 按 MultiSystems 转换为 DeepMD NPY

已验证可用命令:

dpdata test.xyz -i extxyz -t "C" --multi -o deepmd/npy -O deepmd_data

关键参数说明:

  • -i extxyz:指定输入格式为 extxyz;
  • -t C:type_map 使用元素符号(碳为 C),不要写原子序数 6
  • --multi:告诉 dpdata 输入为多体系(MultiSystems),否则会按单体系解析并报错;
  • -o deepmd/npy:输出为 DeepMD numpy 格式;
  • -O deepmd_data:输出目录。

5.3 输出结果验证

转换成功后可做快速抽查:

find deepmd_data -maxdepth 2 -type d | head
find deepmd_data -maxdepth 3 -name "*.npy" | head

6. virial 字段含义与训练建议

6.1 virial 的物理意义

virial 通常表示体系的 维里张量(3×3),与应力张量(stress)密切相关。常见关系(约定不同可能有符号差异):

  • stress ≈ - virial / volume

因此很多软件在训练/输出时会存两种等价信息:

  • stress(单位压力,如 GPa)
  • virial(相当于 stress×volume,单位可能更接近能量,如 eV)

6.2 为什么有些帧没有 virial

典型原因:

  • 周期 bulk 构型(有晶胞)通常提供应力/virial;
  • cluster/真空 slab/非周期构型可能不提供应力,因此没有 virial。

6.3 对 DeepMD 训练的影响

  • 若仅训练 能量 + 力:virial 可忽略,去掉后不会影响能量/力拟合;
  • 若要训练 应力/体性质(NPT、弹性常数等):应保留 virial,但必须保证数据集中标签一致,可采用:
    • 拆分数据:with_virialno_virial 分开训练/分阶段微调;
    • 或统一补齐(不建议补 0,除非训练时对 virial 权重设为 0)。

7. 附:多 Python 环境下运行 dpdata/IPython 的建议

在多 Python 环境中,为避免 dpdata/依赖版本混乱,推荐用目标解释器直接启动:

/path/to/python -m pip install -U dpdata ipython
/path/to/python -m IPython

或在 shell 中直接执行目标解释器的单行转换。


8. 结论

  1. Carbon_GAP_20.tgz 是“模型 + 数据 + 示例”的完整交付包;train_GAP20_optB88vdW.xyz.gz 是单独的训练数据文件(可能为子集/某 functional 导出)。

  2. GAP-20 训练数据为 extxyz/QUIP 风格,部分帧含 virial,导致 dpdata 合并时标签不一致。

  3. 通过 去掉 virial 字段 并在 dpdata CLI 中启用 --multi,可稳定将数据转换为 DeepMD deepmd/npy 格式:

    sed '/^energy=/ s/ virial="[^"]*"//g' Carbon_GAP_20_Training_Set.xyz > test.xyz
    dpdata test.xyz -i extxyz -t C --multi -o deepmd/npy -O deepmd_data