EvelynXuNU's picture
Deploy Multi-LexSum demo
ce7c1f0 verified
Raw
History Blame Contribute Delete
3.29 kB
"""Shared utilities: project paths, logging, deterministic seeding.
This module is the single source of truth for *where files live* in the
project. All other modules import path constants from here rather than
hard-coding paths, so the project is portable across machines/OSes.
"""
from __future__ import annotations
import logging
import os
import random
import sys
from pathlib import Path
import numpy as np
# ---------------------------------------------------------------------------
# Paths
# ---------------------------------------------------------------------------
# PROJECT_ROOT = parent of `src/`. Works on Windows, macOS, Linux.
PROJECT_ROOT: Path = Path(__file__).resolve().parent.parent
DATA_DIR: Path = PROJECT_ROOT / "data"
MODELS_DIR: Path = PROJECT_ROOT / "models"
RESULTS_DIR: Path = PROJECT_ROOT / "results"
DOCS_DIR: Path = PROJECT_ROOT / "docs"
NOTEBOOKS_DIR: Path = PROJECT_ROOT / "notebooks"
# Ensure standard directories exist (idempotent)
for _d in (DATA_DIR, MODELS_DIR, RESULTS_DIR, DOCS_DIR):
_d.mkdir(parents=True, exist_ok=True)
# ---------------------------------------------------------------------------
# Logging
# ---------------------------------------------------------------------------
def get_logger(name: str, level: int = logging.INFO) -> logging.Logger:
"""Return a configured logger with a consistent format across modules.
Parameters
----------
name : str
Logger name, usually `__name__` from the calling module.
level : int
Logging level (default: INFO).
"""
logger = logging.getLogger(name)
if not logger.handlers:
handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(
logging.Formatter(
fmt="%(asctime)s | %(name)s | %(levelname)s | %(message)s",
datefmt="%H:%M:%S",
)
)
logger.addHandler(handler)
logger.setLevel(level)
logger.propagate = False
return logger
# ---------------------------------------------------------------------------
# Reproducibility
# ---------------------------------------------------------------------------
def set_seed(seed: int = 42) -> None:
"""Seed all RNGs we use (Python, NumPy, optional PyTorch/TF)."""
random.seed(seed)
np.random.seed(seed)
os.environ["PYTHONHASHSEED"] = str(seed)
try:
import torch
torch.manual_seed(seed)
if torch.cuda.is_available():
torch.cuda.manual_seed_all(seed)
except ImportError:
pass
try:
import tensorflow as tf
tf.random.set_seed(seed)
except ImportError:
pass
# ---------------------------------------------------------------------------
# Convenience
# ---------------------------------------------------------------------------
def human_bytes(n: int) -> str:
"""Format a byte count as KB/MB/GB."""
for unit in ("B", "KB", "MB", "GB"):
if n < 1024:
return f"{n:.1f} {unit}"
n /= 1024
return f"{n:.1f} TB"
if __name__ == "__main__":
log = get_logger("utils")
log.info(f"PROJECT_ROOT = {PROJECT_ROOT}")
log.info(f"DATA_DIR = {DATA_DIR}")
log.info(f"MODELS_DIR = {MODELS_DIR}")
log.info(f"RESULTS_DIR = {RESULTS_DIR}")