PaddleMaterials Trainer 文档

Ⅰ · 用户指南

1.1 快速上手

# 性质预测(单卡)
python property_prediction/train.py -c property_prediction/configs/spherenet/spherenet_qm9_U0.yaml

# 原子间势(多卡)
python -m paddle.distributed.launch --gpus="0,1,2,3" \
    interatomic_potentials/train.py -c interatomic_potentials/configs/chgnet/chgnet_mptrj.yaml

# 结构生成(单卡)
python structure_generation/train.py -c structure_generation/configs/diffcsp/diffcsp_mp20.yaml

# 临时覆盖配置项(命令行追加 Key=Value)
python <task>/train.py -c <config.yaml> Trainer.max_epochs=50
6 个任务入口:property_prediction/(DimeNet++/MEGNet/SphereNet/iComformer)、interatomic_potentials/(CHGNet/M3GNet/SphereNet)、electronic_structure/(InfGCN/MatENO)、spectrum_enhancement/(SFIN)、spectrum_elucidation/(DiffNMR 系)、structure_generation/(DiffCSP/MatterGen)。完整模型清单见 全任务模型总览
预测式 vs 生成式:前 4 个任务是预测式(train+eval 走 BaseTrainer,推理走 predict.py);后 2 个是生成式(train 走 BaseTrainer,生成走 sample.py + Sampler)。两者模型契约不同,见 §2.3。

1.2 我想做哪件事

flowchart TD Q(["我想做什么?"]) Q --> W1["从头训练"] --> C1["do_train=True
python train.py -c config"] Q --> W2["断点续训"] --> C2["Trainer.resume_from_checkpoint=ckpt"] Q --> W3["加载预训练微调"] --> C3["Trainer.pretrained_model_path=权重"] Q --> W4["只评估/测试"] --> C4["do_train=False do_eval=True
pretrained_model_path=权重"] Q --> W5["多卡加速"] --> C5["paddle.distributed.launch --gpus=..."]

1.3 配置文件

Global:
  do_train / do_eval / do_test : True
Trainer:
  max_epochs / max_iter / seed / output_dir
  eval_freq | eval_freq_steps     # 二选一(epoch 级 vs 步级 eval,互斥)
  save_freq | save_freq_steps     # 检查点节奏
  pretrained_model_path / resume_from_checkpoint
  use_amp / eval_with_no_grad / gradient_accumulation_steps
  best_metric_indicator / name_for_best_metric / greater_is_better
  use_tensorboard / use_visualdl / use_wandb
Model / Dataset / Optimizer / Vocabulary / Metric  # 按 __class_name__ 注册

1.4 Trainer 配置项

配置项作用例子
max_epochs最大训练轮数1000
max_iter全局步数预算,到步早停10000
eval_freq每 N epoch 验证(epoch 级 eval)1
eval_freq_steps每 N 步验证(步级 eval);设了即关闭 epoch 级200
save_freq / save_freq_stepslatest / step_N 检查点节奏2000
resume_from_checkpoint断点续训(含优化器+进度)latest.pdparams 路径
pretrained_model_path加载预训练权重(仅权重)权重路径
use_amp / amp_level混合精度True / 'O1'
gradient_accumulation_steps梯度累积2
eval_with_no_grad评估 no_grad(含高阶导则关)True
best_metric_indicator + name_for_best_metric + greater_is_betterbest 检查点评选口径eval_loss / mae / False

1.5 常见任务

从头训练

python <task>/train.py -c <config.yaml>

断点续训

python <task>/train.py -c <config.yaml> Trainer.resume_from_checkpoint=./output/.../latest.pdparams
恢复优化器状态 + 训练进度;勿与 pretrained_model_path 同用。

加载预训练微调

python <task>/train.py -c <config.yaml> Trainer.pretrained_model_path=./pretrained/model.pdparams

只评估 / 测试

python <task>/train.py -c <config.yaml> \
    Global.do_train=False Global.do_eval=True \
    Trainer.pretrained_model_path=./output/.../best.pdparams

步级 eval(长 epoch 用)

Trainer.eval_freq_steps=200 Trainer.save_freq_steps=2000
设了 eval_freq_steps,epoch 级 eval / epoch 级 best / by-epoch lr 全部关闭,改由步级 eval 接管。

1.6 运行后产物

best.pdparams

验证最优检查点,推理优先用。

latest.pdparams

最近检查点,续训用它。

step_N.pdparams

每 save_freq_steps 步存一个。

run.log

训练日志。

tensorboard/

曲线:tensorboard --logdir <dir>

config.yaml 快照

本次运行配置(含覆盖),便于复现。

output_dir 运行时自动加 _t_<时间戳>_s_<seed> 后缀。

1.7 训练时间线

flowchart LR S(["train.py -c config"]) --> A["装配:模型/数据/优化器"] A --> B["训练循环(逐 epoch)"] B --> C["每 log_freq 步打日志
按节奏存检查点"] C --> D{"按 eval 节奏评估"} D --> E["更新 best + 学习率"] E --> F{"还有 epoch 且未到 max_iter?"} F -- 是 --> B F -- 否 --> G(["产出:best/latest + 日志"])

Ⅱ · 开发者接入指南

2.1 装配全景

flowchart LR C(["YAML"]) --> V[build_vocab] V --> M["build_model
你的模型"] V --> D["build_dataloader
你的 Dataset+collate"] M --> O[build_optimizer] D --> O --> MM["build_metric
你的指标"] --> T[BaseTrainer] --> RUN(["train/eval"]) M -.注册.-> R["__class_name__/__init_params__
MODEL_REGISTRY(权重)"]

2.2 注册约定

Model:
  __class_name__: MyModel        # 类名,需 import 进对应 __init__.py
  __init_params__: { hidden_dim: 128 }
build 函数位置说明
build_model(cfg, vocab=None)models/__init__.pyvocab 注入(若构造函数接受)
build_dataloader(cfg, vocab=None)datasets/__init__.py读 Dataset.{train,val,test}
build_optimizer(cfg, model, max_epochs, n_steps)optimizer/含 lr scheduler
build_metric(cfg) / build_graph_converter / build_vocabmetrics/ · models/ · vocab/同注册模式
MODEL_REGISTRY(models/__init__.py)是预训练权重下载注册表(name→BCE url),与类的 import 注册是两回事。

2.3 模型契约

flowchart TD B(["batch=collate(samples)"]) --> F["model.forward(batch)"] F --> LD["loss_dict:{'loss':Tensor,...}"] --> BL["loss_dict['loss']→backward"] F --> PD["pred_dict:{...}"] --> MET["指标/预测"]
class MyModel(paddle.nn.Layer):
    def __init__(self, hidden_dim=128, vocab=None, **kwargs):
        super().__init__(); self.vocab=vocab; self.target_name="energy"
    def forward(self, batch):
        pred = self._compute(batch)
        loss = some_loss(pred, batch["label"])
        return {"loss_dict": {"loss": loss, "mae": paddle.mean(paddle.abs(pred-batch["label"]))},
                "pred_dict": {self.target_name: pred}}
    def before_train(self, trainer): ...   # 可选 hook

loss_dict["loss"] 是反向唯一入口;其它键可作 best 指标(name_for_best_metric)。

生成式模型(扩散:DiffNMR / DiffCSP / MatterGen)

生成式模型的 训练 也返回 loss_dict(BaseTrainer 优化),但 生成/采样 走独立的 sample() 方法 + Sampler,不经 Trainer:

# 训练(BaseTrainer 优化)
def forward(self, batch):
    return {"loss_dict": {"loss": total_loss, "loss_coord": ..., "loss_atom": ...}}

# 生成(sample.py 入口 + MolecularSampler/StructureSampler,不经 Trainer)
def sample(self, batch, num_inference_steps=1000, **kwargs):
    return generated_structures
预测式任务(性质/势/电子结构/图像增强)推理走 predict.py + BasePredictor 子类;生成式任务(NMR/结构)生成走 sample.py + ppmat/sampler/

2.4 数据集契约

class MyDataset(paddle.io.Dataset):
    def __getitem__(self, idx):
        return {"graph": pgl_graph, "x": np.ndarray, "y": np.ndarray, "id": idx, "info": {...}}
    def __len__(self): ...
collate_fn处理
DefaultCollatorndarray→stack、Mapping→递归、pgl.Graph→batch、Data→Batch.from_data_list
RadiusGraphCollator批量半径图 + triplet 偏移
DensityCollator体密度场:变长 padding + mask
节点特征键名:cart_coords / atom_types / x(RadiusGraphConverter 产出),接入已有模型需保持一致。

2.5 指标

(a) 函数式def metric(pred,label)->scalar,注册到 Metric 段。
(b) 流式:实现 update_step/compute_epoch/reset,框架在 epoch 边界聚合。
best 口径:best_metric_indicator + name_for_best_metric + greater_is_better

2.6 训练入口

config = OmegaConf.to_container(OmegaConf.merge(OmegaConf.load(c), OmegaConf.from_dotlist(args)), resolve=True)
vocab = build_vocab(config.get("Vocabulary"))
model = build_model(config["Model"], vocab=vocab)
loaders = read_dataloader_config(config, vocab=vocab)
opt, lr = build_optimizer(config["Optimizer"], model, config["Trainer"]["max_epochs"], len(loaders[0]))
trainer = BaseTrainer(config["Trainer"], model, *loaders[:2], optimizer=opt, lr_scheduler=lr,
                      compute_metric_func_dict=build_metric(config.get("Metric")))
if do_train: trainer.train()
if do_eval:  trainer.eval(loaders[1])
if do_test:  trainer.eval(loaders[2])

2.7 BaseTrainer 能力

能力配置
训练循环+反向+优化梯度累积、裁剪、AMP
检查点best/latest/step_N(分布式仅 rank0 写)
续训/预训练resume_from_checkpoint / pretrained_model_path
评估节奏eval_freq(epoch)或 eval_freq_steps(步)
lr 调度ReduceOnPlateau(按指标)或其它;by-epoch/by-step
日志/分布式/早停tb/vdl/wandb、fleet、max_iter

2.8 最小骨架

# my_model.py
class MyModel(paddle.nn.Layer):
    def __init__(self, hidden_dim=64, vocab=None, **kw):
        super().__init__(); self.linear=paddle.nn.Linear(hidden_dim,1)
    def forward(self, batch):
        pred=self.linear(batch["x"]).squeeze(-1)
        loss=paddle.nn.functional.mse_loss(pred,batch["y"])
        return {"loss_dict":{"loss":loss,"mae":paddle.mean(paddle.abs(pred-batch["y"]))},
                "pred_dict":{"y":pred}}
# ppmat/models/__init__.py 加: from .my_model import MyModel
# config.yaml: Model/Dataset/Optimizer/Trainer/Global 同标准结构

2.9 常见陷阱

Ⅲ · 贡献者 / 维护者指南

3.1 代码地图

模块职责
ppmat/trainer/base_trainer.py训练/评估循环、检查点、lr、日志、分布式
ppmat/datasets/__init__.py · collate_fn.pybuild_dataloader、DefaultCollator/Radius/Density
ppmat/datasets/build_field.py · build_* .py场/结构/分子/图像构建器
ppmat/datasets/density_dataset.py · grid_sampler.py密度数据集族、网格采样
ppmat/datasets/graph_utils/radius/radius_graph 等图工具
ppmat/models/__init__.py · common/graph_converter.pybuild_model/graph_converter、MODEL_REGISTRY、RadiusGraphConverter
ppmat/optimizer/ · metrics/ · vocab/优化器+lr、指标(函数式+流式)、词表
ppmat/predictor/ · sampler/ · schedulers/推理包、采样器、扩散调度
ppmat/utils/download、io(write_cube/calc_md5)、save_load、logger、misc、crystal、pgl_compat
ppmat/visualization/molecule/crystal/structure/volume/animation
<task>/{train,predict,sample}.py任务入口脚本
test/ · setup.py · requirements.txt · .pre-commit-config.yaml测试、打包、依赖、提交钩子

3.2 架构分层

flowchart TD L1["入口层 <task>/train.py"] --> L2["Trainer 层 BaseTrainer"] L2 --> L3["组件层 build_model/dataloader/optimizer/metric"] L3 --> L4["基础层 models/datasets/optimizer/metrics/vocab/utils"] L2 -.使用.-> U["utils: save_load / logger / download / io"] L4 -.注册.-> R["__class_name__ 反射 + MODEL_REGISTRY"]

分层原则:入口只编排;Trainer 不感知具体模型(只认 forward 契约);组件层走注册反射;基础层可独立单测。

3.3 新增一个任务(checklist)

  1. 建目录 <task>/,含 train.py / predict.py(或 sample.py) / configs/
  2. 实现模型(§2.3 契约),importppmat/models/__init__.py
  3. 实现数据集(§2.4),选/写 collate_fn,importppmat/datasets/__init__.py
  4. (按需)指标、graph converter、词表(注册到 vocab)。
  5. config 模板:Global/Trainer/Model/Dataset/Optimizer/Vocabulary/Metric。
  6. README:命令 + 结果表 + 数据准备说明。
  7. (可选)预训练权重:上传 BCE → MODEL_REGISTRY 登记 → 按 §3.8 打包。
  8. (可选)推理:实现/复用 ppmat/predictor/ 子类。
  9. 测试:test/test_<task>.py(契约、collate、小样本前向)。
  10. 冒烟:max_epochs=1 跑通 → 提交。

3.4 Trainer 内部机制

方法职责边界

方法职责
train()resume → epoch 循环(max_iter 早停)→ 每 epoch 调 train_epoch → epoch 级 streaming/log/save → eval 节奏门 → best/by-epoch lr
train_epoch(train,val)逐 batch forward/loss/backward(梯度累积+AMP+裁剪)→ opt.step + by-step lr → log(log_freq) → 步级 eval(eval_freq_steps) → step 检查点(save_freq_steps)
eval_epoch(loader, reset_streaming_metrics=)gather → compute_metric_func → 流式聚合(reset 受控)→ 返回 meters
_compute_streaming_metrics(stage, reset=)聚合 metric_modules:compute_epoch + 条件 reset

两套 eval 节奏(互斥)

flowchart TD G{"eval_freq_steps
是否设置?"} G -- "None(未设)" --> EP["epoch 级:每 eval_freq epoch → eval_epoch
→ best + by-epoch lr(在 train() 里)"] G -- "非空(已设)" --> ST["步级:每 eval_freq_steps 步 → eval_epoch(在 train_epoch 里)
→ best + latest + by-epoch lr;并关闭 epoch 级"]

检查点与分布式

lr / AMP / 累积

3.5 缓存子系统(密度数据集)

维护注意:缓存键当前不含 split 内容指纹;改 split 顺序需 overwrite=True 或清缓存。mmap 在某些网络 FS 不可用(原版即如此)。

3.6 配置系统

3.7 下载与注册表

3.8 预训练模型包契约

注册的预训练模型须用固定 archive 布局(见 docs/model_package.md):

<model_name>.zip
└── <model_name>/
    ├── <model_name>.yaml      # 配置
    └── checkpoints/
        └── best.pdparams       # 权重

包名、顶层目录、配置文件名须与 MODEL_REGISTRY 的 key 一致。FieldPredictor 等按此布局解析。

3.9 测试

3.10 依赖与发布

3.11 代码风格约定

3.12 维护注意事项(演进时)

↑ 顶部