Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
83aefda
Feat/vendored opencode binary (#299)
guillaume-byte Aug 26, 2026
454d039
Fix/v2.1 UI fixes (#300)
guillaume-byte Aug 26, 2026
40ad072
fix CI core dumped
guillaume-byte Aug 26, 2026
0ed0500
fix stucked CI
guillaume-byte Aug 26, 2026
9e9820a
Deselect scale tests from the fast CI job; cap test job at 15 minutes
guillaume-byte Aug 26, 2026
4728db2
Update CHANGELOG - v2.0.1.dev0
guillaume-byte Aug 26, 2026
87f19ae
Merge branch 'main' into dev
guillaume-byte Aug 26, 2026
328e46e
refactor(examples): one import surface — `import weightslab as wl`
guillaume-byte Sep 4, 2026
3c8c1b4
Resolve MConflicts And merge main to dev
guillaume-byte Sep 6, 2026
c74dc0e
Merge main into dev: docs sidebar tree, UL example rework, label fixes
guillaume-byte Sep 8, 2026
c25bd45
fix(notebook): keep the trainer's stdout out of notebook cell outputs…
guillaume-byte Sep 10, 2026
b0347d3
Interactivity on 100GB+ datasets: O(change) view sync and ledger writ…
AlexGrayBox Sep 10, 2026
0ab50a9
test: fix the four failures in the unit suite
guillaume-byte Sep 10, 2026
5cd4920
Fix Ultralytics issue with v8.*
guillaume-byte Sep 11, 2026
57c7218
video: advertise playable media by media_kind, and budget the clip cache
guillaume-byte Sep 12, 2026
bc5559f
video: draw the poster frame's annotation, and stop the preview cache
guillaume-byte Sep 12, 2026
0d1ed61
eval: put the batch where the model is, and stop one bad signal killi…
guillaume-byte Sep 12, 2026
d8af51d
agent: report the live model, so the studio and the CLI agree on it
guillaume-byte Sep 13, 2026
08f4f4b
opencode: one server per machine, so the studio and the backend share…
guillaume-byte Sep 13, 2026
ac40533
Merge branch 'main' into dev
guillaume-byte Sep 22, 2026
d2d96ec
projection: show the representation the model is learning, live
guillaume-byte Sep 22, 2026
6b1d58f
notebook: let a code generation survive a browser refresh
guillaume-byte Sep 22, 2026
fe6145e
loop: stop the check-in a loop is running, not just its next one
guillaume-byte Sep 22, 2026
e6d29bf
eval: cover the default-device placement with a test
guillaume-byte Sep 22, 2026
a2b8902
test: fix the gRPC serve flake that failed CI with identical code
guillaume-byte Sep 22, 2026
caa1d74
fix(notebook): shut the embedded kernel down instead of aborting at exit
guillaume-byte Sep 23, 2026
e9f7f23
fix utest error
guillaume-byte Sep 25, 2026
9927abc
update cls example with basic CNN 1M parameters
guillaume-byte Sep 25, 2026
b2c23fa
fix chkpt restoring from several root dirs
guillaume-byte Sep 25, 2026
0b13524
fix cls example
guillaume-byte Sep 25, 2026
21fcb4d
se/start: OS-aware cert generation, certs dir fallback, CLI help + do…
guillaume-byte Sep 29, 2026
9078eb3
logs: terminal/file split, survive dictConfig, tqdm mirror; rewind sa…
guillaume-byte Oct 1, 2026
91495d4
Fix certs generation for encrypted communication
guillaume-byte Oct 1, 2026
7ee87b8
Remove useless logs, redundant, and fix dataloader indexing related t…
guillaume-byte Oct 1, 2026
be170bf
Update documentation
guillaume-byte Oct 1, 2026
bef1702
fix related utests with recent bugs fixed and changes
guillaume-byte Oct 1, 2026
1fd1e9c
fix dataloader pinmemory failing test
guillaume-byte Oct 1, 2026
804d235
fix UI plots points budgets
guillaume-byte Oct 1, 2026
476b927
fix test
guillaume-byte Oct 1, 2026
2097c02
Fix pytest timeout, too short
guillaume-byte Oct 1, 2026
df74096
[skip ci] Fix Claude artefacts from doc and add quickstart migration
guillaume-byte Oct 1, 2026
cffe256
[skip ci] Comment auto start training for the examples
guillaume-byte Oct 1, 2026
8dcb81a
Merge branch 'dev' of https://github.com/GrayboxTech/weightslab into …
guillaume-byte Oct 6, 2026
f9638eb
projection: serve any view of 10M samples, and bring your own projection
guillaume-byte Oct 6, 2026
d4e1a1f
tests: stop the suite's cross-test leaks, and fix what they exposed
guillaume-byte Oct 6, 2026
0b6b714
Merge branch 'feature/parametric-umap' into dev
guillaume-byte Oct 6, 2026
1dbf98a
Feature/parametric umap (#310)
guillaume-byte Oct 7, 2026
4e2a30e
remove artefacts files
guillaume-byte Oct 7, 2026
6962226
release tests: restore the OpenCode modules, and make logging survive…
guillaume-byte Oct 7, 2026
2bcc4ef
release: write weightslab/VERSION before building, not only after
guillaume-byte Oct 7, 2026
3652f6f
release: weightslab/VERSION -> 2.0.3.dev0 [skip ci]
guillaume-byte Oct 7, 2026
2a68646
Update Changelog
guillaume-byte Oct 9, 2026
8048e90
release: weightslab/VERSION -> 2.0.3.dev2 [skip ci]
github-actions[bot] Oct 9, 2026
d488cf6
release: v2.0.3.dev3
guillaume-byte Oct 9, 2026
9c2d3b5
release: weightslab/VERSION -> 2.0.3.dev3 [skip ci]
github-actions[bot] Oct 9, 2026
80eea70
release: v2.0.3.dev4
guillaume-byte Oct 10, 2026
522408a
release: weightslab/VERSION -> 2.0.3.dev4 [skip ci]
github-actions[bot] Oct 10, 2026
6ab7ffa
release: v2.0.3.dev5
guillaume-byte Oct 10, 2026
4d185d4
release: weightslab/VERSION -> 2.0.3.dev5 [skip ci]
github-actions[bot] Oct 10, 2026
828e517
Merge branch 'main' into dev
guillaume-byte Oct 13, 2026
84d0292
test: drop the README sandbox-link check
guillaume-byte Oct 13, 2026
cb2286c
fix: exit cleanly after the embedded notebook kernel; quiet the test …
guillaume-byte Oct 13, 2026
60145d0
Merge branch 'main' into dev
guillaume-byte Oct 13, 2026
8e0694f
release: weightslab/VERSION -> 2.0.3.dev6 [skip ci]
github-actions[bot] Oct 14, 2026
171d668
projection: hook the last parameterised layer, so the LiDAR examples …
guillaume-byte Oct 14, 2026
1eaec85
Merge branch 'main' into dev
guillaume-byte Oct 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 119 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,16 @@ jobs:
echo "publish_version=${PUBLISH_VERSION}" >> $GITHUB_OUTPUT
echo "Tag ${GITHUB_REF_NAME} @ ${SHORT_SHA_HEX} -> TestPyPI version ${PUBLISH_VERSION}"

# The packaged weightslab/VERSION states the version being published, so
# the artifact agrees with itself before it is uploaded (the commit back
# to dev/main is sync-version-file's job, after the release).
- name: Write weightslab/VERSION
env:
PUBLISH_VERSION: ${{ steps.compute_version.outputs.publish_version }}
run: |
printf '%s\n' "${PUBLISH_VERSION}" > weightslab/VERSION
echo "weightslab/VERSION -> $(cat weightslab/VERSION)"

- name: Build distributions
env:
SETUPTOOLS_SCM_PRETEND_VERSION_FOR_WEIGHTSLAB: ${{ steps.compute_version.outputs.publish_version }}
Expand Down Expand Up @@ -608,7 +618,24 @@ jobs:
- name: Install build tools
run: python -m pip install --upgrade pip build twine

# The packaged weightslab/VERSION states the version being published:
# the tag's own, PEP 440-normalized (v2.0.3 -> 2.0.3). The commit back to
# main/dev is sync-version-file's job, after the release.
#
# The build is then pinned to that same version. Writing the file dirties
# the checkout, and setuptools_scm's guess-next-dev turns a dirty tree at
# a tag into the NEXT dev version (2.0.4.dev0) instead of the tag's.
- name: Write weightslab/VERSION
id: release_version
run: |
VERSION="$(python -c 'import os; from packaging.version import Version; print(Version(os.environ["GITHUB_REF_NAME"]))')"
printf '%s\n' "${VERSION}" > weightslab/VERSION
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "weightslab/VERSION -> ${VERSION}"

- name: Build distributions
env:
SETUPTOOLS_SCM_PRETEND_VERSION_FOR_WEIGHTSLAB: ${{ steps.release_version.outputs.version }}
run: python -m build

- name: Capture version from wheel
Expand Down Expand Up @@ -931,3 +958,95 @@ jobs:
files: dist/*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

# ═══════════════════════════════════════════════════════════════════════════
# VERSION FILE SYNC — after either release, commit the tag's version into
# weightslab/VERSION: on main AND dev for a main release, on dev only for a
# dev release (a dev version never lands on main this way).
# ═══════════════════════════════════════════════════════════════════════════
# weightslab/VERSION is the last-resort source of weightslab.__version__ (and
# so of the telemetry version): read only when there is no git metadata, no
# setuptools_scm-built _version.py and no installed dist metadata. It never
# overrides a git-derived version, so builds and checkouts are unaffected.
#
# main and dev both reject direct pushes (PR + status-check rulesets) unless
# the pusher is a ruleset bypass actor, which GITHUB_TOKEN is not — hence
# VERSION_SYNC_TOKEN: a token of a bypass actor with contents:write on this
# repo. "[skip ci]" stops that push from re-triggering ci.yml/docs-pages.yml
# (a PAT push triggers workflows, a GITHUB_TOKEN push would not), which would
# otherwise run a TestPyPI publish for the push to main.
sync-version-file:
name: Sync weightslab/VERSION
needs: [detect-target, create-dev-release, create-main-release]
# !cancelled(): exactly one of the two release jobs is skipped on any tag.
if: ${{ !cancelled() && (needs.create-main-release.result == 'success' || needs.create-dev-release.result == 'success') }}
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Require the push token
env:
VERSION_SYNC_TOKEN: ${{ secrets.VERSION_SYNC_TOKEN }}
run: |
if [ -z "${VERSION_SYNC_TOKEN}" ]; then
echo "::error::VERSION_SYNC_TOKEN is not set; main/dev reject pushes from GITHUB_TOKEN, so weightslab/VERSION was not updated for ${GITHUB_REF_NAME}. The release itself is published."
exit 1
fi

- uses: actions/setup-python@v6
with:
python-version: '3.11'

# PEP 440-normalized, so the file holds what a build of the tag reports:
# v2.0.2 -> 2.0.2, v1.3.1-dev0 -> 1.3.1.dev0.
- name: Compute version and target branches
id: target
env:
IS_MAIN: ${{ needs.detect-target.outputs.is_main }}
run: |
set -euo pipefail
python -m pip install --quiet packaging
VERSION="$(python -c 'import os; from packaging.version import Version; print(Version(os.environ["GITHUB_REF_NAME"]))')"
BRANCHES="dev"
if [ "${IS_MAIN}" = "true" ]; then
BRANCHES="main dev"
fi
echo "version=${VERSION}" >> $GITHUB_OUTPUT
echo "branches=${BRANCHES}" >> $GITHUB_OUTPUT
echo "Tag ${GITHUB_REF_NAME} -> weightslab/VERSION=${VERSION} on: ${BRANCHES}"

- uses: actions/checkout@v4
with:
token: ${{ secrets.VERSION_SYNC_TOKEN }}

# Each branch is rewritten from its fresh tip; a push rejected because the
# branch moved meanwhile is retried on the new tip rather than rebased.
- name: Commit weightslab/VERSION
env:
VERSION: ${{ steps.target.outputs.version }}
BRANCHES: ${{ steps.target.outputs.branches }}
run: |
set -euo pipefail
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
for BRANCH in ${BRANCHES}; do
for attempt in 1 2 3; do
git fetch --depth=1 origin "${BRANCH}"
git checkout -q -B "${BRANCH}" FETCH_HEAD
printf '%s\n' "${VERSION}" > weightslab/VERSION
git add weightslab/VERSION
if git diff --cached --quiet; then
echo "${BRANCH}: weightslab/VERSION is already ${VERSION}"
continue 2
fi
git commit -q -m "release: weightslab/VERSION -> ${VERSION} [skip ci]"
if git push origin "HEAD:${BRANCH}"; then
echo "${BRANCH}: weightslab/VERSION -> ${VERSION}"
continue 2
fi
echo "Push to ${BRANCH} rejected (attempt ${attempt}/3); retrying on its new tip"
sleep 5
done
echo "::error::Could not push weightslab/VERSION to ${BRANCH}"
exit 1
done
13 changes: 13 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ Conventions that matter for correctness:
and pause/resume or stats will misbehave.**
- Use `model.get_age()` (steps actually trained; survives checkpoint reloads),
not the raw loop counter.
- Pause from code with `wl.pause_training()` (the counterpart of
`wl.start_training()`): the next guarded step waits for Play. Running a cell
in the Studio notebook pauses training the same way, and it stays paused.
- `task_type` on the dataset/model selects rendering: `classification`,
`segmentation`, `detection`, `detection_pointcloud`.
- **Hyperparameter handle access:** the registered hyperparameters proxy
Expand All @@ -143,6 +146,7 @@ Recording values (pick by what the value is *about*, not by convenience):
| one annotation | `wl.save_instance_signals(...)` | one box's IoU |
| a group of samples | `wl.save_group_signals(signals={...}, group_ids=[...])` | a pair's contrastive loss |
| one training **step** | `wl.save_model_signals(signals={...})` | a gradient norm |
| a sample's place in a 2-D/3-D **projection** | `wl.save_projection_coords(coords, batch_ids=ids, prefix="tsne")` | your own t-SNE / umap-learn layout |

The first three write dataframe rows (sortable/filterable in the grid); the
fourth only plots a curve. Never fake a step-level value by broadcasting it
Expand Down Expand Up @@ -189,6 +193,7 @@ ones when debugging:
| `GRPC_MAX_MESSAGE_BYTES` | `268435456` (256 MB) | Raise it if large tensors/image batches fail. |
| `WEIGHTSLAB_DISABLE_WATCHDOGS` | `0` | Set `1` when debugging with breakpoints (see §5). |
| `GRPC_WATCHDOG_STUCK_SECONDS` | `60` | Lock/RPC stuck threshold + lock-acquire timeout. |
| `WEIGHTSLAB_PROJECTION` | on | Live 3-D parametric-UMAP projection (beta). `0` removes it; per model: `watch_or_edit(model, flag="model", projection=False)`. Tuning: `_EVERY`, `_DIM`, `_NEIGHBORS`, `_GRAPH` — see `docs/projection.rst`. |

**Frontend (Weights Studio) — runtime-injected `window.*` globals:**

Expand Down Expand Up @@ -265,6 +270,14 @@ The train step isn't wrapped in `guard_training_context` (or eval in
`guard_testing_context`). See §3 — these context managers are how the system
gates and separates phases.

**Projection board stays empty, or stopped updating.** `wl.projection.get_tracker()`
is `None` when it is off (`WEIGHTSLAB_PROJECTION=0` or `projection=False`).
Otherwise `.stats()` says why: `fits == 0` means the hooked layer is not on the
forward path (pass `projection={"layer": "<named_modules() name>"}`);
`disabled_reason` is set when 5 fits in a row failed and it turned itself off;
`skipped_nonfinite > 0` means the model's features went NaN. Training is never
affected by any of these. Full page: `weightslab/docs/projection.rst`.

**Large weights/images fail to transfer.** Raise `GRPC_MAX_MESSAGE_BYTES`.

**The agent bar says it's unconfigured.** The LLM agent needs a provider: a
Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
# Changelog - 2026-10-01 v2.0.2
# Changelog - 2026-10-09 v2.0.3.dev2
18 changes: 0 additions & 18 deletions docs/_static/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -110,24 +110,6 @@ body[data-theme="dark"] .wl-only-dark {
background: rgba(120, 120, 120, 0.12);
}

/* Sandbox CTA -- warm gradient built on the #f0a500 accent used elsewhere in
the docs chrome, so the external "try it now" link reads as distinct from
the in-docs Quickstart/Examples buttons without leaving the palette. */
.wl-hero-cta-sandbox,
.wl-hero-cta-sandbox:link,
.wl-hero-cta-sandbox:visited,
.wl-hero-cta-sandbox:active,
.wl-hero-cta-sandbox:focus {
background: linear-gradient(135deg, #f0a500 0%, #e2681c 100%) !important;
border-color: #e2871a !important;
color: #ffffff !important;
}

.wl-hero-cta-sandbox:hover {
background: linear-gradient(135deg, #ffb61f 0%, #f07a2b 100%) !important;
border-color: #f0951f !important;
}

.wl-version-switcher {
display: inline-flex;
align-items: center;
Expand Down
14 changes: 14 additions & 0 deletions docs/_static/examples-gallery.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@
url: 'examples/pytorch/classification.html',
colab: COLAB + 'PyTorch/wl-classification.ipynb'
},
{
badge: 'PyTorch', color: 'pytorch',
title: 'Classification, Fashion-MNIST + UMAP',
desc: 'Train with the live parametric UMAP, reload the 1000-step weights, discard the lowest-loss samples, then compare a PCA you write yourself with the UMAP.',
tags: ['classification', 'fashion-mnist', 'projection', 'umap', 'pca', 'checkpoint', 'beta'],
url: 'examples/pytorch/fashion_mnist_umap.html'
},
{
badge: 'PyTorch', color: 'pytorch',
title: 'Segmentation, BDD100k',
Expand Down Expand Up @@ -90,6 +97,13 @@
desc: 'Per-step training dynamics: global and per-layer gradient norms, weight norms and activation statistics, from one argument on the model wrap.',
tags: ['model signals', 'gradient norm', 'activations', 'per-layer', 'training dynamics'],
url: 'examples/usecases/model_signals.html'
},
{
badge: 'Usecase', color: 'usecase',
title: 'Projections, Fashion-MNIST',
desc: 'The built-in live UMAP while training, then a run that pauses itself at convergence and plugs a notebook-written t-SNE into the Projection Board.',
tags: ['projection', 'umap', 't-sne', 'notebook', 'beta'],
url: 'examples/usecases/projection_fashion_mnist.html'
}
];

Expand Down
Binary file added docs/_static/screenshots/projection-board.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/agent.rst
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ Remote provider, OpenRouter
- Ask for a schema-validated plan instead of free-form JSON + repair. More
reliable, but only on routes that support JSON-schema output (Gemini, GPT-4o).
* - ``fallback_to_local``
- —
- (none)
- ``true`` (the shipped ``agent_config.yaml`` sets ``false``)
- Also set up Ollama, so a failing/absent cloud key still leaves a working agent.

Expand Down
61 changes: 50 additions & 11 deletions docs/build_docs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,42 @@ set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT_DIR"

# The interpreter: PYTHON_BIN, else the activated venv, else the first Python on
# PATH that can build -- one that already has Sphinx, or has pip to install it.
#
# The .exe names matter on Windows: from PowerShell, `bash` is WSL's bash, where
# python3 is often a Linux Python with no pip, while the venv activated in that
# PowerShell is reachable only as python.exe (WSL runs Windows programs by their
# full name). Every path handed to the interpreter below is relative to
# ROOT_DIR, so a Windows Python never sees a /mnt/c/... path.
can_build() {
"$@" -c "import sphinx, furo, myst_parser, sphinx_design, sphinxcontrib.mermaid" >/dev/null 2>&1 ||
"$@" -m pip --version >/dev/null 2>&1
}

PYTHON_CMD=()
if [[ -n "${PYTHON_BIN:-}" ]]; then
PYTHON_CMD=("$PYTHON_BIN")
elif command -v python3 >/dev/null 2>&1; then
PYTHON_CMD=(python3)
elif command -v python >/dev/null 2>&1; then
PYTHON_CMD=(python)
elif command -v py >/dev/null 2>&1; then
PYTHON_CMD=(py -3)
else
echo "[weightslab-docs] ERROR: no Python interpreter found in PATH."
echo "[weightslab-docs] Set PYTHON_BIN explicitly and retry."
candidates=()
if [[ -n "${VIRTUAL_ENV:-}" ]]; then
candidates+=("$VIRTUAL_ENV/bin/python" "$VIRTUAL_ENV/Scripts/python.exe")
fi
candidates+=("python3" "python" "py -3" "python.exe" "py.exe -3")
for candidate in "${candidates[@]}"; do
read -r -a cmd <<< "$candidate"
if command -v "${cmd[0]}" >/dev/null 2>&1 && can_build "${cmd[@]}"; then
PYTHON_CMD=("${cmd[@]}")
break
fi
done
fi

if [[ ${#PYTHON_CMD[@]} -eq 0 ]]; then
echo "[weightslab-docs] ERROR: no Python with Sphinx or pip found in PATH"
echo "[weightslab-docs] (tried python3, python, py, python.exe, py.exe)."
echo "[weightslab-docs] Set PYTHON_BIN to one and retry, e.g.:"
echo " PYTHON_BIN=/path/to/venv/bin/python bash docs/build_docs.sh"
exit 1
fi

Expand Down Expand Up @@ -69,8 +94,22 @@ fi
DOCS_HOST="${WEIGHTSLAB_DOCS_HOST:-127.0.0.1}"
DOCS_PORT_REQUESTED="${WEIGHTSLAB_DOCS_PORT:-8000}"

# Serving needs only the standard library. When the build ran on a Windows
# python.exe from WSL, a native Python serves instead if there is one: `kill`
# from this shell cannot reliably stop a Windows process, so Ctrl+C would leave
# the server running.
SERVE_CMD=("${PYTHON_CMD[@]}")
if [[ "${PYTHON_CMD[0]}" == *.exe ]]; then
for candidate in python3 python; do
if command -v "$candidate" >/dev/null 2>&1 && "$candidate" -c "import http.server" >/dev/null 2>&1; then
SERVE_CMD=("$candidate")
break
fi
done
fi

# Pick the requested port, or the first free one above it.
DOCS_PORT="$("${PYTHON_CMD[@]}" - "$DOCS_HOST" "$DOCS_PORT_REQUESTED" <<'PY' || true
DOCS_PORT="$("${SERVE_CMD[@]}" - "$DOCS_HOST" "$DOCS_PORT_REQUESTED" <<'PY' || true
import socket
import sys

Expand Down Expand Up @@ -110,7 +149,7 @@ cleanup() {
trap cleanup EXIT INT TERM

echo "[weightslab-docs] Serving $HTML_DIR at $DOCS_URL"
"${PYTHON_CMD[@]}" -m http.server "$DOCS_PORT" --bind "$DOCS_HOST" --directory "$HTML_DIR" >/dev/null 2>&1 &
"${SERVE_CMD[@]}" -m http.server "$DOCS_PORT" --bind "$DOCS_HOST" --directory docs/_build/html >/dev/null 2>&1 &
SERVER_PID=$!

# Wait for the socket to accept connections before pointing a browser at it.
Expand All @@ -119,7 +158,7 @@ for _ in $(seq 1 100); do
if ! kill -0 "$SERVER_PID" 2>/dev/null; then
break
fi
if "${PYTHON_CMD[@]}" - "$DOCS_HOST" "$DOCS_PORT" <<'PY' >/dev/null 2>&1
if "${SERVE_CMD[@]}" - "$DOCS_HOST" "$DOCS_PORT" <<'PY' >/dev/null 2>&1
import socket
import sys

Expand Down
2 changes: 1 addition & 1 deletion docs/checkpointing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Directory structure
``root_log_dir`` comes from the top-level ``root_log_dir`` key in your
hyperparameters config (or the ``root_log_dir=`` kwarg on
``wl.watch_or_edit(..., flag="model"/"data"/...)`` for a per-object override)
— see :doc:`configuration`.
, see :doc:`configuration`.

The experiment hash
--------------------
Expand Down
Loading
Loading