|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
A Ray logger will receive logging info from different processes.
|
|
|
"""
|
|
|
|
|
|
import logging
|
|
|
import numbers
|
|
|
from typing import Dict
|
|
|
|
|
|
|
|
|
def concat_dict_to_str(dict: Dict, step):
|
|
|
output = [f"step:{step}"]
|
|
|
for k, v in dict.items():
|
|
|
if isinstance(v, numbers.Number):
|
|
|
output.append(f"{k}:{v:.3f}")
|
|
|
output_str = " - ".join(output)
|
|
|
return output_str
|
|
|
|
|
|
|
|
|
class LocalLogger:
|
|
|
def __init__(self, remote_logger=None, enable_wandb=False, print_to_console=False):
|
|
|
self.print_to_console = print_to_console
|
|
|
if print_to_console:
|
|
|
print("Using LocalLogger is deprecated. The constructor API will change ")
|
|
|
|
|
|
def flush(self):
|
|
|
pass
|
|
|
|
|
|
def log(self, data, step):
|
|
|
if self.print_to_console:
|
|
|
print(concat_dict_to_str(data, step=step), flush=True)
|
|
|
|
|
|
|
|
|
class DecoratorLoggerBase:
|
|
|
def __init__(self, role: str, logger: logging.Logger = None, level=logging.DEBUG, rank: int = 0, log_only_rank_0: bool = True):
|
|
|
self.role = role
|
|
|
self.logger = logger
|
|
|
self.level = level
|
|
|
self.rank = rank
|
|
|
self.log_only_rank_0 = log_only_rank_0
|
|
|
self.logging_function = self.log_by_logging
|
|
|
if logger is None:
|
|
|
self.logging_function = self.log_by_print
|
|
|
|
|
|
def log_by_print(self, log_str):
|
|
|
if not self.log_only_rank_0 or self.rank == 0:
|
|
|
print(f"{self.role} {log_str}", flush=True)
|
|
|
|
|
|
def log_by_logging(self, log_str):
|
|
|
if self.logger is None:
|
|
|
raise ValueError("Logger is not initialized")
|
|
|
if not self.log_only_rank_0 or self.rank == 0:
|
|
|
self.logger.log(self.level, f"{self.role} {log_str}")
|
|
|
|