anilegin's picture
Upload inference-only latent diffusion model
a04730e verified
Raw
History Blame Contribute Delete
1.98 kB
from __future__ import annotations
from pathlib import Path
from typing import Any
import yaml
def load_yaml(path: str | Path) -> dict[str, Any]:
path = Path(path)
with open(path, "r", encoding="utf-8") as f:
return yaml.safe_load(f)
def deep_update(base: dict, update: dict) -> dict:
"""
Recursively merge update into base.
"""
for key, value in update.items():
if (
key in base
and isinstance(base[key], dict)
and isinstance(value, dict)
):
deep_update(base[key], value)
else:
base[key] = value
return base
def load_config(config_path: str | Path) -> dict[str, Any]:
"""
Load a config file and recursively merge files listed under `defaults`.
Example:
defaults:
- ../paths.yaml
- ../data/coco_256.yaml
"""
config_path = Path(config_path)
cfg = load_yaml(config_path)
merged: dict[str, Any] = {}
defaults = cfg.pop("defaults", [])
for default_path in defaults:
default_file = (config_path.parent / default_path).resolve()
default_cfg = load_config(default_file)
merged = deep_update(merged, default_cfg)
merged = deep_update(merged, cfg)
return merged
def get_by_key(cfg: dict[str, Any], key: str) -> Any:
"""
Get nested config value using dot notation.
Example:
get_by_key(cfg, "data.coco_root")
"""
value: Any = cfg
for part in key.split("."):
value = value[part]
return value
def resolve_path_key(cfg: dict[str, Any], key: str) -> Path:
"""
Resolve a path stored in config using dot notation.
"""
return Path(get_by_key(cfg, key)).expanduser().resolve()
def save_yaml(data: dict, path: str | Path) -> None:
path = Path(path)
path.parent.mkdir(parents=True, exist_ok=True)
with open(path, "w", encoding="utf-8") as f:
yaml.safe_dump(data, f, sort_keys=False)