训练与检验模块
概述
core.py 是 PhyMLP Kit 工具包的核心模块,提供配置文件读取、参数解析、作业提交、任务管理等核心功能。该模块包含两个主要类:PUBLIC 和 RUN,共同构成了整个系统的基础架构。
模块架构
模块架构图
core.py 核心模块
├── PUBLIC 类
│ ├── 配置管理
│ ├── 参数解析
│ └── 格式处理
└── RUN 类
├── 训练管理
│ ├── 训练命令生成
│ └── 训练执行
├── 计算管理
│ ├── 计算目录管理
│ ├── 输入文件重写
│ └── 计算执行
└── 作业调度
├── SLURM作业提交
├── 作业状态监控
└── 后处理执行
PUBLIC 类详解
类概述
PUBLIC 类是公共配置管理器,负责:
配置参数管理:定义和维护所有配置参数
配置文件解析:读取和解析
Inputfile.txt配置文件参数验证:验证参数的有效性和完整性
默认值设置:提供合理的默认配置
初始化参数
class PUBLIC:
def __init__(self):
self.current_path = os.getcwd()
self.Inputfile = "Inputfile"
# 所有允许的命令
self.all_keys = [
"PhyMLP_load", "lmp_mpi_load", 'train', 'extxyz_load',
'init_PhyMLP', 'iteration_limit', 'al_mode', 'save_to',
"pot_PhyMLP_load", 'calculate', 'properties', "crystal_structure",
"lattice", "atomic_mass", "vaspkit_load"
]
# 所有支持的计算属性
self.all_properties = ["E-V", "Elastic", "phonon", "P-V"]
# 设置默认参数
self._set_default_parameters()
默认参数设置
参数名 |
默认值 |
描述 |
|---|---|---|
|
“./” |
VASPKIT 工具路径 |
|
“./” |
PhyMLP 安装路径 |
|
“./lmp_mpi” |
LAMMPS 可执行文件路径 |
|
“True” |
是否执行训练 |
|
“./train.exyz” |
训练集文件路径 |
|
“06.PhyMLP” |
初始势函数文件 |
|
“5000” |
最大迭代次数 |
|
“nbh” |
训练模式 |
|
“./pot.PhyMLP” |
势函数保存路径 |
|
“True” |
是否执行计算 |
|
[“E-V”] |
计算性质列表 |
|
“bcc” |
晶体结构类型 |
|
“1” |
晶格常数 |
|
“1” |
原子质量 |
核心方法详解
Read 方法
- PUBLIC.Read(Inputfile)
读取并解析配置文件
- Parameters:
Inputfile (str) – 配置文件路径
- Returns:
解析后的配置信息列表
- Return type:
- Raises:
SystemExit – 当文件读取失败时
功能说明:
打开指定配置文件
逐行读取内容
跳过注释行和空行
移除行内注释
返回有效配置行列表
代码实现:
def Read(self, Inputfile): input_informations = [] try: with open(Inputfile, 'r', encoding='utf-8') as readfile: read_informations = readfile.readlines() for read_information in read_informations: new_line = "".join(read_information.split()) # 移除空白字符 if new_line.startswith('#') or len(new_line) == 0: continue # 跳过注释行和空行 new_line = new_line.split("#")[0] # 移除行内注释 input_informations.append(new_line) return input_informations except Exception as e: print(f"文件读取错误: {e}") sys.exit(1)
Key_and_parament 方法
- PUBLIC.Key_and_parament(input_informations)
解析配置信息并设置类属性
- Parameters:
input_informations (list) – 配置信息列表
- Raises:
SystemExit – 当配置错误时
解析逻辑:
键名映射:处理大小写和命名差异
key_mapping = { 'phymlp_load': 'PhyMLP_load', 'lmp_mpi_load': 'lmp_mpi_load', 'train': 'train', 'extxyz_load': 'extxyz_load', 'init_phymlp': 'init_PhyMLP', # ... 其他映射 }
值解析:支持多种值格式 - 字符串(带引号):”path/to/file” - 数字:5000 - 布尔值:True/False - 列表:[“E-V”, “Elastic”]
特殊处理:
properties参数的特殊解析属性设置:使用
setattr()动态设置类属性
_parse_value 方法
- PUBLIC._parse_value(value_str)
安全地解析配置值字符串
- Parameters:
value_str (str) – 原始值字符串
- Returns:
解析后的值
- Return type:
any
解析策略:
字符串检测:检查是否被引号包围
字面量解析:尝试使用
ast.literal_eval()解析回退机制:解析失败时返回原始字符串
示例:
输入:
'"path/to/file"'→ 输出:"path/to/file"输入:
'5000'→ 输出:5000输入:
'["E-V", "Elastic"]'→ 输出:["E-V", "Elastic"]输入:
'True'→ 输出:True
Bool_commands 方法
- PUBLIC.Bool_commands(bool_command)
验证并转换布尔命令
- Parameters:
bool_command (any) – 布尔命令值
- Returns:
转换后的布尔值
- Return type:
- Raises:
SystemExit – 当值无效时
支持格式:
RUN 类详解
类概述
RUN 类继承自 PUBLIC,负责:
训练任务管理:机器学习势的训练流程控制
计算任务管理:各种物性计算的执行控制
作业调度:SLURM 作业提交和监控
后处理:计算结果的处理和分析
作业调度系统
SLURM 作业提交
- RUN.slurm_sub(job_name, command='')
提交作业到 SLURM 调度系统
- Parameters:
- Raises:
subprocess.CalledProcessError – 作业提交失败时
RuntimeError – 作业监控过程中出错时
作业脚本生成:
根据作业类型生成不同的 SLURM 脚本:
# 训练作业脚本 #!/bin/bash #SBATCH -J calculate_train #SBATCH -N 1 #SBATCH -p xahcnormal #SBATCH --ntasks-per-node=32 mpirun -n 32 {train_command} > train-output.log # 计算作业脚本 #!/bin/bash #SBATCH -J calculate_{job_name} #SBATCH -N 1 #SBATCH -p xahcnormal #SBATCH --ntasks-per-node=32 mpirun -n 32 {lmp_mpi_load} -i {job_name}.in > output.log
执行流程:
创建作业目录
生成 SLURM 脚本文件
提交作业到队列
获取作业 ID
启动作业监控
_wait_for_job_completion 方法
_post_process 方法
_process_phonon 方法
- RUN._process_phonon(current_path, job_name)
声子计算的特殊后处理
处理流程:
# 1. 运行 phonolammps phonolammps PHONON.in -c POSCAR --dim 2 2 2 # 2. 生成 KPATH python get_KPATH.py >> PHONON.log rm ./get_KPATH.py # 3. 修改维度设置 sed -i 's/DIM =/DIM = 2 2 2/' ./KPATH.phonopy # 4. 生成声子谱 phonopy -c POSCAR -p -s KPATH.phonopy
训练管理方法
Train_commands 方法
- RUN.Train_commands(drive)
生成训练命令和准备训练目录
- Parameters:
drive (bool) – 是否执行训练
- Returns:
(训练目录路径, 训练命令) 或 (“No_path”, “Skip_step”)
- Return type:
- Raises:
SystemExit – 训练目录创建失败时
执行步骤:
检查训练开关
创建训练目录
复制初始势函数和训练集
生成训练命令
训练命令格式:
{PhyMLP_load}/bin/MLP train {init_PhyMLP} {extxyz_load} \ --save_to={save_to} \ --iteration_limit={iteration_limit} \ --al_mode={al_mode}
Train 方法
计算管理方法
Calculate_dir 方法
- RUN.Calculate_dir(drive)
创建计算目录并复制必要文件
- Parameters:
drive (bool) – 是否执行计算
- Raises:
SystemExit – 目录创建或文件复制失败时
执行步骤:
检查计算开关
去重计算属性列表
为每个属性: - 从 PhyMLP 模板目录复制计算目录 - 复制势函数文件到计算目录
Rewrite_lammps_in 方法
输入文件修改方法
E-V 计算修改
def _modify_ev_in(self):
lattice_min = '%.2f' % (float(self.lattice) - float(self.lattice) * 0.3)
interval = '%.2f' % (2 * float(self.lattice) * 0.3 / 100)
commands = [
f"sed -i 's/define_mass/mass 1 {self.atomic_mass}/' ./E-V/E-V.in",
f"sed -i 's/crystal_structure/{self.crystal_structure}/' ./E-V/E-V.in",
f"sed -i 's/lattice_constant/{lattice_min}+{interval}*$i/' ./E-V/E-V.in"
]
P-V 计算修改
def _modify_pv_in(self):
interval = '%.6f' % (float(self.lattice) * 0.1 / 50)
basis_volume = float(self.lattice) ** 3
commands = [
f"sed -i 's/define_mass/mass 1 {self.atomic_mass}/' ./P-V/P-V.in",
f"sed -i 's/crystal_structure/{self.crystal_structure}/' ./P-V/P-V.in",
f"sed -i 's/lattice_constant/{self.lattice}-{interval}*$i/' ./P-V/P-V.in",
f"sed -i 's/basis_volume/{basis_volume}/' ./P-V/P-V.in"
]
Execute 方法
使用示例
基本使用流程
#!/usr/bin/env python3
"""core.py 模块使用示例"""
import os
import sys
# 导入核心模块
from phymlp.utils.core import RUN
def main():
# 1. 创建 RUN 实例
run = RUN()
# 2. 读取配置文件
print("步骤1: 读取配置文件...")
input_info = run.Read("Inputfile.txt")
# 3. 解析配置参数
print("步骤2: 解析配置参数...")
run.Key_and_parament(input_info)
# 4. 执行训练(如果需要)
print("步骤3: 准备训练...")
train_drive = run.Bool_commands(run.train)
train_dir, train_cmd = run.Train_commands(train_drive)
print("步骤4: 执行训练...")
run.Train(train_drive, train_dir, train_cmd)
# 5. 执行计算(如果需要)
print("步骤5: 准备计算...")
calc_drive = run.Bool_commands(run.calculate)
run.Calculate_dir(calc_drive)
run.Rewrite_lammps_in(calc_drive)
print("步骤6: 执行计算...")
run.Execute(calc_drive)
print("所有任务完成!")
if __name__ == "__main__":
main()
自定义配置示例
def custom_training_workflow():
"""自定义训练工作流"""
# 创建配置管理器
config = PUBLIC()
# 手动设置参数
config.PhyMLP_load = "/opt/phymlp"
config.lmp_mpi_load = "/usr/local/bin/lmp_mpi"
config.train = True
config.extxyz_load = "./data/training_set.extxyz"
config.init_PhyMLP = "10.PhyMLP"
config.iteration_limit = 10000
config.al_mode = "nbh"
# 创建运行管理器
runner = RUN()
# 继承配置
for attr in dir(config):
if not attr.startswith('_'):
setattr(runner, attr, getattr(config, attr))
# 执行训练
train_dir, train_cmd = runner.Train_commands(True)
runner.Train(True, train_dir, train_cmd)
print("自定义训练完成!")
批量计算示例
def batch_property_calculation():
"""批量执行多种物性计算"""
# 初始化
runner = RUN()
# 设置计算参数
runner.calculate = True
runner.properties = ["E-V", "Elastic", "P-V", "phonon"]
runner.crystal_structure = "fcc"
runner.lattice = "3.615" # 铜的晶格常数
runner.atomic_mass = "63.546"
runner.pot_PhyMLP_load = "./train/pot.PhyMLP"
# 准备计算
runner.Calculate_dir(True)
runner.Rewrite_lammps_in(True)
# 执行计算
runner.Execute(True)
print("批量计算完成!")
错误处理机制
配置文件错误
常见错误: - 文件不存在 - 格式错误 - 参数无效
处理方式:
try:
input_info = run.Read("Inputfile.txt")
run.Key_and_parament(input_info)
except SystemExit as e:
print(f"配置文件错误: {e}")
# 提供修复建议
print("请检查 Inputfile.txt 文件格式和内容")
except Exception as e:
print(f"未知错误: {e}")
作业提交错误
常见错误: - SLURM 命令不存在 - 权限不足 - 队列不可用
处理方式:
def safe_slurm_sub(runner, job_name, command=""):
"""安全的作业提交"""
try:
runner.slurm_sub(job_name, command)
except subprocess.CalledProcessError as e:
print(f"作业提交失败: {e}")
print(f"返回码: {e.returncode}")
print(f"输出: {e.output}")
except Exception as e:
print(f"作业执行错误: {e}")
参数验证
验证函数示例:
def validate_parameters(runner):
"""验证核心参数"""
errors = []
# 检查必要路径
if not os.path.exists(runner.PhyMLP_load):
errors.append(f"PhyMLP路径不存在: {runner.PhyMLP_load}")
if not os.path.exists(runner.lmp_mpi_load):
errors.append(f"LAMMPS路径不存在: {runner.lmp_mpi_load}")
# 检查训练集
if runner.train and not os.path.exists(runner.extxyz_load):
errors.append(f"训练集文件不存在: {runner.extxyz_load}")
# 检查势函数
if runner.calculate and not os.path.exists(runner.pot_PhyMLP_load):
errors.append(f"势函数文件不存在: {runner.pot_PhyMLP_load}")
# 返回错误列表
return errors
性能优化建议
并发作业提交
对于多个计算任务,可以优化提交策略:
def parallel_execute(runner, max_concurrent=2):
"""并行执行计算任务"""
import threading
from queue import Queue
def worker():
while True:
job_name = job_queue.get()
if job_name is None:
break
runner.slurm_sub(job_name)
job_queue.task_done()
# 创建作业队列
job_queue = Queue()
for prop in runner.properties:
job_queue.put(prop.upper())
# 创建工作线程
threads = []
for _ in range(min(max_concurrent, len(runner.properties))):
t = threading.Thread(target=worker)
t.start()
threads.append(t)
# 等待所有作业完成
job_queue.join()
# 停止工作线程
for _ in range(len(threads)):
job_queue.put(None)
for t in threads:
t.join()
资源监控
监控系统资源使用情况:
def monitor_resources(job_id):
"""监控作业资源使用"""
import time
while True:
# 使用 sacct 命令获取资源信息
cmd = f"sacct -j {job_id} --format=JobID,State,CPUTime,MaxRSS,NodeList"
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
if result.returncode == 0:
print(f"资源监控: {result.stdout}")
# 等待一段时间
time.sleep(30)
常见问题解答
Q1: 配置文件读取失败,提示编码错误
解决方案:指定正确的文件编码
# 修改 Read 方法中的文件打开方式
with open(Inputfile, 'r', encoding='utf-8-sig') as readfile:
Q2: SLURM 作业提交后立即失败
可能原因: 1. LAMMPS 可执行文件路径错误 2. 势函数文件不存在 3. 输入文件格式错误
检查步骤:
1. 验证 lmp_mpi_load 路径
2. 检查计算目录中的势函数文件
3. 查看生成的输入文件
Q3: 训练过程中出现 “参数不正确” 错误
解决方案:
1. 检查 Inputfile.txt 中的参数拼写
2. 确保值格式正确
3. 查看 Key_and_parament 方法的输出
Q4: 如何自定义后处理脚本
扩展方法:
class CustomRUN(RUN):
def _post_process(self, job_name, current_path):
"""自定义后处理"""
# 调用父类方法
super()._post_process(job_name, current_path)
# 添加自定义处理
if job_name.lower() == "e-v":
self._custom_ev_analysis(current_path, job_name)
def _custom_ev_analysis(self, current_path, job_name):
"""自定义 E-V 分析"""
custom_cmd = f"cd {current_path}/{job_name} && python custom_analysis.py"
subprocess.Popen(custom_cmd, shell=True).wait()
API 参考
类列表
- class PUBLIC
公共配置管理器
主要方法:
Read(Inputfile):读取配置文件Key_and_parament(input_informations):解析配置Bool_commands(bool_command):验证布尔命令
- class RUN
运行管理器(继承自 PUBLIC)
主要方法:
slurm_sub(job_name, command=""):提交 SLURM 作业Train_commands(drive):生成训练命令Train(train_drive, train_dir, train_command):执行训练Calculate_dir(drive):准备计算目录Rewrite_lammps_in(drive):重写输入文件Execute(drive):执行计算任务
异常列表
- exception SystemExit
当配置错误或执行失败时抛出。
相关链接
更新日志
版本历史
版本 |
更新内容 |
|---|---|
v1.0.0 |
初始版本,基础功能实现 |
v1.1.0 |
添加配置解析和验证 |
v1.2.0 |
集成 SLURM 作业调度 |
v1.3.0 |
改进错误处理和日志 |
v1.4.0 |
添加多种计算类型支持 |
计划功能
更多调度器支持:支持 PBS、LSF 等其他作业调度系统
资源自适应:根据可用资源自动调整计算参数
进度报告:实时训练和计算进度报告
结果分析:集成自动化结果分析工具
Web 界面:提供 Web 管理界面
Note
如果你在使用过程中遇到问题或有改进建议,请在项目仓库提交 Issue。