PolarMACE外场数据与训练流程
用真实CP2K水分子标签准备外场HDF5、训练模型并检查能量力偶极与响应的适用范围。
阅读本篇目录
PolarMACE在局部MACE表示外加入长程静电和电荷/自旋约束。本例把已经完成的CP2K水分子能量、力、偶极和极化率数据用于实际外场训练,重点是输入约定、数据流转和结果检查。
**本例小模型用于教学复现。**它在测试点上的能量、力和偶极误差较小,但固定版本的旋转一致性与极化率响应存在下面列出的实际偏差,不能据此用作正式分子动力学势。
下载自有模型、完整标签、HDF5、转换脚本和四张数据图。本例环境为MACE0.3.16、Python3.11、PyTorch2.8.0+cu126、e3nn0.4.4、ASE3.29;新增依赖只安装到解压目录的.deps,不修改公共模块。
python3 -m zipfile -e mace-optional-practical-wave319-*.zip .
cd mace-optional-practical
bash run.sh
这一步只读取参考数值绘图。需要重新执行固定模型推断或原生转换时,在已分配的计算资源中先准备一次可选依赖:
bash setup.sh
脚本按固定URL下载并校验SHA256。需要可访问上游下载地址;也可先将DEPENDENCIES.json列出的原文件放进.dependency-downloads/,再运行同一脚本。目录中已有.deps时保留已有环境,不覆盖安装。
1 先弄清标签单位与场的方向#
CP2K标签来自PBE、DZVP-MOLOPT-SR-GTH、GTH赝势、600/50 Ry网格、12 Å非周期盒的H₂O计算。CP2K2026.2 P100构建采用GNU13.3、MPICH5.0.1、CUDA12.9、OpenBLAS0.3.33和ScaLAPACK2.2.3。
这里明确采用:能量eV、力eV/Å、偶极e·Å。total_charge=0,total_spin=1;后者是多重度2S+1,闭壳层水分子填1。原子charges的零值仅作占位,权重为0,不是DFT原子电荷标签。
CP2K外加势为V(r)=A·r,因此物理电场E=-A。本例模型的external_field按代码中的+G·μ约定接收电势梯度G:
G [V/Å] = A [原子单位] × 27.2113838565563 / 0.52917720859
物理电场 E = -G
1 e·Å = 4.803204271875351 Debye
程序不会替您自动纠正单位或符号。field_si这个参数也不是“将单位改成SI”的开关。
2 查看训练、验证与测试数据#
module load mace/0.3.16
export TORCH_FORCE_NO_WEIGHTS_ONLY_LOAD=1
python inspect_data.py
原生HDF5读到训练16、验证3、测试9个条件:10个零场训练几何加6个±0.0005 a.u.场;验证为3个零场几何;测试为另外3个零场几何,加同一个训练几何上的6个±0.001 a.u.场。后6个测试是已见结构上的场强外推,不是未见结构泛化。

为避免非周期邻居图的辅助晶胞因坐标绝对值变得很大,先把中性水分子的O从(6,6,6) Å平移到原点;键长、夹角和中性分子的偶极标签保持原值,原始坐标与平移量记在polar-data/SOURCE-MAP.json。原物理盒仍为12 Å;邻居图中的辅助cell不能拿来解释材料体积。
这版普通XYZ命令行没有自动映射外场向量。本包使用原生Configuration与HDF5属性保存external_field,并通过HDF5Dataset逐项读回非零向量。只往XYZ注释行添加一个同名字段,然后直接训练,可能仍然让模型收到零场。
3 看配置,再提交新的训练#
cat train-input/train.yml
sbatch train.sh
squeue -u "$USER"
# 作业完成后
tail -n 20 train-input/native.log
ls train-input/models
脚本申请P100单卡,原生命令为mace_run_train --config train.yml。实际200轮训练采用下面的配置,不向训练器传测试文件:
完整训练配置
name: ys319-polar
model: PolarMACE
train_file: ../polar-data/train.h5
valid_file: ../polar-data/valid.h5
atomic_numbers: '[1,8]'
E0s: '{1: -187.3920308781653, 8: -93.69601543908267}'
batch_size: 1
valid_batch_size: 1
max_num_epochs: 200
default_dtype: float64
seed: 20261108
ema: true
ema_decay: 0.99
swa: false
num_workers: 0
device: cuda
log_dir: logs
model_dir: models
checkpoints_dir: checkpoints
results_dir: results
lr: 0.005
weight_decay: 5.0e-10
config_type_weights: '{''Water'':1.0}'
r_max: 4.0
hidden_irreps: 16x0e+16x1o+16x2e
MLP_irreps: 16x0e
num_interactions: 2
correlation: 2
max_ell: 2
max_L: 2
num_radial_basis: 8
num_cutoff_basis: 5
clip_grad: 10.0
patience: 200
scheduler_patience: 30
eval_interval: 1
save_cpu: true
compute_stress: false
compute_avg_num_neighbors: false
avg_num_neighbors: 2.0
loss: energy_forces_dipole
error_table: EnergyDipoleRMSE
energy_weight: 1.0
forces_weight: 10.0
dipole_weight: 1000.0
atomic_multipoles_max_l: 1
field_feature_max_l: 1
atomic_multipoles_smearing_width: 1.0
field_feature_widths: '[1.0]'
num_recursion_steps: 2
add_local_electron_energy: true
field_si: false
include_electrostatic_self_interaction: false
field_norm_factor: 0.02
atomic_multipoles_max_l=1和field_feature_max_l=1保留向量级的多极/场特征;num_recursion_steps=2是模型更新次数,不是已经求解收敛了电子结构SCF。损失包含能量、力和偶极,没有直接训练极化率张量。E0来自训练集组成的最小二乘参照;所有样本都是H₂O,不能把这组H/O分配值解释为独立原子DFT能量。
本包为复现固定使用兼容MACE0.3.16旧接口的graph_longrange0.4.0。不要将0.4.4同名包直接混入本例;两版接口不同。后续版本应重新核对模型、依赖和物理性质。
4 先用固定模型推断#
bash predict.sh
bash predict.sh --field-z 0.01
--field-z填写物理电场V/Å,脚本再传入Gz=-Ez。默认使用inputs/example.xyz中O居原点的中性水分子,打印完整能量、3×3原子力、偶极向量和净电荷。自行训练完毕后可改模型:
bash predict.sh --model train-input/models/ys319-polar.model
5 实际结果要分两层看#
9个测试条件的能量RMSE为 1.568 meV/atom,力分量RMSE 0.02044 eV/Å,整分子偶极向量RMSE 0.01267 Debye。这些单位由原始标签独立换算,不直接照抄训练日志中按原子归一的标签名称。

但较小的点误差不能替代物理检查:将结构和场一起旋转后,本例最大力协变误差约0.00157 eV/Å;场导数得到的极化率相对完整DFT张量偏差约87.5%,其中yy方向为0、zz方向出现负值。能量对场的曲率、能量一阶导数与模型直接输出偶极之间也没有建立本例所需的一致性。

因此应保留训练、独立测试、旋转平移、坐标有限差分力、场导数与能量曲率这些不同检查。前面的直接偶极训练和直接极化率训练分别解决其标签任务,也不能自动当成满足外场哈密顿量关系的同一个模型。