feat(utils): 配置继承、注册表、日志与 Nvidia GPU 守卫
- 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>
This commit is contained in:
co-authored by
Claude Opus 5
parent
0645fc19f7
commit
f4eff8beee
@@ -0,0 +1,50 @@
|
||||
"""极简注册表:按名字注册 / 构建模型、数据集等组件。"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable, Iterator
|
||||
from typing import Any, TypeVar
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
|
||||
class Registry:
|
||||
def __init__(self, name: str) -> None:
|
||||
self.name = name
|
||||
self._entries: dict[str, Callable[..., Any]] = {}
|
||||
|
||||
def register(self, name: str | None = None) -> Callable[[T], T]:
|
||||
"""装饰器;`name` 缺省时使用被装饰对象的 __name__。"""
|
||||
|
||||
def wrapper(obj: T) -> T:
|
||||
key = name or getattr(obj, "__name__", None)
|
||||
if key is None:
|
||||
raise ValueError(f"无法推断注册名: {obj!r}")
|
||||
if key in self._entries:
|
||||
raise KeyError(f"{self.name} 中已存在同名条目: {key}")
|
||||
self._entries[key] = obj # type: ignore[assignment]
|
||||
return obj
|
||||
|
||||
return wrapper
|
||||
|
||||
def get(self, name: str) -> Callable[..., Any]:
|
||||
if name not in self._entries:
|
||||
raise KeyError(f"{self.name} 中找不到 '{name}',可用: {sorted(self._entries)}")
|
||||
return self._entries[name]
|
||||
|
||||
def build(self, cfg: dict, **kwargs: Any) -> Any:
|
||||
"""按 `{"name": ..., 其余作为构造参数}` 构建对象。"""
|
||||
cfg = dict(cfg)
|
||||
name = cfg.pop("name", None)
|
||||
if name is None:
|
||||
raise KeyError(f"构建 {self.name} 需要 'name' 字段: {cfg}")
|
||||
return self.get(name)(**{**cfg, **kwargs})
|
||||
|
||||
def __contains__(self, name: object) -> bool:
|
||||
return name in self._entries
|
||||
|
||||
def __iter__(self) -> Iterator[str]:
|
||||
return iter(self._entries)
|
||||
|
||||
def __len__(self) -> int:
|
||||
return len(self._entries)
|
||||
Reference in New Issue
Block a user