loratop A developer released loratop, a small terminal UI monitor for tracking LoRA training runs in Ostris AI Toolkit. The tool reads a run's loss_log.db or parses loss, step and learning-rate values from tqdm training output, rendering loss and learning-rate graphs that adapt to narrow terminals and fall back to a sparkline when the optional plotext dependency is unavailable. It is Linux-only, locating the running trainer via /proc, and can be pointed at a run folder, a training log, or a trainer PID. | | /usr/bin/env -S uv run --script | | | SPDX-License-Identifier: MIT | | | /// script | | | dependencies = "rich", "plotext<6" plotext 6 dropped clf/plotsize/build | | | /// | | | """ | | | loratop - a tiny TUI monitor for Ostris AI Toolkit LoRA training. | | | It reads a run's loss log.db ai-toolkit writes it when logging.use ui logger | | | is true or, failing that, parses loss/step/lr from the tqdm output in a | | | training log. It renders loss and lr graphs under two lines of progress. | | | Designed to be readable on tiny screens, so it adapts to narrow terminals | | | and degrades gracefully when optional deps are missing. | | | Linux only: finding the trainer reads /proc. | | | Usage | | | ----- | | | loratop the run in this folder, else the one running trainer | | | loratop output/my lora a run folder: reads its loss log.db, live or finished | | | loratop train.log a training log python run.py cfg train.log 2 &1 | | | loratop 12345 a running trainer's PID: its loss log.db, else its log | | | Run it with uv uv run loratop.py , or chmod +x it and put it on your PATH | | | as loratop. | | | Deps plotext optional, falls back to a sparkline : | | | rich, plotext. Declared inline above, so uv installs them on first run. | | | """ | | | import argparse | | | import os | | | import re | | | import select | | | import shutil | | | import signal | | | import sqlite3 | | | import sys | | | import termios | | | import time | | | import tty | | | from collections import deque | | | ---- optional dependencies ------------------------------------------------- | | | try: | | | import plotext as plt | | | if not hasattr plt, "clf" : plotext 6+: fall back to the sparkline | | | plt = None | | | except ImportError: | | | plt = None | | | try: | | | from rich.console import Console, Group | | | from rich.live import Live | | | from rich.panel import Panel | | | from rich.table import Table | | | from rich.text import Text | | | except ImportError: | | | sys.exit "loratop needs 'rich': run it with uv, or pip install rich" | | | ---- parsing patterns tweak these if your log format differs ------------- | | | matches "loss: 0.0823", "loss=1.2e-01", "avg loss 0.05", etc. | | | RE LOSS = re.compile r"loss =:\s + 0-9 \.? 0-9 + ?: eE -+ ? 0-9 + ? ", re.I | | | matches the tqdm " 500/10000" current/total fragment | | | RE STEP = re.compile r" \d+ \s /\s \d+ " | | | matches "lr: 1.0e-04" | | | RE LR = re.compile r"lr =:\s + 0-9 \.? 0-9 + ?: eE -+ ? 0-9 + ? ", re.I | | | tqdm's own " elapsed