[docs]@dataclasses.dataclassclassLoggingConfig:""" Configuration for logging. Parameters: project: name of the project in Weights & Biases entity: name of the entity in Weights & Biases log_to_screen: whether to log to the screen log_to_file: whether to log to a file log_to_wandb: whether to log to Weights & Biases log_format: format of the log messages """project:str="ace"entity:str="ai2cm"log_to_screen:bool=Truelog_to_file:bool=Truelog_to_wandb:bool=Truelog_format:str="%(asctime)s - %(name)s - %(levelname)s - %(message)s"level:Union[str,int]=logging.INFOdef__post_init__(self):self._dist=Distributed.get_instance()
[docs]defconfigure_logging(self,experiment_dir:str,log_filename:str):""" Configure the global `logging` module based on this LoggingConfig. """ifself.log_to_screenandself._dist.is_root():logging.basicConfig(format=self.log_format,level=self.level)elifself._dist.is_root():logging.basicConfig(level=logging.WARNING)else:# we are not rootlogging.basicConfig(level=logging.ERROR)logger=logging.getLogger()ifself.log_to_fileandself._dist.is_root():ifnotos.path.exists(experiment_dir):raiseValueError(f"experiment directory {experiment_dir} does not exist, ""cannot log files to it")log_path=os.path.join(experiment_dir,log_filename)fh=logging.FileHandler(log_path)fh.setLevel(self.level)fh.setFormatter(logging.Formatter(self.log_format))logger.addHandler(fh)
defconfigure_wandb(self,config:Mapping[str,Any],env_vars:Optional[Mapping[str,Any]]=None,**kwargs,):config_copy={**config}if"environment"inconfig_copy:logging.warning("Not recording environmental variables since 'environment' key is ""already present in config.")elifenv_varsisnotNone:config_copy["environment"]=env_vars# must ensure wandb.configure is called before wandb.initwandb=WandB.get_instance()wandb.configure(log_to_wandb=self.log_to_wandb)wandb.init(config=config_copy,project=self.project,entity=self.entity,dir=config["experiment_dir"],**kwargs,)defclean_wandb(self,experiment_dir:str):wandb=WandB.get_instance()wandb.clean_wandb_dir(experiment_dir=experiment_dir)
deflog_versions():importtorchlogging.info("--------------- Versions ---------------")logging.info("Torch: "+str(torch.__version__))logging.info("----------------------------------------")defretrieve_env_vars(names=ENV_VAR_NAMES)->Dict[str,str]:"""Return a dictionary of specific environmental variables."""output={}fornameinnames:try:value=os.environ[name]exceptKeyError:logging.warning(f"Environmental variable {name} not found.")else:output[name]=valuelogging.info(f"Environmental variable {name}={value}.")returnoutputdeflog_beaker_url(beaker_id=None):"""Log the Beaker ID and URL for the current experiment. beaker_id: The Beaker ID of the experiment. If None, uses the env variable `BEAKER_EXPERIMENT_ID`. Returns the Beaker URL. """ifbeaker_idisNone:try:beaker_id=os.environ["BEAKER_EXPERIMENT_ID"]exceptKeyError:logging.warning("Beaker Experiment ID not found.")returnNonebeaker_url=f"https://beaker.org/ex/{beaker_id}"logging.info(f"Beaker ID: {beaker_id}")logging.info(f"Beaker URL: {beaker_url}")returnbeaker_url@contextlib.contextmanagerdeflog_level(level):"""Temporarily set the log level of the global logger."""logger=logging.getLogger()# presently, data loading uses the root loggerold_level=logger.getEffectiveLevel()try:logger.setLevel(level)yieldfinally:logger.setLevel(old_level)