tiny-llm / src /tinyllm /logger.py
CoolDip00's picture
tiny-llm 75e4579: 6.5b step 5: 5a Space created, 5b secrets added
d656a30 verified
Raw History Blame Contribute Delete
2.14 kB
"""Experiment logging behind one small interface (D-013).
The training loop only calls log / log_sample / finish. Switching backend (W&B now,
TensorBoard as the fallback) means adding one class here. Only scalars and text
samples are logged, never checkpoints (W&B Free plan: 5 GB/month).
W&B login happens once, inside WSL: `uv run wandb login`. The key goes to ~/.netrc,
never into the repo.
"""
class Logger:
"""No-op logger (logger="none"): used by the tests and for quick local runs."""
run_id: str | None = None
def log(self, metrics: dict[str, float], step: int) -> None:
pass
def log_sample(self, text: str, step: int) -> None:
pass
def finish(self) -> None:
pass
class WandbLogger(Logger):
def __init__(self, project: str, name: str, config: dict, mode: str = "online",
run_id: str | None = None, dir: str | None = None):
import wandb # imported lazily: the "none" logger never needs it
self._wandb = wandb
# Passing the stored run id on resume continues the same W&B run (same charts).
self.run = wandb.init(project=project, name=name, config=config, mode=mode,
id=run_id, resume="allow" if run_id else None, dir=dir)
self.run_id = self.run.id
self._samples: list[list] = []
def log(self, metrics: dict[str, float], step: int) -> None:
self.run.log(metrics, step=step)
def log_sample(self, text: str, step: int) -> None:
# W&B tables are immutable, so re-log the growing table: one row per eval.
self._samples.append([step, text])
self.run.log({"samples": self._wandb.Table(columns=["step", "text"], data=self._samples)},
step=step)
def finish(self) -> None:
self.run.finish()
def make_logger(backend: str, **kwargs) -> Logger:
"""kwargs are WandbLogger arguments; the no-op logger ignores them."""
if backend == "none":
return Logger()
if backend == "wandb":
return WandbLogger(**kwargs)
raise ValueError(f"unknown logger {backend!r}; use 'wandb' or 'none'")