| from __future__ import annotations |
|
|
| import argparse |
| import logging |
| import os |
| from pathlib import Path |
|
|
| import yaml |
|
|
| from onescience.utils.uma.scripts.create_finetune_dataset import ( |
| compute_normalizer_and_linear_reference, |
| launch_processing, |
| ) |
| from onescience.utils.uma.units.mlip_unit.api.inference import UMATask |
|
|
|
|
| logging.basicConfig(level=logging.INFO) |
|
|
| TEMPLATE_DIR = Path("configs") |
| DATA_YAML_DIR = Path("data") |
| REGRESSION_LABEL_TO_TASK_YAML = { |
| "e": DATA_YAML_DIR / Path("uma_conserving_data_task_energy.yaml"), |
| "ef": DATA_YAML_DIR / Path("uma_conserving_data_task_energy_force.yaml"), |
| "efs": DATA_YAML_DIR / Path("uma_conserving_data_task_energy_force_stress.yaml"), |
| } |
| UMA_SM_FINETUNE_YAML = Path("uma_sm_finetune_template.yaml") |
|
|
|
|
| def create_yaml( |
| train_path: str, |
| val_path: str, |
| force_rms: float, |
| linref_coeff: list, |
| output_dir: str, |
| dataset_name: str, |
| regression_tasks: str, |
| |
| ): |
| data_task_yaml = TEMPLATE_DIR / REGRESSION_LABEL_TO_TASK_YAML[regression_tasks] |
| with open(data_task_yaml) as file: |
| template = yaml.safe_load(file) |
| template["dataset_name"] = dataset_name |
| template["normalizer_rmsd"] = force_rms |
| template["elem_refs"] = linref_coeff |
| template["train_dataset"]["splits"]["train"]["src"] = train_path |
| template["val_dataset"]["splits"]["val"]["src"] = val_path |
| |
| |
| |
| os.makedirs(output_dir / DATA_YAML_DIR, exist_ok=True) |
| with open( |
| output_dir / REGRESSION_LABEL_TO_TASK_YAML[regression_tasks], "w" |
| ) as yaml_file: |
| yaml.dump(template, yaml_file, default_flow_style=False, sort_keys=False) |
|
|
| uma_finetune_yaml = TEMPLATE_DIR / UMA_SM_FINETUNE_YAML |
| with open(uma_finetune_yaml) as file: |
| template_ft = yaml.safe_load(file) |
| |
| template_ft["defaults"][0]["data"] = REGRESSION_LABEL_TO_TASK_YAML[ |
| regression_tasks |
| ].stem |
| with open(output_dir / UMA_SM_FINETUNE_YAML, "w") as yaml_file: |
| yaml.dump(template_ft, yaml_file, default_flow_style=False, sort_keys=False) |
|
|
|
|
| if __name__ == "__main__": |
| parser = argparse.ArgumentParser() |
| parser.add_argument( |
| "--train-dir", |
| type=str, |
| required=True, |
| help="Directory of ASE atoms objects to convert for training.", |
| ) |
| parser.add_argument( |
| "--val-dir", |
| type=str, |
| required=True, |
| help="Directory of ASE atoms objects to convert for validation.", |
| ) |
| parser.add_argument( |
| "--uma-task", |
| type=str, |
| required=True, |
| choices=[t.value for t in UMATask], |
| help="choose a uma task to finetune", |
| ) |
| parser.add_argument( |
| "--regression-tasks", |
| type=str, |
| choices=["e", "ef", "efs"], |
| required=True, |
| help="Choose to finetune based on regression task set (you must have the corresponding labels in your dataset), can be energy (e), energy+force (ef) or energy+force+stress(efs)", |
| ) |
| |
| |
| |
| |
| |
| |
| parser.add_argument( |
| "--output-dir", |
| type=Path, |
| required=True, |
| help="Output directory to save required finetuning artifacts.", |
| ) |
| parser.add_argument( |
| "--num-workers", |
| type=int, |
| default=8, |
| help="Number of parallel workers for processing files.", |
| ) |
| args = parser.parse_args() |
| assert not Path( |
| args.output_dir |
| ).exists(), f"{args.output_dir} can't already exist, please choose a different dir" |
|
|
| |
| train_path = args.output_dir / "train" |
| launch_processing(args.train_dir, train_path, args.num_workers) |
| force_rms, linref_coeff = compute_normalizer_and_linear_reference( |
| train_path, args.num_workers |
| ) |
| val_path = args.output_dir / "val" |
| launch_processing(args.val_dir, val_path, args.num_workers) |
|
|
| create_yaml( |
| train_path=str(train_path), |
| val_path=str(val_path), |
| force_rms=float(force_rms), |
| linref_coeff=linref_coeff, |
| output_dir=args.output_dir, |
| dataset_name=args.uma_task, |
| regression_tasks=args.regression_tasks, |
| |
| ) |
| logging.info(f"Generated dataset and data config yaml in {args.output_dir}") |
| logging.info( |
| f"To run finetuning, run fairchem -c {args.output_dir}/{UMA_SM_FINETUNE_YAML}" |
| ) |
|
|