- config: yaml `_base_` 继承 + 深度合并 + 命令行 `--set a.b.c=value` 覆盖,检测循环引用 - registry: 组件按名注册与构建,模型/数据集共用 - device: require_cuda() 守卫,按 CLAUDE.md 约定禁止在无 Nvidia GPU 的设备上训练; 评估与导出走 resolve_device() 允许 CPU - labels: multilabel / multiclass 两种图像级标签形式的共用定义 - logging / seed: 控制台+文件日志、随机种子与 cudnn 确定性 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
37 lines
1.0 KiB
Python
37 lines
1.0 KiB
Python
"""日志:控制台 + 可选文件输出。"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import logging
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
_FORMAT = "[%(asctime)s][%(levelname)s][%(name)s] %(message)s"
|
|
_DATEFMT = "%Y-%m-%d %H:%M:%S"
|
|
|
|
|
|
def setup_logging(log_file: str | Path | None = None, level: int | str = logging.INFO) -> logging.Logger:
|
|
root = logging.getLogger("mte")
|
|
root.setLevel(level)
|
|
root.handlers.clear()
|
|
root.propagate = False
|
|
|
|
formatter = logging.Formatter(_FORMAT, datefmt=_DATEFMT)
|
|
|
|
stream = logging.StreamHandler(sys.stdout)
|
|
stream.setFormatter(formatter)
|
|
root.addHandler(stream)
|
|
|
|
if log_file is not None:
|
|
path = Path(log_file)
|
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
file_handler = logging.FileHandler(path, encoding="utf-8")
|
|
file_handler.setFormatter(formatter)
|
|
root.addHandler(file_handler)
|
|
|
|
return root
|
|
|
|
|
|
def get_logger(name: str = "mte") -> logging.Logger:
|
|
return logging.getLogger(name if name.startswith("mte") else f"mte.{name}")
|