runyard is a self-hosted tracker for ML and deep learning runs: status, metrics, samples, logs and checkpoints in a phone-first web UI, notifications when a run finishes, fails or goes silent, and an MCP server so agents can read everything. Far fewer features than W&B or MLflow, on purpose.
Run the server with Docker Compose. One Go binary and PostgreSQL; media and artifacts go to a directory or an S3/R2 bucket.
# server
git clone https://github.com/cobanov/runyard && cd runyard
docker compose up -d --build
docker compose exec app /runyard-server key create my-laptop
Log from Python in three lines. Calls are queued and sent from a background thread, so the library never stops training.
# training script import runyard as ry run = ry.init(project="my-project", config={"lr": 3e-4}) run.log({"loss": loss.item()}, step=step) run.image("samples", grid, step=step) run.alert("loss is NaN", level="error")
Three lines of Python, or no code change at all from tools that speak Weights & Biases, TensorBoard or MLflow. Integrations for transformers, TRL, Accelerate, Lightning, Keras, XGBoost, LightGBM, scikit-learn and torchtune.
A phone-first web UI with live charts, samples, logs and config diffs between runs. A CLI with --json, and an MCP server so coding agents can read runs and alerts.
ntfy, Slack, Discord, Telegram, a webhook or web push to the installed app. Checks raise alerts from the data: a NaN loss, a crossed threshold, a stuck run.
GPU utilisation, memory, temperature and power per host from the runs themselves, next to CPU and RAM. One glance says what is training and how the machine is doing.
PostgreSQL, a media directory or an S3-compatible bucket, optional users and teams. Reach it over Tailscale, a tunnel, or bind it to a port.
A clean exit marks a run finished, an exception failed, and five minutes without a heartbeat crashed. What could not be sent is saved at exit for runyard sync.