| from boltzgen.utils.quiet import quiet_startup |
|
|
| quiet_startup() |
|
|
| import os |
|
|
| |
| os.environ.setdefault("CUEQ_DEFAULT_CONFIG", "1") |
| os.environ.setdefault("CUEQ_DISABLE_AOT_TUNING", "1") |
|
|
| from typing import List, Optional, Union |
|
|
| import torch |
| from omegaconf import OmegaConf, listconfig |
| from pytorch_lightning import LightningModule, Trainer |
|
|
| from pytorch_lightning.strategies import DDPStrategy |
|
|
| from boltzgen.task.predict.data_from_generated import FromGeneratedDataModule |
| from boltzgen.task.predict.writer import ( |
| DesignWriter, |
| FoldingWriter, |
| ) |
| from boltzgen.task.task import Task |
| from boltzgen.utils.pipeline_progress_bar import PipelineProgressBar |
| from boltzgen.model.models.boltz import Boltz |
|
|
|
|
| class Predict(Task): |
| """A task to run model inference.""" |
|
|
| def __init__( |
| self, |
| data: Union[FromGeneratedDataModule], |
| writer: Union[DesignWriter, FoldingWriter], |
| checkpoint: str, |
| output: str, |
| name: str, |
| recycling_steps: int, |
| sampling_steps: int, |
| diffusion_samples: int = 1, |
| keys_dict_out: Optional[List] = None, |
| keys_dict_batch: Optional[List] = None, |
| slurm: bool = False, |
| matmul_precision: Optional[str] = None, |
| trainer: Optional[dict] = None, |
| override: Optional[dict] = None, |
| debug: bool = False, |
| use_ema: bool = False, |
| write_manifest: bool = False, |
| compile_pairformer: bool = False, |
| compile_structure: bool = False, |
| checkpoint_diffusion_conditioning: bool = False, |
| ) -> None: |
| """Initialize the task. |
| |
| Parameters |
| ---------- |
| checkpoint : str |
| The path to the model checkpoint. |
| output : str |
| The path to save the inference results. |
| slurm : bool, optional |
| Whether to run on SLURM, by default False |
| matmul_precision : Optional[str], optional |
| The matmul precision, by default None |
| trainer : Optional[dict], optional |
| The configuration for the trainer, by default None |
| override : Optional[dict], optional |
| The override configuration for the model, by default None |
| |
| """ |
| self.data = data |
| self.checkpoint = checkpoint |
| self.output = output |
| self.slurm = slurm |
| self.matmul_precision = matmul_precision |
| self.trainer = trainer |
| self.override = override if override is not None else {} |
| self.predict_args = { |
| "recycling_steps": recycling_steps, |
| "sampling_steps": sampling_steps, |
| "diffusion_samples": diffusion_samples, |
| } |
| if keys_dict_batch is not None: |
| self.predict_args["keys_dict_batch"] = keys_dict_batch |
| if keys_dict_out is not None: |
| self.predict_args["keys_dict_out"] = keys_dict_out |
| self.debug = debug |
| self.use_ema = use_ema |
| self.write_manifest = write_manifest |
| self.writer = writer |
| self.compile_pairformer = compile_pairformer |
| self.compile_structure = compile_structure |
| self.checkpoint_diffusion_conditioning = checkpoint_diffusion_conditioning |
|
|
| def run(self, config: OmegaConf = None, run_prediction=True) -> None: |
| |
| quiet_startup() |
|
|
| |
| if len(self.data.predict_set) == 0: |
| print("No predictions required") |
| return |
|
|
| |
| torch.set_grad_enabled(False) |
|
|
| |
| if self.matmul_precision is not None: |
| torch.set_float32_matmul_precision(self.matmul_precision) |
|
|
| |
| if self.trainer is None: |
| self.trainer = {} |
|
|
| |
| devices = self.trainer.get("devices", 1) |
|
|
| if self.debug: |
| if isinstance(devices, int): |
| devices = 1 |
| elif isinstance(devices, (list, listconfig.ListConfig)): |
| devices = [devices[0]] |
| self.trainer["devices"] = devices |
| self.data.num_workers = 0 |
|
|
| |
| if self.slurm: |
| self.trainer["devices"] = int( |
| os.environ.get("SLURM_NTASKS_PER_NODE", "auto") |
| ) |
| self.trainer["num_nodes"] = int(os.environ.get("SLURM_NNODES", 1)) |
|
|
| |
| self.model_module: LightningModule = Boltz.load_from_checkpoint( |
| self.checkpoint, |
| strict=True, |
| use_ema=self.use_ema, |
| checkpoint_diffusion_conditioning=self.checkpoint_diffusion_conditioning, |
| map_location="cpu", |
| weights_only=False, |
| predict_args=self.predict_args, |
| **self.override, |
| ) |
| self.model_module.eval() |
|
|
| if self.compile_pairformer: |
| self.model_module.is_pairformer_compiled = True |
| self.model_module.pairformer_module = torch.compile( |
| self.model_module.pairformer_module, dynamic=True, fullgraph=False |
| ) |
| if self.compile_structure: |
| self.model_module.structure_module.score_model.is_token_transformer_compiled = True |
| self.model_module.structure_module.score_model.token_transformer = ( |
| torch.compile( |
| self.model_module.structure_module.score_model.token_transformer, |
| dynamic=True, |
| fullgraph=False, |
| ) |
| ) |
|
|
| |
| strategy = "auto" |
| num_devices = ( |
| len(devices) |
| if isinstance(devices, (list, listconfig.ListConfig)) |
| else devices |
| ) |
| if num_devices > 1: |
| strategy = DDPStrategy() |
| if num_devices > len(self.data.predict_set): |
| devices = max(1, len(self.data.predict_set)) |
| msg = f"Fewer designs than devices. Setting devices to {devices}." |
| print(msg) |
| self.trainer["devices"] = devices |
|
|
| self.lightning_trainer = Trainer( |
| default_root_dir=self.output, |
| strategy=strategy, |
| callbacks=[self.writer] |
| + ( |
| [PipelineProgressBar()] |
| if os.environ.get("BOLTZGEN_PIPELINE_STEP") |
| else [] |
| ), |
| **self.trainer, |
| ) |
| if run_prediction: |
| |
| self.lightning_trainer.predict( |
| self.model_module, datamodule=self.data, return_predictions=False |
| ) |
| del self.model_module |
|
|