Spaces:
Runtime error
Runtime error
import functools | |
import logging | |
import os | |
import sys | |
from time import time | |
from packaging.version import Version | |
import wandb | |
from typing import Dict, Optional, Any | |
if Version(wandb.__version__) < Version("0.20.0"): | |
WANDB_USE_SYNC = True | |
else: | |
WANDB_USE_SYNC = False | |
def log( | |
run, | |
data: Dict[str, Any], | |
step: Optional[int] = None, | |
commit: Optional[bool] = None, | |
sync: Optional[bool] = None, | |
) -> None: | |
if run is not None: | |
# Note: wandb changed the .log API with version 0.20.0. | |
# This includes: "Removed no-op sync argument from wandb.Run::log function" | |
# We didn't test whether sync has any function here. But since we did | |
# all our development with it, let's keep it here for now. | |
# See https://github.com/wandb/wandb/releases/tag/v0.20.0 | |
if WANDB_USE_SYNC: | |
run.log(data, step, commit, sync) | |
else: | |
run.log(data, step, commit) | |
else: | |
print(data) | |
# See: https://github.com/microsoft/Swin-Transformer/blob/main/logger.py | |
# See: https://github.com/Meituan-AutoML/Twins/blob/main/logger.py | |
def create_logger(output_dir: str, dist_rank: int, name: str) -> logging.Logger: | |
# create logger | |
logger = logging.getLogger(name) | |
logger.setLevel(logging.DEBUG) | |
logger.propagate = False | |
# create formatter | |
fmt = "[%(asctime)s %(name)s]: %(levelname)s %(message)s" | |
# create console handlers | |
if name.endswith("main"): | |
console_handler = logging.StreamHandler(sys.stdout) | |
console_handler.setLevel(logging.INFO) | |
console_handler.setFormatter( | |
logging.Formatter(fmt=fmt, datefmt="%Y-%m-%d %H:%M:%S") | |
) | |
logger.addHandler(console_handler) | |
# create file handlers | |
file_handler = logging.FileHandler( | |
os.path.join(output_dir, f"{name}.log"), mode="a" | |
) | |
file_handler.setLevel(logging.DEBUG) | |
file_handler.setFormatter(logging.Formatter(fmt=fmt, datefmt="%Y-%m-%d %H:%M:%S")) | |
logger.addHandler(file_handler) | |
return logger | |
def log_decorator(logger, _func=None): | |
def log_decorator_info(func): | |
def log_decorator_wrapper(*args, **kwargs): | |
"""Create a list of the positional arguments passed to function. | |
- Using repr() for string representation for each argument. repr() is similar to str() only | |
difference being it prints with a pair of quotes and if we calculate a value we get more | |
precise value than str(). | |
""" | |
# py_file_caller = getframeinfo(stack()[1][0]) | |
local_rank = os.environ.get("LOCAL_RANK", default=None) | |
rank = os.environ.get("LOCAL_RANK", default=None) | |
try: | |
"""log return value from the function""" | |
start_time = time() | |
value = func(*args, **kwargs) | |
if local_rank is None or rank is None: | |
logger.info( | |
f"Function '{func.__name__}' - Execution time: {(time() - start_time):.1f} seconds." | |
) | |
else: | |
logger.info( | |
f"Function '{func.__name__}' - Execution time: {(time() - start_time):.1f} " | |
f"seconds on rank {os.environ['RANK']} and local_rank {os.environ['LOCAL_RANK']}." | |
) | |
except Exception as err: | |
logger.error(f"Exception: {err}") | |
raise | |
return value | |
# Return the pointer to the function | |
return log_decorator_wrapper | |
# Decorator was called with arguments, so return a decorator function that can read and return a function | |
if _func is None: | |
return log_decorator_info | |
# Decorator was called without arguments, so apply the decorator to the function immediately | |
else: | |
return log_decorator_info(_func) | |